Removed JAI

Removed JAI, added CODI AI.  Fixed encounters & NPCs in Forest of Hope Central.  Fixed Outcast store not opening.  Added Druid Grove & associated NPCS.
This commit is contained in:
Jaysyn904
2022-12-04 01:43:33 -05:00
parent 9a3a98bf52
commit f143ccfc24
353 changed files with 136542 additions and 85666 deletions

View File

@@ -0,0 +1,242 @@
//::///////////////////////////////////////////////
//:: Name drusilla_ondeath
//:: Copyright (c) 2022 Project RATDOG
//:://////////////////////////////////////////////
/*
Drusilla the Druid's OnDeath script
*/
//:://////////////////////////////////////////////
//:: Created By: Jaysyn
//:: Created On: 20221129
//:://////////////////////////////////////////////
#include "sql_db_partywide"
#include "pqj_inc"
void main()
{
object oNPC = OBJECT_SELF;
object oPC = GetLastKiller();
// Makes sure armor's droppable flag is set to 0
/* SetDroppableFlag(GetItemInSlot(INVENTORY_SLOT_CHEST, OBJECT_SELF), 0);
if ((GetResRef(oNPC) == "ra_bandit001") ||
(GetResRef(oNPC) == "ra_brigand001") ||
(GetResRef(oNPC) == "ra_brigand002"))
{
object oArmor = GetItemInSlot(INVENTORY_SLOT_CHEST, oNPC);
object oWeapon = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND, oNPC);
object oShield = GetItemInSlot(INVENTORY_SLOT_LEFTHAND, oNPC);
// Give a 3% chance to drop armor &/or equipped weapon
int bDroppableA = d100() > 97;
int bDroppableW = d100() > 97;
int bDroppableS = d100() > 97;
SetDroppableFlag(oArmor, bDroppableA);
SetDroppableFlag(oWeapon, bDroppableW);
SetDroppableFlag(oWeapon, bDroppableS);
}*/
int nVFX = GetLocalInt(OBJECT_SELF,"SpawnVFX");
if(nVFX)
{
ApplyEffectToObject(DURATION_TYPE_PERMANENT,SupernaturalEffect(EffectVisualEffect(nVFX)),OBJECT_SELF);
}
int nFirey = GetLocalInt(OBJECT_SELF,"FIREY");
if (nFirey)
{
effect eVis = EffectVisualEffect(VFX_DUR_INFERNO_NO_SOUND);
eVis = SupernaturalEffect(eVis);
eVis = ExtraordinaryEffect(eVis);
DelayCommand(0.0f, ApplyEffectToObject(DURATION_TYPE_PERMANENT,eVis,OBJECT_SELF));
}
int nShadowy = GetLocalInt(OBJECT_SELF,"SHADOWY");
if (nShadowy)
{
effect eVis = EffectVisualEffect(VFX_DUR_PROT_SHADOW_ARMOR);
eVis = SupernaturalEffect(eVis);
eVis = ExtraordinaryEffect(eVis);
DelayCommand(0.0f, ApplyEffectToObject(DURATION_TYPE_PERMANENT,eVis,OBJECT_SELF));
}
int nStony = GetLocalInt(OBJECT_SELF,"STONY");
if (nStony)
{
effect eVis = EffectVisualEffect(VFX_DUR_PROT_STONESKIN);
eVis = SupernaturalEffect(eVis);
eVis = ExtraordinaryEffect(eVis);
DelayCommand(0.0f, ApplyEffectToObject(DURATION_TYPE_PERMANENT,eVis,OBJECT_SELF));
}
int nWoody = GetLocalInt(OBJECT_SELF,"WOODY");
if (nWoody)
{
effect eVis = EffectVisualEffect(VFX_DUR_PROT_BARKSKIN);
eVis = SupernaturalEffect(eVis);
eVis = ExtraordinaryEffect(eVis);
DelayCommand(0.0f, ApplyEffectToObject(DURATION_TYPE_PERMANENT,eVis,OBJECT_SELF));
}
int nIcy = GetLocalInt(OBJECT_SELF,"ICY");
if (nIcy)
{
effect eVis = EffectVisualEffect(VFX_DUR_ICESKIN);
eVis = SupernaturalEffect(eVis);
eVis = ExtraordinaryEffect(eVis);
DelayCommand(0.0f, ApplyEffectToObject(DURATION_TYPE_PERMANENT,eVis,OBJECT_SELF));
}
int nConcealed20 = GetLocalInt(OBJECT_SELF,"CONCEALED20");
if (nConcealed20)
{
effect eVis = EffectVisualEffect(VFX_DUR_BLUR );
effect eConceal = EffectConcealment(20, 0);
eVis = SupernaturalEffect(eVis);
eVis = ExtraordinaryEffect(eVis);
DelayCommand(0.0f, ApplyEffectToObject(DURATION_TYPE_PERMANENT,eVis,OBJECT_SELF));
}
int nConcealed50 = GetLocalInt(OBJECT_SELF,"CONCEALED50");
if (nConcealed50)
{
effect eVis = EffectVisualEffect(VFX_DUR_BLUR );
effect eConceal = EffectConcealment(50, 0);
eVis = SupernaturalEffect(eVis);
eVis = ExtraordinaryEffect(eVis);
DelayCommand(0.0f, ApplyEffectToObject(DURATION_TYPE_PERMANENT,eVis,OBJECT_SELF));
}
int nGlow = GetLocalInt (OBJECT_SELF,"GLOW_COLOR");
if (nGlow == 1)
{
effect eVis = EffectVisualEffect(VFX_DUR_GLOW_BLUE);
eVis = SupernaturalEffect(eVis);
eVis = ExtraordinaryEffect(eVis);
DelayCommand(0.0f, ApplyEffectToObject(DURATION_TYPE_PERMANENT,eVis,OBJECT_SELF));
}
else if (nGlow == 2)
{
effect eVis = EffectVisualEffect(VFX_DUR_GLOW_BROWN);
eVis = SupernaturalEffect(eVis);
eVis = ExtraordinaryEffect(eVis);
DelayCommand(0.0f, ApplyEffectToObject(DURATION_TYPE_PERMANENT,eVis,OBJECT_SELF));
}
else if (nGlow == 3)
{
effect eVis = EffectVisualEffect(VFX_DUR_GLOW_GREEN);
eVis = SupernaturalEffect(eVis);
eVis = ExtraordinaryEffect(eVis);
DelayCommand(0.0f, ApplyEffectToObject(DURATION_TYPE_PERMANENT,eVis,OBJECT_SELF));
}
else if (nGlow == 4)
{
effect eVis = EffectVisualEffect(VFX_DUR_GLOW_GREY);
eVis = SupernaturalEffect(eVis);
eVis = ExtraordinaryEffect(eVis);
DelayCommand(0.0f, ApplyEffectToObject(DURATION_TYPE_PERMANENT,eVis,OBJECT_SELF));
}
else if (nGlow == 5)
{
effect eVis = EffectVisualEffect(VFX_DUR_GLOW_LIGHT_BLUE);
eVis = SupernaturalEffect(eVis);
eVis = ExtraordinaryEffect(eVis);
DelayCommand(0.0f, ApplyEffectToObject(DURATION_TYPE_PERMANENT,eVis,OBJECT_SELF));
}
else if (nGlow == 6)
{
effect eVis = EffectVisualEffect(VFX_DUR_GLOW_LIGHT_BROWN);
eVis = SupernaturalEffect(eVis);
eVis = ExtraordinaryEffect(eVis);
DelayCommand(0.0f, ApplyEffectToObject(DURATION_TYPE_PERMANENT,eVis,OBJECT_SELF));
}
else if (nGlow == 7)
{
effect eVis = EffectVisualEffect(VFX_DUR_GLOW_LIGHT_GREEN);
eVis = SupernaturalEffect(eVis);
eVis = ExtraordinaryEffect(eVis);
DelayCommand(0.0f, ApplyEffectToObject(DURATION_TYPE_PERMANENT,eVis,OBJECT_SELF));
}
else if (nGlow == 8)
{
effect eVis = EffectVisualEffect(VFX_DUR_GLOW_LIGHT_ORANGE);
eVis = SupernaturalEffect(eVis);
eVis = ExtraordinaryEffect(eVis);
DelayCommand(0.0f, ApplyEffectToObject(DURATION_TYPE_PERMANENT,eVis,OBJECT_SELF));
}
else if (nGlow == 9)
{
effect eVis = EffectVisualEffect(VFX_DUR_GLOW_LIGHT_PURPLE);
eVis = SupernaturalEffect(eVis);
eVis = ExtraordinaryEffect(eVis);
DelayCommand(0.0f, ApplyEffectToObject(DURATION_TYPE_PERMANENT,eVis,OBJECT_SELF));
}
else if (nGlow == 10)
{
effect eVis = EffectVisualEffect(VFX_DUR_GLOW_LIGHT_RED);
eVis = SupernaturalEffect(eVis);
eVis = ExtraordinaryEffect(eVis);
DelayCommand(0.0f, ApplyEffectToObject(DURATION_TYPE_PERMANENT,eVis,OBJECT_SELF));
}
else if (nGlow == 11)
{
effect eVis = EffectVisualEffect(VFX_DUR_GLOW_LIGHT_YELLOW);
eVis = SupernaturalEffect(eVis);
eVis = ExtraordinaryEffect(eVis);
DelayCommand(0.0f, ApplyEffectToObject(DURATION_TYPE_PERMANENT,eVis,OBJECT_SELF));
}
else if (nGlow == 12)
{
effect eVis = EffectVisualEffect(VFX_DUR_GLOW_ORANGE);
eVis = SupernaturalEffect(eVis);
eVis = ExtraordinaryEffect(eVis);
DelayCommand(0.0f, ApplyEffectToObject(DURATION_TYPE_PERMANENT,eVis,OBJECT_SELF));
}
else if (nGlow == 13)
{
effect eVis = EffectVisualEffect(VFX_DUR_GLOW_PURPLE);
eVis = SupernaturalEffect(eVis);
eVis = ExtraordinaryEffect(eVis);
DelayCommand(0.0f, ApplyEffectToObject(DURATION_TYPE_PERMANENT,eVis,OBJECT_SELF));
}
else if (nGlow == 14)
{
effect eVis = EffectVisualEffect(VFX_DUR_GLOW_RED);
eVis = SupernaturalEffect(eVis);
eVis = ExtraordinaryEffect(eVis);
DelayCommand(0.0f, ApplyEffectToObject(DURATION_TYPE_PERMANENT,eVis,OBJECT_SELF));
}
else if (nGlow == 15)
{
effect eVis = EffectVisualEffect(VFX_DUR_GLOW_WHITE);
eVis = SupernaturalEffect(eVis);
eVis = ExtraordinaryEffect(eVis);
DelayCommand(0.0f, ApplyEffectToObject(DURATION_TYPE_PERMANENT,eVis,OBJECT_SELF));
}
else if (nGlow == 16)
{
effect eVis = EffectVisualEffect(VFX_DUR_GLOW_YELLOW);
eVis = SupernaturalEffect(eVis);
eVis = ExtraordinaryEffect(eVis);
DelayCommand(0.0f, ApplyEffectToObject(DURATION_TYPE_PERMANENT,eVis,OBJECT_SELF));
}
//:: Track which PC's have seen Drusilla dead
SQL_SetLocalIntOnAll(oPC, "bKilledDrusilla", 1);
//:: Set quest stage & update DB.
AddPersistentJournalQuestEntry("VengefulDruid", 99, oPC);
//:: Execute CODI AI NPC OnDeath script
ExecuteScript("no_ai_dth", OBJECT_SELF);
//:: Execute Default NPC OnDeath script
//ExecuteScript("nw_c2_default7", OBJECT_SELF);
//:: Execute PRC NPC OnDeath script
ExecuteScript("prc_npc_death", OBJECT_SELF);
}

View File

@@ -0,0 +1,45 @@
//::///////////////////////////////////////////////
//:: drusilla_onpercep
//:: Copyright (c) 2022 Project RATDOG
//::///////////////////////////////////////////////
/*
Makes the NPC speak to the PC upon seeing them
the first time.
*/
//::///////////////////////////////////////////////
//:: Created By: Jaysyn
//:: Created On: 20221202
//::///////////////////////////////////////////////
void main()
{
//:: Declare major variables
object oPC = GetLastPerceived();
object oNPC = OBJECT_SELF;
string sUUID = GetObjectUUID(oPC);
string sTag = GetTag(oNPC);
//:: Only looks out for players
if (!GetIsPC(oPC)) return;
//:: Must be seen & not just heard
if (!GetLastPerceptionSeen()) return;
//:: If NPC has seen PC before stop
int DoOnce = GetLocalInt(oPC,"SeenBy"+sTag);
if (DoOnce==TRUE) return;
//:: Execute the PRC NPC OnPerception script
ExecuteScript("prc_npc_percep", OBJECT_SELF);
//:: Mark that NPC has seen the PC before
SetLocalInt(oPC,"SeenBy"+sTag,GetLocalInt(oPC,"SeenBy"+sTag) + 1);
//SetLocalInt(OBJECT_SELF, GetTag(OBJECT_SELF), TRUE);
//:: Execute the CODI AI NPC OnPerception script
ExecuteScript("no_ai_per", OBJECT_SELF);
//:: Start conversation
ActionStartConversation(oPC, "");
}

View File

@@ -1,99 +0,0 @@
/*/////////////////////// [Destroy Ourself] ////////////////////////////////////
Filename: J_AI_DestroySelf
///////////////////////// [Destroy Ourself] ////////////////////////////////////
This is executed OnDeath to clean up the corpse. It helps - clears all
non-droppable stuff.
It is not fired if there are corpses or whatever :-)
Sorts destroyed things.
Oh, if this is executed any other time when they are dead, they are
destroyed instantly.
///////////////////////// [History] ////////////////////////////////////////////
1.3 - Added to replace a include function for death.
- No locals are destroyed. The game should do that anyway. Items are, though.
1.4 -
///////////////////////// [Workings] ///////////////////////////////////////////
this, if ever fired, will destroy the creature. It is not deleayed - there
is a special function in the death script to check the whole "Did I get
raised?" stuff.
I suppose you can edit this to put a corpse in :-D
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: N/A - none needed.
///////////////////////// [Destroy Ourself] //////////////////////////////////*/
// Exectued from death, to speed things up.
#include "J_INC_CONSTANTS"
// This will delete all un-droppable items, before they fade out.
void DeleteAllThings();
// Used in DeleteAllThings.
void ClearSlot(int iSlotID);
void main()
{
// To not crash limbo. Destroying in limbo crashes a server (1.2 bugfix)
if(GetIsObjectValid(GetArea(OBJECT_SELF)))
{
// Must be dead.
if(GetIsDead(OBJECT_SELF))
{
// Totally dead - no death file, no raising.
SetAIInteger(I_AM_TOTALLY_DEAD, TRUE);
// Ok, we are going to set we are lootable (maybe)
if(GetSpawnInCondition(AI_FLAG_OTHER_USE_BIOWARE_LOOTING, AI_OTHER_MASTER))
{
// As it is now destroyable, it should destroy itself if it has
// no inventory. SetLootable is set up on spawn.
// 75: "[Dead] Setting to selectable/destroyable (so we go) for Bioware corpses."
DebugActionSpeakByInt(75);
SetIsDestroyable(TRUE, FALSE, TRUE);
}
else // Destroy self normally
{
// Debug
// 76: "[Dead] Destroying self finally."
DebugActionSpeakByInt(76);
DeleteAllThings();
// Just in case, we set destroyable, but not raiseable.
SetIsDestroyable(TRUE, FALSE, FALSE);
// Remove plot/immoral/lootable flags JUST in case.
SetPlotFlag(OBJECT_SELF, FALSE);
SetImmortal(OBJECT_SELF, FALSE);
SetLootable(OBJECT_SELF, FALSE);
// Destroy ourselves
DestroyObject(OBJECT_SELF);
}
}
}
// Note: we never do more then one death removal check. DM's can re-raise and kill a NPC if they wish.
}
// Used in DeleteAllThings.
void ClearSlot(int iSlotID)
{
object oItem = GetItemInSlot(iSlotID);
if(GetIsObjectValid(oItem) && !GetDroppableFlag(oItem))
DestroyObject(oItem);
}
// This will delete all un-droppable items, before they fade out.
void DeleteAllThings()
{
// Destroy all equipped slots - 0 to 18 (18 = NUM_INVENTORY_SLOTS)
int iSlotID;
for(iSlotID = 0; iSlotID <= NUM_INVENTORY_SLOTS; iSlotID++)
{
ClearSlot(iSlotID);
}
// Destroy all inventory items
object oItem = GetFirstItemInInventory();
while(GetIsObjectValid(oItem))
{
if(!GetDroppableFlag(oItem))
DestroyObject(oItem);
oItem = GetNextItemInInventory();
}
}

View File

@@ -1,61 +0,0 @@
/*/////////////////////// [Execute Combat Action] //////////////////////////////
Filename: J_AI_DeterCombat
///////////////////////// [Execute Combat Action] //////////////////////////////
Fired from other scripts, this runs an actual actions.
It also contains the Pre-combat and Post-combat action events. In essense
they therefore fire if they percieve a target, or a new round, or maybe
a spell cast at - any combat action.
Therefore, they only fire if the default AI is being used :-)
Do NOT mess with this file, please. :-D
///////////////////////// [History] ////////////////////////////////////////////
1.3 - AI Include only fired from here. This script is executed from others,
as the default in place of custom AI scripts.
1.4 - Mainly See the generic AI include file for changes. This is just
what calls DetermineCombatRound() and associated things.
///////////////////////// [Workings] ///////////////////////////////////////////
This is simple:
- We execute it if there is no other AI files.
- We use a stored target for things like "On Percieve, attack seen", so
we react as normal.
If there is a custom AI file specified, this won't fire.
It cleans things up, and is the only script in the whole set that has
j_inc_generic_ai in, reducing file size, and compile times. AI is more
manageable too!
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: See J_INC_GENERIC_AI
///////////////////////// [Execute Combat Action] ////////////////////////////*/
#include "J_INC_GENERIC_AI"
void main()
{
// Pre-combat-event
if(FireUserEvent(AI_FLAG_UDE_COMBAT_ACTION_PRE_EVENT, EVENT_COMBAT_ACTION_PRE_EVENT))
// We may exit if it fires
if(ExitFromUDE(EVENT_COMBAT_ACTION_PRE_EVENT)) return;
// Check: Are we imputting a target? We imputt it even if invalid
object oTarget = GetLocalObject(OBJECT_SELF, AI_TEMP_SET_TARGET);
// * Don't speak when dead. 1.4 change (an obvious one to make)
if(CanSpeak())
{
// Speak combat round speakstring
SpeakArrayString(AI_TALK_ON_COMBAT_ROUND, TRUE);
}
// Call combat round using include
AI_DetermineCombatRound(oTarget);
// Delete it whatever happens
DeleteAIObject(AI_TEMP_SET_TARGET);
// Fire end of combat action event.
FireUserEvent(AI_FLAG_UDE_COMBAT_ACTION_EVENT, EVENT_COMBAT_ACTION_EVENT);
}

View File

@@ -1,39 +0,0 @@
/*/////////////////////// [On Heartbeat - Animations] //////////////////////////
Filename: J_AI_Heart_aimat
///////////////////////// [On Heartbeat - Animations] //////////////////////////
To keep the heartbeat small, I've divided all the bits that MIGHT fire
into other scripts. This makes it smaller, and faster.
I've also shortened the perception script too - and along with the heartbeat
is the largest, Out-Of-Combat script. It isn't divided up by execute scripts,
but should be leaner.
///////////////////////// [History] ////////////////////////////////////////////
1.3 - Added to speed up heartbeat and keep filesize down on un-used parts.
1.4 - Changed to nw_i0_generic, as to include all animations, whatever NwN version.
///////////////////////// [Workings] ///////////////////////////////////////////
This is executed as file HEARTBEAT_ANIMATIONS_FILE, from the heartbeat
script (Default1, or onheartbeat). It can run by itself, using the SoU
animations - better then me changing and making my own, as they are vastly
improved from NwN!
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: N/A
///////////////////////// [On Heartbeat - Animations] ////////////////////////*/
// Generic Include File. This contains animations whatever NwN version it is.
#include "NW_I0_GENERIC"
void main()
{
if(GetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS))
{
PlayMobileAmbientAnimations_NonAvian();
}
else if(GetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS_AVIAN))
{
PlayMobileAmbientAnimations_Avian();
}
else if(GetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS))
{
PlayImmobileAmbientAnimations();
}
}

View File

@@ -1,188 +0,0 @@
/*/////////////////////// [On Heartbeat - Buff] ////////////////////////////////
Filename: j_ai_heart_buff
///////////////////////// [On Heartbeat - Buff] ////////////////////////////////
This is ExecuteScript'ed from the heartbeat file, if they want to buff
themselves with spells to be prepared for any battle coming up.
///////////////////////// [History] ////////////////////////////////////////////
1.3 - Added
1.4 - Will Add all the appropriate Hordes spells, notably the missing epic ones.
///////////////////////// [Workings] ///////////////////////////////////////////
This contains Advance Buffing - IE quick protection spells.
I've done what ones I think are useful - IE most protection ones & summons!
This doesn't include any which are (potentionally) very short duration (IE:
1 round/level, or a set value):
Elemntal shield/Wounding whispers (though you can add all of these!)
Aid, bless, aura of vitality, aura of glory, blood frenzy, prayer,
divine* Range (Power, Might, Shield, Favor), Expeditious retreat,
holy/unholy aura (or protection from /magic circle against),
natures balance, one with the land, shield of faith, virtue, war cry, dirge,
death armor, mestals acid sheath.
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: N/A
///////////////////////// [On Heartbeat - Buff] //////////////////////////////*/
// Constants for some unconstantanated spells
#include "J_INC_CONSTANTS"
// Wrapper, to stop repeating the same lines! :-)
int BuffCastSpell(int nSpell);
void main()
{
// For summons counter.
int nCnt, bBreak;
// FAST BUFF SELF
// Stop what we are doing first, to perform the actions.
ClearAllActions();
// Always cast "Epic Warding" and "Epic Mage Armor".
BuffCastSpell(FEAT_EPIC_SPELL_EPIC_WARDING);
BuffCastSpell(FEAT_EPIC_SPELL_MAGE_ARMOUR);
// Combat Protections
if(!BuffCastSpell(SPELL_PREMONITION))
if(!BuffCastSpell(SPELL_GREATER_STONESKIN))
BuffCastSpell(SPELL_STONESKIN);
// Visage Protections
if(!BuffCastSpell(SPELL_SHADOW_SHIELD))
if(!BuffCastSpell(SPELL_ETHEREAL_VISAGE))
BuffCastSpell(SPELL_GHOSTLY_VISAGE);
// Mantle Protections
if(!BuffCastSpell(SPELL_GREATER_SPELL_MANTLE))
if(!BuffCastSpell(SPELL_SPELL_MANTLE))
BuffCastSpell(SPELL_LESSER_SPELL_MANTLE);
// True seeing, see invisibility. We take true seeing to be better then the latter.
if(BuffCastSpell(SPELL_TRUE_SEEING))
BuffCastSpell(SPELL_SEE_INVISIBILITY);
// Elemental Protections. 4 lots. From 40/- to 10/-
if(!BuffCastSpell(SPELL_ENERGY_BUFFER))
if(!BuffCastSpell(SPELL_PROTECTION_FROM_ELEMENTS))
if(!BuffCastSpell(SPELL_RESIST_ELEMENTS))
BuffCastSpell(SPELL_ENDURE_ELEMENTS);
// Mental Protections
if(!BuffCastSpell(SPELL_MIND_BLANK))
if(!BuffCastSpell(SPELL_LESSER_MIND_BLANK))
BuffCastSpell(SPELL_CLARITY);
// Globes
if(!BuffCastSpell(SPELL_GLOBE_OF_INVULNERABILITY))
BuffCastSpell(SPELL_MINOR_GLOBE_OF_INVULNERABILITY);
// Invisibility
// Note: Improved has 50% consealment, etherealness has just invisiblity.
if(!BuffCastSpell(SPELL_IMPROVED_INVISIBILITY))
BuffCastSpell(SPELL_DISPLACEMENT);//50% consealment
if(!BuffCastSpell(SPELL_ETHEREALNESS))
if(!BuffCastSpell(SPELL_INVISIBILITY_SPHERE))
if(!BuffCastSpell(SPELL_INVISIBILITY))
BuffCastSpell(SPELL_SANCTUARY);
// The stat-increasing ones.
if(!BuffCastSpell(SPELL_GREATER_BULLS_STRENGTH))
BuffCastSpell(SPELL_BULLS_STRENGTH);
if(!BuffCastSpell(SPELL_GREATER_CATS_GRACE))
BuffCastSpell(SPELL_CATS_GRACE);
if(!BuffCastSpell(SPELL_GREATER_EAGLE_SPLENDOR))
BuffCastSpell(SPELL_EAGLE_SPLEDOR);
if(!BuffCastSpell(SPELL_GREATER_FOXS_CUNNING))
BuffCastSpell(SPELL_FOXS_CUNNING);
if(!BuffCastSpell(SPELL_GREATER_ENDURANCE))
BuffCastSpell(SPELL_ENDURANCE);
if(!BuffCastSpell(AI_SPELL_OWLS_INSIGHT))
if(!BuffCastSpell(SPELL_GREATER_OWLS_WISDOM))
BuffCastSpell(SPELL_OWLS_WISDOM);
// Mage armor or shield. Don't stack them.
if(!BuffCastSpell(SPELL_SHIELD))
BuffCastSpell(SPELL_MAGE_ARMOR);
// Entropic Shield (20% consealment, 1 turn/level)
BuffCastSpell(SPELL_ENTROPIC_SHIELD);
// Protection from negative energy
if(!BuffCastSpell(SPELL_UNDEATHS_ETERNAL_FOE))
BuffCastSpell(SPELL_DEATH_WARD);
//Misc Protections which have no more powerful.
BuffCastSpell(SPELL_BARKSKIN);
BuffCastSpell(SPELL_ENTROPIC_SHIELD);
BuffCastSpell(SPELL_PROTECTION_FROM_SPELLS);
BuffCastSpell(SPELL_REGENERATE);
BuffCastSpell(SPELL_DARKVISION);
BuffCastSpell(SPELL_REGENERATE);
BuffCastSpell(SPELL_SPELL_RESISTANCE);
BuffCastSpell(SPELL_FREEDOM_OF_MOVEMENT);
BuffCastSpell(SPELL_FREEDOM_OF_MOVEMENT);
// Low durations (Rounds per caster level)
// if(!BuffCastSpell(SPELL_ELEMENTAL_SHIELD))
// BuffCastSpell(SPELL_WOUNDING_WHISPERS);
// BuffCastSpell(SPELL_DEATH_ARMOR);
//Summon Ally.
// Spell ID's: These are quite odd. Spells.2da:
/*
174 Summon_Creature_I 1
175 Summon_Creature_II 2
176 Summon_Creature_III 3
177 Summon_Creature_IV 4
178 Summon_Creature_IX 9
179 Summon_Creature_V 5
180 Summon_Creature_VI 6
181 Summon_Creature_VII 7
182 Summon_Creature_VIII 8
*/
// We can loop through. 9 first, then 8-5, then undead ones, then 4-1
if(!BuffCastSpell(SPELL_SUMMON_CREATURE_IX))// 9
{
// 8, 7, 6, 5.
for(nCnt = SPELL_SUMMON_CREATURE_VIII;
(nCnt >= SPELL_SUMMON_CREATURE_V && bBreak != TRUE);
nCnt--)
{
if(BuffCastSpell(nCnt)) bBreak = TRUE;
}
// Then undead
if(bBreak != TRUE)
{
if(!BuffCastSpell(SPELL_CREATE_GREATER_UNDEAD))
{
if(!BuffCastSpell(SPELL_CREATE_UNDEAD))
{
if(!BuffCastSpell(SPELL_ANIMATE_DEAD))
{
// Lastly, the 4-1 ones.
for(nCnt = SPELL_SUMMON_CREATURE_IV;
nCnt >= SPELL_SUMMON_CREATURE_I;
nCnt--)
{
if(BuffCastSpell(nCnt)) break;
}
}
}
}
}
}
// Finally, equip the best melee weapon to look more prepared.
// Don't use a ranged, we can equip it manually if need be :=P
// but sneak attackers would have a field day if we didn't have
// a melee weapon out...
ActionEquipMostDamagingMelee();
}
// Wrapper, to stop repeating the same lines! :-)
int BuffCastSpell(int nSpell)
{
if(GetHasSpell(nSpell))
{
ActionCastSpellAtObject(nSpell, OBJECT_SELF, METAMAGIC_ANY, FALSE, FALSE, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
return TRUE;
}
return FALSE;
}

View File

@@ -1,40 +0,0 @@
/*/////////////////////// [On Heartbeat - Move Nearer PC] //////////////////////
Filename: J_AI_Heart_Serch
///////////////////////// [On Heartbeat - Move Nearer PC] //////////////////////
This is fired to perform moving nearer the PC, or searching towards them.
Yes, like the Henchmen and Battle AI code. I am sure they won't mind - if
they do, I will remove it :-)
///////////////////////// [History] ////////////////////////////////////////////
1.3 - Added
1.4 - Reformatted as with the rest of the AI
///////////////////////// [Workings] ///////////////////////////////////////////
This makes the NPC move nearer to a PC. Fires if the spawn condition
is on and the timer is not, and only 1/4 heartbeats to lessen the effect.
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: N/A
///////////////////////// [On Heartbeat - Move Nearer PC] ////////////////////*/
#include "J_INC_CONSTANTS"
void main()
{
object oPC = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC);
if(GetIsObjectValid(oPC) && GetIsEnemy(oPC) &&
GetDistanceToObject(oPC) <
IntToFloat(GetBoundriedAIInteger(AI_SEARCH_IF_ENEMIES_NEAR_RANGE, 25, 50, 5)))
{
vector vPC = GetPosition(oPC);
// Whats the distance we use to move a bit nearer?
int nRandom = 10 + Random(10);
// Randomise a point nearby.
vPC.x += IntToFloat(nRandom - (Random(2 * nRandom + 1)));
vPC.y += IntToFloat(nRandom - (Random(2 * nRandom + 1)));
vPC.z += IntToFloat(nRandom - (Random(2 * nRandom + 1)));
// Define the location
location lNew = Location(GetArea(oPC), vPC, IntToFloat(Random(359)));
SetLocalTimer(AI_TIMER_SEARCHING, GetDistanceToObject(oPC));
ClearAllActions();
ActionMoveToLocation(lNew);
}
}

View File

@@ -1,332 +0,0 @@
/*/////////////////////// [On Blocked] /////////////////////////////////////////
Filename: J_AI_OnBlocked or nw_c2_defaulte
///////////////////////// [On Blocked] /////////////////////////////////////////
Added in user defined constant - won't open any doors.
0 = Default (even if not set) opens as appropriate
1 = Always bashes the door.
2 = Never open any doors
3 = Never opens plot doors
They will: (int is intellgience needed)
1. Open if not trapped (7 int)
2. Unlock if possible, and rank is high enough, and it needs no key and is not trapped (7 int)
3. Untrap the door, if possible, if trapped (7 int)
4. Else, if has high enough stats, try Knock. (10 int)
6. Else Equip appropriate weapons and bash (5 int)
Note: This also fires for blocking via. creatures. It is optimised, and
works by re-targeting and doing a few small things to do with blocking.
///////////////////////// [History] ////////////////////////////////////////////
1.0 - Opens with Knock. Unlocks door. Ignores trapped doors.
1.3 - Debug messages.
- New events, even if the change of using them is small!
- No ClearAllactions so any previous movings will carry on once the door is gone.
- Removed debug messages
- Added Creature reaction code
1.4 - Need to add a "hands" check (done on spawn, to set a setting to not
open doors at all, IE: We do NOT have hands, do not open doors), so
its a little more realistic "out of the box"
- Fixed an instance of GetObjectSeen being repeated.
- Fixed the variable AI_DOOR_INTELLIGENCE not being got via GetAIInteger().
- Removed unneeded else statement.
///////////////////////// [Workings] ///////////////////////////////////////////
Uses simple code to deal with a door in the best way possible.
Uses DoDoorAction, which is added to the top of an action queue and doesn't,
therefore, delete any ActionAttack's and so on below it. (Or I hope it
is like this)
Creatures are reacted by with ClearAllActions usually.
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: GetBlockingDoor, GetIsDoorActionPossible, GetLocked, GetLockKeyRequired
GetLockKeyTag, GetLockUnlockDC, GetPlotFlag, DoDoorAction
///////////////////////// [On Blocked] ///////////////////////////////////////*/
#include "J_INC_OTHER_AI"
// Fires the end-blocked event.
void FireBlockedEvent();
// Range attack oTarget.
int RangedAttack(object oTarget = OBJECT_INVALID);
void main()
{
// Pre-on blocked-event. Returns TRUE if we interrupt this script call.
if(FirePreUserEvent(AI_FLAG_UDE_ON_BLOCKED_PRE_EVENT, EVENT_ON_BLOCKED_PRE_EVENT)) return;
// AI status check. Is the AI on?
if(GetAIOff()) return;
// This CAN return a blocking creature.
object oBlocker = GetBlockingDoor();
int nBlockerType = GetObjectType(oBlocker);
if(!GetIsObjectValid(oBlocker)) return;
// Anyone blocked by an enemy will re-target them (and attack them), blocked
// by someone they cannot get they will cast seeing spells and react, and if
// blocked by a friend, they may run back and use a ranged weapon if they
// have one.
if(nBlockerType == OBJECT_TYPE_CREATURE)
{
// Are we doing something that should not be overriden? (even fleeing,
// if stuck, we can't do anything else then move again on heartbeat!)
if(GetIsPerformingSpecialAction()) return;
// Blocked timer, we normally do an action. A small timer stops a lot
// of lag.
if(GetLocalTimer(AI_TIMER_BLOCKED)) return;
// Set the timer for 1 second
SetLocalTimer(AI_TIMER_BLOCKED, 1.0);
// Is it an enemy?
if(GetIsEnemy(oBlocker))
{
// Check if seen or heard
if(GetObjectSeen(oBlocker) || GetObjectHeard(oBlocker))
{
// Enemy :-) We can re-target (as know of thier presence), using
// them as a target.
// - This overrides even casting a spell - basically, as we should
// be moving, this will re-cast it at someone or something in range
SetAIObject(AI_ATTACK_SPECIFIC_OBJECT, oBlocker);
// Check if we can do combat - if we cannot, we can re-do combat
// next time
if(!GetIsBusyWithAction())
{
// Attacks if we are not attacking
ClearAllActions();
DetermineCombatRound(oBlocker);
return;
}
}
else
{
// Invisible? Not there? Some odd error? We set that we know of
// someone invisible, and will attack if not in combat.
if(GetHasEffect(EFFECT_TYPE_INVISIBILITY, oBlocker) ||
GetStealthMode(oBlocker) == STEALTH_MODE_ACTIVATED)
{
SetAIObject(AI_LAST_TO_GO_INVISIBLE, oBlocker);
}
// Shout to allies
AISpeakString(AI_SHOUT_CALL_TO_ARMS);
// Check if we can do combat
if(!GetIsBusyWithAction())
{
// Attacks if we are not attacking
ClearAllActions();
DetermineCombatRound();
return;
}
}
}
// Else is non-enemy, a friend or neutral
else
{
// As we are blocked by them, we re-do combat - we have a choice of
// either using a Bow to attack our target (if that was what
// we were doing) and move back a little, or re-initiate combat
// Were we attacking in combat?
object oPrevious = GetAttackTarget();
// Check action
if(GetCurrentAction() == ACTION_ATTACKOBJECT)
{
// This gets set to FALSE if we can cutthrough attack,
// or whatever.
int bPreviousAttackFailed = FALSE;
// Check if we can see our previous target
if(GetObjectSeen(oPrevious) ||
(GetObjectHeard(oPrevious) && LineOfSightObject(OBJECT_SELF, oPrevious)))
{
// We can! see if we can re-attack with ranged weapon, else
// doesn't matter we can see them
bPreviousAttackFailed = RangedAttack(oPrevious);
}
// If we havn't added an action yet...
if(bPreviousAttackFailed == FALSE)
{
// We have not stopped the script - so determine combat
// round against nearest seen or heard enemy!
if(!RangedAttack())
{
// Else normal round to try and get a new target
ClearAllActions();
DetermineCombatRound();
}
}
// Action attack, normally means melee attack. If we can, we
// attack our previous target if seen, ELSE we will re-initate
// combat.
AISpeakString(AI_SHOUT_I_WAS_ATTACKED);
// Fire the On blocked event as normal
FireBlockedEvent();
return;
}
else // if(nAction == ACTION_CASTSPELL and others)
{
// Reinitate combat, but don't attack oPrevious
ClearAllActions();
DetermineCombatRound();
// Action attack, normally means melee attack. If we can, we
// attack our previous target if seen, ELSE we will re-initate
// combat.
AISpeakString(AI_SHOUT_I_WAS_ATTACKED);
// Fire the On blocked event as normal
FireBlockedEvent();
return;
}
}
}
// Placeable - Currently not returned, however, added just in case!
else if(nBlockerType == OBJECT_TYPE_PLACEABLE)
{
// Check for plot, and therefore attack it to bring it down.
// - Remember, ActionAttack will re-initiate when combat round fires
// again in 3 or 6 seconds (or less, if we just were moving)
if(!GetPlotFlag(oBlocker) &&
GetIsPlaceableObjectActionPossible(oBlocker, PLACEABLE_ACTION_BASH))
{
// Do placeable action
DoPlaceableObjectAction(oBlocker, PLACEABLE_ACTION_BASH);
FireBlockedEvent();
return;
}
return;
}
// Door behaviour
else if(nBlockerType == OBJECT_TYPE_DOOR)
{
int nDoorIntelligence = GetAIInteger(AI_DOOR_INTELLIGENCE);
int nInt = GetAbilityScore(OBJECT_SELF, ABILITY_INTELLIGENCE);
if(nDoorIntelligence == 1)// 1 = Always bashes the doors, plot, locked or anything.
{
DoDoorAction(oBlocker, DOOR_ACTION_BASH);
// We re-initiate combat.
FireBlockedEvent();
return;
}
else if(nDoorIntelligence == 2)// 2 = Never open anything, bashing or not.
{
FireBlockedEvent();
return;
}
else if(nDoorIntelligence == 3)// 3 = Never tries anything against plot doors.
{
if(GetPlotFlag(oBlocker))
{
FireBlockedEvent();
return;
}
}
if(nInt >= 5)
{
// Need some intelligence :-)
if(nInt >= 7)
{
// Right, first, we may...shock...open it!!!
// Checks Key, lock, trap and if the action is possible.
if(GetIsDoorActionPossible(oBlocker, DOOR_ACTION_OPEN) &&
!GetLocked(oBlocker) &&
!GetIsTrapped(oBlocker) &&
(!GetLockKeyRequired(oBlocker) ||
(GetLockKeyRequired(oBlocker) && GetItemPossessor(GetObjectByTag(GetLockKeyTag(oBlocker))) == OBJECT_SELF)))
{
DoDoorAction(oBlocker, DOOR_ACTION_OPEN);
FireBlockedEvent();
return;
}
// Unlock it with the skill, if it is not trapped and we can :-P
// We take 20 off the door DC, thats our minimum roll, after all.
if(GetLocked(oBlocker) &&
!GetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_OPENING_LOCKED_DOORS, AI_OTHER_COMBAT_MASTER) &&
!GetLockKeyRequired(oBlocker) && GetHasSkill(SKILL_OPEN_LOCK) &&
GetIsDoorActionPossible(oBlocker, DOOR_ACTION_UNLOCK) && !GetIsTrapped(oBlocker) &&
(GetSkillRank(SKILL_OPEN_LOCK) >= (GetLockLockDC(oBlocker) - 20)))
{
DoDoorAction(oBlocker, DOOR_ACTION_UNLOCK);
FireBlockedEvent();
return;
}
// Specilist thing - knock
if(nInt >= 10)
{
if((GetIsDoorActionPossible(oBlocker, DOOR_ACTION_KNOCK)) &&
GetLockUnlockDC(oBlocker) <= 25 &&
!GetLockKeyRequired(oBlocker) && GetHasSpell(SPELL_KNOCK))
{
DoDoorAction(oBlocker, DOOR_ACTION_KNOCK);
FireBlockedEvent();
return;
}
}
}
// If Our Int is over 5, we will bash after everything else.
if(GetIsDoorActionPossible(oBlocker, DOOR_ACTION_BASH) && !GetPlotFlag(oBlocker))
{
if(GetAttackTarget() != oBlocker)
{
DoDoorAction(oBlocker, DOOR_ACTION_BASH);
}
FireBlockedEvent();
return;
}
}
}
// Fire Blocked event
FireBlockedEvent();
}
// Fires the end-blocked event.
void FireBlockedEvent()
{
// Fire End-blocked-UDE
FireUserEvent(AI_FLAG_UDE_ON_BLOCKED_EVENT, EVENT_ON_BLOCKED_EVENT);
}
// Range attack oTarget.
int RangedAttack(object oTarget)
{
// If we are primarily melee, don't use this
if(!GetSpawnInCondition(AI_FLAG_COMBAT_BETTER_AT_HAND_TO_HAND, AI_COMBAT_MASTER)) return FALSE;
object oRangedTarget = oTarget;
if(!GetIsObjectValid(oRangedTarget))
{
oRangedTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN, CREATURE_TYPE_IS_ALIVE, TRUE);
if(!GetIsObjectValid(oTarget))
{
oTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_HEARD, CREATURE_TYPE_IS_ALIVE, TRUE);
// heard must be in LOS to attack, as we are probably stuck
if(!GetIsObjectValid(oTarget) && LineOfSightObject(OBJECT_SELF, oRangedTarget))
{
return FALSE;
}
}
}
// Ranged weapon attack against oTarget
// doesn't matter we can see them
object oRanged = GetAIObject(AI_WEAPON_RANGED);
int nAmmo = GetAIInteger(AI_WEAPON_RANGED_AMMOSLOT);
// Check ammo and validness
if(GetIsObjectValid(oRanged) && (nAmmo == INVENTORY_SLOT_RIGHTHAND ||
GetIsObjectValid(GetItemInSlot(nAmmo))))
{
// Attack with it
ClearAllActions();
ActionEquipItem(oRanged, INVENTORY_SLOT_RIGHTHAND);
ActionAttack(oRangedTarget);
// Stop
return TRUE;
}
return FALSE;
}

View File

@@ -1,37 +0,0 @@
/*/////////////////////// [On Combat Round End] ////////////////////////////////
Filename: nw_c2_default3 or J_AI_OnCombatrou
///////////////////////// [On Combat Round End] ////////////////////////////////
This is run every 3 or 6 seconds, if the creature is in combat. It is
executed only in combat automatically.
It runs what the AI should do, bascially.
///////////////////////// [History] ////////////////////////////////////////////
1.3 - Executes same script as the other parts of the AI to cuase a new action
1.4 -
///////////////////////// [Workings] ///////////////////////////////////////////
Calls the combat AI file using the J_INC_OTHER_AI include function,
DetermineCombatRound.
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: GetAttackTarget, GetLastHostileActor, GetAttemptedAttackTarget,
GetAttemptedSpellTarget (Or these are useful at least!)
///////////////////////// [On Combat Round End] //////////////////////////////*/
#include "J_INC_OTHER_AI"
void main()
{
// Pre-combat-round-event. Returns TRUE if we interrupt this script call.
if(FirePreUserEvent(AI_FLAG_UDE_END_COMBAT_ROUND_PRE_EVENT, EVENT_END_COMBAT_ROUND_PRE_EVENT)) return;
// AI status check. Is the AI on?
if(GetAIOff()) return;
// It is our normal call (every 3 or 6 seconds, when we can change actions)
// so no need to delete, and we fire the UDE's.
// Determine combat round against an invalid target (as default)
DetermineCombatRound();
// Fire End of end combat round event
FireUserEvent(AI_FLAG_UDE_END_COMBAT_ROUND_EVENT, EVENT_END_COMBAT_ROUND_EVENT);
}

View File

@@ -1,160 +0,0 @@
/*/////////////////////// [On Conversation] ////////////////////////////////////
Filename: J_AI_OnConversat or nw_c2_default4
///////////////////////// [On Conversation] ////////////////////////////////////
OnConversation/ Listen to shouts.
Documented, and checked. -Working-
Added spawn in condition - Never clear actions when talking.
///////////////////////// [History] ////////////////////////////////////////////
1.3 - Added in conversation thing - IE we can set speakstrings, no need for conversation file.
- Sorted more shouts out.
- Should work right, and not cause too many actions (as we ignore
shouts for normally 12 or so seconds before letting them affect us again).
1.4 - Deafness incorpreated.
///////////////////////// [Workings] ///////////////////////////////////////////
Uses RespondToShout to react to allies' shouts, and just attacks any enemy
who speaks, or at least moves to them. (OK, dumb if they are invisible, but
oh well, they shouldn't talk so loud!)
Remember, whispers are never heard if too far away, speakstrings don't go
through walls, and shouts are always heard (so we don't go off to anyone
not in our area, remember)
Deafness causes us to never hear battle, so unless we see the target speaking
we do not react. Doesn't apply to normal conversations - although if we cannot
talk (also restricted by deafness) then so be it.
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: GetListenPatternNumber, GetLastSpeaker, TestStringAgainstPattern,
GetMatchedSubstring
///////////////////////// [On Conversation] //////////////////////////////////*/
#include "J_INC_OTHER_AI"
void main()
{
// Pre-conversation-event. Returns TRUE if we interrupt this script call.
if(FirePreUserEvent(AI_FLAG_UDE_ON_DIALOGUE_PRE_EVENT, EVENT_ON_DIALOGUE_PRE_EVENT)) return;
// AI status check. Is the AI on?
if(GetAIOff()) return;
// Declarations
int nMatch = GetListenPatternNumber();
object oShouter = GetLastSpeaker();
string sSpoken = GetMatchedSubstring(0);
// We can ignore everything under special cases - EG no valid shouter,
// we are fleeing, its us, or we are not in the same area.
// - We break out of the script if this happens.
if(!GetIsObjectValid(oShouter) || /* Must be a valid speaker! */
oShouter == OBJECT_SELF || /* Not us! */
GetIsPerformingSpecialAction() || /* Not fleeing */
GetIgnore(oShouter) || /* Not ignoring the shouter */
GetArea(oShouter) != GetArea(OBJECT_SELF))/* Same area (Stops loud yellow shouts getting NPCs) */
{
// Fire End of Dialogue event
FireUserEvent(AI_FLAG_UDE_ON_DIALOGUE_EVENT, EVENT_ON_DIALOGUE_EVENT);
return;
}
// Conversation if not a shout.
if(nMatch == -1)
{
// * Don't speak when dead. 1.4 change (an obvious one to make)
if(CanSpeak())
{
// Make sure it is a PC and we are not fighting.
if(!GetIsFighting() && (GetIsPC(oShouter) || GetIsDMPossessed(oShouter)))
{
// If we have something random (or not) to say instead of
// the conversation, we will say that.
if(GetLocalInt(OBJECT_SELF, ARRAY_SIZE + AI_TALK_ON_CONVERSATION))
{
ClearAllActions();// Stop
SetFacingPoint(GetPosition(oShouter));// Face
SpeakArrayString(AI_TALK_ON_CONVERSATION);// Speak string
PlayAnimation(ANIMATION_LOOPING_TALK_NORMAL, 1.0, 3.0);// "Talk", then resume potitions.
ActionDoCommand(ExecuteScript(FILE_WALK_WAYPOINTS, OBJECT_SELF));
}
else
{
// If we are set to NOT clear all actions, we won't.
if(!GetSpawnInCondition(AI_FLAG_OTHER_NO_CLEAR_ACTIONS_BEFORE_CONVERSATION, AI_OTHER_MASTER))
{
ClearAllActions();
}
BeginConversation();
}
}
}
}
// If it is a valid shout...and a valid shouter.
// - Not a DM. Not ignoring shouting. Not a Debug String.
else if(!GetLocalTimer(AI_TIMER_SHOUT_IGNORE_ANYTHING_SAID) &&// Not listening (IE heard already)
!GetIsDM(oShouter) && FindSubString(sSpoken, "[Debug]") == -1 &&
// 1.4 - Deafness (or they are seen) check, for fun.
(!GetHasEffect(EFFECT_TYPE_DEAF) || GetObjectSeen(oShouter)))
{
if(GetIsFriend(oShouter) || GetFactionEqual(oShouter))
{
// If they are a friend, not a PC, and a valid number, react.
// In the actual RespondToShout call, we do check to see if we bother.
// - Is PC - or is...master?
// - Shouts which are not negative, and not AI_ANYTHING_SAID_CONSTANT.
if(nMatch >= 0 && nMatch != AI_SHOUT_ANYTHING_SAID_CONSTANT &&
!GetIsPC(oShouter) && !GetIsPC(GetMaster(oShouter)))
{
// Respond to the shout
RespondToShout(oShouter, nMatch);
}
// Else either is PC or is shout 0 (everything!)
// - not if we are in combat, or they are not.
else if(!CannotPerformCombatRound() &&
GetIsInCombat(oShouter) &&
GetObjectType(oShouter) == OBJECT_TYPE_CREATURE)
{
// 57: "[Shout] Friend (may be PC) in combat. Attacking! [Friend] " + GetName(oShouter)
DebugActionSpeakByInt(57, oShouter);
// Respond to oShouter
IWasAttackedResponse(oShouter);
}
}
else if(GetIsEnemy(oShouter) && GetObjectType(oShouter) == OBJECT_TYPE_CREATURE)
{
// If we hear anything said by an enemy, and are not fighting, attack them!
if(!CannotPerformCombatRound())
// the negatives are associate shouts, Normally (!)
// 0+ are my shouts. 0 is anything
{
// We make sure it isn't an emote (set by default)
if(nMatch == AI_SHOUT_ANYTHING_SAID_CONSTANT &&
GetSpawnInCondition(AI_FLAG_OTHER_DONT_RESPOND_TO_EMOTES, AI_OTHER_MASTER))
{
// Jump out if its an emote - "*Nods*"
if(GetStringLeft(sSpoken, 1) == EMOTE_STAR &&
GetStringRight(sSpoken, 1) == EMOTE_STAR)
{
// Fire End of Dialogue event
FireUserEvent(AI_FLAG_UDE_ON_DIALOGUE_EVENT, EVENT_ON_DIALOGUE_EVENT);
return;
}
}
// 58: "[Shout] Responding to shout [Enemy] " + GetName(oShouter) + " Who has spoken!"
DebugActionSpeakByInt(58, oShouter);
// Short non-respond
SetLocalTimer(AI_TIMER_SHOUT_IGNORE_ANYTHING_SAID, 6.0);
// Attack the enemy!
ClearAllActions();
DetermineCombatRound(oShouter);
// Shout to allies to attack the shouter
AISpeakString(AI_SHOUT_I_WAS_ATTACKED);
}
}
}
// Fire End of Dialogue event
FireUserEvent(AI_FLAG_UDE_ON_DIALOGUE_EVENT, EVENT_ON_DIALOGUE_EVENT);
}

View File

@@ -1,241 +0,0 @@
/*/////////////////////// [On Damaged] /////////////////////////////////////////
Filename: nw_c2_default6 or J_AI_OnDamaged
///////////////////////// [On Damaged] /////////////////////////////////////////
We attack any damager if same area (and not already fighting
then search for enemies (defaults to searching if there are no enemies left).
///////////////////////// [History] ////////////////////////////////////////////
1.3 - If we have a damager, not equal faction, and not a DM...
- We set Max Elemental damage.
- Sets the highest damager and amount (if the new damager is seen/heard)
- Polymorph improved a little
- Hide check
- Morale penalty (if set)
1.4 - Elemental damage fixed with bugfixed introduced in later patches.
- Moved things around, more documentation, a little more ordered.
- Added the missing silent shout strings to get allies to attack.
- Damaged taunting will not happen if we are dead.
///////////////////////// [Workings] ///////////////////////////////////////////
Now with fixes, we can correctly set physical damage done (and elemental
damage).
Otherwise, this acts like a hositile spell, or a normal attack or pickpocket
attempt would - and attack the damn person who dares damage us!
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: GetTotalDamageDealt, GetLastDamager, GetCurrentHitPoints (and max),
GetDamageDealtByType (must be done seperatly for each, doesn't count melee damage)
///////////////////////// [On Damaged] ///////////////////////////////////////*/
#include "J_INC_OTHER_AI"
void main()
{
// Pre-damaged-event. Returns TRUE if we interrupt this script call.
if(FirePreUserEvent(AI_FLAG_UDE_DAMAGED_PRE_EVENT, EVENT_DAMAGED_PRE_EVENT)) return;
// AI status check. Is the AI on?
if(GetAIOff()) return;
// Define Objects/Integers.
int nDamage = GetTotalDamageDealt();
object oDamager = GetLastDamager();
// Check to see if we will polymorph.
int nPolymorph = GetAIConstant(AI_POLYMORPH_INTO);
// Total up the physical damage
// Polymorph check.
if(nPolymorph >= 0)
{
// We won't polymorph if already so
if(!GetHasEffect(EFFECT_TYPE_POLYMORPH))
{
// Polymorph into the requested shape. Cannot be dispelled.
effect eShape = SupernaturalEffect(EffectPolymorph(nPolymorph));
effect eVis = EffectVisualEffect(VFX_FNF_SUMMON_UNDEAD);
DelayCommand(1.0, ApplyEffectToObject(DURATION_TYPE_PERMANENT, eShape, OBJECT_SELF));
DelayCommand(1.0, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, OBJECT_SELF));
}
DeleteAIConstant(AI_POLYMORPH_INTO);// We set it to invalid (sets to 0).
}
// First, we check AOE spells...
if(GetObjectType(oDamager) == OBJECT_TYPE_AREA_OF_EFFECT)
{
// Set the damage done by it (the last damage)
// Set to the tag of the AOE, prefixed AI style to be sure.
// - Note, doesn't matter about things like
if(nDamage > 0)
{
// Set it to object to string, which we will delete later anywho.
SetAIInteger(ObjectToString(oDamager), nDamage);
}
}
// Hostile attacker...but it doesn't matter (at the moment) if they even
// did damage.
// * GetIgnoreNoFriend() wrappers DM, Validity, Faction Equal and Dead checks in one
else if(!GetIgnoreNoFriend(oDamager))
{
// Adjust automatically if set. (and not an AOE)
if(GetSpawnInCondition(AI_FLAG_OTHER_CHANGE_FACTIONS_TO_HOSTILE_ON_ATTACK, AI_OTHER_MASTER))
{
if(!GetIsEnemy(oDamager) && !GetFactionEqual(oDamager))
{
AdjustReputation(oDamager, OBJECT_SELF, -100);
}
}
// Turn of hiding, a timer to activate Hiding in the main file. This is
// done in each of the events, with the opposition checking seen/heard.
TurnOffHiding(oDamager);
// Did they do damage to use? (IE: No DR) Some things are inapproprate
// to check if no damage was actually done.
if(nDamage > 0)
{
// Speak the damaged string, if applicable.
// * Don't speak when dead. 1.4 change (an obvious one to make)
if(CanSpeak())
{
SpeakArrayString(AI_TALK_ON_DAMAGED);
}
// 1.4 note: These two variables are currently *unused* apart from
// healing. When healing a being (even another NPC) they are checked
// for massive damage. Can not bother to set the highest damager for now.
// NEW:
int nHighestDamage = GetAIInteger(AI_HIGHEST_DAMAGE_AMOUNT);
if(nDamage >= nHighestDamage)
{
SetAIInteger(AI_HIGHEST_DAMAGE_AMOUNT, nDamage);
}
/* OLD:
// Get the previous highest damager, and highest damage amount
object oHighestDamager = GetAIObject(AI_HIGHEST_DAMAGER);
int nHighestDamage = GetAIInteger(AI_HIGHEST_DAMAGE_AMOUNT);
// Set the highest damager, if they are seen or heard, and have done loads.
if((GetObjectSeen(oDamager) || GetObjectHeard(oDamager)) &&
nDamage >= nHighestDamage || !GetIsObjectValid(oHighestDamager))
{
SetAIObject(AI_HIGHEST_DAMAGER, oDamager);
SetAIInteger(AI_HIGHEST_DAMAGE_AMOUNT, nDamage);
}
// Else, if the original was not valid...or not seen/heard, we
// delete it so we don't bother to use it later.
else if(!GetIsObjectValid(oHighestDamager) ||
(!GetObjectSeen(oHighestDamager) && !GetObjectHeard(oHighestDamager)))
{
DeleteAIObject(AI_HIGHEST_DAMAGER);
DeleteAIInteger(AI_HIGHEST_DAMAGE_AMOUNT);
}
*/
// Get all the physical damage. Elemental damage is then nDamage minus
// the physical damage.
int nPhysical = GetDamageDealtByType(DAMAGE_TYPE_BASE_WEAPON |
DAMAGE_TYPE_BLUDGEONING |
DAMAGE_TYPE_PIERCING |
DAMAGE_TYPE_SLASHING);
// If they are all -1, then we make nPhysical 0.
if(nPhysical <= -1) nPhysical = 0;
// Physical damage - only sets if the last damager is the last attacker.
if(GetAIObject(AI_STORED_LAST_ATTACKER) == oDamager)
{
// Get the previous highest damage and test it
if(nPhysical > GetAIInteger(AI_HIGHEST_PHISICAL_DAMAGE_AMOUNT))
{
// If higher, and was a melee/ranged attacker, set it.
// This does include other additional physical damage - EG:
// weapon property: Bonus Damage.
SetAIInteger(AI_HIGHEST_PHISICAL_DAMAGE_AMOUNT, nPhysical);
}
}
// Set the max elemental damage done, for better use of elemental
// protections. This is set for the most damage...so it could be
// 1 (for a +1 fire weapon, any number of hits) or over 50 (good
// fireball/flame storm etc.)
int nElemental = nDamage - nPhysical;
if(nElemental > GetAIInteger(MAX_ELEMENTAL_DAMAGE))
{
SetAIInteger(MAX_ELEMENTAL_DAMAGE, nElemental);
}
// Set the last damage done, may set to 0 of course :-P
// * This is only set if they did damage us at all, however.
SetAIInteger(LAST_ELEMENTAL_DAMAGE, nElemental);
// Morale: We may get a penalty if it does more than a cirtain amount of HP damage.
// Other: We set highest damager and amount.
if(!GetSpawnInCondition(AI_FLAG_FLEEING_FEARLESS, AI_TARGETING_FLEE_MASTER))
{
// Get penalty and how much damage at once needs to be done
int nPenalty = GetBoundriedAIInteger(AI_DAMAGE_AT_ONCE_PENALTY, 6, 50, 1);
int nToDamage = GetBoundriedAIInteger(AI_DAMAGE_AT_ONCE_FOR_MORALE_PENALTY, GetMaxHitPoints()/6, GetMaxHitPoints(), 1);
if(nDamage > nToDamage)
{
// 61: "[Damaged] Morale Penalty for 600 seconds [Penalty]" + IntToString(iPenalty)
DebugActionSpeakByInt(61, OBJECT_INVALID, nPenalty);
// Apply penalty
SetMoralePenalty(nPenalty, 300.0);
}
}
}
// If we are not attacking anything, and not in combat, react!
if(!CannotPerformCombatRound())
{
// 62: "[Damaged] Not in combat: DCR [Damager]" + GetName(oDamager)
DebugActionSpeakByInt(62, oDamager);
// Check if they are in the same area. Can be a left AOE spell.
// Don't attack purposly across area's.
if(GetArea(oDamager) == GetArea(OBJECT_SELF))
{
// Shout to allies to attack the enemy who attacked me
AISpeakString(AI_SHOUT_I_WAS_ATTACKED);
DetermineCombatRound(oDamager);
}
else
{
// Shout to allies to attack, or be prepared.
AISpeakString(AI_SHOUT_CALL_TO_ARMS);
DetermineCombatRound();
}
}
else
{
// Shout to allies to attack, or be prepared.
AISpeakString(AI_SHOUT_CALL_TO_ARMS);
}
}
// Else it is friendly, or invalid damager
else
{
// Still will react - eg: A left AOE spell (which might mean a battle
// just happened)
if(!CannotPerformCombatRound())
{
// Shout to allies to attack generally. No target to specifically attack,
// as it is an ally.
AISpeakString(AI_SHOUT_CALL_TO_ARMS);
// 63: [Damaged] Not in combat: DCR. Ally hit us. [Damager(Ally?)]" + GetName(oDamager)
DebugActionSpeakByInt(63, oDamager);
DetermineCombatRound();
}
else
{
// Shout to allies to attack, or be prepared.
AISpeakString(AI_SHOUT_CALL_TO_ARMS);
}
}
// User defined event - for normally immoral creatures.
if(GetCurrentHitPoints() == 1)
{
// Fire the immortal damaged at 1 HP event.
FireUserEvent(AI_FLAG_UDE_DAMAGED_AT_1_HP, EVENT_DAMAGED_AT_1_HP);
}
// Fire End of Damaged event
FireUserEvent(AI_FLAG_UDE_DAMAGED_EVENT, EVENT_DAMAGED_EVENT);
}

View File

@@ -1,164 +0,0 @@
/*/////////////////////// [On Death] ///////////////////////////////////////////
Filename: J_AI_OnDeath or nw_c2_default7
///////////////////////// [On Death] ///////////////////////////////////////////
Speeded up no end, when compiling, with seperate Include.
Cleans up all un-droppable items, all ints and all local things when destroyed.
Check down near the bottom for a good place to add XP or corpse lines ;-)
///////////////////////// [History] ////////////////////////////////////////////
1.3 - Added in Turn of corpses toggle
- Added in appropriate space for XP awards, marked with ideas (effect death)
1.4 - Removed the redudnant notes on the "You have gained 0 experience" message
///////////////////////// [Workings] ///////////////////////////////////////////
You can edit this for experience, there is a seperate section for it.
It will use DeathCheck to execute a cleanup-and-destroy script, that removes
any coprse, named "j_ai_destroyself".
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: GetLastKiller.
///////////////////////// [On Death] /////////////////////////////////////////*/
// We only require the constants/debug file. We have 1 function, not worth another include.
#include "J_INC_CONSTANTS"
// We need a wrapper. If the amount of deaths, got in this, is not equal to iDeaths,
// we don't execute the script, else we do. :-P
void DeathCheck(int nDeaths);
void main()
{
// If we are set to, don't fire this script at all
if(GetAIInteger(I_AM_TOTALLY_DEAD)) return;
// Pre-death-event. Returns TRUE if we interrupt this script call.
if(FirePreUserEvent(AI_FLAG_UDE_DEATH_PRE_EVENT, EVENT_DEATH_PRE_EVENT)) return;
// Note: No AI on/off check here.
// Who killed us? (alignment changing, debug, XP).
object oKiller = GetLastKiller();
// Stops if we just applied EffectDeath to ourselves.
if(GetLocalTimer(AI_TIMER_DEATH_EFFECT_DEATH)) return;
// Special: To stop giving out multiple amounts of XP, we use EffectDeath
// to change the killer, so the XP systems will NOT award MORE XP.
// - Even the default one suffers from this!
if(GetAIInteger(WE_HAVE_DIED_ONCE))
{
if(!GetLocalTimer(AI_TIMER_DEATH_EFFECT_DEATH))
{
// Don't apply effect death to self more then once per 2 seconds.
SetLocalTimer(AI_TIMER_DEATH_EFFECT_DEATH, 2.0);
// This should make the last killer us.
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectResurrection(), OBJECT_SELF);
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(GetMaxHitPoints()), OBJECT_SELF);
}
}
else if(oKiller != OBJECT_SELF)
{
// Set have died once, stops giving out mulitple amounts of XP.
SetAIInteger(WE_HAVE_DIED_ONCE, TRUE);
/*/////////////////////// [Experience] /////////////////////////////////////////
THIS is the place for it, below this comment.
It is useful to use GetFirstFactionMember (and Next), GiveXPToCreature,
GetXP, SetXP, GetChallengeRating (of self) all are really useful.
Bug note: GetFirstFactionMember/Next with the PC parameter means either ONLY PC,
and so NPC henchmen, unless FALSE is used, will not be even recognised.
///////////////////////// [Experience] ///////////////////////////////////////*/
// Do XP things (Use object "oKiller" for who killed us).
/*/////////////////////// [Experience] ///////////////////////////////////////*/
}
// Note: Here we do a simple way of checking how many times we have died.
// Nothing special. Debugging most useful aspect.
int nDeathCounterNew = GetAIInteger(AMOUNT_OF_DEATHS);
nDeathCounterNew++;
SetAIInteger(AMOUNT_OF_DEATHS, nDeathCounterNew);
// Here is the last time (in game seconds) we died. It is used in the executed script
// to make sure we don't prematurly remove areselves.
// We may want some sort of visual effect - like implosion or something, to fire.
int nDeathEffect = GetAIConstant(AI_DEATH_VISUAL_EFFECT);
// Valid constants from 0 and up. Apply to our location (not to us, who will go!)
if(nDeathEffect >= 0)
{
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(nDeathEffect), GetLocation(OBJECT_SELF));
}
// Default Commoner alignment changing. (If the commoner is not evil!)
if(GetLevelByClass(CLASS_TYPE_COMMONER) > 0 &&
GetAlignmentGoodEvil(OBJECT_SELF) != ALIGNMENT_EVIL &&
!GetSpawnInCondition(AI_FLAG_OTHER_NO_COMMONER_ALIGNMENT_CHANGE, AI_OTHER_MASTER))
{
if(GetIsPC(oKiller))
{
AdjustAlignment(oKiller, ALIGNMENT_EVIL, 5);
}
else
{
// If it is a summon, henchmen or familar of a PC, we adust the PC itself
// Clever, eh?
object oMaster = GetMaster(oKiller);
if(GetIsObjectValid(oMaster) && GetIsPC(oMaster))
{
AdjustAlignment(oMaster, ALIGNMENT_EVIL, 5);
}
}
}
// Always shout when we are killed. Reactions - Morale penalty, and
// attack the killer.
AISpeakString(AI_SHOUT_I_WAS_KILLED);
// Speaks the set death speak, like "AGGGGGGGGGGGGGGGGGGG!! NOOOO!" for instance :-)
// Note for 1.4: No need for "CanSpeak()" for this, of course.
SpeakArrayString(AI_TALK_ON_DEATH);
// First check - do we use "destroyable corpses" or not? (default, yes)
if(!GetSpawnInCondition(AI_FLAG_OTHER_TURN_OFF_CORPSES, AI_OTHER_MASTER))
{
// We will actually dissapear after 30.0 seconds if not raised.
int nTime = GetAIInteger(AI_CORPSE_DESTROY_TIME);
if(nTime == 0) // Error checking
{
nTime = 30;
}
// 64: "[Death] Checking corpse status in " + IntToString(nTime) + " [Killer] " + GetName(oKiller) + " [Times Died Now] " + IntToString(nDeathCounterNew)
DebugActionSpeakByInt(64, oKiller, nTime, IntToString(nDeathCounterNew));
// Delay check
DelayCommand(IntToFloat(nTime), DeathCheck(nDeathCounterNew));
}
else
{
/************************ [Alternative Corpses] ********************************
This is where you can add some alternative corpse code - EG looting
and so on, without disrupting the rest of the AI (as the corpses
are turned off).
************************* [Alternative Corpses] *******************************/
// Add alternative corpse code here
/************************ [Alternative Corpses] *******************************/
}
// Signal the death event.
FireUserEvent(AI_FLAG_UDE_DEATH_EVENT, EVENT_DEATH_EVENT);
}
// We need a wrapper. If the amount of deaths, got in this, is not equal to iDeaths,
// we don't execute the script, else we do. :-P
void DeathCheck(int nDeaths)
{
// Do the deaths imputted equal the amount we have suffered?
if(GetAIInteger(AMOUNT_OF_DEATHS) == nDeaths)
{
// - This now includes a check for Bioware's lootable functions and using them.
ExecuteScript(FILE_DEATH_CLEANUP, OBJECT_SELF);
}
}

View File

@@ -1,85 +0,0 @@
/*/////////////////////// [On Disturbed] ///////////////////////////////////////
Filename: J_AI_OnDisturbed or nw_c2_default8
///////////////////////// [On Disturbed] ///////////////////////////////////////
This will attack pickpockets, and inventory disturbers. Note: Stupidly, Bioware
made this only affect the creature by stealing. Still, oh well :-(
This means that the only event which fires it is pickpocketing.
///////////////////////// [History] ////////////////////////////////////////////
1.3 - Changed why we determine combat round
- Any change in inventory will trigger appropriate SetWeapons again.
- Added turn of hide things.
1.4 - Cleaned up a bit. Removed unused declared variable.
///////////////////////// [Workings] ///////////////////////////////////////////
Only fired by stealing, great. Oh well, it will attack any disturber anyway.
It *might* not be fired if the natural spot check to notice a theft doesn't
work. No idea personally.
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: GetInventoryDisturbItem, GetLastDisturbed,
GetInventoryDisturbType (I think it is always be stolen :-( ).
///////////////////////// [On Disturbed] /////////////////////////////////////*/
#include "J_INC_OTHER_AI"
void main()
{
// Pre-disturbed-event. Returns TRUE if we interrupt this script call.
if(FirePreUserEvent(AI_FLAG_UDE_DISTURBED_PRE_EVENT, EVENT_DISTURBED_PRE_EVENT)) return;
// AI status check. Is the AI on?
if(GetAIOff()) return;
// Declare major variables
object oDisturber = GetLastDisturbed();
object oItem = GetInventoryDisturbItem();
int nType = GetInventoryDisturbType();
int nBase = GetBaseItemType(oItem);
// We will reset weapons if it is a weapon.
// Reset weapons, or specifically healers kits.
if(GetIsObjectValid(oItem))
{
// Kits
if(nBase == BASE_ITEM_HEALERSKIT)
{
SetLocalInt(OBJECT_SELF, AI_WEAPONSETTING_SETWEAPONS, 2);
ExecuteScript(FILE_RE_SET_WEAPONS, OBJECT_SELF);
}
else // Think it is a weapon. Saves time :-)
{
SetLocalInt(OBJECT_SELF, AI_WEAPONSETTING_SETWEAPONS, 1);
ExecuteScript(FILE_RE_SET_WEAPONS, OBJECT_SELF);
}
}
// Fight! Or search!
if(!GetIgnoreNoFriend(oDisturber) &&
(nType == INVENTORY_DISTURB_TYPE_STOLEN || GetIsEnemy(oDisturber)))
{
// Turn of hiding, a timer to activate Hiding in the main file. This is
// done in each of the events, with the opposition checking seen/heard.
TurnOffHiding(oDisturber);
// Can we attack?
if(!CannotPerformCombatRound())
{
// Someone specific to attack
AISpeakString(AI_SHOUT_I_WAS_ATTACKED);
// One debug speak. We always do one.
// 65: "[Disturbed] (pickpocket) Attacking Enemy Distrube [Disturber] " + GetName(oTarget) + " [Type] " + IntToString(iType)
DebugActionSpeakByInt(65, oDisturber, nType);
// Attack the disturber
DetermineCombatRound(oDisturber);
}
else
{
// Get allies interested.
AISpeakString(AI_SHOUT_CALL_TO_ARMS);
}
}
// Fire End-heartbeat-UDE
FireUserEvent(AI_FLAG_UDE_DISTURBED_EVENT, EVENT_DISTURBED_EVENT);
}

View File

@@ -1,114 +0,0 @@
/*/////////////////////// [On Heartbeat] ///////////////////////////////////////
Filename: nw_c2_default1 or J_AI_OnHeartbeat
///////////////////////// [On Heartbeat] ///////////////////////////////////////
Removed stupid stuff, special behaviour, sleep.
Also, note please, I removed waypoints and day/night posting from this.
It can be re-added if you like, but it does reduce heartbeats.
Added in better checks to see if we should fire this script. Stops early if
some conditions (like we can't move, low AI settings) are set.
Hint: If nothing is used within this script, either remove it from creatures
or create one witch is blank, with just a "void main(){}" at the top.
Hint 2: You could add this very small file to your catche of scripts in the
module properties, as it runs on every creature every 6 seconds (ow!)
This also uses a system of Execute Script :-D This means the heartbeat, when
compiled, should be very tiny.
Note: NO Debug strings!
Note 2: Remember, I use default SoU Animations/normal animations. As it is
executed, we can check the prerequisists here, and then do it VIA
execute script.
-Working- Best possible, fast compile.
///////////////////////// [History] ////////////////////////////////////////////
1.3 - Added more "buffs" to fast buff.
- Fixed animations (they both WORK and looping ones do loop right!)
- Loot behaviour!
- Randomly moving nearer a PC in 25M if set.
- Removed silly day/night optional setting. Anything we can remove, is a good idea.
1.4 - Removed AI level setting. Not good to use, I mistakenly added it.
///////////////////////// [Workings] ///////////////////////////////////////////
This fires off every 6 seconds (with PCs in the area, or AI_LEVEL_HIGH without)
and therefore is intensive.
It fires of ExecutesScript things for the different parts - saves CPU stuff
if the bits are not used.
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: Basically, none. Nothing activates this script. Fires every 6 seconds.
///////////////////////// [On Heartbeat] /////////////////////////////////////*/
// - This includes J_Inc_Constants
#include "J_INC_HEARTBEAT"
void main()
{
// Special - Runner from the leader shouts, each heartbeat, to others to get thier
// attention that they are being attacked.
// - Includes fleeing making sure (so it resets the ActionMoveTo each 6 seconds -
// this is not too bad)
// - Includes door bashing stop heartbeat
if(PerformSpecialAction()) return;
// Pre-heartbeat-event. Returns TRUE if we interrupt this script call.
if(FirePreUserEvent(AI_FLAG_UDE_HEARTBEAT_PRE_EVENT, EVENT_HEARTBEAT_PRE_EVENT)) return;
// AI status check. Is the AI on?
if(GetAIOff() || GetSpawnInCondition(AI_FLAG_OTHER_LAG_IGNORE_HEARTBEAT, AI_OTHER_MASTER)) return;
// Define the enemy and player to use.
object oEnemy = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY);
object oPlayer = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC);
// We can skip to the end if we are in combat, or something...
if(!JumpOutOfHeartBeat() && // We don't stop due to effects.
!GetIsInCombat() && // We are not in combat.
!GetIsObjectValid(GetAttackTarget()) && // Second combat check.
!GetObjectSeen(oEnemy)) // Nearest enemy is not seen.
{
// Fast buffing...if we have the spawn in condition...
if(GetSpawnInCondition(AI_FLAG_COMBAT_FLAG_FAST_BUFF_ENEMY, AI_COMBAT_MASTER) &&
GetIsObjectValid(oEnemy) && GetDistanceToObject(oEnemy) <= 40.0)
{
// ...we may do an advanced buff. If we cannot see/hear oEnemy, but oEnemy
// is within 40M, we cast many defensive spells instantly...
ExecuteScript(FILE_HEARTBEAT_TALENT_BUFF, OBJECT_SELF);
//...if TRUE (IE it does something) we turn of future calls.
DeleteSpawnInCondition(AI_FLAG_COMBAT_FLAG_FAST_BUFF_ENEMY, AI_COMBAT_MASTER);
// This MUST STOP the heartbeat event - else, the actions may be interrupted.
return;
}
// Execute waypoints file if we have waypoints set up.
if(GetWalkCondition(NW_WALK_FLAG_CONSTANT))
{
ExecuteScript(FILE_WALK_WAYPOINTS, OBJECT_SELF);
}
// We can't have any waypoints for the other things
else
{
// We must have animations set, and not be "paused", so doing a
// longer looping one
// - Need a valid player.
if(GetIsObjectValid(oPlayer) && !IsInConversation(OBJECT_SELF))
{
// We may search for PC enemies, 25% chance to move closer to PC's
if(GetSpawnInCondition(AI_FLAG_OTHER_SEARCH_IF_ENEMIES_NEAR, AI_OTHER_MASTER) &&
!GetLocalTimer(AI_TIMER_SEARCHING) && d4() == 1)
{
ExecuteScript(FILE_HEARTBEAT_WALK_TO_PC, OBJECT_SELF);
}
// Else, Do we have any animations to speak of?
// If we have a nearby PC, we do animations.
else if(GetHasValidAnimations())
{
ExecuteScript(FILE_HEARTBEAT_ANIMATIONS, OBJECT_SELF);
}
}
}
}
// Fire End-heartbeat-UDE
FireUserEvent(AI_FLAG_UDE_HEARTBEAT_EVENT, EVENT_HEARTBEAT_EVENT);
}

View File

@@ -1,220 +0,0 @@
/*/////////////////////// [On Percieve] ////////////////////////////////////////
Filename: J_AI_OnPercieve or nw_c2_default2
///////////////////////// [On Percieve] ////////////////////////////////////////
If the target is an enemy, attack
Will determine combat round on that person, is an enemy, basically.
Includes shouting for a big radius - if the spawn in condition is set to this.
NOTE: Debug strings in this file will be uncommented for speed by default.
- It is one of the most intensive scripts as it runs so often.
- Attempted to optimise as much as possible.
///////////////////////// [History] ////////////////////////////////////////////
1.3 - We include j_inc_other_ai to initiate combat (or go into combat again)
- j_inc_other_ai holds all other needed functions/integers ETC.
- Turn off hide things.
- Added "Only attack if attacked"
- Removed special conversation things. Almost no one uses them, and the taunt system is easier.
- Should now search around if they move to a dead body, and only once they get there.
1.4 - TO DO:
1. Perception needs checking - attacking outside perception ranges!
2. Vanishing targets, etc. test, improve.
3. Problems with dispelling invisibility. Maybe either do change the line to create placable, or, of course, cast at location (dispells cannot be metamagiked or whatever) Source
4. No Effect Type Ethereal. Source
///////////////////////// [Workings] ///////////////////////////////////////////
It fires:
- When a creature enters it perception range (Set in creature properties) and
is seen or heard.
* Tests show (and in general) it fires HEARD first, then immediantly SEEN if,
of course, they are visible. Odd really, but true.
- When a creature uses invisiblity/leaves the area in the creatures perception
range
- When a creature appears suddenly, already in the perception range (not
the other way round, normally)
- When a creature moves out of the creatures perception range, and therefore
becomes unseen.
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: GetLastPerceived, GetLastPerceptionSeen, GetLastPerceptionHeard,
GetLastPerceptionVanished, GetLastPerceptionInaudible.
///////////////////////// [On Percieve] //////////////////////////////////////*/
#include "J_INC_OTHER_AI"
void main()
{
// Pre-percieve-event. Returns TRUE if we interrupt this script call.
if(FirePreUserEvent(AI_FLAG_UDE_PERCIEVE_PRE_EVENT, EVENT_PERCIEVE_PRE_EVENT)) return;
// AI status check. Is the AI on?
if(GetAIOff()) return;
// Declare main things.
// - We declare OUTSIDE if's JUST IN CASE!
object oPerceived = GetLastPerceived();
object oAttackTarget = GetAttackTarget();
// 1.4: Very rarely is our attack target valid, so we will set it to
// what we would have melee attacked when DCR was called.
if(GetIgnoreNoFriend(oAttackTarget) || oAttackTarget == OBJECT_SELF)
{
oAttackTarget = GetAIObject(AI_LAST_MELEE_TARGET);
}
int bSeen = GetLastPerceptionSeen();
int bHeard = GetLastPerceptionHeard();
int bVanished = GetLastPerceptionVanished();
int bInaudiable = GetLastPerceptionInaudible();
// Debug
DebugActionSpeak("*** PER ***: " + GetName(oPerceived) + "| SEEN: " + IntToString(bSeen) +
"| HEARD: " + IntToString(bHeard) + "| VANISHED: " + IntToString(bVanished) +
"| INAUDIABLE: " + IntToString(bInaudiable));
// Need to be valid and not ignorable.
if(GetIsObjectValid(oPerceived) &&
!GetIsDM(oPerceived) &&
!GetIgnore(oPerceived))
{
// First, easy enemy checks.
if(GetIsEnemy(oPerceived) && !GetFactionEqual(oPerceived))
{
DebugActionSpeak("*** PER *** ENEMY");
// Turn of hiding, a timer to activate Hiding in the main file. This is
// done in each of the events, with the opposition checking seen/heard.
TurnOffHiding(oPerceived);
// Well, are we both inaudible and vanished?
// * the GetLastPerception should only say what specific event has fired!
if(bVanished || bInaudiable)
{
DebugActionSpeak("*** PER *** VANISHED OR INAUDIBLE");
// If they just became invisible because of the spell
// invisiblity, or improved invisiblity...we set a local object.
// - Beta: Added in ethereal as well.
if(GetHasEffect(EFFECT_TYPE_INVISIBILITY, oPerceived) ||
GetHasEffect(EFFECT_TYPE_SANCTUARY, oPerceived) ||
GetStealthMode(oPerceived) == STEALTH_MODE_ACTIVATED)
{
// Set object, AND the location they went invisible!
SetAIObject(AI_LAST_TO_GO_INVISIBLE, oPerceived);
// We also set thier location for AOE dispelling - same name
SetAILocation(AI_LAST_TO_GO_INVISIBLE, GetLocation(oPerceived));
}
// If they were our target, follow! >:-D
// - Optional, on spawn option, for following through areas.
if(oAttackTarget == oPerceived)
{
DebugActionSpeak("*** PER *** VANISHED OR INAUDIBLE AND IS CURRENT TARGET");
// This means they have exited the area! follow!
if(GetArea(oPerceived) != GetArea(OBJECT_SELF))
{
ClearAllActions();
// 51: "[Perception] Our Enemy Target changed areas. Stopping, moving too...and attack... [Percieved] " + GetName(oPerceived)
DebugActionSpeakByInt(51, oPerceived);
// Call to stop silly moving to enemies if we are fleeing
ActionMoveToEnemy(oPerceived);
}
// - Added check for not casting a spell. If we are, we finnish
// (EG: AOE spell) and automatically carry on.
// 1.4: If we are using a targetted spell, we do cancle our
// spellcasting if it is them.
else if(GetCurrentAction() != ACTION_CASTSPELL ||
GetAttackTarget() == oPerceived)
{
ClearAllActions();
// 52: "[Perception] Enemy Vanished (Same area) Retargeting/Searching [Percieved] " + GetName(oPerceived)
DebugActionSpeakByInt(52, oPerceived);
DetermineCombatRound(oPerceived);
}
}
}// End if just gone out of perception
// ELSE they have been SEEN or HEARD. We don't check specifics.
else //if(bSeen || bHeard)
{
// If they have been made seen, and they are our attack target,
// we must re-do combat round - unless we are casting a spell.
if(bSeen && GetCurrentAction() != ACTION_CASTSPELL &&
(oAttackTarget == oPerceived || !GetObjectSeen(oAttackTarget)))
{
// 53: "[Perception] Enemy seen, and was old enemy/cannot see current. Re-evaluating (no spell) [Percieved] " + GetName(oPerceived)
DebugActionSpeakByInt(53, oPerceived);
DetermineCombatRound(oPerceived);
// Shout to allies to attack oPerceived
AISpeakString(AI_SHOUT_I_WAS_ATTACKED);
}
// Else We check if we are already attacking.
else if(!CannotPerformCombatRound() &&
!GetSpawnInCondition(AI_FLAG_OTHER_ONLY_ATTACK_IF_ATTACKED, AI_OTHER_MASTER))
{
// * Don't speak when dead. 1.4 change (an obvious one to make)
if(CanSpeak())
{
// Special shout, d1000 though!
SpeakArrayString(AI_TALK_ON_PERCIEVE_ENEMY, TRUE);
}
// Stop stuff because of facing point - New enemy
HideOrClear();
// Get all allies in 60M to come to thier aid. Talkvolume silent
// shout does not seem to work well.
// - void function. Checks for the spawn int. in it.
// - Turns it off in it too (5 minutes - 1.4)
// - Variable range On Spawn
ShoutBossShout(oPerceived);
// 54: "[Perception] Enemy Seen. Not in combat, attacking. [Percieved] " + GetName(oPerceived)
DebugActionSpeakByInt(54, oPerceived);
// 1.4 change: SetFacingPoint(GetPosition(oPerceived));
// Is now part of DetermineCombatRound().
// * This means other events will work similarily.
DetermineCombatRound(oPerceived);
// Warn others
AISpeakString(AI_SHOUT_I_WAS_ATTACKED);
}
}
}
// Else, they are an equal faction, or not an enemy (or both)
else
{
// If they are dead, or fighting, eg: we saw something on
// waypoints, we charge in to investigate.
// * Higher intelligence will buff somewhat as well!
if((GetIsDead(oPerceived) || GetIsInCombat(oPerceived)) &&
(bSeen || bHeard))
{
if(GetIsDead(oPerceived))
{
// 55: "[Perception] Percieved Dead Friend! Moving into investigate [Percieved] " + GetName(oPerceived)
DebugActionSpeakByInt(55, oPerceived);
}
else
{
// 56: "[Perception] Percieved Alive Fighting Friend! Moving to and attacking. [Percieved] " + GetName(oPerceived)
DebugActionSpeakByInt(56, oPerceived);
}
// Check if we can attack
if(!CannotPerformCombatRound())
{
// Hide or clear actions
HideOrClear();
// If we were called to arms, react
CallToArmsResponse(oPerceived);
}
else
{
// Warn others even if we don't, or cannot, attack
AISpeakString(AI_SHOUT_CALL_TO_ARMS);
}
}
}
}
// Fire End of Percieve event
FireUserEvent(AI_FLAG_UDE_PERCIEVE_EVENT, EVENT_PERCIEVE_EVENT);
}

View File

@@ -1,136 +0,0 @@
/*/////////////////////// [On Phisical Attacked] ///////////////////////////////
Filename: J_AI_OnPhiAttack or nw_c2_default5
///////////////////////// [On Phisical Attacked] ///////////////////////////////
On Attacked
No checking for fleeing or warnings.
Very boring really!
///////////////////////// [History] ////////////////////////////////////////////
1.3 - Added hiding things
1.4 - Missing Silent Shouts have been added.
///////////////////////// [Workings] ///////////////////////////////////////////
Got some simple Knockdown timer, so that we use heal sooner if we keep getting
a creature who is attempting to knock us down.
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: GetLastAttacker, GetLastWeaponUsed, GetLastAttackMode, GetLastAttackType
///////////////////////// [On Phisical Attacked] /////////////////////////////*/
#include "J_INC_OTHER_AI"
void main()
{
// Pre-attacked-event. Returns TRUE if we interrupt this script call.
if(FirePreUserEvent(AI_FLAG_UDE_ATTACK_PRE_EVENT, EVENT_ATTACK_PRE_EVENT)) return;
// AI status check. Is the AI on?
if(GetAIOff()) return;
// Set up objects.
object oAttacker = GetLastAttacker();
object oWeapon = GetLastWeaponUsed(oAttacker);
//int nMode = GetLastAttackMode(oAttacker); // Currently unused
int nAttackType = GetLastAttackType(oAttacker);
// Check if they are valid, a DM, we are ignoring them, they are dead now, or invalid
if(!GetIgnoreNoFriend(oAttacker))
{
// Adjust automatically if set.
if(GetSpawnInCondition(AI_FLAG_OTHER_CHANGE_FACTIONS_TO_HOSTILE_ON_ATTACK, AI_OTHER_MASTER))
{
if(!GetIsEnemy(oAttacker))
{
AdjustReputation(oAttacker, OBJECT_SELF, -100);
}
}
// If we were attacked by knockdown, for a timer of X seconds, we make
// sure we attempt healing at a higher level.
if(!GetLocalTimer(AI_TIMER_KNOCKDOWN) &&
(nAttackType == SPECIAL_ATTACK_IMPROVED_KNOCKDOWN ||
nAttackType == SPECIAL_ATTACK_KNOCKDOWN) &&
!GetIsImmune(OBJECT_SELF, IMMUNITY_TYPE_KNOCKDOWN) &&
GetBaseAttackBonus(oAttacker) + 20 >= GetAC(OBJECT_SELF))
{
SetLocalTimer(AI_TIMER_KNOCKDOWN, 30.0);
}
// Set last hostile, valid attacker (Used in the On Damaged event)
SetAIObject(AI_STORED_LAST_ATTACKER, oAttacker);
// * Don't speak when dead. 1.4 change (an obvious one to make)
if(CanSpeak())
{
// Speak the phisically attacked string, if applicable.
// Speak the damaged string, if applicable.
SpeakArrayString(AI_TALK_ON_PHISICALLY_ATTACKED);
}
// Turn of hiding, a timer to activate Hiding in the main file. This is
// done in each of the events, with the opposition checking seen/heard.
TurnOffHiding(oAttacker);
// We set if we are attacked in HTH onto a low-delay timer.
// - Not currently used
/*if(!GetLocalTimer(AI_TIMER_ATTACKED_IN_HTH))
{
// If the weapon is not ranged, or is not valid, set the timer.
if(!GetIsObjectValid(oWeapon) ||
!GetWeaponRanged(oWeapon))
{
SetLocalTimer(AI_TIMER_ATTACKED_IN_HTH, f18);
}
}*/
// If we are not fighting, and they are in the area, attack. Else, determine anyway.
if(!CannotPerformCombatRound())
{
// Must be in our area to go after now.
if(GetArea(oAttacker) == GetArea(OBJECT_SELF))
{
// 59: "[Phisically Attacked] Attacking back. [Attacker(enemy)] " + GetName(oAttacker)
DebugActionSpeakByInt(59, oAttacker);
// Attack the attacker
DetermineCombatRound(oAttacker);
// Shout to allies to attack the enemy who attacked me
AISpeakString(AI_SHOUT_I_WAS_ATTACKED);
}
else
{
// Shout to allies to attack, or be prepared.
AISpeakString(AI_SHOUT_CALL_TO_ARMS);
// 60: "[Phisically Attacked] Not same area. [Attacker(enemy)] " + GetName(oAttacker)
DebugActionSpeakByInt(60, oAttacker);
// May find another hostile to attack...
DetermineCombatRound();
}
}
else
{
// Shout to allies to attack, or be prepared.
AISpeakString(AI_SHOUT_CALL_TO_ARMS);
}
}
// Else, invalid, DM, ally, etc...must be prepared at least (could be
// they are charmed or something!)
else
{
// If we are not fighting, prepare for battle. Something bad must have
// happened.
if(!CannotPerformCombatRound())
{
// Respond to oAttacker as if they shouted for help.
IWasAttackedResponse(oAttacker);
}
else
{
// Shout to allies to attack, or be prepared.
AISpeakString(AI_SHOUT_CALL_TO_ARMS);
}
}
// Fire End of Attacked event
FireUserEvent(AI_FLAG_UDE_ATTACK_EVENT, EVENT_ATTACK_EVENT);
}

View File

@@ -1,84 +0,0 @@
/*/////////////////////// [On Rested] //////////////////////////////////////////
Filename: J_AI_OnRest or nw_c2_defaulta
///////////////////////// [On Rested] //////////////////////////////////////////
This will play the sitting animation for 6 seconds, just something for resting.
Also, walks waypoints (as resting would stop this) :-) and signals event (if so be)
Feel free to edit.
It does have the spell trigger information resetting, however. This can
only be removed if they have no spell triggers, although it is hardly worth it.
///////////////////////// [History] ////////////////////////////////////////////
1.3 - Added sitting.
1.4 - Will be editing this down. No need to reset anything on rest, for a
better working AI.
IDEA: Change so that we will work through all spells/feats in order.
If, at cirtain levels, we do not have any spells to cast from that
level (set in a global stored integer in the general AI) we ignore all
spells in that level. Same for each talent category (no need to use
talents for them in the spawn script).
If not in combat (EG: In heartbeat) we reset the integers saying "don't
bother checking those spells" to false.
///////////////////////// [Workings] ///////////////////////////////////////////
This fires once, at the END of resting.
If ClearAllActions is added, the resting is actually stopped, or so it seems.
It doesn't fire more then once.
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: None, it seems.
///////////////////////// [On Rested] ////////////////////////////////////////*/
#include "J_INC_CONSTANTS"
// Resets all spell triggers used for sString
void LoopResetTriggers(string sString, object oTrigger);
void main()
{
// Pre-rest-event. Returns TRUE if we interrupt this script call.
if(FirePreUserEvent(AI_FLAG_UDE_RESTED_PRE_EVENT, EVENT_RESTED_PRE_EVENT)) return;
// AI status check. Is the AI on?
if(GetAIOff()) return;
// Simple debug.
// 66: "[Rested] Resting. Type: " + IntToString(GetLastRestEventType())
DebugActionSpeakByInt(66, OBJECT_INVALID, GetLastRestEventType());
// Reset all spell triggers.
// Set all triggers
object oTrigger = GetAIObject(AI_SPELL_TRIGGER_CREATURE);
if(GetIsObjectValid(oTrigger))
{
LoopResetTriggers(SPELLTRIGGER_NOT_GOT_FIRST_SPELL, oTrigger);
LoopResetTriggers(SPELLTRIGGER_DAMAGED_AT_PERCENT, oTrigger);
LoopResetTriggers(SPELLTRIGGER_IMMOBILE, oTrigger);
LoopResetTriggers(SPELLTRIGGER_START_OF_COMBAT, oTrigger);
}
// Some sitting for a few seconds.
ActionPlayAnimation(ANIMATION_LOOPING_SIT_CROSS, 1.0, 6.0);
DelayCommand(9.0, ExecuteScript(FILE_WALK_WAYPOINTS, OBJECT_SELF));
// Fire End-heartbeat-UDE
FireUserEvent(AI_FLAG_UDE_RESTED_EVENT, EVENT_RESTED_EVENT);
}
// Resets all spell triggers used for sString
void LoopResetTriggers(string sString, object oTrigger)
{
int nCnt, bBreak, bUsed;
for(nCnt = 1; bBreak != TRUE; nCnt++)
{
// Check max for this setting
bUsed = GetLocalInt(oTrigger, sString + USED);
if(bUsed)
{
DeleteLocalInt(oTrigger, sString + USED);
}
else
{
bBreak = TRUE;
}
}
}

View File

@@ -1,644 +0,0 @@
/*/////////////////////// [On Spawn] ///////////////////////////////////////////
Filename: J_AI_OnSpawn or nw_c2_default9
///////////////////////// [On Spawn] ///////////////////////////////////////////
This file contains options that will determine some AI behaviour, and a lot
of toggles for turning things on/off. A big read, but might be worthwhile.
The documentation is actually fully in the readme files, under the name
"On Spawn.html", under "AI File Explanations".
The order of the options:
- Important Spawn Settings N/A
- Targeting & Fleeing (AI_TARGETING_FLEE_MASTER)
- Fighting & Spells (AI_COMBAT_MASTER)
- Other Combat - Healing, Skills & Bosses (AI_OTHER_COMBAT_MASTER)
- Other - Death corpses, minor things (AI_OTHER_MASTER)
- User Defined (AI_UDE_MASTER)
- Shouts N/A
- Default Bioware settings (WP's, Anims) (NW_GENERIC_MASTER)
The OnSpawn file is a settings file. These things are set onto a creature, to
define cirtain actions. If more than one creature has this script, they all
use the settings, unless If/Else statements are used somehow. There is also
the process of setting any spells/feats availible, and hiding and walk waypoints
are started.
Other stuff:
- Targeting is imporant :-D
- If you delete this script, there is a template for the On Spawn file
in the zip it came in, for use in the "scripttemplate" directory.
///////////////////////// [History] ////////////////////////////////////////////
Note: I have removed:
- Default "Teleporting" and exit/return (this seemed bugged anyway, or useless)
- Spawn in animation. This can be, of course, re-added.
- Day/night posting. This is uneeded, with a changed walk waypoints that does it automatically.
1.0-1.2 - Used short amount of spawn options.
1.3 - All constants names are changed, I am afraid.
- Added Set/Delete/GetAIInteger/Constant/Object. This makes sure that the AI
doesn't ever interfere with other things - it pre-fixes all stored things
with AI_INTEGER_ (and so on)
1.4 - TO DO: Clear up some old non-working ones
- Added in User Defined part of the script, an auto-turn-off-spells for
Ranger and Paladin classes. Need to test - perhaps 1.64 fixed it?
Spawn options changed:
- Removed AI level settings (can still be done manually)
- Added optional (and off by default) fear-visual for fleeing
///////////////////////// [Workings] ///////////////////////////////////////////
Note: You can do without all the comments (it may be that you don't want
the extra KB it adds or something, although it does not at all slow down a module)
so as long as you have these at the end:
AI_SetUpEndOfSpawn();
DelayCommand(2.0, SpawnWalkWayPoints());
Oh, and the include file (Below, "j_inc_spawnin") must be at the top like
here. Also recommended is the AI_INTELLIGENCE and AI_MORALE being set (if
not using custom AI).
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: GetIsEncounterCreature
///////////////////////// [On Spawn] /////////////////////////////////////////*/
// Treasure Includes - See end of spawn for uncomment options.
//#include "nw_o2_coninclude"
// Uncomment this if you want default NwN Treasure - Uses line "GenerateNPCTreasure()" at the end of spawn.
// - This generates random things from the default pallet based on the creatures level + race
//#include "x0_i0_treasure"
// Uncomment this if you want the SoU Treasure - Uses line "CTG_GenerateNPCTreasure()" at the end of spawn.
// - This will spawn treasure based on chests placed in the module. See "x0_i0_treasure" for more information.
// This is required for all spawn in options!
#include "J_INC_SPAWNIN"
void main()
{
/************************ [Important Spawn Settings] **************************/
SetAIInteger(AI_INTELLIGENCE, 10);
// Intelligence value of the creauture. Can be 1-10, read readme's for help.
SetAIInteger(AI_MORALE, 10);
// Will save (See readme). Remember: -1 or below means they always flee.
//SetCustomAIFileName("CUSTOM_AI_FILE");
// Sets our custom AI file. Really, only animation settings will apply when this is set.
// - Can sort actions against a imputted target (EG: On Percieved enemy) by
// "GetLocalObject(OBJECT_SELF, "AI_TEMP_SET_TARGET");"
/************************ [Important Spawn Settings] **************************/
/************************ [Targeting] ******************************************
All targeting settings.
************************* [Targeting] *****************************************/
//SetSpawnInCondition(AI_FLAG_TARGETING_LIKE_LOWER_HP, AI_TARGETING_FLEE_MASTER);
// We only attack the lowest current HP.
//SetSpawnInCondition(AI_FLAG_TARGETING_LIKE_LOWER_AC, AI_TARGETING_FLEE_MASTER);
// We only attack the lowest AC (as in 1.2).
//SetSpawnInCondition(AI_FLAG_TARGETING_LIKE_LOWER_HD, AI_TARGETING_FLEE_MASTER);
// Target the lowest hit dice
//SetSpawnInCondition(AI_FLAG_TARGETING_LIKE_MAGE_CLASSES, AI_TARGETING_FLEE_MASTER);
// We go straight for mages/sorcerors. Nearest one.
//SetSpawnInCondition(AI_FLAG_TARGETING_LIKE_ARCHERS, AI_TARGETING_FLEE_MASTER);
// We go for the nearest enemy with a ranged weapon equipped.
//SetSpawnInCondition(AI_FLAG_TARGETING_LIKE_PCS, AI_TARGETING_FLEE_MASTER);
// We go for the nearest seen PC enemy.
//SetAIConstant(AI_FAVOURED_ENEMY_RACE, RACIAL_TYPE_HUMAN);
// The AI attacks the nearest enemy, seen, of this race. Use the RACIAL_* constants.
//SetAIConstant(AI_FAVOURED_ENEMY_CLASS, CLASS_TYPE_BARD);
// The AI attacks the nearest enemy, seen, of this class. Use the CLASS_* constants.
// Target changing - see readme for info.
//SetAIInteger(AI_MAX_TURNS_TO_ATTACK_ONE_TARGET, 6);
// Maximum rounds to attack the current target, before re-checking.
// % Chance to re-set each target type each round (Could result in current target still)
//SetAIInteger(AI_MELEE_LAST_TO_NEW_TARGET_CHANCE, 20);
//SetAIInteger(AI_RANGED_LAST_TO_NEW_TARGET_CHANCE, 20);
//SetAIInteger(AI_SPELL_LAST_TO_NEW_TARGET_CHANCE, 20);
// We only target PC's if there are any in range if this is set
//SetSpawnInCondition(AI_FLAG_TARGETING_FILTER_FOR_PC_TARGETS, AI_TARGETING_FLEE_MASTER);
// Main explanation of AI_SetAITargetingValues, see the AI readme (spawn file)
// - Remember, uncommenting one will just ignore it (so will never check target's
// AC without TARGETING_AC on)
AI_SetAITargetingValues(TARGETING_MANTALS, TARGET_LOWER, 1, 12);
// Spell mantals are checked only for the spell target. Either Absense of or got any.
AI_SetAITargetingValues(TARGETING_RANGE, TARGET_HIGHER, 2, 9);
// Range - very imporant! Basis for all ranged/spell attacks.
AI_SetAITargetingValues(TARGETING_AC, TARGET_LOWER, 2, 6);
// AC is used for all phisical attacks. Lower targets lower (By default).
AI_SetAITargetingValues(TARGETING_SAVES, TARGET_LOWER, 2, 4);
// Used for spell attacks. Saves are sorta a AC versus spells.
// Phisical protections. Used by spells, ranged and melee.
// Jasperre - simple check if we are a fighter (hit lower phisicals) or a
// mage (attack higher!)
if(GetBaseAttackBonus(OBJECT_SELF) > ((GetHitDice(OBJECT_SELF)/2) + 1))
{
// Fighter/Clerics (It is over a mages BAB + 1 (IE 0.5 BAB/Level) target lower
AI_SetAITargetingValues(TARGETING_PHISICALS, TARGET_LOWER, 2, 6);
}
else
{
// Mages target higher (so dispel/elemental attack those who fighters
// cannot hit as much). (the lowest BAB, under half our hit dice in BAB)
AI_SetAITargetingValues(TARGETING_PHISICALS, TARGET_HIGHER, 1, 5);
}
// Base attack bonus. Used for spells and phisical attacks. Checked with GetBaseAttackBonus.
AI_SetAITargetingValues(TARGETING_BAB, TARGET_LOWER, 1, 4);
// Hit dice - how powerful in levels the enemy is. Used for all checks.
AI_SetAITargetingValues(TARGETING_HITDICE, TARGET_LOWER, 1, 3);
//AI_SetAITargetingValues(TARGETING_HP_PERCENT, TARGET_LOWER, 1, 3);
//AI_SetAITargetingValues(TARGETING_HP_CURRENT, TARGET_LOWER, 1, 3);
//AI_SetAITargetingValues(TARGETING_HP_MAXIMUM, TARGET_LOWER, 1, 3);
// The HP's are the last thing to choose a target with.
/************************ [Targeting] *****************************************/
/************************ [Fleeing] ********************************************
Fleeing - these are toggled on/off by FEARLESS flag.
3 or under intelligence will just run away. 4 or more will know where allies
are, and if there are none, will not run.
************************* [Fleeing] *******************************************/
SetSpawnInCondition(AI_FLAG_FLEEING_FEARLESS, AI_TARGETING_FLEE_MASTER);
// Forces them to not flee. This may be set with AI_SetMaybeFearless at the end.
//SetSpawnInCondition(AI_FLAG_FLEEING_NEVER_FIGHT_IMPOSSIBLE_ODDS, AI_TARGETING_FLEE_MASTER);
// This will make the creature never fight against impossible odds (8HD+ different)
//SetSpawnInCondition(AI_FLAG_FLEEING_TURN_OFF_GROUP_MORALE, AI_TARGETING_FLEE_MASTER);
// This turns OFF any sort of group morale bonuses.
//SetAIInteger(AMOUNT_OF_HD_DIFFERENCE_TO_CHECK, -2);
// If enemy is within this amount of HD, we do not check morale.
//SetAIInteger(BASE_MORALE_SAVE, 20);
// Base DC of the will save. It is set to 20 + HD difference - Morale - Group morale mod.
//SetAIInteger(HP_PERCENT_TO_CHECK_AT, 80);
// %HP needed to be at to check morale. This doesn't affect "Never fight impossible odds"
//SetSpawnInCondition(AI_FLAG_FLEEING_NO_OVERRIDING_HP_AMOUNT, AI_TARGETING_FLEE_MASTER);
// This will turn off overriding HP checks. AI may decide to run even
// not at the %HP above, this turns the checks off.
//SetAIInteger(AI_DAMAGE_AT_ONCE_FOR_MORALE_PENALTY, GetMaxHitPoints()/6);
// Damage needed to be done at once to get a massive morale penalty (Below)
//SetAIInteger(AI_DAMAGE_AT_ONCE_PENALTY, 6);
// Penalty for the above, set for some time to negativly affect morale. Added to save DC for fleeing.
//SetSpawnInCondition(AI_FLAG_FLEEING_FLEE_TO_NEAREST_NONE_SEEN, AI_TARGETING_FLEE_MASTER);
// If set, just runs to nearest non-seen ally, and removes the loop for a good group of allies to run to.
//SetSpawnInCondition(AI_FLAG_FLEEING_FLEE_TO_OBJECT, AI_TARGETING_FLEE_MASTER);
// They will flee to the nearest object of the tag below, if set.
//SetLocalString(OBJECT_SELF, AI_FLEE_OBJECT, "BOSS_TAG_OR_WHATEVER");
// This needs setting if the above is to work.
//SetSpawnInCondition(AI_FLAG_FLEEING_USE_VISUAL_EFFECT, AI_TARGETING_FLEE_MASTER);
// If this is on, we play a visual effect while we flee.
/************************ [Fleeing] *******************************************/
/************************ [Combat - Fighters] **********************************
Fighter (Phiscal attacks, really) specific stuff - disarmed weapons, better
at hand to hand, and archer behaviour.
************************* [Combat - Fighters] *********************************/
SetSpawnInCondition(AI_FLAG_COMBAT_PICK_UP_DISARMED_WEAPONS, AI_COMBAT_MASTER);
// This sets to pick up weapons which are disarmed.
//SetAIInteger(AI_RANGED_WEAPON_RANGE, 3);
// This is the range at which they go into melee (from using a ranged weapon). Default is 3 or 5.
//SetSpawnInCondition(AI_FLAG_COMBAT_BETTER_AT_HAND_TO_HAND, AI_COMBAT_MASTER);
// Set if you want them to move forwards into HTH sooner. Will always
// if the enemy is a mage/archer, else % based on range.
//SetSpawnInCondition(AI_FLAG_COMBAT_ARCHER_ATTACKING, AI_COMBAT_MASTER);
// For archers. If they have ally support, they'd rather move back & shoot then go into HTH.
//SetSpawnInCondition(AI_FLAG_COMBAT_ARCHER_ALWAYS_MOVE_BACK, AI_COMBAT_MASTER);
// This forces the move back from attackers, and shoot bows. Very small chance to go melee.
//SetSpawnInCondition(AI_FLAG_COMBAT_ARCHER_ALWAYS_USE_BOW, AI_COMBAT_MASTER);
// This will make the creature ALWAYs use any bows it has. ALWAYS.
//SetSpawnInCondition(AI_FLAG_COMBAT_NO_GO_FOR_THE_KILL, AI_COMBAT_MASTER);
// Turns off any attempts to kill dying PCs, or attack low hit point people.
// This is only ever attempted at 9 or 10 intelligence anyway.
/************************ [Combat - Fighters] *********************************/
/************************ [Combat - Spell Casters] *****************************
Spellcaster AI has been improved significantly. As well as adding all new spells,
now spellcasters more randomly choose spells from the same level (EG: they
may choose not to cast magic missile, and cast negative energy ray instead).
There are also options here for counterspelling, fast buffing, Cheat cast spells,
dispelling, spell triggers, long ranged spells first, immunity toggles, and AOE settings.
************************* [Combat - Spell Casters] ****************************/
//SetSpawnInCondition(AI_FLAG_COMBAT_LONGER_RANGED_SPELLS_FIRST, AI_COMBAT_MASTER);
// Casts spells only if the caster would not move into range to cast them.
// IE long range spells, then medium, then short (unless the enemy comes to us!)
//SetSpawnInCondition(AI_FLAG_COMBAT_FLAG_FAST_BUFF_ENEMY, AI_COMBAT_MASTER);
// When an enemy comes in 40M, we fast-cast many defensive spells, as if prepared.
//SetSpawnInCondition(AI_FLAG_COMBAT_SUMMON_FAMILIAR, AI_COMBAT_MASTER);
// The caster summons thier familiar/animal companion. Either a nameless Bat or Badger respectivly.
// Counterspelling/Dispelling...
// It checks for these classes within the 20M counterspell range.
//SetSpawnInCondition(AI_FLAG_COMBAT_COUNTER_SPELL_ARCANE, AI_COMBAT_MASTER);
// If got dispels, it counterspells Arcane (Mage/Sorceror) spellcasters.
//SetSpawnInCondition(AI_FLAG_COMBAT_COUNTER_SPELL_DIVINE, AI_COMBAT_MASTER);
// If got dispels, it counterspells Divine (Cleric/Druid) spellcasters.
//SetSpawnInCondition(AI_FLAG_COMBAT_COUNTER_SPELL_ONLY_IN_GROUP, AI_COMBAT_MASTER);
// Recommended. Only counterspells with 5+ allies in group.
//SetSpawnInCondition(AI_FLAG_COMBAT_DISPEL_MAGES_MORE, AI_COMBAT_MASTER);
// Targets seen mages to dispel, else uses normal spell target.
SetSpawnInCondition(AI_FLAG_COMBAT_DISPEL_IN_ORDER, AI_COMBAT_MASTER);
// This will make the mage not dispel just anything all the time, but important (spell-stopping)
// things first, others later, after some spells. If off, anything is dispelled.
// AOE's
//SetSpawnInCondition(AI_FLAG_COMBAT_NEVER_HIT_ALLIES, AI_COMBAT_MASTER);
// Override toggle. Forces to never cast AOE's if it will hit an ally + harm them.
//SetSpawnInCondition(AI_FLAG_COMBAT_AOE_DONT_MIND_IF_THEY_SURVIVE, AI_COMBAT_MASTER);
// Allies who will survive the blast are ignored for calculating best target.
//SetAIInteger(AI_AOE_ALLIES_LOWEST_IN_AOE, 3);
// Defualt: 3. If amount of allies in blast radius are equal or more then
// this, then that location is ignored.
//SetAIInteger(AI_AOE_HD_DIFFERENCE, -8);
// Very weak allies (who are not comparable to us) are ignored if we would hit them.
// For these 2, if neither are set, the AI will choose AOE more if there are
// lots of enemies, or singles if there are not many.
//SetSpawnInCondition(AI_FLAG_COMBAT_SINGLE_TARGETING, AI_COMBAT_MASTER);
// For Same-level spells, single target spells are used first.
//SetSpawnInCondition(AI_FLAG_COMBAT_MANY_TARGETING, AI_COMBAT_MASTER);
// For Same-level spells, AOE spells are used first.
SetSpawnInCondition(AI_FLAG_COMBAT_IMPROVED_INSTANT_DEATH_SPELLS, AI_COMBAT_MASTER);
// A few Death spells may be cast top-prioritory if the enemy will always fail saves.
SetSpawnInCondition(AI_FLAG_COMBAT_IMPROVED_SUMMON_TARGETING, AI_COMBAT_MASTER);
// Will use a better target to summon a creature at (EG: Ranged attacker)
SetSpawnInCondition(AI_FLAG_COMBAT_IMPROVED_IMMUNITY_CHECKING, AI_COMBAT_MASTER);
// Turns On "GetIsImmune" checks. Auto on for 7+ Intel.
SetSpawnInCondition(AI_FLAG_COMBAT_IMPROVED_SPECIFIC_SPELL_IMMUNITY, AI_COMBAT_MASTER);
// Turns On checks for Globes & levels of spells. Auto on for 9+ Intel.
//SetSpawnInCondition(AI_FLAG_COMBAT_MORE_ALLY_BUFFING_SPELLS, AI_COMBAT_MASTER);
// This will make the caster buff more allies - or, in fact, use spells
// to buff allies which they might have not used before.
//SetSpawnInCondition(AI_FLAG_COMBAT_USE_ALL_POTIONS, AI_COMBAT_MASTER);
// Uses all buffing spells before melee.
//SetAICheatCastSpells(SPELL_MAGIC_MISSILE, SPELL_ICE_DAGGER, SPELL_HORIZIKAULS_BOOM, SPELL_MELFS_ACID_ARROW, SPELL_NEGATIVE_ENERGY_RAY, SPELL_FLAME_ARROW);
// Special: Mages cast for ever with this set.
// Spell triggers
//SetSpellTrigger(SPELLTRIGGER_NOT_GOT_FIRST_SPELL, FALSE, 1, SPELL_PREMONITION);
// This is just an example. See readme for more info.
/************************ [Combat - Spell Casters] ****************************/
/************************ [Combat - Dragons] ***********************************
I have a fondness for dragons - in NWN they are deprived of many abilities. Here
are some new ones for your enjoyment! Switches and flying for ANYTHING! :-)
************************* [Combat - Dragons] **********************************/
//SetSpawnInCondition(AI_FLAG_COMBAT_NO_WING_BUFFET, AI_COMBAT_MASTER);
//This sets so there is no Dragon wing buffet. Readme has details of it.
//SetAIInteger(AI_DRAGON_FREQUENCY_OF_BUFFET, 3);
// Min. Amount of Rounds between each buffet. See readme for counter defaults. Def: 3
//SetAIInteger(AI_DRAGON_FREQUENCY_OF_BREATH, 3);
// Min. Amount of Rounds between each breath use. See readme for counter defaults. Def: 3
// Default checks for dragon flying automatic turning on of flying.
if(GetLevelByClass(CLASS_TYPE_DRAGON) || MyPRCGetRacialType(OBJECT_SELF) == RACIAL_TYPE_DRAGON)
{
SetSpawnInCondition(AI_FLAG_COMBAT_FLYING, AI_COMBAT_MASTER);
// This turns ON combat flying. I think anything winged looks A-OK. See readme for info.
}
/************************ [Combat - Dragons] **********************************/
/************************ [Combat Other - Healers/Healing] *********************
Healing behaviour - not specifically clerics. See readme.
************************* [Combat Other - Healers/Healing] ********************/
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_HEAL_AT_PERCENT_NOT_AMOUNT, AI_OTHER_COMBAT_MASTER);
// if this is set, we ignore the amount we need to be damaged, as long
// as we are under AI_HEALING_US_PERCENT.
//SetAIInteger(AI_HEALING_US_PERCENT, 50);
// % of HP we need to be at until we heal us at all. Default: 50
//SetAIInteger(AI_HEALING_ALLIES_PERCENT, 60);
// % of HP allies would need to be at to heal them Readme = info. Default: 60
SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_WILL_RAISE_ALLIES_IN_BATTLE, AI_OTHER_COMBAT_MASTER);
// Turns on rasing dead with Resurrection/Raise dead.
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_CURING, AI_OTHER_COMBAT_MASTER);
// This turns off all healing.
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_ONLY_CURE_SELF, AI_OTHER_COMBAT_MASTER);
// This turns off ally healing.
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_ONLY_RESTORE_SELF, AI_OTHER_COMBAT_MASTER);
// This turns off ally restoring (Remove/Restoration).
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_USE_BAD_HEALING_SPELLS, AI_OTHER_COMBAT_MASTER);
// This forces all cure spells to be used, check readme.
//SetAIInteger(SECONDS_BETWEEN_STATUS_CHECKS, 30);
// Seconds between when we loop everyone for bad effects like Fear/stun ETC. If not set, done each round.
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_GIVE_POTIONS_TO_HELP, AI_OTHER_COMBAT_MASTER);
// ActionGiveItem standard healing potion's to allies who need them, if they possess them.
/************************ [Combat Other - Healers/Healing] ********************/
/************************ [Combat Other - Skills] ******************************
Skills are a part of fighting - EG Taunt. These are mainly on/off switches.
A creature will *may* use it if they are not set to "NO_" for the skill.
************************* [Combat Other - Skills] *****************************/
// "NO" - This is for forcing the skill NEVER to be used by the combat AI.
// "FORCE" - This forces it on (and to be used), except if they have no got the skill.
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_PICKPOCKETING, AI_OTHER_COMBAT_MASTER);
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_FORCE_PICKPOCKETING, AI_OTHER_COMBAT_MASTER);
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_TAUNTING, AI_OTHER_COMBAT_MASTER);
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_FORCE_TAUNTING, AI_OTHER_COMBAT_MASTER);
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_EMPATHY, AI_OTHER_COMBAT_MASTER);
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_FORCE_EMPATHY, AI_OTHER_COMBAT_MASTER);
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_HIDING, AI_OTHER_COMBAT_MASTER);
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_FORCE_HIDING, AI_OTHER_COMBAT_MASTER);
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_OPENING_LOCKED_DOORS, AI_OTHER_COMBAT_MASTER);
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_FORCE_OPENING_LOCKED_DOORS, AI_OTHER_COMBAT_MASTER);
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_USING_HEALING_KITS, AI_OTHER_COMBAT_MASTER);
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_PARRYING, AI_OTHER_COMBAT_MASTER);
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_FORCE_PARRYING, AI_OTHER_COMBAT_MASTER);
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_SEARCH, AI_OTHER_COMBAT_MASTER);
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_FORCE_SEARCH, AI_OTHER_COMBAT_MASTER);
// - Concentration - special notes in the readme
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_CONCENTRATION, AI_OTHER_COMBAT_MASTER);
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_FORCE_CONCENTRATION, AI_OTHER_COMBAT_MASTER);
/************************ [Combat Other - Skills] *****************************/
/************************ [Combat Other - Leaders] *****************************
Leaders/Bosses can be set to issue some orders and inspire more morale - and bring
a lot of allies to a battle at once!
************************* [Combat Other - Leaders] ****************************/
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_GROUP_LEADER, AI_OTHER_COMBAT_MASTER);
// Special leader. Can issuse some orders. See readme for details.
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_BOSS_MONSTER_SHOUT, AI_OTHER_COMBAT_MASTER);
// Boss shout. 1 time use - calls all creatures in X meters (below) for battle!
//SetAIInteger(AI_BOSS_MONSTER_SHOUT_RANGE, 60);
// Defaults to a 60 M range. This can change it. Note: 1 toolset square = 10M.
/************************ [Combat Other - Leaders] ****************************/
/************************ [Other - Behaviour/Generic] **************************
This is generic behaviours - alright, really it is all things that cannot
really be categorised.
************************* [Other - Behaviour/Generic] *************************/
//SetSpawnInCondition(AI_FLAG_OTHER_NO_CLEAR_ACTIONS_BEFORE_CONVERSATION, AI_OTHER_MASTER);
// No ClearAllActions() before BeginConversation. May keep a creature sitting.
//SetSpawnInCondition(AI_FLAG_OTHER_NO_POLYMORPHING, AI_OTHER_MASTER);
// This will stop all polymorphing spells feats from being used.
//SetSpawnInCondition(AI_FLAG_OTHER_CHEAT_MORE_POTIONS, AI_OTHER_MASTER);
// If at low HP, and no potion, create one and use it.
//SetAIConstant(AI_POLYMORPH_INTO, POLYMORPH_TYPE_WEREWOLF);
// Polymorph to this creature when damaged (once, natural effect).
//AI_CreateRandomStats(-3, 3, 6);
// Create (Effect-applied) random statistics.
//AI_CreateRandomOther(-2, 2, -2, 2, -2, 2, -2, 2);
// Create (Effect-applied) random HP, saves, AC.
//SetSpawnInCondition(AI_FLAG_OTHER_RETURN_TO_SPAWN_LOCATION, AI_OTHER_MASTER);
// This will store our spawn location, and then move back there after combat.
SetSpawnInCondition(AI_FLAG_OTHER_DONT_RESPOND_TO_EMOTES, AI_OTHER_MASTER);
// This will ignore ALL chat by PC's (Enemies) who speak actions in Stars - *Bow*
//SetSpawnInCondition(AI_FLAG_OTHER_DONT_SHOUT, AI_OTHER_MASTER);
// Turns off all silent talking NPC's do to other NPC's.
//SetSpawnInCondition(AI_FLAG_OTHER_SEARCH_IF_ENEMIES_NEAR, AI_OTHER_MASTER);
// Move randomly closer to enemies in range set below.
//SetAIInteger(AI_SEARCH_IF_ENEMIES_NEAR_RANGE, 25);
// This is the range creatures use, in metres.
//SetSpawnInCondition(AI_FLAG_OTHER_ONLY_ATTACK_IF_ATTACKED, AI_OTHER_MASTER);
// One shot. We won't instantly attack a creature we see. See readme.
//SetAIInteger(AI_DOOR_INTELLIGENCE, 1);
// 3 Special "What to do with Doors" settings. See readme. Good for animals.
//SetSpawnInCondition(AI_FLAG_OTHER_REST_AFTER_COMBAT, AI_OTHER_MASTER);
// When combat is over, creature rests. Useful for replenising health.
//SetSpawnInCondition(AI_FLAG_OTHER_NO_PLAYING_VOICE_CHAT, AI_OTHER_MASTER);
// Stops any use of "PlayVoiceChat". Use with Custom speakstrings.
/*** Death settings - still under AI_OTHER_MASTER ***/
//AI_SetDeathResRef("Resref Here");
// Creates a creature from the string set. Instantly destroys this creatures body on death.
//SetAIConstant(AI_DEATH_VISUAL_EFFECT, VFX_FNF_IMPLOSION);
// Fires this visual effect number instantly on death. Use FNF and IMP ones.
//SetAIInteger(AI_CORPSE_DESTROY_TIME, 30);
// Seconds before body finally gets destroyed. Used for Clerical Raise Dead on NPC's.
//SetSpawnInCondition(AI_FLAG_OTHER_TURN_OFF_CORPSES, AI_OTHER_MASTER);
// This turns off the SetDestroyable() usually performed, and the above timer.
//SetSpawnInCondition(AI_FLAG_OTHER_USE_BIOWARE_LOOTING, AI_OTHER_MASTER);
// Makes the death file use Bioware's cool SetLootable() feature when corpses would disappear.
/*** Lag and a few performance settings - still under AI_OTHER_MASTER ***/
//SetSpawnInCondition(AI_FLAG_OTHER_LAG_NO_ITEMS, AI_OTHER_MASTER);
// The creature doesn't check for, or use any items that cast spells.
//SetSpawnInCondition(AI_FLAG_OTHER_LAG_NO_SPELLS, AI_OTHER_MASTER);
//The creature doesn't ever cast spells (and never checks them)
//SetSpawnInCondition(AI_FLAG_OTHER_LAG_NO_LISTENING, AI_OTHER_MASTER);
// The creature doesn't have SetListening() set. Turns of the basic listening for shouts.
//SetSpawnInCondition(AI_FLAG_OTHER_LAG_EQUIP_MOST_DAMAGING, AI_OTHER_MASTER);
// Uses EquipMostDamaging(), like Bioware code. No shield/second weapon equipped.
//SetSpawnInCondition(AI_FLAG_OTHER_LAG_NO_CURING_ALLIES, AI_OTHER_MASTER);
// This will stop checks for and curing of allies ailments.
//SetSpawnInCondition(AI_FLAG_OTHER_LAG_IGNORE_HEARTBEAT, AI_OTHER_MASTER);
// Stops the heartbeat running (Except Pre-Heartbeat-event).
//SetSpawnInCondition(AI_FLAG_OTHER_LAG_TARGET_NEAREST_ENEMY, AI_OTHER_MASTER);
// Ignores targeting settings. VERY good for lag/bad AI. Attacks nearest seen enemy.
/************************ [Other - Behaviour/Generic] *************************/
/************************ [User Defined and Shouts] ****************************
The user defined events, set up to fire here.
- New "Start combat attack" and "End Combat Attack" events
- New "Pre" events. Use these to optionally stop a script from firing
under cirtain circumstances as well! (Read nw_c2_defaultd or j_ai_onuserdef)
(User Defined Event = UDE)
************************* [User Defined and Shouts] ***************************/
// This is REQUIRED if we use any Pre-events. If not there, it will default
// to the default User Defined Event script for the default AI.
SetCustomUDEFileName("k_ai_onuserdef");
//SetSpawnInCondition(AI_FLAG_UDE_HEARTBEAT_EVENT, AI_UDE_MASTER); // UDE 1001
//SetSpawnInCondition(AI_FLAG_UDE_HEARTBEAT_PRE_EVENT, AI_UDE_MASTER); // UDE 1021
//SetSpawnInCondition(AI_FLAG_UDE_PERCIEVE_EVENT, AI_UDE_MASTER); // UDE 1002
//SetSpawnInCondition(AI_FLAG_UDE_PERCIEVE_PRE_EVENT, AI_UDE_MASTER); // UDE 1022
//SetSpawnInCondition(AI_FLAG_UDE_END_COMBAT_ROUND_EVENT, AI_UDE_MASTER); // UDE 1003
//SetSpawnInCondition(AI_FLAG_UDE_END_COMBAT_ROUND_PRE_EVENT, AI_UDE_MASTER); // UDE 1023
//SetSpawnInCondition(AI_FLAG_UDE_ON_DIALOGUE_EVENT, AI_UDE_MASTER); // UDE 1004
//SetSpawnInCondition(AI_FLAG_UDE_ON_DIALOGUE_PRE_EVENT, AI_UDE_MASTER); // UDE 1024
//SetSpawnInCondition(AI_FLAG_UDE_ATTACK_EVENT, AI_UDE_MASTER); // UDE 1005
//SetSpawnInCondition(AI_FLAG_UDE_ATTACK_PRE_EVENT, AI_UDE_MASTER); // UDE 1025
//SetSpawnInCondition(AI_FLAG_UDE_DAMAGED_EVENT, AI_UDE_MASTER); // UDE 1006
//SetSpawnInCondition(AI_FLAG_UDE_DAMAGED_PRE_EVENT, AI_UDE_MASTER); // UDE 1026
//SetSpawnInCondition(AI_FLAG_UDE_DEATH_EVENT, AI_UDE_MASTER); // UDE 1007
//SetSpawnInCondition(AI_FLAG_UDE_DEATH_PRE_EVENT, AI_UDE_MASTER); // UDE 1027
//SetSpawnInCondition(AI_FLAG_UDE_DISTURBED_EVENT, AI_UDE_MASTER); // UDE 1008
//SetSpawnInCondition(AI_FLAG_UDE_DISTURBED_PRE_EVENT, AI_UDE_MASTER); // UDE 1028
//SetSpawnInCondition(AI_FLAG_UDE_RESTED_EVENT, AI_UDE_MASTER); // UDE 1009
//SetSpawnInCondition(AI_FLAG_UDE_RESTED_PRE_EVENT, AI_UDE_MASTER); // UDE 1029
//SetSpawnInCondition(AI_FLAG_UDE_SPELL_CAST_AT_EVENT, AI_UDE_MASTER); // UDE 1011
//SetSpawnInCondition(AI_FLAG_UDE_SPELL_CAST_AT_PRE_EVENT, AI_UDE_MASTER); // UDE 1031
//SetSpawnInCondition(AI_FLAG_UDE_ON_BLOCKED_EVENT, AI_UDE_MASTER); // UDE 1015
//SetSpawnInCondition(AI_FLAG_UDE_ON_BLOCKED_PRE_EVENT, AI_UDE_MASTER); // UDE 1035
//SetSpawnInCondition(AI_FLAG_UDE_COMBAT_ACTION_EVENT, AI_UDE_MASTER); // UDE 1012
// Fires when we have finnished all combat actions.
//SetSpawnInCondition(AI_FLAG_UDE_COMBAT_ACTION_PRE_EVENT, AI_UDE_MASTER); // UDE 1032
// This fires at the start of DetermineCombatRound() *IF they can do an action*.
//SetSpawnInCondition(AI_FLAG_UDE_DAMAGED_AT_1_HP, AI_UDE_MASTER); // UDE 1014
// Fires when we are damaged, and are at 1 HP. Use for immortal-flagged creatures.
/*** Speakstrings - as it were, said under cirtain conditions % chance each time ***/
//AI_SetSpawnInSpeakArray(AI_TALK_ON_CONVERSATION, 100, 4, "Hello there", "I hope you enjoy your stay", "Do you work here too?", "*Hic*");
// On Conversation - see readme. Replaces BeginConversation().
// Morale
//AI_SetSpawnInSpeakArray(AI_TALK_ON_MORALE_BREAK, 100, 3, "No more!", "I'm outta here!", "Catch me if you can!");
// Spoken at running point, if they run to a group of allies.
//AI_SetSpawnInSpeakArray(AI_TALK_ON_CANNOT_RUN, 100, 3, "Never give up! Never surrender!", "I've no where to run, so make my day!", "RRRAAAAA!!!");
// Spoken at running point, if they can find no ally to run to, and 4+ Intelligence. See readme
//AI_SetSpawnInSpeakValue(AI_TALK_ON_STUPID_RUN, "Ahhhhgggg! NO MORE! Run!!");
// As above, when morale breaks + no ally, but they panic and run from enemy at 3 or less intelligence.
// Combat
//AI_SetSpawnInSpeakArray(AI_TALK_ON_COMBAT_ROUND_EQUAL, 5, 4, "Come on!", "You won't win!", "We are not equals! I am better!", "Nothing will stop me!");
//AI_SetSpawnInSpeakArray(AI_TALK_ON_COMBAT_ROUND_THEM_OVER_US, 5, 4, "I'll try! try! and try again!", "Tough man, are we?", "Trying out your 'skills'? Pathetic excuse!", "Nothing good will come from killing me!");
//AI_SetSpawnInSpeakArray(AI_TALK_ON_COMBAT_ROUND_US_OVER_THEM, 5, 4, "My strength is mighty then yours!", "You will definatly die!", "NO chance for you!", "No mercy! Not for YOU!");
// Spoken each DetermineCombatRound. % is /1000. See readme for Equal/Over/Under values.
//AI_SetSpawnInSpeakArray(AI_TALK_ON_TAUNT, 100, 3, "You're going down!", "No need to think, let my blade do it for you!", "Time to meet your death!");
// If the creature uses thier skill, taunt, on an enemy this will be said.
// Event-driven.
//AI_SetSpawnInSpeakArray(AI_TALK_ON_PERCIEVE_ENEMY, 70, 6, "Stand and fight, lawbreaker!", "Don't run from the law!", "I have my orders!", "I am ready for violence!", "CHARGE!", "Time you died!");
// This is said when they see/hear a new enemy, and start attacking them.
//AI_SetSpawnInSpeakArray(AI_TALK_ON_DAMAGED, 20, 2, "Ouch, damn you!", "Haha! Nothing will stop me!");
// A random value is set to speak when damaged, and may fire same time as below ones.
//AI_SetSpawnInSpeakArray(AI_TALK_ON_PHISICALLY_ATTACKED, 20, 2, "Hah! Mear weapons won't defeat me!", "Pah! You cannot defeat me with such rubbish!");
// This is said when an enemy attacks the creature with a melee/ranged weapon.
//AI_SetSpawnInSpeakArray(AI_TALK_ON_HOSTILE_SPELL_CAST_AT, 20, 2, "No one spell will stop me!", "Is that all you have!?!");
// This is said when an enemy attacks the creature with a hostile spell.
//AI_SetSpawnInSpeakValue(AI_TALK_ON_DEATH, "Agggggg!");
// This will ALWAYS be said, whenever the creature dies.
// Specific potion ones.
//AI_SetSpawnInSpeakValue(AI_TALK_WE_PASS_POTION, "Here! Catch!");
// This will be spoken when the creature passes a potion to an ally. See readme.
//AI_SetSpawnInSpeakValue(AI_TALK_WE_GOT_POTION, "Got it!");
// This will be spoken by the creature we pass the potion too, using AssignCommand().
// Leader ones
//AI_SetSpawnInSpeakValue(AI_TALK_ON_LEADER_SEND_RUNNER, "Quickly! We need help!");
// This will be said when the leader, if this creature, sends a runner.
//AI_SetSpawnInSpeakValue(AI_TALK_ON_LEADER_ATTACK_TARGET, "Help attack this target!");
// When the leader thinks target X should be attacked, it will say this.
//AI_SetSpawnInSpeakValue(AI_TALK_ON_LEADER_BOSS_SHOUT, "Come my minions! To battle!");
// This will be said when the leader, if this creature, sees an enemy and uses his "Boss Monster Shout", if turned on.
/************************ [User Defined and Shouts] ***************************/
/************************ [Bioware: Animations/Waypoints/Treasure] *************
All Bioware Stuff. I'd check out "x0_c2_spwn_def" for the SoU/Hordes revisions.
************************* [Bioware: Animations/Waypoints/Treasure] ************/
// SetSpawnInCondition(NW_FLAG_STEALTH, NW_GENERIC_MASTER);
// SetSpawnInCondition(NW_FLAG_SEARCH, NW_GENERIC_MASTER);
// Uses said skill while WalkWaypoints()
// SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING, NW_GENERIC_MASTER);
// Separate the NPC's waypoints into day & night. See comment in "nw_i0_generic" for use.
// SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS, NW_GENERIC_MASTER);
// This will cause an NPC to use common animations it possesses,
// and use social ones to any other nearby friendly NPCs.
// SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS, NW_GENERIC_MASTER);
// Same as above, except NPC will wander randomly around the area.
// SetAnimationCondition(NW_ANIM_FLAG_IS_CIVILIZED);
// Interacts with placeables + More civilized actions. See Readme.
// SetAnimationCondition(NW_ANIM_FLAG_CHATTER);
// Will use random voicechats during animations, if Civilized
// SetAnimationCondition(NW_ANIM_FLAG_IS_MOBILE_CLOSE_RANGE);
// Will move around the area a bit more, if using Immobile Animations. See readme.
// Treasure generating.
//CTG_GenerateNPCTreasure();
// SoU. Requires "x0_i0_treasure" to be uncommented. See readme.
//GenerateNPCTreasure();
// Default NwN. Requires "nw_o2_coninclude" to be uncommented. See readme.
/************************ [Bioware: Animations/Waypoints/Treasure] ************/
// AI Behaviour. DO NOT CHANGE! DO NOT CHANGE!!!
AI_SetUpEndOfSpawn();
// This MUST be called. It fires these events:
// SetUpSpells, SetUpSkillToUse, SetListeningPatterns, SetWeapons, AdvancedAuras.
// These MUST be called! the AI might fail to work correctly if they don't fire!
/************************ [User] ***********************************************
This is the ONLY place you should add user things, on spawn, such as
visual effects or anything, as it is after SetUpEndOfSpawn. By default, this
does have encounter animations on. This is here, so is easily changed :-D
Be careful otherwise.
Notes:
- SetListening is already set to TRUE, unless AI_FLAG_OTHER_LAG_NO_LISTENING is on.
- SetListenPattern's are set from 0 to 7.
- You can use the wrappers AI_SpawnInInstantVisual and AI_SpawnInPermamentVisual
for visual effects (Instant/Permament as appropriate).
************************* [User] **********************************************/
// Example (and default) of user addition:
// - If we are from an encounter, set mobile (move around) animations.
if(GetIsEncounterCreature())
{
SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS, NW_GENERIC_MASTER);
}
// Leave this in if you use the variable for creature attacks, as for golems. Bioware's code.
int nNumber = GetLocalInt(OBJECT_SELF, "CREATURE_VAR_NUMBER_OF_ATTACKS");
if(nNumber > 0)
{
SetBaseAttackBonus(nNumber);
}
// If we are a ranger or paladin class, do not cast spells. This can be
// manually removed if wished. To get the spells they have working correctly,
// remove this, and use Monster Abilties instead of thier normal class spells.
// if(GetLevelByClass(CLASS_TYPE_RANGER) >= 1 || GetLevelByClass(CLASS_TYPE_PALADIN) >= 1)
// {
// SetSpawnInCondition(AI_FLAG_OTHER_LAG_NO_SPELLS, AI_OTHER_MASTER);
// }
/************************ [User] **********************************************/
// Note: You shouldn't really remove this, even if they have no waypoints.
DelayCommand(2.0, SpawnWalkWayPoints());
// Delayed walk waypoints, as to not upset instant combat spawning.
// This will also check if to change to day/night posts during the walking, no heartbeats.
}

View File

@@ -1,493 +0,0 @@
/*/////////////////////// [On Spell Cast At] ///////////////////////////////////
Filename: j_ai_onspellcast or nw_c2_defaultb
///////////////////////// [On Spell Cast At] ///////////////////////////////////
What does this do? Well...
- Any AOE spell effects are set in a timer, so we can react to them right
- Reacts to hostile casters, or allies in combat
And the normal attack :-)
///////////////////////// [History] ////////////////////////////////////////////
1.3 - Added special AOE checks.
- Hide checks.
1.4 - Added more silent shouts. Edited the formatting. Moved a few things around.
///////////////////////// [Workings] ///////////////////////////////////////////
This is fired when EventSpellCastAt(object oCaster, int nSpell, int bHarmful=TRUE)
is signaled on the creature.
GetLastSpellCaster() = oCaster (Door, Placeable, Creature who cast it)
GetLastSpell() = nSpell (The spell cast at us)
GetLastSpellHarmful()= bHarmful (If it is harmful!)
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: GetLastSpellCaster, GetLastSpellHarmful GetLastSpell()
///////////////////////// [On Spell Cast At] /////////////////////////////////*/
#include "J_INC_OTHER_AI"
// Sets a local timer if the spell is an AOE one
void SetAOESpell(int nSpellCast, object oCaster);
// Gets the nearest AOE cast by oCaster, of sTag.
object GetNearestAOECastBy(string sTag, object oCaster);
// Gets the amount of protections we have - IE globes
int GetOurSpellLevelImmunity();
void main()
{
// Pre-spell cast at-event. Returns TRUE if we interrupt this script call.
if(FirePreUserEvent(AI_FLAG_UDE_SPELL_CAST_AT_PRE_EVENT, EVENT_SPELL_CAST_AT_PRE_EVENT)) return;
// AI status check. Is the AI on?
if(GetAIOff()) return;
object oCaster = GetLastSpellCaster();
int bHarmful = GetLastSpellHarmful();
int nSpellCast = GetLastSpell();
object oAttackerOfCaster;
// If harmful, we set the spell to a timer, if an AOE one.
if(bHarmful && GetIsObjectValid(oCaster))
{
// Might set AOE spell to cast.
SetAOESpell(nSpellCast, oCaster);
}
// If not a creature, probably an AOE or trap.
if(GetObjectType(oCaster) != OBJECT_TYPE_CREATURE)
{
// 67: "[Spell] Caster isn't a creature! May look for target [Caster] " + GetName(oCaster)
DebugActionSpeakByInt(67, oCaster);
// Shout to allies to attack, or be prepared.
AISpeakString(AI_SHOUT_CALL_TO_ARMS);
// Attack anyone else around
if(!CannotPerformCombatRound())
{
// Determine Combat Round
DetermineCombatRound();
}
}
// If a friend, or dead, or a DM, or invalid, or self, we ignore them.
else if(!GetIgnoreNoFriend(oCaster) && oCaster != OBJECT_SELF)
{
// 1.3 changes here:
// - We do NOT need to know if it is hostile or not, except if it is hostile
// and they are not our faction! We do, however, use bHarmful for speakstrings.
// If harmful, we attack anyone! (and if is enemy)
// 1.4: Faction equal check in GetIgnoreNoFriend()
if(bHarmful || GetIsEnemy(oCaster))
{
// Spawn in condition hostile thingy
if(GetSpawnInCondition(AI_FLAG_OTHER_CHANGE_FACTIONS_TO_HOSTILE_ON_ATTACK, AI_OTHER_MASTER))
{
if(!GetIsEnemy(oCaster))
{
AdjustReputation(oCaster, OBJECT_SELF, -100);
}
}
if(bHarmful)
{
// * Don't speak when dead. 1.4 change (an obvious one to make)
if(CanSpeak())
{
// Hostile spell speaksting, if set.
SpeakArrayString(AI_TALK_ON_HOSTILE_SPELL_CAST_AT);
}
}
// Turn of hiding check
TurnOffHiding(oCaster);
// We attack
if(!CannotPerformCombatRound())
{
// 68: "[Spell:Enemy/Hostile] Not in combat. Attacking: [Caster] " + GetName(oCaster)
DebugActionSpeakByInt(68, oCaster);
DetermineCombatRound(oCaster);
}
// Shout to allies to attack the enemy who attacked me, got via. Last Hostile Actor.
AISpeakString(AI_SHOUT_I_WAS_ATTACKED);
}
// Else, was neutral perhaps. Don't attack them anyway.
else
{
// 69: "[Spell] (ally). Not in combat. May Attack/Move [Caster] " + GetName(oCaster)
DebugActionSpeakByInt(69, oCaster);
// Set special action to investigate - as if this event was triggered
// by I_WAS_ATTACKED.
// If we are already attacking, we do not move
if(CannotPerformCombatRound())
{
// Shout to allies to attack, or be prepared.
AISpeakString(AI_SHOUT_CALL_TO_ARMS);
}
else
{
// We react as if the caster, a neutral, called for help ala
// I_WAS_ATTACKED (they might not have, might just be
// preperation for something), but normally, this is a neutral
// casting a spell. Do not respond to PC's.
if(!GetIsPC(oCaster))
{
IWasAttackedResponse(oCaster);
}
}
}
}
// If they are not a faction equal, and valid, we help them.
else if(GetIsObjectValid(oCaster) && GetFactionEqual(oCaster))
{
IWasAttackedResponse(oCaster);
}
// Fire End-spell cast at-UDE
FireUserEvent(AI_FLAG_UDE_SPELL_CAST_AT_EVENT, EVENT_SPELL_CAST_AT_EVENT);
}
// Sets a local timer if the spell is an AOE one
void SetAOESpell(int nSpellCast, object oCaster)
{
// Check it is one we can check
int bStop = TRUE;
switch(nSpellCast)
{
case SPELL_ACID_FOG:
case SPELL_MIND_FOG:
case SPELL_STORM_OF_VENGEANCE:
case SPELL_GREASE:
case SPELL_CREEPING_DOOM:
case SPELL_SILENCE:
case SPELL_BLADE_BARRIER:
case SPELL_CLOUDKILL:
case SPELL_STINKING_CLOUD:
case SPELL_WALL_OF_FIRE:
case SPELL_INCENDIARY_CLOUD:
case SPELL_ENTANGLE:
case SPELL_EVARDS_BLACK_TENTACLES:
case SPELL_CLOUD_OF_BEWILDERMENT:
case SPELL_STONEHOLD:
case SPELL_VINE_MINE:
case SPELL_SPIKE_GROWTH:
case SPELL_VINE_MINE_HAMPER_MOVEMENT:
case SPELL_VINE_MINE_ENTANGLE:
{
bStop = FALSE;
}
break;
}
// Check immune level
int nImmuneLevel = GetOurSpellLevelImmunity();
if(nImmuneLevel >= 9)
{
bStop = TRUE;
}
// Check
if(bStop == TRUE)
{
return;
}
// We do use intelligence here...
int nAIInt = GetBoundriedAIInteger(AI_INTELLIGENCE);
int bIgnoreSaves;
int bIgnoreImmunities;
object oAOE;
// If it is low, we ignore all things that we could ignore with it...
if(nAIInt <= 3)
{
bIgnoreSaves = TRUE;
bIgnoreImmunities = TRUE;
}
// Average ignores saves
else if(nAIInt <= 7)
{
bIgnoreSaves = TRUE;
bIgnoreImmunities = FALSE;
}
// Else, we do both.
else
{
bIgnoreSaves = FALSE;
bIgnoreImmunities = FALSE;
}
int bSetAOE = FALSE;// TRUE means set to timer
int nSaveDC = 11;
// Get the caster DC, the most out of WIS, INT or CHA...
int nInt = GetAbilityModifier(ABILITY_INTELLIGENCE, oCaster);
int nWis = GetAbilityModifier(ABILITY_WISDOM, oCaster);
int nCha = GetAbilityModifier(ABILITY_CHARISMA, oCaster);
if(nInt > nWis && nInt > nCha)
{
nSaveDC += nInt;
}
else if(nWis > nCha)
{
nSaveDC += nWis;
}
else
{
nSaveDC += nCha;
}
// Note:
// - No reaction type/friendly checks. Signal Event is only fired if the
// spell WILL pierce any PvP/Friendly/Area settings
// We check immunities here, please note...
switch(nSpellCast)
{
// First: IS GetIsReactionTypeHostile ones.
case SPELL_EVARDS_BLACK_TENTACLES:
// Fortitude save, but if we are immune to the hits, its impossible to hurt us
{
// If save immune OR AC immune, we ignore this.
if(25 >= GetAC(OBJECT_SELF) && nImmuneLevel < 4 &&
((GetFortitudeSavingThrow(OBJECT_SELF) < nSaveDC + 2) || bIgnoreSaves))
{
bSetAOE = TRUE;
// Nearest string of tag
oAOE = GetNearestAOECastBy(AI_AOE_PER_EVARDS_BLACK_TENTACLES, oCaster);
}
}
case SPELL_SPIKE_GROWTH:
case SPELL_VINE_MINE_HAMPER_MOVEMENT:
// d4 damage. LOTS of speed loss.
// Reflex save, or immunity, would stop the speed
{
if(nImmuneLevel < 3 &&
(!GetIsImmune(OBJECT_SELF, IMMUNITY_TYPE_MOVEMENT_SPEED_DECREASE) || bIgnoreImmunities) &&
((GetReflexSavingThrow(OBJECT_SELF) < nSaveDC + 5) || bIgnoreSaves))
{
bSetAOE = TRUE;
// Both use ENTANGLE AOE's
oAOE = GetNearestAOECastBy(AI_AOE_PER_ENTANGLE, oCaster);
}
}
break;
case SPELL_ENTANGLE:
case SPELL_VINE_MINE_ENTANGLE:
{
if(nImmuneLevel < 1 &&
(!GetHasFeat(FEAT_WOODLAND_STRIDE) || bIgnoreImmunities) &&
(!GetIsImmune(OBJECT_SELF, IMMUNITY_TYPE_ENTANGLE) || bIgnoreImmunities) &&
((GetReflexSavingThrow(OBJECT_SELF) < nSaveDC + 4) || bIgnoreSaves))
{
bSetAOE = TRUE;
// Both use ENTANGLE AOE's
oAOE = GetNearestAOECastBy(AI_AOE_PER_ENTANGLE, oCaster);
}
}
break;
case SPELL_WEB:
{
if(nImmuneLevel < 1 &&
(!GetHasFeat(FEAT_WOODLAND_STRIDE) || bIgnoreImmunities) &&
(!GetIsImmune(OBJECT_SELF, IMMUNITY_TYPE_ENTANGLE) || bIgnoreImmunities) &&
((GetReflexSavingThrow(OBJECT_SELF) < nSaveDC + 4) || bIgnoreSaves))
{
bSetAOE = TRUE;
// Web AOE
oAOE = GetNearestAOECastBy(AI_AOE_PER_WEB, oCaster);
}
}
break;
// Fort save
case SPELL_STINKING_CLOUD:
{
if(nImmuneLevel < 3 &&
(!GetIsImmune(OBJECT_SELF, IMMUNITY_TYPE_POISON) || bIgnoreImmunities) &&
(!GetIsImmune(OBJECT_SELF, IMMUNITY_TYPE_DAZED) || bIgnoreImmunities) &&
((GetFortitudeSavingThrow(OBJECT_SELF) < nSaveDC + 6) || bIgnoreSaves))
{
bSetAOE = TRUE;
// Stinking cloud persistant AOE.
oAOE = GetNearestAOECastBy(AI_AOE_PER_FOGSTINK, oCaster);
}
}
break;
// Fort save
case SPELL_CLOUD_OF_BEWILDERMENT:
{
if(nImmuneLevel < 2 &&
((GetFortitudeSavingThrow(OBJECT_SELF) < nSaveDC + 7) || bIgnoreSaves))
{
bSetAOE = TRUE;
// Bewilderment cloud persistant AOE.
oAOE = GetNearestAOECastBy(AI_AOE_PER_FOGBEWILDERMENT, oCaster);
}
}
break;
// Special: Mind save is the effect.
case SPELL_STONEHOLD:
{
if(nImmuneLevel < 6 &&
(!GetIsImmune(OBJECT_SELF, IMMUNITY_TYPE_MIND_SPELLS) || bIgnoreImmunities) &&
((GetWillSavingThrow(OBJECT_SELF) < nSaveDC + 7) || bIgnoreSaves))
{
bSetAOE = TRUE;
// Stonehold persistant AOE.
oAOE = GetNearestAOECastBy(AI_AOE_PER_STONEHOLD, oCaster);
}
}
break;
// Special: EFFECT_TYPE_SAVING_THROW_DECREASE is the effect.
case SPELL_MIND_FOG:
{
if(nImmuneLevel < 5 &&
(!GetIsImmune(OBJECT_SELF, IMMUNITY_TYPE_SAVING_THROW_DECREASE) || bIgnoreImmunities) &&
((GetWillSavingThrow(OBJECT_SELF) < nSaveDC + 6) || bIgnoreSaves))
{
bSetAOE = TRUE;
// Mind fog
oAOE = GetNearestAOECastBy(AI_AOE_PER_FOGMIND, oCaster);
}
}
break;
// Special: Feats, knockdown
case SPELL_GREASE:
{
if(nImmuneLevel < 1 &&
(!GetIsImmune(OBJECT_SELF, IMMUNITY_TYPE_KNOCKDOWN) || bIgnoreImmunities) &&
(!GetHasFeat(FEAT_WOODLAND_STRIDE, OBJECT_SELF) || bIgnoreImmunities) &&
((GetReflexSavingThrow(OBJECT_SELF) < nSaveDC + 2) || bIgnoreSaves))
{
bSetAOE = TRUE;
// Grease
oAOE = GetNearestAOECastBy(AI_AOE_PER_GREASE, oCaster);
}
}
break;
// All other ReactionType ones. Some have different saves though!
case SPELL_BLADE_BARRIER: // Reflex
case SPELL_INCENDIARY_CLOUD:// reflex
case SPELL_WALL_OF_FIRE:// Reflex
{
if(nImmuneLevel < 6 &&
(((GetReflexSavingThrow(OBJECT_SELF) < nSaveDC + 6) &&
!GetHasFeat(FEAT_IMPROVED_EVASION) &&
!GetHasFeat(FEAT_EVASION)) || bIgnoreSaves))
{
bSetAOE = TRUE;
if(nSpellCast == SPELL_BLADE_BARRIER)
{
// BB
oAOE = GetNearestAOECastBy(AI_AOE_PER_WALLBLADE, oCaster);
}
else if(nSpellCast == SPELL_INCENDIARY_CLOUD)
{
// Fog of fire
oAOE = GetNearestAOECastBy(AI_AOE_PER_FOGFIRE, oCaster);
}
else if(nSpellCast == SPELL_WALL_OF_FIRE)
{
// Wall of fire
oAOE = GetNearestAOECastBy(AI_AOE_PER_WALLFIRE, oCaster);
}
}
}
break;
case SPELL_ACID_FOG: // Fort: Half. No check, always damages.
case SPELL_CLOUDKILL:// No save!
case SPELL_CREEPING_DOOM: // No save!
{
if(nImmuneLevel < 6)
{
bSetAOE = TRUE;
if(nSpellCast == SPELL_ACID_FOG)
{
// Acid fog
oAOE = GetNearestAOECastBy(AI_AOE_PER_FOGACID, oCaster);
}
else if(nSpellCast == SPELL_CLOUDKILL)
{
// Cloud Kill
oAOE = GetNearestAOECastBy(AI_AOE_PER_FOGKILL, oCaster);
}
else if(nSpellCast == SPELL_CREEPING_DOOM)
{
// Creeping doom
oAOE = GetNearestAOECastBy(AI_AOE_PER_CREEPING_DOOM, oCaster);
}
}
}
// Storm - because the AI likes it, we stay in it if it is ours :-)
case SPELL_STORM_OF_VENGEANCE: // Reflex partial. No check, always damages.
{
if(oCaster != OBJECT_SELF && nImmuneLevel < 9)
{
bSetAOE = TRUE;
// Storm of vengance
oAOE = GetNearestAOECastBy(AI_AOE_PER_STORM, oCaster);
}
}
}
if(bSetAOE)
{
if(!GetLocalTimer(AI_TIMER_AOE_SPELL_EVENT + IntToString(nSpellCast)))
{
SetLocalTimer(AI_TIMER_AOE_SPELL_EVENT + IntToString(nSpellCast), 18.0);
// Set nearest AOE
if(GetIsObjectValid(oAOE))
{
// Set nearest AOE of this spell to the local
object oNearest = GetAIObject(AI_TIMER_AOE_SPELL_EVENT + IntToString(nSpellCast));
if(GetDistanceToObject(oAOE) < GetDistanceToObject(oNearest) ||
!GetIsObjectValid(oNearest))
{
SetAIObject(AI_TIMER_AOE_SPELL_EVENT + IntToString(nSpellCast), oAOE);
}
}
}
}
}
// Gets the nearest AOE cast by oCaster, of sTag.
object GetNearestAOECastBy(string sTag, object oCaster)
{
int nCnt = 1;
object oAOE = GetNearestObjectByTag(sTag, OBJECT_SELF, nCnt);
object oReturn = OBJECT_INVALID;
// Loop
while(GetIsObjectValid(oAOE) && !GetIsObjectValid(oReturn))
{
// Check creator
if(GetAreaOfEffectCreator(oAOE) == oCaster)
{
oReturn = oAOE;
}
nCnt++;
oAOE = GetNearestObjectByTag(sTag, OBJECT_SELF, nCnt);
}
return oReturn;
}
// Gets the amount of protections we have - IE globes
int GetOurSpellLevelImmunity()
{
int nNatural = GetLocalInt(OBJECT_SELF, AI_SPELL_IMMUNE_LEVEL);
// Stop here, if natural is over 4
if(nNatural > 4) return nNatural;
// Big globe affects 4 or lower spells
if(GetHasSpellEffect(SPELL_GLOBE_OF_INVULNERABILITY, OBJECT_SELF) || nNatural >= 4)
return 4;
// Minor globe is 3 or under
if(GetHasSpellEffect(SPELL_MINOR_GLOBE_OF_INVULNERABILITY, OBJECT_SELF) ||
// Shadow con version
GetHasSpellEffect(SPELL_GREATER_SHADOW_CONJURATION_MINOR_GLOBE, OBJECT_SELF) ||
nNatural >= 3)
return 3;
// 2 and under is ethereal visage.
if(GetHasSpellEffect(SPELL_ETHEREAL_VISAGE, OBJECT_SELF) || nNatural >= 2)
return 2;
// Ghostly Visarge affects 1 or 0 level spells, and any spell immunity.
if(GetHasSpellEffect(SPELL_GHOSTLY_VISAGE, OBJECT_SELF) || nNatural >= 1 ||
// Or shadow con version.
GetHasSpellEffect(SPELL_GREATER_SHADOW_CONJURATION_MIRROR_IMAGE, OBJECT_SELF))
return 1;
// Return nNatural, which is 0-9
return FALSE;
}

View File

@@ -1,326 +0,0 @@
/*/////////////////////// [On User Defined] ////////////////////////////////////
Filename: J_AI_OnUserDef or nw_c2_defaultd
///////////////////////// [Workings] ///////////////////////////////////////////
1.4 Adds proper Pre-event functionality. Use this to make sure you keep the
AI working, but making small additions using this event.
Can be deleted to save space if you want :-)
How to use user defined events (brief):
There are a set of optional Spawn In values you can set within the spawn file.
If you set one of the Events to fire, it will activate this script. Then,
under the correct choice (EG I choose the Pre-Heartbeat event, then I
uncomment the line "SetSpawnInCondition(AI_FLAG_UDE_HEARTBEAT_PRE_EVENT, AI_UDE_MASTER);"
and find, in this file, the section with EVENT_HEARTBEAT_PRE_EVENT above it).
add in whatever to do.
With my Pre-heartbeat example, if I wanted it to check for a PC, then
check for a combat dummy, and attack it, I'd add this between the brackets:
// Code:
// Not in combat, of course!
if(!GetIsInCombat())
{
// Function in j_inc_npc_attack to get nearest PC
object oPC = GetNearestPCCreature();
// Why check for a PC? Well, it saves memory
if(GetIsObjectValid(oPC) && GetDistanceToObject(oPC) <= 40.0)
{
object oDummy = GetNearestObjectByTag("DUMMY");
if(GetIsObjectValid(oDummy))
{
ClearAllActions();
ActionAttack(oDummy);
// Exit (Stop the rest of the script)
SetToExitFromUDE(EVENT_HEARTBEAT_PRE_EVENT);
// Stop rest of script
return;
}
}
}
// End code
Simple, no?
You can delete sections you don't need, and is recommended as long as you know
how to use User Defined events.
///////////////////////// [History] ////////////////////////////////////////////
1.3 - Added in with some documentation
1.4 - Changed Pre-events. Now, it uses Execute Script. Will need to set
a special string on the creature to now what script to fire.
- It means they work correctly, however!
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: Dependant on event. See seperate event scripts.
///////////////////////// [On User Defined] //////////////////////////////////*/
// This contains a lot of useful things.
// - Combat starting
// - Constant values
// - Get/Set spawn in values.
#include "J_INC_OTHER_AI"
// This contains some useful things to get NPC's to attack and so on.
#include "J_INC_NPC_ATTACK"
/************************ [UDE Values] *****************************************
These are uneeded, but here for reference. Use the constants in the file
"j_inc_constants" like "EVENT_HEARTBEAT_PRE_EVENT" which is classed as 1021.
* The normal death event might not fire before the creature has vanished.
Use the Pre-event (but with no stopping the death event) if you want a special
death event to happen.
Name Normal-End event - Pre-Event
Heartbeat Event 1001 1021
Percieve Event 1002 1022
Combat Round Event 1003 1023
Dialog Event 1004 1024
Attack Event 1005 1025
Damaged Event 1006 1026
Death Event 1007 1027
Disturbed Event 1008 1028
Rested Event 1009 1029
Spell Cast At Event 1011 1031
Combat Action Event 1012 1032
Damaged 1HP Event 1014 -
Blocked Event 1015 1035
************************* [UDE Values] ****************************************/
void main()
{
// Get the user defined number.
// * NOTE: YOU MUST USE AI_GetUDENumber(), not GetUserDefinedEventNumber()!
int nEvent = AI_GetUDENumber();
// Events.
switch(nEvent)
{
// Event Heartbeat
// Arguments: Basically, none. Nothing activates this script. Fires every 6 seconds.
case EVENT_HEARTBEAT_PRE_EVENT:
{
// This fires before the rest of the On Heartbeat file does
// Exit (Stop the rest of the script)
SetToExitFromUDE(EVENT_HEARTBEAT_PRE_EVENT);
}
break;
case EVENT_HEARTBEAT_EVENT:
{
// This fires after the rest of the On Heartbeat file does
}
break;
// Event Percieve
// Arguments: GetLastPerceived, GetLastPerceptionSeen, GetLastPerceptionHeard,
// GetLastPerceptionVanished, GetLastPerceptionInaudible.
case EVENT_PERCIEVE_PRE_EVENT:
{
// This fires before the rest of the On Percieve file does
// Exit (Stop the rest of the script)
SetToExitFromUDE(EVENT_PERCIEVE_PRE_EVENT);
}
break;
case EVENT_PERCIEVE_EVENT:
{
// This fires after the rest of the On Percieve file does
}
break;
// Event Combat Round End
// Arguments: GetAttackTarget, GetLastHostileActor, GetAttemptedAttackTarget,
// GetAttemptedSpellTarget (Or these are useful at least!)
case EVENT_END_COMBAT_ROUND_PRE_EVENT:
{
// This fires before the rest of the On Combat Round End file does
// Exit (Stop the rest of the script)
SetToExitFromUDE(EVENT_END_COMBAT_ROUND_PRE_EVENT);
}
break;
case EVENT_END_COMBAT_ROUND_EVENT:
{
// This fires after the rest of the On Combat Round End file does
}
break;
// Event Dialogue
// Arguments: GetListenPatternNumber, GetLastSpeaker, TestStringAgainstPattern,
// GetMatchedSubstring (I think),
case EVENT_ON_DIALOGUE_PRE_EVENT:
{
// This fires before the rest of the dialog file does
// Exit (Stop the rest of the script)
SetToExitFromUDE(EVENT_ON_DIALOGUE_PRE_EVENT);
}
break;
case EVENT_ON_DIALOGUE_EVENT:
{
// This fires after the rest of the dialog file does
}
break;
// Event Attacked
// Arguments: GetLastAttacker, GetLastWeaponUsed, GetLastAttackMode,
// GetLastAttackType
case EVENT_ATTACK_PRE_EVENT:
{
// This fires before the rest of the Attacked file does
// Exit (Stop the rest of the script)
SetToExitFromUDE(EVENT_ATTACK_PRE_EVENT);
}
break;
case EVENT_ATTACK_EVENT:
{
// This fires after the rest of the Attacked file does
}
break;
// Event Damaged
// Arguments: GetTotalDamageDealt, GetLastDamager, GetCurrentHitPoints
// (and max), GetDamageDealtByType
case EVENT_DAMAGED_PRE_EVENT:
{
// This fires before the rest of the damaged file does
// Exit (Stop the rest of the script)
SetToExitFromUDE(EVENT_DAMAGED_PRE_EVENT);
}
break;
case EVENT_DAMAGED_EVENT:
{
// This fires after the rest of the damaged file does
}
break;
// Event Death
// Arguments: GetLastKiller
case EVENT_DEATH_PRE_EVENT:
{
// This fires before the rest of the death file does
// Exit (Stop the rest of the script)
SetToExitFromUDE(EVENT_DEATH_PRE_EVENT);
}
break;
case EVENT_DEATH_EVENT:
{
// This fires after the rest of the death file does
}
break;
// Event Distrubed
// Arguments: GetInventoryDisturbItem, GetLastDisturbed,
// GetInventoryDisturbType (should always be stolen :-( ).
case EVENT_DISTURBED_PRE_EVENT:
{
// This fires before the rest of the disturbed file does
// Exit (Stop the rest of the script)
SetToExitFromUDE(EVENT_DISTURBED_PRE_EVENT);
}
break;
case EVENT_DISTURBED_EVENT:
{
// This fires after the rest of the disturbed file does
}
break;
// Event Rested
// Arguments: None
// Note: Not sure if this fires at the end of rest event, but the actual
// duration of the rest is 0, so you never "see" it.
case EVENT_RESTED_PRE_EVENT:
{
// This fires before the rest of the rested file does
// Exit (Stop the rest of the script)
SetToExitFromUDE(EVENT_RESTED_PRE_EVENT);
}
break;
case EVENT_RESTED_EVENT:
{
// This fires after the rest of the rested file does
}
break;
// Event Spell cast at
// Arguments: GetLastSpellCaster, GetLastSpellHarmful GetLastSpell()
case EVENT_SPELL_CAST_AT_PRE_EVENT:
{
// This fires before the rest of the Spell Cast At file does
// Exit (Stop the rest of the script)
SetToExitFromUDE(EVENT_SPELL_CAST_AT_PRE_EVENT);
}
break;
case EVENT_SPELL_CAST_AT_EVENT:
{
// This fires after the rest of the Spell Cast At End file does
}
break;
// Event Blocked
// Arguements: GetBlockingDoor, GetIsDoorActionPossible, GetLocked,
// GetLockKeyRequired, GetLockKeyTag, GetLockUnlockDC, GetPlotFlag.
case EVENT_ON_BLOCKED_PRE_EVENT:
{
// This fires before the rest of the on blocked file does
// Exit (Stop the rest of the script)
SetToExitFromUDE(EVENT_ON_BLOCKED_PRE_EVENT);
}
break;
case EVENT_ON_BLOCKED_EVENT:
{
// This fires after the rest of the on blocked file does
}
break;
// Event Combat Action
// Arguments: GetAttackTarget(), and lots of others.
// Note: Fires when DetermineCombatRound runs to perform an action.
case EVENT_COMBAT_ACTION_PRE_EVENT:
{
// This fires before the rest of the Determine Combat Round call does
// Exit (Stop the rest of the script)
SetToExitFromUDE(EVENT_COMBAT_ACTION_PRE_EVENT);
}
break;
case EVENT_COMBAT_ACTION_EVENT:
{
// This fires after the rest of the Determine Combat Round call does
// Calling ClearAllActions should stop any actions added in the call.
}
break;
// Event Damaged at 1 HP.
// Arguments: None really.
// Note: Fires OnDamaged, when we have exactly 1HP. Use for Immortal Creatures.
case EVENT_DAMAGED_AT_1_HP:
{
// This fires after the rest of the On Combat Round End file does
}
break;
// End all in-built events. Add more in here, if you wish.
}
}

View File

@@ -1,31 +0,0 @@
/*/////////////////////// [Set Weapons] ////////////////////////////////////////
Filename: J_AI_SetWeapons
///////////////////////// [Set Weapons] ////////////////////////////////////////
Executed to re-set any weapons, or set them at spawn, using ExecuteScript.
It isn't included in the generic AI or onspawn to try and speed it up a little
///////////////////////// [History] ////////////////////////////////////////////
1.3 - Added to a new file, removed from spawn include.
1.4 - Nothing changed here. Include file might have changed however.
///////////////////////// [Workings] ///////////////////////////////////////////
It can be easily re-added to the spawn include, however, the generic AI calls
it so little, that it may well be useful to keep a seperate file anyway.
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: RESET_HEALING_KITS
///////////////////////// [Set Weapons] //////////////////////////////////////*/
#include "J_INC_SETWEAPONS"
void main()
{
if(GetAIInteger(RESET_HEALING_KITS))
{
ResetHealingKits(OBJECT_SELF);
DeleteAIInteger(RESET_HEALING_KITS);
}
else
{
// Set weapons if not
SetWeapons(OBJECT_SELF);
}
}

View File

@@ -1,98 +0,0 @@
/*/////////////////////// [Resume Waypoint Walking] ////////////////////////////
Filename: j_ai_walkwaypoin
///////////////////////// [Resume Waypoint Walking] ////////////////////////////
Executed On Spawn, and from the end of combat, to resume walking
Notes:
Needed my own file as to execute and be sure it exsisted. This means
the Non-override version will not use 2 different waypoint files most of the
time.
///////////////////////// [History] ////////////////////////////////////////////
1.0 - Added
1.3 - Changed to SoU waypoints. fired from End of Spawn and heartbeat.
It also returns to start location if set.
1.4 -
///////////////////////// [Workings] ///////////////////////////////////////////
Might change to SoU waypoints, this, at the moment, will just
walk normal waypoints.
GEORG:
Short rundown on WalkWaypoints
You can create a set of waypoints with their tag constructed like this:
WP_[TAG]_XX where [TAG] is the exact, case sensitive tag of the creature
you want to walk these waypoints and XX the number of the waypoint.
Numbers must be ascending without a gap and must always contain 2 digits.
If your creature's tag is MY_Monster, the tags would be
WP_MY_Monster_01, WP_MY_Monster_02, ...
You can auto-create a first waypoint in the toolset by rightclicking on a
creature and selecting the "Create Waypoint" option. You can create
subsequent waypoints by rightclicking on the ground while the creature is
still selected and choosing "Create Waypoint".
If you want to make your creature have a different patrol route at night,
you can create a different set of WayPoints prefixed with WN_ (i.e.
WN_MY_Monster_01, WN_MY_Monster_02, ...).
You can also define so called POST waypoints for creatures that do not have
a route of waypoints but you want to return to their position after a combat
(i.e. Guards at a gate). This can be done by creating a single Waypoint with
the tag POST_[TAG] for day and NIGHT_[TAG] for night posts. Creatures will
automaticall switch between those posts when day changes to night and vice
versa.
Waypoints can be between areas and creatures will move there, if you set a
global integer variable called X2_SWITCH_CROSSAREA_WALKWAYPOINTS on your
module to 1.
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: WAYPOINT_RUN, WAYPOINT_PAUSE are set On Spawn to remember
the pause/run actions.
///////////////////////// [Resume Waypoint Walking] //////////////////////////*/
#include "NW_I0_GENERIC"
#include "J_INC_DEBUG"
const string WAYPOINT_RUN = "WAYPOINT_RUN";
const string WAYPOINT_PAUSE = "WAYPOINT_PAUSE";
const int AI_FLAG_OTHER_RETURN_TO_SPAWN_LOCATION = 0x00020000;
const string AI_OTHER_MASTER = "AI_OTHER_MASTER";
const string AI_LOCATION = "AI_LOCATION";
const string AI_RETURN_TO_POINT = "AI_RETURN_TO_POINT";
// For return to.
int AI_GetSpawnInCondition(int nCondition, string sName, object oTarget = OBJECT_SELF);
void main()
{
// FIRST, if we are meant to move back to the start location, do it.
if(AI_GetSpawnInCondition(AI_FLAG_OTHER_RETURN_TO_SPAWN_LOCATION, AI_OTHER_MASTER))
{
location lReturnPoint = GetLocalLocation(OBJECT_SELF, AI_LOCATION + AI_RETURN_TO_POINT);
object oReturnArea = GetAreaFromLocation(lReturnPoint);
if(GetIsObjectValid(oReturnArea))
{
if((GetArea(OBJECT_SELF) == oReturnArea &&
GetDistanceBetweenLocations(GetLocation(OBJECT_SELF), lReturnPoint) > 3.0) ||
GetArea(OBJECT_SELF) != oReturnArea)
{
// 77: "[Waypoints] Returning to spawn location. [Area] " + GetName(oInput)
DebugActionSpeakByInt(77, GetAreaFromLocation(lReturnPoint));
ActionForceMoveToLocation(lReturnPoint);
return;
}
}
}
// Use on-spawn run/pauses.
WalkWayPoints(GetLocalInt(OBJECT_SELF, WAYPOINT_RUN), GetLocalFloat(OBJECT_SELF, WAYPOINT_PAUSE));
}
int AI_GetSpawnInCondition(int nCondition, string sName, object oTarget)
{
return (GetLocalInt(oTarget, sName) & nCondition);
}

View File

@@ -1,109 +0,0 @@
/*/////////////////////// [Ability - Dragon Wing Buffet] ///////////////////////
Filename: J_AI_WingBuffet
///////////////////////// [Ability - Dragon Wing Buffet] ///////////////////////
"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.
///////////////////////// [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] ///////////////////////////////////////////
Executed via. ExecuteScript from the AI file, it is seperate because it is
almost a new AI ability.
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: N/A
///////////////////////// [Ability - Dragon Wing Buffet] /////////////////////*/
void main()
{
// Stop the creature's actions.
ClearAllActions();// To rid errors.
// Declare major variables
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;
// Use a delay based on range,
float fDelay;
// Declare effects
effect eDam;
effect eKnockDown = EffectKnockdown();
effect eVis = EffectVisualEffect(VFX_IMP_PULSE_WIND);
// Pulse of wind applied...
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, lSelf);
// Get first target in spell area
object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_GARGANTUAN, lSelf);
while(GetIsObjectValid(oTarget))
{
// Get thier location (for visual) and the delay.
lTarget = GetLocation(oTarget);
fDelay = GetDistanceToObject(oTarget)/20.0;
// Wind pulse to all
DelayCommand(fDelay, ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, lTarget));
// Do not effect allies.
if(!GetIsFriend(oTarget) && !GetFactionEqual(oTarget))
{
// Send a message about the wing buffet (allies do not see this)
SendMessageToPC(oTarget, sMessage);
// Huge creatures (IE: Dragon size) are not affected.
if(GetCreatureSize(oTarget) != CREATURE_SIZE_HUGE)
{
// A standard (not spell) reflex save negates the damage and knockdown
if(!ReflexSave(oTarget, nDC))
{
// Randomise damage. (nDC = Hit dice)
nDamage = Random(nDC) + 11;
// Define the damage
eDam = EffectDamage(nDamage, DAMAGE_TYPE_BLUDGEONING);
// Randomise knockdown duration, to minimum of 6.0 (1.0/2 = 0.5. + 5.5 = 6.0)
fRandomKnockdown = 5.5 + ((IntToFloat(Random(30)) + 1.0)/10.0);
// 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));
}
}
}
// Get next target in spell area
oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_GARGANTUAN, lSelf);
}
// Do a great flapping wings on land effect.
effect eAppear = EffectAppear();
ApplyEffectToObject(DURATION_TYPE_INSTANT, eAppear, OBJECT_SELF);
// Attack the nearest seen (so not to stand there for 6 seconds, but get
// back in the action!).
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));
}
}
}

View File

@@ -1,133 +0,0 @@
/*/////////////////////// [Ability - Dragon Flying] ////////////////////////////
Filename: J_AI_WingFlying
///////////////////////// [Ability - Dragon Flying] ////////////////////////////
Hey, a dragon can fly (if we are set to, mind you!) this is executed from
the default AI, using local objects to "fly" to, a duration based on the
distance between the 2 places.
When we fly down, we apply knockdown to the targets in the area's affected
if not huge size, like wing buffet.
NOTE:
- Can be used with NPC's who are not dragons, but if they are not huge,
the damage is not done (only the pulses at thier location and the target
location)
///////////////////////// [History] ////////////////////////////////////////////
1.3 - Added
1.4 - Added an actual spell event fire for the damage. It might not have
registered with some hostile monsters otherwise! (EG: DR)
///////////////////////// [Workings] ///////////////////////////////////////////
Executed via. ExecuteScript from the AI file, it is seperate because it is
almost a new AI ability.
It is a 6 second or more fly - note it adds 1/10 second more for each
1M between targets. Not too much, but enough.
Does damage to landing and taking off sites too :-)
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: N/A
///////////////////////// [Ability - Dragon Flying] //////////////////////////*/
#include "J_INC_CONSTANTS"
// Damages area with blast of flying
void DoDamageToArea(location lLocation);
void main()
{
// Get the target location
object oJumpTo = GetAIObject(AI_FLYING_TARGET);
location lJumpTo = GetLocation(oJumpTo);
DeleteAIObject(AI_FLYING_TARGET);
// Errors
if(!GetIsObjectValid(oJumpTo)) return;
ClearAllActions();// To rid errors.
SetFacingPoint(GetPosition(oJumpTo));
// Get location of ourselves, to damage those as we fly away.
location lSelf = GetLocation(OBJECT_SELF);
// Jump to the next location, using a delay of 3.0 seconds + Distance/10
float fDuration = 3.0 + (GetDistanceBetweenLocations(lSelf, lJumpTo)/10.0);
if(GetCreatureSize(OBJECT_SELF) == CREATURE_SIZE_HUGE)
{
// Damage instantly
DelayCommand(1.0, DoDamageToArea(lSelf));
// Delay the jump down damage - a little extra delay mind you.
DelayCommand(fDuration + 1.2, DoDamageToArea(lJumpTo));
}
else
{
// Visual effects only
effect eImpact = EffectVisualEffect(VFX_IMP_PULSE_WIND);
// Pulse of wind applied...
DelayCommand(1.0, ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eImpact, lSelf));
// Delay the new wind
DelayCommand(fDuration + 1.2, ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eImpact, lJumpTo));
}
// New determine combat round - via. Action attacking.
DelayCommand(fDuration + 1.5, ActionAttack(oJumpTo));
effect eFly = EffectDisappearAppear(lJumpTo);
DelayCommand(1.0, ApplyEffectToObject(DURATION_TYPE_TEMPORARY, eFly, OBJECT_SELF, fDuration - 1.0));
}
// Damages area with blast of flying
void DoDamageToArea(location lLocation)
{
// Declare effects
effect eKnockDown = EffectKnockdown();
int nDamage;
int nDC = GetHitDice(OBJECT_SELF);
effect eDam;
effect eVis = EffectVisualEffect(VFX_IMP_PULSE_WIND);
// Use a delay based on range,
float fDelay;
string sMessage = GetName(OBJECT_SELF) + " is flying!";
location lTarget;
float fRandomKnockdown;
// Pulse of wind applied...
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, lLocation);
//Apply the VFX impact and effects
//Get first target in spell area
object oTarget = GetFirstObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_GARGANTUAN, lLocation);
while(GetIsObjectValid(oTarget))
{
lTarget = GetLocation(oTarget);
fDelay = GetDistanceBetweenLocations(lTarget, lLocation)/20.0;
// Visual wind pulse
DelayCommand(fDelay, ApplyEffectAtLocation(DURATION_TYPE_INSTANT, eVis, lTarget));
//Get next target in spell area
// Do not effect allies.
if(!GetIsFriend(oTarget) && !GetFactionEqual(oTarget))
{
SendMessageToPC(oTarget, sMessage);
// Can't knock over huge things!
if(GetCreatureSize(oTarget) != CREATURE_SIZE_HUGE)
{
// Signal spell cast at event
// * Using: SPELLABILITY_DRAGON_WING_BUFFET - just so something is used
SignalEvent(oTarget, EventSpellCastAt(OBJECT_SELF, SPELLABILITY_DRAGON_WING_BUFFET));
// Reflex save for damage
if(!ReflexSave(oTarget, nDC))
{
// Randomise damage. (nDC = Hit dice)
nDamage = Random(nDC) + 11;
eDam = EffectDamage(nDamage, DAMAGE_TYPE_BLUDGEONING);
// Randomise knockdown, to minimum of 6.0 (1.0/2 = 0.5. + 5.5 = 6.0)
fRandomKnockdown = 5.5 + ((IntToFloat(Random(30)) + 1.0)/10.0);
// 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));
}
}
}
oTarget = GetNextObjectInShape(SHAPE_SPHERE, RADIUS_SIZE_GARGANTUAN, lLocation);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,187 +0,0 @@
/*/////////////////////// [Include - Debugging] ////////////////////////////////
Filename: J_Inc_Debug
///////////////////////// [Include - Debugging] ////////////////////////////////
This contains DebugActionSpeak, the debug function.
Makes it easier to uncomment debug lines.
///////////////////////// [History] ////////////////////////////////////////////
1.3 - Added
- In beta, changed it so this file controls all debug strings. Just
uncomment them and recompile to turn it on/off.
1.4 - TO DO: Added some more debug strings I use
///////////////////////// [Workings] ///////////////////////////////////////////
DebugActionSpeak normally writes a timestamped log entry, and speak a silent
string Server Admins can hear.
1.3 added:
- DebugActionSpeakByInt(int iInteger);
- Removes many strings into this file
- Can easily comment out all string so they are not added to compiled
scripts if debugging unused (This saves space on compiled files :-D )
- Always uncomment the right bits if not using any debugging.
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: N/A
///////////////////////// [Include - Debugging] //////////////////////////////*/
// This will speak a cirtain integer number string (similar to a dialog reference).
// - I (Jass) have just moved all strings I used all the time into here, so
// if the strings are uncommented, they will not be compiled
// - The numbers have no reference to much really.
// - Calls DebugActionSpeak!
// - See J_INC_DEBUG to uncomment/recomment in
void DebugActionSpeakByInt(int iInteger, object oInput = OBJECT_INVALID, int nInput = FALSE, string sInput = "");
// Speaks and stamps a debug string.
// - See J_INC_DEBUG to uncomment/recomment the debug strings.
// - Only used in special circumstances.
void DebugActionSpeak(string sString);
// This will speak a cirtain integer number string (similar to a dialog reference).
// - I (Jass) have just moved all strings I used all the time into here, so
// if the strings are uncommented, they will not be compiled
// - The numbers have no reference to much really.
// - Calls DebugActionSpeak!
// - See J_INC_DEBUG to uncomment/recomment in
void DebugActionSpeakByInt(int iInteger, object oInput = OBJECT_INVALID, int nInput = FALSE, string sInput = "")
{
// TO UNCOMMENT/COMMENT:
// - Add/Remove in "//" before the next lines "/*"
// - Recompile all files
///*
string sDebug;
switch(iInteger)
{
// - Generic AI stuff
case 1: sDebug = "[DCR:Melee] Most Damaging Weapon. Target: " + GetName(oInput); break;
case 2: sDebug = "[DCR:Melee] Most Damaging as Not Effective"; break;
case 3: sDebug = "[DCR:Melee] Melee Code. No valid melee target/Dead. Exiting"; break;
case 4: sDebug = "[DCR:Melee] Melee attack. [Target] " + GetName(oInput) + " [Feat/Attack] " + IntToString(nInput); break;
case 5: sDebug = "[DCR:Caster] Defensive Casting Mode ON [Enemy] " + GetName(oInput); break;
case 6: sDebug = "[DCR:Caster] Moving away from AOO's. [Enemy] " + GetName(oInput); break;
case 7: sDebug = "[DCR:Casting] Talent(item) [TalentID] " + IntToString(nInput) + " [Target] " + GetName(oInput) + " [Location] " + sInput; break;
case 8: sDebug = "[DCR:Casting] Workaround for Spontaeous [SpellID] " + IntToString(nInput) + " [Target] " + GetName(oInput); break;
case 9: sDebug = "[DCR:Casting] NormalSpell [ID] " + IntToString(nInput) + " [Target] " + GetName(oInput) + " [Location] " + sInput; break;
case 10: sDebug = "[DCR:Casting] TalentSpell. [ID] " + IntToString(nInput) + " [Target] " + GetName(oInput) + " [Location] " + sInput; break;
case 11: sDebug = "[DCR:Casting] SubSpecialSpell. [ID] " + IntToString(nInput) + " [Target] " + GetName(oInput) + " [Location] " + sInput; break;
case 12: sDebug = "[DCR:Casting] NormalRandomSpell. [ID] " + IntToString(nInput) + " [Target] " + GetName(oInput) + " [Location] " + sInput; break;
case 13: sDebug = "[DCR:Casting] Backup spell caught: " + IntToString(nInput); break;
case 14: sDebug = "[DCR:Feat] [ID] " + IntToString(nInput) + " [Enemy] " + GetName(oInput); break;
case 15: sDebug = "[DCR:Casting] Grenade [ID] " + IntToString(nInput) + " [Target] " + GetName(oInput) + " [Location] " + sInput; break;
case 16: sDebug = "[AOE Call] Moving out of/Dispeling an AOE. [Tag] " + GetTag(oInput); break;
case 17: sDebug = "[DCR:Special] Darkness + Caster. No seen enemy. Dispel/Move."; break;
case 18: sDebug = "[DRC:Talent] Using Talent (Healing). [TalentID] " + IntToString(nInput) + " [Target] " + GetName(oInput); break;
case 19: sDebug = "[DCR:Healing] (Should) Healing [Target]" + GetName(oInput) + " [CurrentHP|Max|ID|Rank|Power] " + IntToString(nInput); break;
case 20: sDebug = "[DCR Healing] Boss Action, create Critical Wounds potion"; break;
case 21: sDebug = "[DCR:Casting] Healing self with healing kit, [Kit] " + GetName(oInput); break;
case 22: sDebug = "[DCR:Feat] Summoning my familiar"; break;
case 23: sDebug = "[DCR:Feat] Summoning my animal companion"; break;
case 24: sDebug = "[DCR:Fleeing] Stupid/Panic/Flee moving from enemies/position - We are a commoner/no morale/failed < 3 int"; break;
case 25: sDebug = "[DCR:Fleeing] Fleeing to allies. [ID Array] " + sInput + " [Ally] " + GetName(oInput); break;
case 26: sDebug = "[DCR:GFTK] Attacking a PC who is dying/asleep! [Enemy]" + GetName(oInput); break;
case 27: sDebug = "[DCR:Moving] Archer Retreating back from the enemy [Enemy]" + GetName(oInput); break;
case 28: sDebug = "[DCR:Turning] Using Turn Undead"; break;
case 29: sDebug = "[DCR:Bard Song] Using"; break;
case 30: sDebug = "[DCR:Bard Curse Song] Using"; break;
case 31: sDebug = "[DCR:All Spells] Error! No casting (No spells, items, target Etc)."; break;
case 32: sDebug = "[DCR:All Spells] [Modifier|BaseDC|SRA] " + IntToString(nInput); break;
case 33: sDebug = "[DCR:Casting] Cheat Spell. End of Spells. [Spell] " + IntToString(nInput) + "[Target]" + GetName(oInput); break;
case 34: sDebug = "[DCR:All Spells] Ranged Spells. Should use closer spells/move nearer"; break;
case 35: sDebug = "[DCR:Dragon] Breath weapon & attacking [Breath ID] " + IntToString(nInput) + " [Target] " + GetName(oInput); break;
case 36: sDebug = "[DCR:Dragon] Wing Buffet [Target] " + GetName(oInput); break;
case 37: sDebug = "[DCR:Beholder] Teleport"; break;
case 38: sDebug = "[DCR:Beholder] Rays"; break;
case 39: sDebug = "[DCR:Targeting] No valid enemies in sight, moving to allies target's. [Target] " + GetName(oInput); break;
case 40: sDebug = "[DCR:Targeting] Override Target Seen. [Name]" + GetName(oInput); break;
case 41: sDebug = "[DCR:Targeting] No seen in LOS, Attempting to MOVE to something [Target]" + GetName(oInput); break;
case 42: sDebug = "[DCR:Skill] Using agressive skill (+Attack). [Skill] " + IntToString(nInput) + " [Enemy]" + GetName(oInput); break;
case 43: sDebug = "[DCR:Pre-Melee Spells] All Potions Using. [Spell ID] " + IntToString(nInput); break;
case 44: sDebug = "[DCR:Pre-Melee Spells] True Strike Emptive attack [Target] " + GetName(oInput); break;
case 45: sDebug = "[DCR:CounterSpell] Counterspelling. [Target] " + GetName(oInput); break;
case 46: sDebug = "[DRC] START [Intruder]" + GetName(oInput); break;
case 47: sDebug = "[DCR] [PREMITURE EXIT] Cannot Do Anything."; break;
case 48: sDebug = "[DCR] [PREMITURE EXIT] Dazed move away."; break;
case 49: sDebug = "[DCR] [PREMITURE EXIT] Fleeing or otherwise"; break;
case 50: sDebug = "[DRC] END - DELETE PAST TARGETS"; break;
// Perception
case 51: sDebug = "[Perception] Our Enemy Target changed areas. Stopping, moving too...and attack... [Percieved] " + GetName(oInput); break;
case 52: sDebug = "[Perception] Enemy Vanished (Same area) Retargeting/Searching [Percieved] " + GetName(oInput); break;
case 53: sDebug = "[Perception] Enemy seen, and was old enemy/cannot see current. Re-evaluating (no spell) [Percieved] " + GetName(oInput); break;
case 54: sDebug = "[Perception] Enemy Seen. Not in combat, attacking. [Percieved] " + GetName(oInput); break;
case 55: sDebug = "[Perception] Percieved Dead Friend! Moving and Searching [Percieved] " + GetName(oInput); break;
case 56: sDebug = "[Perception] Percieved Alive Fighting Friend! Moving to and attacking. [Percieved] " + GetName(oInput); break;
// Conversation
case 57: sDebug = "[Shout] Friend (may be PC) in combat. Attacking! [Friend] " + GetName(oInput); break;
case 58: sDebug = "[Shout] Responding to shout [Enemy] " + GetName(oInput) + " Who has spoken!"; break;
// Phisical Attacked
case 59: sDebug = "[Phisically Attacked] Attacking back. [Attacker(enemy)] " + GetName(oInput); break;
case 60: sDebug = "[Phisically Attacked] Not same area. [Attacker(enemy)] " + GetName(oInput); break;
// Damaged
case 61: sDebug = "[Damaged] Morale Penalty for 600 seconds [Penalty]" + IntToString(nInput); break;
case 62: sDebug = "[Damaged] Not in combat: DCR [Damager]" + GetName(oInput); break;
case 63: sDebug = "[Damaged] Not in combat: DCR. Ally hit us. [Damager(Ally?)]" + GetName(oInput); break;
// Death
case 64: sDebug = "[Death] Checking corpse status in " + IntToString(nInput) + " [Killer] " + GetName(oInput) + " [Times Died Now] " + sInput; break;
// Disturbed
case 65: sDebug = "[Disturbed] (pickpocket) Attacking Enemy [Disturber] " + GetName(oInput) + " [Type] " + IntToString(nInput); break;
// Rest
case 66: sDebug = "[Rested] Resting. [Type(should be invalid)] " + IntToString(nInput); break;
// Spell Cast at
case 67: sDebug = "[Spell] Caster isn't a creature! May look for target [Caster] " + GetName(oInput); break;
case 68: sDebug = "[Spell:Enemy/Hostile] Not in combat. Attacking: [Caster] " + GetName(oInput); break;
case 69: sDebug = "[Spell] (ally). Not in combat. May Attack/Move [Caster] " + GetName(oInput); break;
// Spell Other AI
// - Shouts
case 70: sDebug = "[Shout] Reacting To Shout. [ShoutNo.] " + IntToString(nInput) + " [Shouter] " + GetName(oInput); break;
// Constants
// - Search
case 71: sDebug = "[Search] Resting"; break;
case 72: sDebug = "[Search] Searching, No one to attack. [Rounds Remaining] " + IntToString(nInput) + ". [Possible target] " + GetName(oInput); break;
// - DCR
case 73: sDebug = "[Call for DCR] Default AI [Pre-Set Target]" + GetName(oInput); break;
case 74: sDebug = "[Call for DCR] Custom AI [" + sInput + "] [Pre-Set Target]" + GetName(oInput); break;
// Destroy self
case 75: sDebug = "[Dead] Setting to selectable/destroyable (so we go) for Bioware corpses."; break;
case 76: sDebug = "[Dead] Destroying self finally."; break;
// Waypoints
case 77: sDebug = "[Waypoints] Returning to spawn location. [Area] " + GetName(oInput); break;
default: return; break;
}
if(sDebug != "")
{
DebugActionSpeak(sDebug);
}
// */
}
void DebugActionSpeak(string sString)
{
// You MUST uncomment this line, IF you use either of the below things
string sNew = "[Debug]" + GetName(OBJECT_SELF) + "[ObjectID]" + ObjectToString(OBJECT_SELF) + " [Debug] " + sString;
// Note, uncomment this, so that DM's can hear the debug speaks, normally it is
// only server admins who can hear the debug. If you are not testing, it might
// be best to keep this uncommented.
// Futher: - Must have debug mode set to 1
// - Only the server admin can seem to see this.
// SpeakString(sNew, TALKVOLUME_TALK);
// Note, uncomment this line to send a message to the first PC in the module.
// - Useful for singleplayer testing
//SendMessageToPC(GetFirstPC(), sNew);
// This writes the entry to the log, very important, if debugging
// Futher: - If left up for a long time, logs can get very big with the AI
// - Use to find problems in the AI and report to me :-D (Jasperre)
WriteTimestampedLogEntry(sNew);
}
// Debug: To compile this script full, uncomment all of the below.
/* - Add two "/"'s at the start of this line
void main()
{
return;
}
//*/

File diff suppressed because it is too large Load Diff

View File

@@ -1,605 +0,0 @@
/*/////////////////////// [Include - Heartbeat] ////////////////////////////////
Filename: J_INC_Heartbeat
///////////////////////// [Include - Heartbeat] ////////////////////////////////
This contains any heartbeat function calls.
Note that the heartbeat uses ExecuteScript for larget behaviours that are
better split up so the heartbeat is as tiny as possible.
///////////////////////// [History] ////////////////////////////////////////////
1.3 - After Beta - Added
1.4 - TO DO
- Add in some function (see rest script) that resets if we are not in
combat
- Some more of the things we should do even if interrupted not the
heartbeat.
- Have moved "after combat searching" into here. It isn't long - but
it is more reliable. The special action is cancled if there is combat
going on, of course.
///////////////////////// [Workings] ///////////////////////////////////////////
This is included in nw_c2_default1 and J_AI_OnHeartbeat.
Contains things like in J_INC_OTHER_AI, but only for the heartbeat event.
Keeps it cleaner to read.
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: N/A
///////////////////////// [Include - Heartbeat] //////////////////////////////*/
#include "J_INC_CONSTANTS"
// Bioware walk waypoints condition name
const string sWalkwayVarname = "NW_WALK_CONDITION";
// Walk waypoint constant set in the SoU waypoint include
const int NW_WALK_FLAG_CONSTANT = 0x00000002;
// Checks:
// * No valid location
// * Petrified, paralised, ETC.
// Note: If sleep is found, it may apply Zzzz randomly, as well as stopping.
int JumpOutOfHeartBeat();
// This checks fleeing, door bashing and so on, to stop the heartbeat
// and perform the override special action, rather then run normal behaviour.
int PerformSpecialAction();
// Get whether the condition is set
// * Bioware SoU Waypoint call.
int GetWalkCondition(int nCondition, object oCreature=OBJECT_SELF);
// Cast fleeing spells.
// - Invisiblity (best)
// - Haste/Expeditious Retreat
void ActionCastFleeingSpells();
// Cast fleeing spells.
// - Invisiblity (best)
// - Haste/Expeditious Retreat
void ActionCastMoveToCombatSpells();
// Attempt to cast nSpell. TRUE if true.
// Searching and fleeing spells use this.
int HeartbeatSpellCast(int nSpell);
// Used in Search(). This apply Trueseeing, See invisibility, or Invisiblity purge
// if we have neither of the 3 on us.
void SearchSpells();
// Returns TRUE if any of the animation settings are on.
int GetHasValidAnimations();
// Checks:
// * No valid location
// * Petrified, paralised, ETC.
// Note: If sleep is found, it may apply Zzzz randomly, as well as stopping.
int JumpOutOfHeartBeat()
{
// What to return
int bReturn = FALSE;
// Checks:
// * No valid location
// * Petrified, paralised, ETC.
// Note: If sleep is found, it may apply Zzzz randomly, as well as stopping.
// Effect checking
effect eCheck = GetFirstEffect(OBJECT_SELF);
int nEffectType;
while(GetIsEffectValid(eCheck) && bReturn == FALSE)
{
nEffectType = GetEffectType(eCheck);
// Sleep is special
if(nEffectType == EFFECT_TYPE_SLEEP)
{
bReturn = 2;// This immediantly breaks.
}
// ALL these stop heartbeat.
else if(nEffectType == EFFECT_TYPE_PARALYZE || nEffectType == EFFECT_TYPE_STUNNED ||
nEffectType == EFFECT_TYPE_FRIGHTENED || /* Removed sleep above */
nEffectType == EFFECT_TYPE_TURNED || nEffectType == EFFECT_TYPE_PETRIFY ||
nEffectType == EFFECT_TYPE_DAZED || nEffectType == EFFECT_TYPE_TIMESTOP ||
nEffectType == EFFECT_TYPE_DISAPPEARAPPEAR || nEffectType == EFFECT_TYPE_CHARMED ||
nEffectType == EFFECT_TYPE_DOMINATED || nEffectType == EFFECT_TYPE_CONFUSED)
{
bReturn = 1;// 1 = No Zzz. We continue to check for Zzz as well.
}
eCheck = GetNextEffect(OBJECT_SELF);
}
// Do we fire the heartbeat event?
if(bReturn != FALSE)
{
// If it is sleep... Zzzzz sometimes.
if(bReturn == 2 && d6() == 1)
{
ApplyEffectToObject(DURATION_TYPE_INSTANT,
EffectVisualEffect(VFX_IMP_SLEEP),
OBJECT_SELF);
}
// Fire event 1001
FireUserEvent(AI_FLAG_UDE_HEARTBEAT_EVENT, EVENT_HEARTBEAT_EVENT);
}
return bReturn;
}
// This checks fleeing, door bashing and so on, to stop the heartbeat
// and perform the override special action, rather then run normal behaviour.
int PerformSpecialAction()
{
int nAction = GetCurrentSetAction();
object oTarget = GetAttackTarget();
object oRunTarget;
switch(nAction)
{
// - Leader has made me a runner. I must run to a nearby group calling
// for help to get more men
case AI_SPECIAL_ACTIONS_ME_RUNNER:
{
oRunTarget = GetAIObject(AI_RUNNER_TARGET);
if(GetIsObjectValid(oRunTarget))
{
if(GetObjectSeen(oRunTarget))
{
// Stop thinking we are a runner if we can see the run target
ResetCurrentAction();
AISpeakString(AI_SHOUT_HELP_MY_FRIEND);
return FALSE;
}
else
{
// Else run to them
if(GetObjectHeard(oRunTarget))
{
AISpeakString(AI_SHOUT_HELP_MY_FRIEND);
}
ClearAllActions();
ActionMoveToObject(oRunTarget, TRUE);
return TRUE;
}
}
}
break;
// - I am fleeing.
case AI_SPECIAL_ACTIONS_FLEE:
{
oRunTarget = GetAIObject(AI_FLEE_TO);
if(GetIsObjectValid(oRunTarget))
{
// If they are a leader, and seen, and they are running, we
// obviously follow only.
if(GetSpawnInCondition(AI_FLAG_OTHER_COMBAT_GROUP_LEADER, AI_OTHER_COMBAT_MASTER, oRunTarget) ||
GetLocalInt(oRunTarget, AI_CURRENT_ACTION) == AI_SPECIAL_ACTIONS_FLEE)
{
ClearAllActions();
// New - cast fleeing spells. Important (and only used
// at higher intelligence) things like Expeditious retreat.
// - Only used once - one invisibility or haste. Deleted above.
ActionCastFleeingSpells();
ActionForceFollowObject(oRunTarget, 3.0);
}
else if(GetObjectSeen(oRunTarget))
{
// If we see the flee target, reset targets
ResetCurrentAction();
// We will delete the local int (set to TRUE) which we
// stopped fleeing spells from being used
DeleteAIInteger(AI_HEARTBEAT_FLEE_SPELLS);
// Speak to allies to come :-)
AISpeakString(AI_SHOUT_HELP_MY_FRIEND);
// Also reset visual effect
RemoveFleeingVisual();
// And attack/heal self
ClearAllActions();
DetermineCombatRound();
// Return TRUE, we attacked
return TRUE;
}
else
{
// Else flee!
if(GetObjectHeard(oRunTarget))
{
AISpeakString(AI_SHOUT_HELP_MY_FRIEND);
}
ClearAllActions();
// New - cast fleeing spells. Important (and only used
// at higher intelligence) things like Expeditious retreat.
// - Only used once - one invisibility or haste. Deleted above.
ActionCastFleeingSpells();
ActionMoveToObject(oRunTarget, TRUE);
return TRUE;
}
}
else
{
// Check if we have bad intellgence, if we have, we will run away
// from the nearest enemy we can see or hear.
if(GetAIInteger(AI_INTELLIGENCE) <= 3)
{
oRunTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN, CREATURE_TYPE_IS_ALIVE, TRUE);
if(!GetIsObjectValid(oRunTarget))
{
oRunTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_HEARD, CREATURE_TYPE_IS_ALIVE, TRUE);
if(!GetIsObjectValid(oRunTarget))
{
oRunTarget = GetLastHostileActor();
if(!GetIsObjectValid(oRunTarget) || GetIsDead(oRunTarget))
{
// If we do not have anyone to run from, stop
ResetCurrentAction();
// Speak to allies to come :-)
AISpeakString(AI_SHOUT_HELP_MY_FRIEND);
// Also reset visual effect
RemoveFleeingVisual();
// And attack/heal self
ClearAllActions();
DetermineCombatRound();
// Return TRUE, we attacked
return TRUE;
}
}
}
// Run from enemy (1.4: Was oTarget, now oRunTarget)
ClearAllActions();
ActionMoveAwayFromObject(oRunTarget, TRUE, 50.0);
return TRUE;
}
// If we see the flee target, reset targets
ResetCurrentAction();
// Speak to allies to come :-)
AISpeakString(AI_SHOUT_HELP_MY_FRIEND);
// Also reset visual effect
RemoveFleeingVisual();
// And attack/heal self
ClearAllActions();
DetermineCombatRound();
// Return TRUE, we attacked/healed
return TRUE;
}
}
break;
// If this is set, we are usually in combat - and must move out of an AOE.
case AI_SPECIAL_ACTIONS_MOVE_OUT_OF_AOE:
{
// We must be X distance away from a cirtain AOE, if we are not, we
// move.
oRunTarget = GetAIObject(AI_AOE_FLEE_FROM);
// If not valid, or already far enough away, delete special action
// and return false.
if(!GetIsObjectValid(oRunTarget) ||
GetLocalFloat(OBJECT_SELF, AI_AOE_FLEE_FROM_RANGE) < GetDistanceToObject(oRunTarget))
{
ResetCurrentAction();
return FALSE;
}
else
{
// Valid and still in range
// - Run away
ClearAllActions();
ActionMoveAwayFromLocation(GetLocation(oRunTarget), TRUE, GetLocalFloat(OBJECT_SELF, AI_AOE_FLEE_FROM_RANGE));
return TRUE;
}
}
break;
// If this is the one, we will search around for enemies - usually done
// at the end of a combat round, it is more reliable here.
case AI_SPECIAL_ACTIONS_SEARCH_AROUND:
{
// If we are in combat, delete this special thing, and return FALSE
if(GetIsObjectValid(GetAttemptedSpellTarget()) ||
GetIsObjectValid(GetAttemptedAttackTarget()) ||
GetIsObjectValid(GetAttackTarget()))
{
// Reset, and return FALSE.
ResetCurrentAction();
return FALSE;
}
// Added this so special actions do not get ignored (EG: healkitting)
// It will not do anything, but no heartbeat will be performed. These
// kind of actions happen at the end of combat (healing self of damage ETC)
// So, basically, will keep in mind it's still searching, but will leave
// it until no busy actions are being done.
else if(GetIsBusyWithAction())
{
return TRUE;
}
// We search for a cirtain number of rounds, set in the generic AI
// file, when we first start searching, or restart even. The generic
// AI will not actually do search actions, and if it finds no enemy,
// will probably just increase the integer to do more search rounds.
// * Will be intelligence + 2 to start.
int nRoundsRemaining = GetAIInteger(AI_SEARCH_ROUNDS_REMAINING);
// Decrease rounds remaining
nRoundsRemaining--;
// Set new one onto us to use next time
SetAIInteger(AI_SEARCH_ROUNDS_REMAINING, nRoundsRemaining);
// * Note: If nRoundsRemaining is 0 at the end of this function, we
// will remove this action as the current special one.
// Get the target to move to/around
// * Can be invalid, but usually the creature we just killed or noticed
// lying on the ground.
object oTarget = GetAIObject(AI_SEARCH_TARGET);
// Stop now (Small amounts of movement each time seem more cautious)
ClearAllActions();
// Check some spells. Cast one if we have no true seeing ETC.
SearchSpells();
// Stealth/search.
int bStealth = GetStealthMode(OBJECT_SELF);
int bSearch = GetDetectMode(OBJECT_SELF);
// We perfere to hide again if we search if set to...sneaky!
if(GetSpawnInCondition(AI_FLAG_OTHER_COMBAT_FORCE_HIDING, AI_OTHER_COMBAT_MASTER))
{
if(bStealth != STEALTH_MODE_ACTIVATED)
{
SetActionMode(OBJECT_SELF, ACTION_MODE_STEALTH, TRUE);
}
}
else
{
// If we are hiding, stop to search (we shouldn't be - who knows?)
if(bStealth == STEALTH_MODE_ACTIVATED)
{
SetActionMode(OBJECT_SELF, ACTION_MODE_STEALTH, FALSE);
}
// And search!
if(bSearch != DETECT_MODE_ACTIVE && !GetHasFeat(FEAT_KEEN_SENSE))
{
SetActionMode(OBJECT_SELF, ACTION_MODE_DETECT, TRUE);
}
}
// We check around the target, if there is one.
if(GetIsObjectValid(oTarget))
{
// Move to the location of oTarget
ActionMoveToLocation(GetLocation(oTarget));
// If it is a chest ETC. We close it.
if(GetIsOpen(oTarget))
{
if(GetObjectType(oTarget) == OBJECT_TYPE_DOOR)
{
ActionCloseDoor(oTarget);
}
else
{
// Close it
ActionDoCommand(DoPlaceableObjectAction(oTarget, PLACEABLE_ACTION_USE));
}
}
}
// We will get nearest enemy at the very least
else
{
// Use nearest heard
object oEnemy = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY,
OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_HEARD);
if(GetIsObjectValid(oEnemy))
{
// Move to location
ActionMoveToLocation(GetLocation(oEnemy));
}
}
// Note: Here, we will return to spawn location after moving to the
// object, if it is a valid setting, else we do the normal randomwalk
if(GetSpawnInCondition(AI_FLAG_OTHER_RETURN_TO_SPAWN_LOCATION, AI_OTHER_MASTER))
{
ActionMoveToLocation(GetAILocation(AI_RETURN_TO_POINT));
}
else
{
// 72: "[Search] Searching, No one to attack. [Rounds Remaining] " + IntToString(nRoundsRemaining) + ". [Possible target] " + GetName(oTarget)
DebugActionSpeakByInt(72, oTarget, nRoundsRemaining);
// Randomly walk.
ActionRandomWalk();
}
// If we have 0 rounds left of searching time, we turn of this special
// action, walk waypoints, and probably rest.
if(nRoundsRemaining == 0)
{
// Rest after combat?
if(GetSpawnInCondition(AI_FLAG_OTHER_REST_AFTER_COMBAT, AI_OTHER_MASTER))
{
// 71: "[Search] Resting"
DebugActionSpeakByInt(71);
// Yes - we use ActionRest(). It can possibly still fail if
// enemies are still around!
ActionRest();
ActionWait(1.0);
}
else
{
// Else, just execute Walk Waypoints
ExecuteScript(FILE_WALK_WAYPOINTS, OBJECT_SELF);
}
// Delete this special action
ResetCurrentAction();
}
// If we havn't bailed out early and returned FALSE (do normal hb) we
// will return TRUE, we have something to do at least.
return TRUE;
}
break;
// Move to combat - we buff (and only buff again after 1 minute of running)
// and either follow the person who wants us to help them, or we will run to the
// location set.
// * Set only by "AI_HELP_MY_FRIEND_CONSTANT" at the moment.
case AI_SPECIAL_ACTIONS_MOVE_TO_COMBAT:
{
// We get a location to move to first
location lTarget = GetAILocation(AI_MOVE_TO_COMBAT_LOCATION);
object oObject = GetAreaFromLocation(lTarget);
// Check if the location is valid
if(GetIsObjectValid(oObject) && GetArea(OBJECT_SELF) == oObject)
{
// Just move, rapidly, to lTarget.
ClearAllActions();
// Buff up an action
ActionCastMoveToCombatSpells();
// Move (fast) to that location
ActionMoveToLocation(lTarget, TRUE);
// If we see/hear combat, we'll attack
return TRUE;
}
else
{
// Get who we should "follow" or move to.
oObject = GetAIObject(AI_MOVE_TO_COMBAT_OBJECT);
if(GetIsObjectValid(oObject))
{
// Just move, rapidly, to oTarget. It isn't "real" following,
// but paced. Means it looks OK. Need to test - but should be OK.
ClearAllActions();
// Buff up an action
ActionCastMoveToCombatSpells();
// Move (fast) to that location
ActionMoveToObject(oTarget, TRUE);
// If we see/hear combat, we'll attack
return TRUE;
}
else
{
// Remove the special action and return FALSE
ResetCurrentAction();
return FALSE;
}
}
}
break;
}
// Return false to carry on a normal heartbeat
return FALSE;
}
// Get whether the condition is set
// * Bioware SoU Waypoint call.
int GetWalkCondition(int nCondition, object oCreature=OBJECT_SELF)
{
return (GetLocalInt(oCreature, sWalkwayVarname) & nCondition);
}
// Cast fleeing spells.
// - Invisiblity (best)
// - Haste/Expeditious Retreat
void ActionCastFleeingSpells()
{
// Not got local
if(GetAIInteger(AI_HEARTBEAT_FLEE_SPELLS)) return;
// Set local
SetAIInteger(AI_HEARTBEAT_FLEE_SPELLS, TRUE);
// Invisibilities
if(HeartbeatSpellCast(SPELL_IMPROVED_INVISIBILITY)) return;
if(HeartbeatSpellCast(SPELL_INVISIBILITY)) return;
// Haste
if(HeartbeatSpellCast(SPELL_MASS_HASTE)) return;
if(HeartbeatSpellCast(SPELL_HASTE)) return;
if(HeartbeatSpellCast(SPELL_EXPEDITIOUS_RETREAT)) return;
}
// Cast fleeing spells.
// - Invisiblity (best)
// - Haste/Expeditious Retreat
void ActionCastMoveToCombatSpells()
{
// Timer to stop too many spells at once
if(GetLocalTimer(AI_TIMER_MOVE_TO_COMBAT_BUFF)) return;
// We first will cast a preperation spell before jumping in!
// This is used once per minute.
SetLocalTimer(AI_TIMER_MOVE_TO_COMBAT_BUFF, 60.0);
// We possibly cast a few spell first - stoneskin range, see
// invisible range, and invisibility range.
// Protection things
// * Cast 1 spell!
if(HeartbeatSpellCast(SPELL_PREMONITION)) return;
if(HeartbeatSpellCast(SPELL_GREATER_STONESKIN)) return;
if(HeartbeatSpellCast(SPELL_STONESKIN)) return;
// Invisibility range
if(HeartbeatSpellCast(SPELL_ETHEREALNESS)) return;
if(HeartbeatSpellCast(SPELL_IMPROVED_INVISIBILITY)) return;
if(HeartbeatSpellCast(SPELL_INVISIBILITY_SPHERE)) return;
if(HeartbeatSpellCast(SPELL_INVISIBILITY)) return;
// See invisible things
if(HeartbeatSpellCast(SPELL_TRUE_SEEING)) return;
if(HeartbeatSpellCast(SPELL_SEE_INVISIBILITY)) return;
// Stealth! Only if we are good at it, of course.
// Spawn in conditions for it
if(!GetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_HIDING, AI_OTHER_COMBAT_MASTER))
{
// Need skill or force on
if((GetSkillRank(SKILL_HIDE) - 4 >= GetHitDice(OBJECT_SELF)) ||
GetSpawnInCondition(AI_FLAG_OTHER_COMBAT_FORCE_HIDING, AI_OTHER_COMBAT_MASTER))
{
// Use hide
SetActionMode(OBJECT_SELF, ACTION_MODE_STEALTH, TRUE);
return;
}
}
}
// Used in Search(). This apply Trueseeing, See invisibility, or Invisiblity purge
// if we have neither of the 3 on us.
void SearchSpells()
{
effect eCheck = GetFirstEffect(OBJECT_SELF);
int nEffectType, bBreak;
while(GetIsEffectValid(eCheck) && bBreak == FALSE)
{
nEffectType = GetEffectType(eCheck);
if(nEffectType == EFFECT_TYPE_TRUESEEING ||
nEffectType == EFFECT_TYPE_SEEINVISIBLE)
{
bBreak = TRUE;
}
eCheck = GetNextEffect(OBJECT_SELF);
}
// We have effects, stop.
if(bBreak == TRUE || GetHasSpellEffect(SPELL_INVISIBILITY_PURGE))
{
return;
}
// Else we apply the best spell we have.
if(HeartbeatSpellCast(SPELL_TRUE_SEEING)) return;
if(HeartbeatSpellCast(SPELL_SEE_INVISIBILITY)) return;
if(HeartbeatSpellCast(SPELL_INVISIBILITY_PURGE)) return;
}
// Attempt to cast nSpell. TRUE if true.
int HeartbeatSpellCast(int nSpell)
{
// 1.4: added check to see if has effect already
if(GetHasSpell(nSpell) && !GetHasSpellEffect(nSpell, OBJECT_SELF))
{
ActionCastSpellAtObject(nSpell, OBJECT_SELF);
return TRUE;
}
return FALSE;
}
// Returns TRUE if any of the animation settings are on.
int GetHasValidAnimations()
{
int nCheck = GetLocalInt(OBJECT_SELF, NW_GENERIC_MASTER);
if((nCheck & NW_FLAG_AMBIENT_ANIMATIONS) ||
(nCheck & NW_FLAG_AMBIENT_ANIMATIONS_AVIAN) ||
(nCheck & NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS))
{
return TRUE;
}
return FALSE;
}

View File

@@ -1,447 +0,0 @@
/*/////////////////////// [Include - NPC (Combat) Attack] //////////////////////
Filename: J_INC_NPC_Attack
///////////////////////// [Include - NPC (Combat) Attack] //////////////////////
What does this do?
It is a wrapper/include for getting a creature to attack target X, or do
Y. I use this for conversations, triggers, the lot, as a simple wrapper
that will execute my AI.
There are several functions here to do things, that may be useful wrappers.
And it also keeps Combat files SMALL! I uses Execute Script to fire the
combat file, not include it here.
///////////////////////// [History] ////////////////////////////////////////////
1.3 - Added
1.4 - TO DO:
- Bugfix a few things (copy/paste errors)
- Add example script to use (User defined events)
///////////////////////// [Workings] ///////////////////////////////////////////
Include this in any conversation file or whatever, and mearly read the
descriptions of the different functions, and it will do what it says :-)
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: N/A
///////////////////////// [Include - NPC (Combat) Attack] ////////////////////*/
// Include the constants for the combat, spawn integers ETC.
#include "J_INC_CONSTANTS"
// Hostile amount
const int HOSTILE = -100;// Reputation to change to
const int TYPE_ALL_PCS = 1;// is all PC's in the world.
const int TYPE_ALL_AREA = 2;// is all PC's in the specific area.
const int TYPE_IN_RANGE = 3;// is all PC's within fRange.
// A slightly modified way to determine a combat round.
// * oTarget - The target to attack
// * sShout - The string to silently speak to get allies to come and help
void DetermineSpeakCombatRound(object oTarget = OBJECT_INVALID, string sShout = "");
// A slightly modified way to determine a combat round.
// * oTarget - The target to attack
// * oAttacker - The NPC who you want to determine a combat round, on oTarget
void DetermineSpeakCombatRoundNotMe(object oTarget, object oAttacker);
// This is the main wrapper to get an NPC to attack in conversation.
// * fDelay - The delay AFTER adjusting reputation, that we attack and shout
// * bPlot - The plot flag to set US to (Usually FALSE).
// * bImmortal - The immortal flag US to set to (Usually FALSE).
// Example, how to keep flags already set:
// HostileAttackPCSpeaker(0.0, GetPlotFlag(), GetImmortal());
// * bAllAllies - This will determine combat rounds against the target, that are in 50.0M. False = Don't
void HostileAttackPCSpeaker(float fDelay = 0.0, int bPlot = FALSE, int bImmortal = FALSE, int bAllAllies = TRUE);
// This will make our faction hostile to the target, and attack them.
// * oTarget - The target object to attack
// * fDelay - The delay AFTER adjusting reputation, that we attack and shout
// * bPlot - The plot flag to set US to (Usually FALSE).
// * bImmortal - The immortal flag US to set to (Usually FALSE).
// Example, how to keep flags already set:
// HostileAttackObject(oPC, 0.0, GetPlotFlag(), GetImmortal());
// * bAllAllies - This will determine combat rounds against the target, that are in 50.0M. False = Don't
void HostileAttackObject(object oTarget, float fDelay = 0.0, int bPlot = FALSE, int bImmortal = FALSE, int bAllAllies = TRUE);
// This will make our faction hostile to the target, and shout.
// * oTarget - The target object to shout about.
// Use: Placeables, disturbers and so on.
// Note: Placeables are normally defaulted hostile faction! Must change it to work
void ShoutAbout(object oTarget);
// This will make our faction hostile to ALL(!) PC's...in the area or game or range
// * nType - TYPE_ALL_PCS (1) is all PC's in the world.
// - TYPE_ALL_AREA (2) is all PC's in the specific area.
// - TYPE_IN_RANGE (3) is all PC's within fRange.
// * bPlot - The plot flag to set US to (Usually FALSE).
// * bImmortal - The immortal flag US to set to (Usually FALSE).
// * bAllAllies - This will determine combat rounds against the target, that are in 50.0M. False = Don't
void HostileAttackAllPCs(int nType = 1, float fRange = 40.0, int bPlot = FALSE, int bImmortal = FALSE, int bAllAllies = TRUE);
// This will thier most damaging weapon, and wait to disarm it.
// * fDuration - Delay until the weapon is withdrawn.
// * bRanged - if TRUE, it will equip a ranged weapon as a prioritory (EquipRanged call)
void EquipWeaponsDuration(float fDuration, int bRanged = FALSE);
// Disarms the persons right-hand-weapon
void RemoveWeapons();
// Plays talks like "ATTACK!" and "Group Near Me" etc.
// * nLowest, nHighest - the High/Lowest value to use.
// 0 = ATTACK, 1 = TAUNT, 2-4 = BATTLE(1-3), 5 = ENEMIES, 6 = GROUP, 7 = HELP.
void PlaySomeTaunt(int nLowest = 0, int nHighest = 7);
// Gets all allies of ourselves to attack oTarget
// * oTarget - The target to attack.
void AlliesAttack(object oTarget);
// Returns the nearest PC object
object GetNearestPCCreature();
// Returns the nearest enemy (but doesn't determine if it can see/hear it)
object GetNearestEnemyCreature();
// Returns the nearest friend
object GetNearestFriendCreature();
// A slightly modified way to determine a combat round.
// * oTarget - The target to attack
// * sShout - The string to silently speak to get allies to come and help
void DetermineSpeakCombatRound(object oTarget, string sShout)
{
// Shout
if(sShout != "") AISpeakString(sShout);
// Check for custom AI script, else fire default.
string sAI = GetCustomAIFileName();
// Fire default AI script
if(sAI == "")
{
// Sanity check - to not fire this off multiple times, we make sure temp
// object is not the same as oTarget (and valid)
if(!GetIsObjectValid(oTarget) || (GetIsObjectValid(oTarget) &&
!GetLocalTimer(AI_DEFAULT_AI_COOLDOWN)))
{
SetLocalObject(OBJECT_SELF, AI_TEMP_SET_TARGET, oTarget);
ExecuteScript(COMBAT_FILE, OBJECT_SELF);
SetLocalTimer(AI_DEFAULT_AI_COOLDOWN, 0.1);
}
}
// Fire custom AI script
else
{
SetLocalObject(OBJECT_SELF, AI_TEMP_SET_TARGET, oTarget);
ExecuteScript(sAI, OBJECT_SELF);
}
}
// A slightly modified way to determine a combat round.
// * oTarget - The target to attack
// * oAttacker - The NPC who you want to determine a combat round, on oTarget
void DetermineSpeakCombatRoundNotMe(object oTarget, object oAttacker)
{
// Check for custom AI script, else fire default.
string sAI = GetLocalString(oAttacker, AI_CUSTOM_AI_SCRIPT);
// Fire default AI script
if(sAI == "")
{
// Sanity check - to not fire this off multiple times, we make sure temp
// object is not the same as oTarget (and valid)
if(!GetIsObjectValid(oTarget) || (GetIsObjectValid(oTarget) &&
!GetLocalTimer(AI_DEFAULT_AI_COOLDOWN)))
{
SetLocalObject(oAttacker, AI_TEMP_SET_TARGET, oTarget);
ExecuteScript(COMBAT_FILE, oAttacker);
SetLocalTimer(AI_DEFAULT_AI_COOLDOWN, 0.1);
}
}
// Fire custom AI script
else
{
SetLocalObject(oAttacker, AI_TEMP_SET_TARGET, oTarget);
ExecuteScript(sAI, oAttacker);
}
}
// This is the main wrapper to get an NPC to attack in conversation.
// * fDelay - The delay AFTER adjusting reputation, that we attack and shout
// * bPlot - The plot flag to set US to (Usually FALSE).
// * bImmortal - The immortal flag US to set to (Usually FALSE).
// Example, how to keep flags already set:
// HostileAttackPCSpeaker(0.0, GetPlotFlag(), GetImmortal());
// * bAllAllies - This will determine combat rounds against the target, that are in 50.0M. False = Don't
void HostileAttackPCSpeaker(float fDelay = 0.0, int bPlot = FALSE, int bImmortal = FALSE, int bAllAllies = TRUE)
{
// Get the PC
object oPC = GetPCSpeaker();
// Error checking
if(!GetIsObjectValid(oPC) || GetIsDM(oPC)) return;
// Change our flags for plot and immortal (usually turns them off)
SetPlotFlag(OBJECT_SELF, bPlot);
SetImmortal(OBJECT_SELF, bImmortal);
// We make them hostile to our faction
AdjustReputation(oPC, OBJECT_SELF, HOSTILE);
// Attack them
SetLocalObject(OBJECT_SELF, AI_TO_ATTACK, oPC);
if(fDelay > 0.0)
{
// Round start...
DelayCommand(fDelay, DetermineSpeakCombatRound(oPC, AI_SHOUT_I_WAS_ATTACKED));
if(bAllAllies) DelayCommand(fDelay, AlliesAttack(oPC));
}
else
{
// Round start...
DetermineSpeakCombatRound(oPC, AI_SHOUT_I_WAS_ATTACKED);
if(bAllAllies) AlliesAttack(oPC);
}
}
// This will make our faction hostile to the target, and attack them.
// * oTarget - The target object to attack
// * fDelay - The delay AFTER adjusting reputation, that we attack and shout
// * bPlot - The plot flag to set US to (Usually FALSE).
// * bImmortal - The immortal flag US to set to (Usually FALSE).
// Example, how to keep flags already set:
// HostileAttackObject(oPC, 0.0, GetPlotFlag(), GetImmortal());
// * bAllAllies - This will determine combat rounds against the target, that are in 50.0M. False = Don't
void HostileAttackObject(object oTarget, float fDelay = 0.0, int bPlot = FALSE, int bImmortal = FALSE, int bAllAllies = TRUE)
{
// Error checking
if(!GetIsObjectValid(oTarget) || GetIsDM(oTarget)) return;
// Change our flags for plot and immortal (usually turns them off)
SetPlotFlag(OBJECT_SELF, bPlot);
SetImmortal(OBJECT_SELF, bImmortal);
// We make them hostile to our faction
AdjustReputation(oTarget, OBJECT_SELF, HOSTILE);
// Attack them
SetLocalObject(OBJECT_SELF, AI_TO_ATTACK, oTarget);
if(fDelay > 0.0)
{
// Round start...
DelayCommand(fDelay, DetermineSpeakCombatRound(oTarget, AI_SHOUT_I_WAS_ATTACKED));
}
else
{
// Round start...
DetermineSpeakCombatRound(oTarget, AI_SHOUT_I_WAS_ATTACKED);
}
}
// This will make our faction hostile to the target, and shout.
// * oTarget - The target object to shout about.
// Use: Placeables, disturbers and so on.
void ShoutAbout(object oTarget)
{
// We make them hostile to our faction
AdjustReputation(oTarget, OBJECT_SELF, HOSTILE);
// And shout for others to attack
AISpeakString(AI_SHOUT_CALL_TO_ARMS);
}
// This will make our faction hostile to ALL(!) PC's...in the area or game or range
// * nType - TYPE_ALL_PCS (1) is all PC's in the world.
// - TYPE_ALL_AREA (2) is all PC's in the specific area.
// - TYPE_IN_RANGE (3) is all PC's within fRange.
// * bPlot - The plot flag to set US to (Usually FALSE).
// * bImmortal - The immortal flag US to set to (Usually FALSE).
// * bAllAllies - This will determine combat rounds against the target, that are in 50.0M. False = Don't
void HostileAttackAllPCs(int nType = 1, float fRange = 40.0, int bPlot = FALSE, int bImmortal = FALSE, int bAllAllies = TRUE)
{
object oPC, oToAttack;
int bShout, nCnt;
float fNearestEnemy = 10000.0;
object oArea = GetArea(OBJECT_SELF);
switch(nType)
{
case TYPE_ALL_PCS:// s all PC's in the world.
{
oPC = GetFirstPC();
while(GetIsObjectValid(oPC))
{
if(!GetIsDM(oPC) &&
GetIsObjectValid(GetArea(oPC)))
{
AdjustReputation(oPC, OBJECT_SELF, HOSTILE);
if(GetArea(oPC) == oArea)
{
if(GetDistanceToObject(oPC) <= fNearestEnemy)
{
oToAttack = oPC;
}
}
bShout = TRUE;
}
oPC = GetNextPC();
}
}
break;
case TYPE_ALL_AREA:// is all PC's in the specific area.
{
nCnt = 1;
oPC = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC, OBJECT_SELF, nCnt);
while(GetIsObjectValid(oPC))
{
// Attack it! (if not a DM!)
if(!GetIsDM(oPC))
{
AdjustReputation(oPC, OBJECT_SELF, HOSTILE);
if(GetArea(oPC) == oArea)
{
if(GetDistanceToObject(oPC) <= fNearestEnemy)
{
oToAttack = oPC;
}
}
bShout = TRUE;
}
// Next one
nCnt++;
oPC = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC, OBJECT_SELF, nCnt);
}
}
break;
case TYPE_IN_RANGE:// is all PC's within fRange.
{
nCnt = 1;
oPC = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC, OBJECT_SELF, nCnt);
while(GetIsObjectValid(oPC) && GetDistanceToObject(oPC) <= fRange)
{
// Attack it! (if not a DM!)
if(!GetIsDM(oPC))
{
AdjustReputation(oPC, OBJECT_SELF, HOSTILE);
if(GetArea(oPC) == oArea)
{
if(GetDistanceToObject(oPC) <= fNearestEnemy)
{
oToAttack = oPC;
}
}
bShout = TRUE;
}
// Next one
nCnt++;
oPC = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC, OBJECT_SELF, nCnt);
}
}
break;
}
// Attack nearest one (if valid)
if(GetIsObjectValid(oToAttack))
{
// Change our flags for plot and immortal (usually turns them off)
SetPlotFlag(OBJECT_SELF, bPlot);
SetImmortal(OBJECT_SELF, bImmortal);
DetermineSpeakCombatRound(oToAttack);
if(bAllAllies) AlliesAttack(oToAttack);
}
// Check if we shout
if(bShout) AISpeakString(AI_SHOUT_CALL_TO_ARMS);
}
// This will thier most damaging weapon, and wait to disarm it.
// * fDuration - Delay until the weapon is withdrawn.
// * bRanged - if TRUE, it will equip a ranged weapon as a prioritory (EquipRanged call)
void EquipWeaponsDuration(float fDuration, int bRanged = FALSE)
{
if(bRanged)
{
// Equip any most damaging (don't use oVersus, incase it doesn't arm anything)
ActionEquipMostDamagingRanged();
}
else
{
// Equip any most damaging (don't use oVersus, incase it doesn't arm anything)
ActionEquipMostDamagingMelee();
}
// Delay the un-equip
DelayCommand(fDuration, RemoveWeapons());
}
// Disarms the persons right-hand-weapon
void RemoveWeapons()
{
// cannot be in combat, duh!
if(GetIsInCombat() || GetIsObjectValid(GetAttackTarget()))
return;
// Get the weapon, make sure it is valid, and...
object oUnequip = GetItemInSlot(INVENTORY_SLOT_RIGHTHAND);
if(GetIsObjectValid(oUnequip))
{
// ...unequip it.
ClearAllActions();
ActionUnequipItem(oUnequip);
}
}
/*::///////////////////////////////////////////////
//:: PlaySomeTaunt
//::///////////////////////////////////////////////
Plays talks like "ATTACK!" and "Group Near Me" etc.
* iLowest, iHighest - the High/Lowest value to use.
0 = ATTACK, 1 = TAUNT, 2-4 = BATTLE(1-3), 5 = ENEMIES, 6 = GROUP, 7 = HELP.
//::///////////////////////////////////////////////
//:: Created by : Jasperre
//:://///////////////////////////////////////////*/
void PlaySomeTaunt(int nLowest, int nHighest)
{
int nRandom = Random(nHighest) + nLowest;
int nVoice = VOICE_CHAT_ATTACK;
switch (nRandom)
{
case 0: nVoice = VOICE_CHAT_ATTACK; break;
case 1: nVoice = VOICE_CHAT_TAUNT; break;
case 2: nVoice = VOICE_CHAT_BATTLECRY1; break;
case 3: nVoice = VOICE_CHAT_BATTLECRY2; break;
case 4: nVoice = VOICE_CHAT_BATTLECRY3; break;
case 5: nVoice = VOICE_CHAT_ENEMIES; break;
case 6: nVoice = VOICE_CHAT_GROUP; break;
case 7: nVoice = VOICE_CHAT_HELP; break;
default: nVoice = VOICE_CHAT_ATTACK; break;
}
PlayVoiceChat(nVoice);
}
// Gets all allies of ourselves to attack oTarget
// * oTarget - The target to attack.
void AlliesAttack(object oTarget)
{
if(!GetIsObjectValid(oTarget)) return;
int nCnt = 1;
object oAlly = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, OBJECT_SELF, nCnt, CREATURE_TYPE_IS_ALIVE, TRUE);
while(GetIsObjectValid(oAlly) && GetDistanceToObject(oAlly) <= 50.0)
{
// A slightly modified way to determine a combat round.
// * oTarget - The target to attack
// * oAttacker - The NPC who you want to determine a combat round, on oTarget
DetermineSpeakCombatRoundNotMe(oTarget, oAlly);
nCnt++;
oAlly = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, OBJECT_SELF, nCnt, CREATURE_TYPE_IS_ALIVE, TRUE);
}
}
// Returns the nearest PC object
object GetNearestPCCreature()
{
return GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC);
}
// Returns the nearest enemy (but doesn't determine if it can see/hear it)
object GetNearestEnemyCreature()
{
return GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY);
}
// Returns the nearest friend
object GetNearestFriendCreature()
{
return GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND);
}
// Debug: To compile this script full, uncomment all of the below.
/* - Add two "/"'s at the start of this line
void main()
{
return;
}
//*/

View File

@@ -1,723 +0,0 @@
/*/////////////////////// [Include - Other AI Functions] ///////////////////////
Filename: J_INC_Other_AI
///////////////////////// [Include - Other AI Functions] ///////////////////////
This contains fuctions and calls for these scripts:
nw_c2_default2 - Percieve
nw_c2_default3 - On Combat round End (For DetermineCombatRound() only)
nw_c2_default4 - Conversation (shout)
nw_c2_default5 - Phisical attacked
nw_c2_default6 - Damaged
nw_c2_default8 - Disturbed
nw_c2_defaultb - Spell cast at
Ones that don't use this use different or no includes.
HOPEFULLY it will make them faster, if they don't run combat.
They use Execute Script to initiate combat. (With the override ones
initiating the override version, the normal initiateing the normal).
///////////////////////// [History] ////////////////////////////////////////////
1.3 - Added to speed up compilings and gather non-combat, or other workings
in one place.
1.4 - TO DO:
-
///////////////////////// [Workings] ///////////////////////////////////////////
This is included in other AI files.
They then use these functions in them scripts.
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: N/A
///////////////////////// [Include - Other AI Functions] /////////////////////*/
// All constants.
#include "J_INC_CONSTANTS"
// Responds to it (like makinging the callers attacker thier target)
// Called in OnConversation, and thats it. Use "ShouterFriend" To stop repeated GetIsFriend calls.
void RespondToShout(object oShouter, int nShoutIndex);
// Gets any possible target which is attacking oShouter (and isn't an ally)
// or who oShouter is attacking. oShouter should be a ally.
object GetIntruderFromShout(object oShouter);
// Shouts, or really brings all people in 60.0M(by default) to the "shouter"
void ShoutBossShout(object oEnemy);
// This sets a morale penalty, to the exsisting one, if there is one.
// It will reduce itself after fDuration (or if we die, ETC, it is deleted).
// It is deleted at the end of combat as well.
void SetMoralePenalty(int nPenalty, float fDuration = 0.0);
// Removes nPenalty amount if it can.
void RemoveMoralePenalty(int nPenalty);
// At 5+ intelligence, we fire off any dispells at oPlaceables location
void SearchDispells(object oPlaceable);
// This MAY make us set a local timer to turn off hiding.
// Turn of hiding, a timer to activate Hiding in the main file. This is
// done in each of the events, with the opposition checking seen/heard.
void TurnOffHiding(object oIntruder);
// Used when we percieve a new enemy and are not in combat. Hides the creature
// appropriatly with spawn settings and ability.
// - At least it will clear all actions if it doesn't set hiding on
void HideOrClear();
// This MIGHT move to oEnemy
// - Checks special actions, such as fleeing, and may run instead!
void ActionMoveToEnemy(object oEnemy);
// Returns TRUE if we have under 0 morale, set to flee.
// - They then run! (Badly)
int PerceptionFleeFrom(object oEnemy);
// This wrappers commonly used code for a "Call to arms" type response.
// * We know of no enemy, so we will move to oAlly, who either called to
// us, or, well, we know of.
// * Calls out AI_SHOUT_CALL_TO_ARMS too.
void CallToArmsResponse(object oAlly);
// This wrappers commonly used code for a "I was attacked" type response.
// * We know there will be an enemy - or should be - and if we find one to attack
// (using GetIntruderFromShout()) - we attack it (and call another I was attacked)
// else, this will run CallToArmsResponse(oAlly);
// * Calls out AI_SHOUT_I_WAS_ATTACKED, or AI_SHOUT_CALL_TO_ARMS too.
void IWasAttackedResponse(object oAlly);
/*::///////////////////////////////////////////////
//:: Name: ShoutBossShout
//::///////////////////////////////////////////////
This is used in the OnPercieve, and if we are set to,
we will "shout" and bring lots of allies a running
//:://///////////////////////////////////////////*/
void ShoutBossShout(object oEnemy)
{
// 1.4 - Added a 5 minute cooldown timer for this. Thusly, if the boss lingers,
// so will the big shout they do.
if(GetSpawnInCondition(AI_FLAG_OTHER_COMBAT_BOSS_MONSTER_SHOUT, AI_OTHER_COMBAT_MASTER) &&
!GetLocalTimer(AI_TIMER_BOSS_SHOUT_COOLDOWN))
{
// Get the range (and default to 60.0 M)
float fRange = IntToFloat(GetBoundriedAIInteger(AI_BOSS_MONSTER_SHOUT_RANGE, 60, 370));
// We loop through nearest not-seen, not-heard allies and get them
// to attack the person.
int nCnt = 1;
// Not seen, not heard...
object oAlly = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND,
OBJECT_SELF, nCnt, CREATURE_TYPE_IS_ALIVE, TRUE,
CREATURE_TYPE_PERCEPTION, PERCEPTION_NOT_SEEN_AND_NOT_HEARD);
// Get who thier target is.
object oThierTarget;
while(GetIsObjectValid(oAlly) && GetDistanceToObject(oAlly) <= fRange)
{
oThierTarget = GetLocalObject(oAlly, AI_TO_ATTACK);
// If they are not attacking the enemy, we assing them to attack.
if(oThierTarget != oEnemy)
{
// Can't be in combat.
if(!GetIsInCombat(oAlly))
{
// Set them to move to this
SetLocalObject(oAlly, AI_TO_ATTACK, oEnemy);
// Make them attack the person
SetLocalObject(oAlly, AI_TEMP_SET_TARGET, oEnemy);
ExecuteScript(COMBAT_FILE, oAlly);
}
}
nCnt++;
oAlly = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND,
OBJECT_SELF, nCnt, CREATURE_TYPE_IS_ALIVE, TRUE,
CREATURE_TYPE_PERCEPTION, PERCEPTION_NOT_SEEN_AND_NOT_HEARD);
}
// * Don't speak when dead. 1.4 change (an obvious one to make)
if(CanSpeak())
{
// Speak a string associated with this action being carried out
SpeakArrayString(AI_TALK_ON_LEADER_BOSS_SHOUT);
}
// Remove it for 5 minutes.
SetLocalTimer(AI_TIMER_BOSS_SHOUT_COOLDOWN, 300.0);
}
}
// This MAY make us set a local timer to turn off hiding.
// Turn of hiding, a timer to activate Hiding in the main file. This is
// done in each of the events, with the opposition checking seen/heard.
void TurnOffHiding(object oIntruder)
{
if(!GetLocalTimer(AI_TIMER_TURN_OFF_HIDE) &&
// Are we actually seen/heard or is it just an AOE?
(GetObjectSeen(OBJECT_SELF, oIntruder) ||
GetObjectHeard(OBJECT_SELF, oIntruder)))
{
SetLocalTimer(AI_TIMER_TURN_OFF_HIDE, 18.0);
}
}
// Used when we percieve a new enemy and are not in combat. Hides the creature
// appropriatly with spawn settings and ability.
// - At least it will clear all actions if it doesn't set hiding on
void HideOrClear()
{
// Spawn in conditions for it
if(!GetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_HIDING, AI_OTHER_COMBAT_MASTER) &&
GetActionMode(OBJECT_SELF, ACTION_MODE_STEALTH) == FALSE)
{
// Need skill or force on
int nRank = GetSkillRank(SKILL_HIDE);
if((nRank - 4 >= GetHitDice(OBJECT_SELF) && nRank >= 7) ||
GetSpawnInCondition(AI_FLAG_OTHER_COMBAT_FORCE_HIDING, AI_OTHER_COMBAT_MASTER))
{
// Use hide
ClearAllActions(TRUE);
SetActionMode(OBJECT_SELF, ACTION_MODE_STEALTH, TRUE);
// Stop
return;
}
}
// Else clear all actions normally.
ClearAllActions();
}
/*::///////////////////////////////////////////////
//:: Respond To Shouts
//:: Copyright (c) 2001 Bioware Corp.
//::///////////////////////////////////////////////
Useage:
//NOTE ABOUT BLOCKERS
int NW_GENERIC_SHOUT_BLOCKER = 2;
It should be noted that the Generic Script for On Dialogue attempts to get a local
set on the shouter by itself. This object represents the LastOpenedBy object. It
is this object that becomes the oIntruder within this function.
//NOTE ABOUT INTRUDERS
These are the enemy that attacked the shouter.
//NOTE ABOUT EVERYTHING ELSE
I_WAS_ATTACKED = 1;
If not in combat, attack the attackee of the shouter. Basically the best
way to get people to come and help us, if we know of an attacker!
* Call this after we call DetermineCombatRound() to make sure that any
responses know of the attackers. It doesn't matter in actual fact, but
useful anyway.
CALL_TO_ARMS = 3;
If not in combat, determine combat round. By default, it should check any
allies it can see/hear for thier targets and help them too.
* Better if we do not know of a target (and thusly our allies wouldn't know
of them as well) so the allies will move to us.
HELP_MY_FRIEND = 4;
This is a runner thing. Said when the runner sees the target to run to.
Gets a local location, and sets off people to run to it.
If no valid area for the location, no moving :-P
We also shout this if we are fleeing. It will set the person to buff too.
LEADER_FLEE_NOW = 5
We flee to a pre-set object or follow the leader (who should be fleeing).
LEADER_ATTACK_TARGET = 6
We attack the intruder next round, by setting it as a local object to
override other choices.
I_WAS_KILLED = 7
If lots are killed in one go - ouch! morale penalty each time someone dies.
I_WAS_OPENED = 8
Chests/Doors which say this get the AI onto the tails of those who opened it, OR
they get searched! :-)
//::///////////////////////////////////////////////
// Modified almost completely: Jasperre
//:://///////////////////////////////////////////*/
// Gets any possible target which is attacking oShouter (and isn't an ally)
// or who oShouter is attacking. oShouter should be a ally.
object GetIntruderFromShout(object oShouter)
{
// First, get who they specifically want to attack (IE: Input target the shout
// is usually for)
object oIntruder = GetLocalObject(oShouter, AI_OBJECT + AI_ATTACK_SPECIFIC_OBJECT);
if(GetIgnoreNoFriend(oIntruder) || (!GetObjectSeen(oShouter) && !GetObjectHeard(oShouter)))
{
// Or, we look for the last melee target (which, at least, will be set)
oIntruder = GetLocalObject(oShouter, AI_OBJECT + AI_LAST_MELEE_TARGET);
if(GetIgnoreNoFriend(oIntruder) || (!GetObjectSeen(oShouter) && !GetObjectHeard(oShouter)))
{
// Current actual attack target of the shouter
oIntruder = GetAttackTarget(oShouter);
if(GetIgnoreNoFriend(oIntruder) || (!GetObjectSeen(oShouter) && !GetObjectHeard(oShouter)))
{
// Last hostile actor of the shouter
oIntruder = GetLastHostileActor(oShouter);
if(GetIgnoreNoFriend(oIntruder) || (!GetObjectSeen(oShouter) && !GetObjectHeard(oShouter)))
{
return OBJECT_INVALID;
}
}
}
}
return oIntruder;
}
// Responds to it (like makinging the callers attacker thier target)
// Called in OnConversation, and thats it. Use "ShouterFriend" To stop repeated GetIsFriend calls.
void RespondToShout(object oShouter, int nShoutIndex)
{
// We use oIntruder to set who to attack.
object oIntruder;
// Check nShoutIndex against known constants
switch(nShoutIndex)
{
// Note: Not checked in sequential order (especially as they are constants).
// Instead, it is "Ones which if we are in combat, we still check" first.
// Attack a specific object which the leader shouted about.
case AI_SHOUT_LEADER_ATTACK_TARGET_CONSTANT:
{
// If a leader, we set it as a local object, nothing more
if(GetSpawnInCondition(AI_FLAG_OTHER_COMBAT_GROUP_LEADER, AI_OTHER_COMBAT_MASTER, oShouter))
{
// 70. "[Shout] Reacting To Shout. [ShoutNo.] " + IntToString(iInput) + " [Shouter] " + GetName(oInput)
DebugActionSpeakByInt(70, oShouter, nShoutIndex);
oIntruder = GetLocalObject(oShouter, AI_ATTACK_SPECIFIC_OBJECT);
if(GetObjectSeen(oIntruder))
{
// Set local object to use in next DetermineCombatRound.
// We do not interrupt current acition (EG: Life saving stoneskins!) to re-direct.
SetAIObject(AI_ATTACK_SPECIFIC_OBJECT, oIntruder);
// 6 second delay.
SetLocalTimer(AI_TIMER_SHOUT_IGNORE_ANYTHING_SAID, 6.0);
}
}
return;
}
break;
// Leader flee now - mass retreat to those who hear it.
case AI_SHOUT_LEADER_FLEE_NOW_CONSTANT:
{
// If a leader, we set it as a local object, nothing more
if(GetSpawnInCondition(AI_FLAG_OTHER_COMBAT_GROUP_LEADER, AI_OTHER_COMBAT_MASTER, oShouter))
{
// Get who we are going to run too
oIntruder = GetLocalObject(oShouter, AI_FLEE_TO);
// RUN! If intruder set is over 5.0M or no valid intruder
ClearAllActions();
// 70. "[Shout] Reacting To Shout. [ShoutNo.] " + IntToString(iInput) + " [Shouter] " + GetName(oInput)
DebugActionSpeakByInt(70, oShouter, nShoutIndex);
// Set to run
SetCurrentAction(AI_SPECIAL_ACTIONS_FLEE);
// Turn on fleeing visual effect
ApplyFleeingVisual();
// Ignore talk for 12 seconds
SetLocalTimer(AI_TIMER_SHOUT_IGNORE_ANYTHING_SAID, 12.0);
// If valid, we run to the intruder
if(GetIsObjectValid(oIntruder))
{
SetAIObject(AI_FLEE_TO, oIntruder);
ActionMoveToObject(oIntruder);
}
else // Else, we will just follow our leader!
{
SetAIObject(AI_FLEE_TO, oShouter);
ActionForceFollowObject(oShouter, 3.0);
}
}
return;
}
break;
// All others (IE: We need to not be in combat for these)
// Anything that requires "DetermineCombatRound()" is here.
// If the shout is number 8, it is "I was opened" and so can only be a
// placeable or door.
case AI_SHOUT_I_WAS_OPENED_CONSTANT:
{
// If we are already attacking, we ignore this shout.
if(CannotPerformCombatRound()) return;
// We need somewhat complexe here - to get thier opener.
int nType = GetObjectType(oShouter);
// Check object type. If not a placeable nor door - stop script.
if(nType == OBJECT_TYPE_PLACEABLE ||
nType == OBJECT_TYPE_DOOR)
{
// 70. "[Shout] Reacting To Shout. [ShoutNo.] " + IntToString(iInput) + " [Shouter] " + GetName(oInput)
DebugActionSpeakByInt(70, oShouter, nShoutIndex);
// Now, we assign the placeable/door to set thier opener.
// We do this by just executing a script that does it.
ExecuteScript(FILE_SET_OPENER, oShouter);
// We can immediantly get this would-be attacker!
oIntruder = GetLocalObject(oShouter, AI_PLACEABLE_LAST_OPENED_BY);
if(GetIsObjectValid(oIntruder))
{
// Attack
ClearAllActions();
DetermineCombatRound(oShouter);
}
else
{
// Move to the object who shouted in detect mode
SetActionMode(OBJECT_SELF, ACTION_MODE_DETECT, TRUE);
ActionMoveToObject(oShouter, TRUE);
}
}
return;
}
break;
// Call to arms requires nothing special. It is only called if
// There is no target the shouter has to attack specifically, rather then
// "I_WAS_ATTACKED" which would have.
case AI_SHOUT_CALL_TO_ARMS_CONSTANT:
{
// If we are already attacking, we ignore this shout.
if(CannotPerformCombatRound()) return;
// Ignore for 6 seconds
SetLocalTimer(AI_TIMER_SHOUT_IGNORE_ANYTHING_SAID, 6.0);
// 70. "[Shout] Reacting To Shout. [ShoutNo.] " + IntToString(iInput) + " [Shouter] " + GetName(oInput)
DebugActionSpeakByInt(70, oShouter, nShoutIndex);
// do standard Call to Arms response - IE: Move to oShouter
CallToArmsResponse(oShouter);
return;
}
break;
// "Help my friend" is when a runner is running off (sorta fleeing) to
// get help. This will move to the location set on them to reinforce.
case AI_SHOUT_HELP_MY_FRIEND_CONSTANT:
{
// If we are already attacking, we ignore this shout.
if(CannotPerformCombatRound()) return;
// Ignore things for 6 seconds
SetLocalTimer(AI_TIMER_SHOUT_IGNORE_ANYTHING_SAID, 6.0);
// We move to where the runner/shouter wants us.
location lMoveTo = GetLocalLocation(oShouter, AI_LOCATION + AI_HELP_MY_FRIEND_LOCATION);
// 70. "[Shout] Reacting To Shout. [ShoutNo.] " + IntToString(iInput) + " [Shouter] " + GetName(oInput)
DebugActionSpeakByInt(70, oShouter, nShoutIndex);
// If the location is valid
if(GetIsObjectValid(GetAreaFromLocation(lMoveTo)))
{
// New special action, but one that is overrided by combat
SetCurrentAction(AI_SPECIAL_ACTIONS_MOVE_TO_COMBAT);
SetAIObject(AI_MOVE_TO_COMBAT_OBJECT, oShouter);
SetAILocation(AI_MOVE_TO_COMBAT_LOCATION, lMoveTo);
// Move to the location of the fight, attack.
ClearAllActions();
// Move to the fights location
ActionMoveToLocation(lMoveTo, TRUE);
// When we see someone fighting, we'll DCR
return;
}
else
{
// Else, if we do not know of the friends attackers, or the location
// they are at, we will follow them without casting any preperation
// spells.
ClearAllActions();
ActionForceFollowObject(oShouter, 3.0);
// When we see an enemy, we'll attack!
return;
}
return;
}
break;
// "I was attacked" is called when a creature is hurt or sees an enemy,
// and starts to attack them. This means they know who the enemy is -
// and thusly we can get it from them (Ususally GetLastHostileActor()
// "I was killed" is the same, but applies a morale penalty too
case AI_SHOUT_I_WAS_ATTACKED_CONSTANT:
case AI_SHOUT_I_WAS_KILLED_CONSTANT:
{
// If it was "I was killed", we apply a short morale penatly
// Penalty is "Hit dice / 4 + 1" (so always 1 minimum) for 18 seconds.
if(nShoutIndex == AI_SHOUT_I_WAS_KILLED_CONSTANT)
{
SetMoralePenalty(GetHitDice(oShouter)/4 + 1, 18.0);
}
// If we are already attacking, we ignore this shout.
if(CannotPerformCombatRound()) return;
// 70. "[Shout] Reacting To Shout. [ShoutNo.] " + IntToString(iInput) + " [Shouter] " + GetName(oInput)
DebugActionSpeakByInt(70, oShouter, nShoutIndex);
// Ignore for 6 seconds
SetLocalTimer(AI_TIMER_SHOUT_IGNORE_ANYTHING_SAID, 6.0);
// Respond to oShouter's request for help - find thier target, and
// attack!
IWasAttackedResponse(oShouter);
return;
}
break;
}
}
// At 5+ intelligence, we fire off any dispells at oPlaceables location
void SearchDispells(object oPlaceable)
{
// No dispelling at low intelligence.
if(GetBoundriedAIInteger(AI_INTELLIGENCE) < 5) return;
location lPlace = GetLocation(oPlaceable);
// Move closer if not seen.
if(!GetObjectSeen(oPlaceable))
{
// Move nearer - 6 M is out of the dispell range
ActionMoveToObject(oPlaceable, TRUE, 6.0);
}
// Dispell if we have any - at the location of oPlaceable.
if(GetHasSpell(SPELL_LESSER_DISPEL))
{
ActionCastSpellAtLocation(SPELL_LESSER_DISPEL, lPlace);
}
else if(GetHasSpell(SPELL_DISPEL_MAGIC))
{
ActionCastSpellAtLocation(SPELL_DISPEL_MAGIC, lPlace);
}
else if(GetHasSpell(SPELL_GREATER_DISPELLING))
{
ActionCastSpellAtLocation(SPELL_GREATER_DISPELLING, lPlace);
}
else if(GetHasSpell(SPELL_MORDENKAINENS_DISJUNCTION))
{
ActionCastSpellAtLocation(SPELL_MORDENKAINENS_DISJUNCTION, lPlace);
}
}
// This sets a morale penalty, to the exsisting one, if there is one.
// It will reduce itself (by the penalty) after fDuration (or if we die, ETC, it is deleted).
// It is deleted at the end of combat as well.
void SetMoralePenalty(int nPenalty, float fDuration = 0.0)
{
int nNewPenalty = GetAIInteger(AI_MORALE_PENALTY) + nPenalty;
SetAIInteger(AI_MORALE_PENALTY, nNewPenalty);
DelayCommand(fDuration, RemoveMoralePenalty(nPenalty));
}
// Removes nPenalty amount if it can.
void RemoveMoralePenalty(int nPenalty)
{
int nNewPenalty = GetAIInteger(AI_MORALE_PENALTY) - nPenalty;
if(nNewPenalty > 0 && !GetIsDead(OBJECT_SELF))
{
SetAIInteger(AI_MORALE_PENALTY, nNewPenalty);
}
else
{
DeleteAIInteger(AI_MORALE_PENALTY);
}
}
// This MIGHT move to oEnemy
// - Checks special actions, such as fleeing, and may run instead!
void ActionMoveToEnemy(object oEnemy)
{
// Make sure that we are not fleeing badly (-1 morale from all enemies)
if(GetIsEnemy(oEnemy))
{
// -1 morale, flee
if(PerceptionFleeFrom(oEnemy)) return;
}
if(GetIsPerformingSpecialAction())
{
// Stop if we have an action we don't want to override
return;
}
// End default is move to the enemy
ClearAllActions();
ActionMoveToObject(oEnemy, TRUE);
// combat round to heal/search/whatever
if(!GetFactionEqual(oEnemy))
{
ActionDoCommand(DetermineCombatRound(oEnemy));
}
}
// Returns TRUE if we have under 0 morale, set to flee.
// - They then run! (Badly)
int PerceptionFleeFrom(object oEnemy)
{
object oRunTarget = oEnemy;
if(GetAIInteger(AI_INTELLIGENCE) < FALSE)
{
// Valid run from target
if(!GetIsObjectValid(oRunTarget))
{
oRunTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN, CREATURE_TYPE_IS_ALIVE, TRUE);
if(!GetIsObjectValid(oRunTarget))
{
oRunTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_HEARD, CREATURE_TYPE_IS_ALIVE, TRUE);
if(!GetIsObjectValid(oRunTarget))
{
oRunTarget = GetLastHostileActor();
if(!GetIsObjectValid(oRunTarget) || GetIsDead(oRunTarget))
{
// Stop - nothing to flee from!
return FALSE;
}
}
}
}
// Run from enemy
ClearAllActions();
ActionMoveAwayFromObject(oRunTarget, TRUE, 50.0);
return TRUE;
}
// 0 or more morale.
return FALSE;
}
// This wrappers commonly used code for a "Call to arms" type response.
// * We know of no enemy, so we will move to oAlly, who either called to
// us, or, well, we know of.
// * Calls out AI_SHOUT_CALL_TO_ARMS too.
void CallToArmsResponse(object oAlly)
{
// Shout to allies to attack, or be prepared.
AISpeakString(AI_SHOUT_CALL_TO_ARMS);
// If we are over 2 meters away from oShouter, we move to them using
// the special action
if(GetDistanceToObject(oAlly) > 2.0 || !GetObjectSeen(oAlly))
{
// New special action, but one that is overrided by combat
location lAlly = GetLocation(oAlly);
SetCurrentAction(AI_SPECIAL_ACTIONS_MOVE_TO_COMBAT);
SetAIObject(AI_MOVE_TO_COMBAT_OBJECT, oAlly);
SetAILocation(AI_MOVE_TO_COMBAT_LOCATION, lAlly);
// Move to the location of the fight, attack.
ClearAllActions();
// Move to the fights location
ActionMoveToLocation(lAlly, TRUE);
// When we see someone fighting, we'll DCR
return;
}
else
{
// Determine it anyway - we will search around oShouter
// if nothing is found...but we are near to the shouter
DetermineCombatRound(oAlly);
return;
}
}
// This wrappers commonly used code for a "I was attacked" type response.
// * We know there will be an enemy - or should be - and if we find one to attack
// (using GetIntruderFromShout()) - we attack it (and call another I was attacked)
// else, this will run CallToArmsResponse(oAlly);
// * Calls out AI_SHOUT_I_WAS_ATTACKED, or AI_SHOUT_CALL_TO_ARMS too.
void IWasAttackedResponse(object oAlly)
{
// Get the indruder. This is either who oShouter is currently attacking,
// or the last attacker of them.
object oIntruder = GetIntruderFromShout(oAlly);
// If valid, of course attack!
if(GetIsObjectValid(oIntruder))
{
// 1.4 Note:
// * It used to check "Are they seen". Basically, this is redudant
// with the checks used in DetermineCombatRound(). It will do the
// searching using oIntruder whatever.
// Stop, and attack
ClearAllActions();
DetermineCombatRound(oIntruder);
// Shout I was attacked - we've set our intruder now
AISpeakString(AI_SHOUT_I_WAS_ATTACKED);
return;
}
// If invalid, we act as if it was "Call to arms" type thing.
// Call to arms is better to use normally, of course.
else
{
// Shout to allies to attack, or be prepared.
AISpeakString(AI_SHOUT_CALL_TO_ARMS);
// We see if they are attacking anything:
oIntruder = GetAttackTarget(oAlly);
if(!GetIsObjectValid(oIntruder))
{
oIntruder = GetLocalObject(oAlly, AI_OBJECT + AI_LAST_MELEE_TARGET);
}
// If valid, we will move to a point bisecting the intruder and oAlly, or
// move to oAlly. Should get interrupted once we see the attack target.
// * NEED TO TEST
if(GetIsObjectValid(oIntruder))
{
// New special action, but one that is overrided by combat
vector vTarget = GetPosition(oIntruder);
vector vSource = GetPosition(OBJECT_SELF);
vector vDirection = vTarget - vSource;
float fDistance = VectorMagnitude(vDirection) / 2.0;
vector vPoint = VectorNormalize(vDirection) * fDistance + vSource;
location lTarget = Location(GetArea(OBJECT_SELF), vPoint, DIRECTION_NORTH);
SetCurrentAction(AI_SPECIAL_ACTIONS_MOVE_TO_COMBAT);
SetAIObject(AI_MOVE_TO_COMBAT_OBJECT, oAlly);
SetAILocation(AI_MOVE_TO_COMBAT_LOCATION, lTarget);
// Move to the location of the fight, attack.
ClearAllActions();
// Move to the fights location
ActionMoveToLocation(lTarget, TRUE);
// When we see someone fighting, we'll DCR
return;
}
// If we are over 2 meters away from oShouter, we move to them using
// the special action
else if(GetDistanceToObject(oAlly) > 2.0 || !GetObjectSeen(oAlly))
{
// New special action, but one that is overrided by combat
location lAlly = GetLocation(oAlly);
SetCurrentAction(AI_SPECIAL_ACTIONS_MOVE_TO_COMBAT);
SetAIObject(AI_MOVE_TO_COMBAT_OBJECT, oAlly);
SetAILocation(AI_MOVE_TO_COMBAT_LOCATION, lAlly);
// Move to the location of the fight, attack.
ClearAllActions();
// Move to the fights location
ActionMoveToLocation(lAlly, TRUE);
// When we see someone fighting, we'll DCR
return;
}
else
{
// Determine it anyway - we will search around oShouter
// if nothing is found...but we are near to the shouter
DetermineCombatRound(oAlly);
return;
}
}
}
// Debug: To compile this script full, uncomment all of the below.
/* - Add two "/"'s at the start of this line
void main()
{
return;
}
//*/

View File

@@ -1,479 +0,0 @@
/*/////////////////////// [Include - Set Effects] //////////////////////////////
Filename: J_INC_SetEffects
///////////////////////// [Include - Set Effects] //////////////////////////////
This can be executed on a PC or NPC, and sets what thier current effects
are - the hostile ones.
It is executed on a PC every 6 seconds in combat, delayed by a timer,
by other NPCs who want to target them.
It is meant to be more efficient then doing countless checks against other
NPCs and PCs for what effects they already have on them.
///////////////////////// [History] ////////////////////////////////////////////
1.3 - Added
1.4 - Changed so fear and stun was seperate.
Uncommandable still is now for any uncommandable effects.
- TO DO
- Make the ability decrease into "light" "major" and so on, about 4
ratings, each set as more decreases are present.
///////////////////////// [Workings] ///////////////////////////////////////////
ExecuteScript - might not work faster. If so, it is easy to add into the
generic AI and have oTarget to set to.
It searches the code and sets 3 custom integers, but only once (so not
during the loop)
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: N/A
///////////////////////// [Include - Set Effects] ////////////////////////////*/
#include "J_INC_CONSTANTS"
#include "prc_inc_racial"
//void main (){}
// List (use Global to not conflict with the nwscript.nss!)
const int GlobalEffectUncommandable = 0x00000001;// Stun. Sleep. Fear. Turning. Paralsis. Petrify.
const int GlobalEffectSilenced = 0x00000002;// Eeek!
const int GlobalEffectSlowed = 0x00000004;// Stop with haste.
const int GlobalEffectUltravision = 0x00000008;
const int GlobalEffectSeeInvisible = 0x00000010; // NOT Inc. Trueseeing
const int GlobalEffectTrueSeeing = 0x00000020;
const int GlobalEffectTimestop = 0x00000040;
const int GlobalEffectInvisible = 0x00000080;
const int GlobalEffectDeaf = 0x00000100;// Ack!
const int GlobalEffectHaste = 0x00000200;
const int GlobalEffectPolymorph = 0x00000400;// Only attack
const int GlobalEffectBlindness = 0x00000800;// Oh no! Cannot see others to cast spells.
const int GlobalEffectDisease = 0x00001000;
const int GlobalEffectPoison = 0x00002000;
const int GlobalEffectCurse = 0x00004000;
const int GlobalEffectNegativeLevel = 0x00008000;
const int GlobalEffectEntangle = 0x00010000;
const int GlobalEffectMovementSpeedDecrease = 0x00020000;
const int GlobalEffectDarkness = 0x00040000;// Noo! Need ultravision!
const int GlobalEffectDazed = 0x00080000;// Special: 1.30 patch, we can move!
const int GlobalEffectEthereal = 0x00100000;
const int GlobalEffectPetrify = 0x00200000;
const int GlobalEffectParalyze = 0x00400000;// Divided from Uncommandable for healing of
const int GlobalEffectSpellFailure = 0x00800000;// Makes sure spells are not cast under high failure.
const int GlobalEffectDamageShield = 0x01000000;// All damage shields
const int GlobalEffectFear = 0x02000000;// 1.4. Remove fear + G.Rest. Removes.
const int GlobalEffectStun = 0x04000000;// 1.4. G.Rest. Removes.
//int GlobalEffectAbilityDecrease = 0; // In combat include
// These are Globals for spell effects, to not csat them on us again, and to
// speed things up...
// These are *good* spells. This effect is only set up on us.
const int GlobalHasStoneSkinProtections = 0x00000001;
const int GlobalHasElementalProtections = 0x00000002;
const int GlobalHasVisageProtections = 0x00000004;
const int GlobalHasMantalProtections = 0x00000008;
const int GlobalHasGlobeProtections = 0x00000010;
const int GlobalHasMindResistanceProtections = 0x00000020;
const int GlobalHasAidingSpell = 0x00000040;
const int GlobalHasRangedConsealment = 0x00000080;
const int GlobalHasRageSpells = 0x00000100;
const int GlobalHasBullsStrengthSpell = 0x00000200;
const int GlobalHasCatsGraceSpell = 0x00000400;
const int GlobalHasClairaudienceSpell = 0x00000800;
const int GlobalHasDeathWardSpell = 0x00001000;
const int GlobalHasDivinePowerSpell = 0x00002000;
const int GlobalHasEaglesSpledorSpell = 0x00004000;
const int GlobalHasEnduranceSpell = 0x00008000;
const int GlobalHasFoxesCunningSpell = 0x00010000;
const int GlobalHasProtectionEvilSpell = 0x00020000;
const int GlobalHasProtectionGoodSpell = 0x00040000;
const int GlobalHasLightSpell = 0x00080000;
const int GlobalHasConsealmentSpells = 0x00100000;// Displacement
const int GlobalHasProtectionSpellsSpell = 0x00200000;
const int GlobalHasRegenerateSpell = 0x00400000;
const int GlobalHasOwlsWisdomSpell = 0x00800000;
const int GlobalHasSpellResistanceSpell = 0x01000000;
const int GlobalHasSpellWarCrySpell = 0x02000000;
//const int GlobalHasElementalShieldSpell = 0x04000000;// Is general effect
const int GlobalHasDomainSpells = 0x08000000;
const int GlobalHasDeflectionACSpell = 0x10000000;
const int GlobalHasNaturalACSpell = 0x20000000;
const int GlobalHasOtherACSpell = 0x40000000;
const int GlobalHasWeaponHelpSpell = 0x80000000;
// Other, AOE ones
//const int GlobalHasAreaEffectDamaging = 0x04000000;
//const int GlobalHasAreaEffectImpeding = 0x08000000;
int TempEffectHex, TempSpellHex;
// Sets up an effects thing to that
void AI_SetTargetHasEffect(int nEffectHex);
// Sets we have spell iSpellHex's effects.
void AI_SetWeHaveSpellsEffect(int nSpellHex);
// Sets up effects on oTarget
void AI_SetEffectsOnTarget(object oTarget = OBJECT_SELF);
// Simple return TRUE if it matches hex.
// - Effects tested on oTarget
int AI_GetAIHaveEffect(int nEffectHex, object oTarget = OBJECT_SELF);
// Simple return TRUE if it matches hex.
// * Can only be used on ourself.
int AI_GetAIHaveSpellsEffect(int nSpellHex);
// Sets up an effects thing to that
void AI_SetTargetHasEffect(int nEffectHex)
{
TempEffectHex = TempEffectHex | nEffectHex;
}
// Sets we have spell iSpellHex's effects.
void AI_SetWeHaveSpellsEffect(int nSpellHex)
{
TempSpellHex = TempSpellHex | nSpellHex;
}
// Simple return TRUE if it matches hex.
// - Effects tested on oTarget
int AI_GetAIHaveEffect(int nEffectHex, object oTarget = OBJECT_SELF)
{
return (GetLocalInt(oTarget, AI_EFFECT_HEX) & nEffectHex);
}
// Simple return TRUE if it matches hex.
// * Can only be used on ourself.
int AI_GetAIHaveSpellsEffect(int nSpellHex)
{
return (GetLocalInt(OBJECT_SELF, AI_SPELL_HEX) & nSpellHex);
}
// Sets up effects on oTarget
void AI_SetEffectsOnTarget(object oTarget = OBJECT_SELF)
{
TempEffectHex = FALSE;
TempSpellHex = FALSE;
// Checks our effects once.
effect eCheck = GetFirstEffect(oTarget);
int nEffect, nEffectAbilityDecrease, nSpellID;
// EFFECTS:
// For ALL targets (that we will use), we set up effects on a system of Hexes.
// like spawn in things. Replaces GetHasSpellEffect, except genralising -
// IE we will NOT cast more than one of the stoneskin type things at once.
while(GetIsEffectValid(eCheck))
{
nEffect = GetEffectType(eCheck);
switch(nEffect)
{
case EFFECT_TYPE_INVALIDEFFECT:
case EFFECT_TYPE_VISUALEFFECT:
// Don't check these for spell values.
break;
case EFFECT_TYPE_PARALYZE: // Also makes you uncommandable
{
AI_SetTargetHasEffect(GlobalEffectParalyze);
AI_SetTargetHasEffect(GlobalEffectUncommandable);
}
break;
case EFFECT_TYPE_STUNNED: // Also makes you uncommandable
{
AI_SetTargetHasEffect(GlobalEffectStun);
AI_SetTargetHasEffect(GlobalEffectUncommandable);
}
break;
case EFFECT_TYPE_FRIGHTENED: // Also makes you uncommandable
{
AI_SetTargetHasEffect(GlobalEffectFear);
AI_SetTargetHasEffect(GlobalEffectUncommandable);
}
break;
// * Cannot remove these, but make you unable to move.
case EFFECT_TYPE_SLEEP:
case EFFECT_TYPE_TURNED:
case EFFECT_TYPE_DISAPPEARAPPEAR:// Added for dragon flying
case EFFECT_TYPE_CONFUSED:// 1.4 added. wasn't in before
AI_SetTargetHasEffect(GlobalEffectUncommandable);
break;
case EFFECT_TYPE_DAZED:
AI_SetTargetHasEffect(GlobalEffectDazed);
break;
case EFFECT_TYPE_SILENCE:
AI_SetTargetHasEffect(GlobalEffectSilenced);
break;
case EFFECT_TYPE_SLOW:
AI_SetTargetHasEffect(GlobalEffectSlowed);
break;
case EFFECT_TYPE_ULTRAVISION:
AI_SetTargetHasEffect(GlobalEffectUltravision);
break;
case EFFECT_TYPE_SEEINVISIBLE:
AI_SetTargetHasEffect(GlobalEffectSeeInvisible);
break;
// Caused by Beholder things mainly, but this stops any spell being
// cast, not just, for example, arcane spells cast in armor.
case EFFECT_TYPE_SPELL_FAILURE:
AI_SetTargetHasEffect(GlobalEffectSpellFailure);
break;
// Penetrates darkness.
case EFFECT_TYPE_TRUESEEING:
AI_SetTargetHasEffect(GlobalEffectTrueSeeing);
break;
// Timestop - IE don't cast same spell twice.
case EFFECT_TYPE_TIMESTOP:
AI_SetTargetHasEffect(GlobalEffectTimestop);
break;
// Invisibility/Improved (although improved only uses normal in the spell)
// Sneak attack/whatever :-)
// - include the spell EFFECT_TYPE_ETHEREAL.
case EFFECT_TYPE_INVISIBILITY:
case EFFECT_TYPE_IMPROVEDINVISIBILITY:
AI_SetTargetHasEffect(GlobalEffectInvisible);
break;
// Deaf - spell failing of 20%, but still cast.
case EFFECT_TYPE_DEAF:
AI_SetTargetHasEffect(GlobalEffectDeaf);
break;
// Special invis.
case EFFECT_TYPE_ETHEREAL:
AI_SetTargetHasEffect(GlobalEffectEthereal);
break;
// Haste - so don't cast haste again and whatever.
case EFFECT_TYPE_HASTE:
AI_SetTargetHasEffect(GlobalEffectHaste);
break;
// Haste - so don't cast haste again and whatever.
case EFFECT_TYPE_POLYMORPH:
AI_SetTargetHasEffect(GlobalEffectPolymorph);
break;
// Blindness - oh no, can't see, only hear!
case EFFECT_TYPE_BLINDNESS:
AI_SetTargetHasEffect(GlobalEffectBlindness);
break;
// Damage shield = Elemental shield, wounding whispers, Death armor, mestals
// sheth and so on.
case EFFECT_TYPE_ELEMENTALSHIELD:
AI_SetTargetHasEffect(GlobalEffectDamageShield);
break;
// Things we may want to remove VIA cirtain spells, we set here - may as well.
// Same setting as any other.
// IF we can remove it (not confusion ETC of course) then we set it.
case EFFECT_TYPE_DISEASE:
AI_SetTargetHasEffect(GlobalEffectDisease);
break;
case EFFECT_TYPE_POISON:
AI_SetTargetHasEffect(GlobalEffectPoison);
break;
// SoU Petrify
// Note: Also makes them uncommandable
case EFFECT_TYPE_PETRIFY:
{
AI_SetTargetHasEffect(GlobalEffectPetrify);
AI_SetTargetHasEffect(GlobalEffectUncommandable);
}
break;
case EFFECT_TYPE_CURSE:
AI_SetTargetHasEffect(GlobalEffectCurse);
break;
case EFFECT_TYPE_NEGATIVELEVEL:
AI_SetTargetHasEffect(GlobalEffectNegativeLevel);
break;
case EFFECT_TYPE_ABILITY_DECREASE:
case EFFECT_TYPE_AC_DECREASE:
case EFFECT_TYPE_ATTACK_DECREASE:
case EFFECT_TYPE_DAMAGE_DECREASE:
case EFFECT_TYPE_DAMAGE_IMMUNITY_DECREASE:
case EFFECT_TYPE_SAVING_THROW_DECREASE:
case EFFECT_TYPE_SPELL_RESISTANCE_DECREASE:
case EFFECT_TYPE_SKILL_DECREASE:
// Special - we add one to this, to determine when to use restoration
nEffectAbilityDecrease++;
break;
case EFFECT_TYPE_ENTANGLE:
AI_SetTargetHasEffect(GlobalEffectEntangle);
break;
case EFFECT_TYPE_MOVEMENT_SPEED_DECREASE:
AI_SetTargetHasEffect(GlobalEffectMovementSpeedDecrease);
break;
case EFFECT_TYPE_DARKNESS:
AI_SetTargetHasEffect(GlobalEffectDarkness);
break;
default:
{
// Check spells *we* (1.4 change: now checks OBJECT_SELF)
// have on...so we don't cast over them!
nSpellID = GetEffectSpellId(eCheck);
if(nSpellID != -1 && oTarget == OBJECT_SELF)
{
switch(nSpellID)
{
// All weapon things are on one variable. We cast the best.
case SPELL_MAGIC_WEAPON:
case SPELL_BLESS_WEAPON:
case SPELL_FLAME_WEAPON:
case SPELL_GREATER_MAGIC_WEAPON:
case SPELL_BLACKSTAFF:
case SPELL_BLADE_THIRST:
AI_SetWeHaveSpellsEffect(GlobalHasWeaponHelpSpell);
break;
case SPELL_ENDURE_ELEMENTS:
case SPELL_ENERGY_BUFFER:
case SPELL_RESIST_ELEMENTS:
case SPELL_PROTECTION_FROM_ELEMENTS:
AI_SetWeHaveSpellsEffect(GlobalHasElementalProtections);
break;
case SPELL_BARKSKIN:
case SPELL_STONE_BONES: // +3 to undead
AI_SetWeHaveSpellsEffect(GlobalHasNaturalACSpell);
break;
case SPELL_SHIELD:
case SPELL_DIVINE_SHIELD:
AI_SetWeHaveSpellsEffect(GlobalHasDeflectionACSpell);
break;
case SPELL_EPIC_MAGE_ARMOR:// Epic spell +20 to AC.
case SPELL_MAGE_ARMOR:
AI_SetWeHaveSpellsEffect(GlobalHasOtherACSpell);
break;
case SPELL_ENTROPIC_SHIELD:
AI_SetWeHaveSpellsEffect(GlobalHasRangedConsealment);
break;
case AI_SPELL_EPIC_WARDING:
case SPELL_STONESKIN:
case SPELL_GREATER_STONESKIN:
case SPELL_PREMONITION:
case SPELL_SHADES_STONESKIN: // Stoneskin one: 342
AI_SetWeHaveSpellsEffect(GlobalHasStoneSkinProtections);
break;
case SPELL_GHOSTLY_VISAGE:
case SPELL_SHADOW_SHIELD:
case SPELL_ETHEREAL_VISAGE:
case SPELL_GREATER_SHADOW_CONJURATION_MIRROR_IMAGE: // one: 351 is gostly visage. Speeds up not using number
case SPELL_SHADOW_EVADE: // Shadow dancer
case SPELLABILITY_AS_GHOSTLY_VISAGE: // Assassin
AI_SetWeHaveSpellsEffect(GlobalHasVisageProtections);
break;
case SPELL_GREATER_SPELL_MANTLE:
case SPELL_SPELL_MANTLE:
case SPELL_LESSER_SPELL_MANTLE:
AI_SetWeHaveSpellsEffect(GlobalHasMantalProtections);
break;
case SPELL_MINOR_GLOBE_OF_INVULNERABILITY:
case SPELL_GLOBE_OF_INVULNERABILITY:
case SPELL_GREATER_SHADOW_CONJURATION_MINOR_GLOBE:
AI_SetWeHaveSpellsEffect(GlobalHasGlobeProtections);
break;
case SPELL_AID:
case SPELL_PRAYER:
case SPELL_BLESS:
AI_SetWeHaveSpellsEffect(GlobalHasAidingSpell);
break;
case SPELL_BULLS_STRENGTH:
case SPELL_GREATER_BULLS_STRENGTH:
case SPELLABILITY_BG_BULLS_STRENGTH: // Blackguard
AI_SetWeHaveSpellsEffect(GlobalHasBullsStrengthSpell);
break;
case SPELL_CATS_GRACE:
case SPELL_GREATER_CATS_GRACE:
case AI_SPELLABILITY_HARPER_CATS_GRACE: // Harper
AI_SetWeHaveSpellsEffect(GlobalHasCatsGraceSpell);
break;
case SPELL_CLAIRAUDIENCE_AND_CLAIRVOYANCE:
AI_SetWeHaveSpellsEffect(GlobalHasClairaudienceSpell);
break;
case SPELL_CLARITY:
case SPELL_LESSER_MIND_BLANK:
case SPELL_MIND_BLANK:
AI_SetWeHaveSpellsEffect(GlobalHasMindResistanceProtections);
break;
case SPELL_DEATH_WARD:
case SPELL_UNDEATHS_ETERNAL_FOE:// Similar to death ward. Got more things.
AI_SetWeHaveSpellsEffect(GlobalHasDeathWardSpell);
break;
case SPELL_DISPLACEMENT:// 50% consealment
AI_SetWeHaveSpellsEffect(GlobalHasConsealmentSpells);
break;
case SPELL_DIVINE_POWER:
AI_SetWeHaveSpellsEffect(GlobalHasDivinePowerSpell);
break;
case SPELL_EAGLE_SPLEDOR:
case SPELL_GREATER_EAGLE_SPLENDOR:
case AI_SPELLABILITY_HARPER_EAGLE_SPLEDOR: // Harper
AI_SetWeHaveSpellsEffect(GlobalHasEaglesSpledorSpell);
break;
case SPELL_ENDURANCE:
case SPELL_GREATER_ENDURANCE:
AI_SetWeHaveSpellsEffect(GlobalHasEnduranceSpell);
break;
case SPELL_FOXS_CUNNING:
case SPELL_GREATER_FOXS_CUNNING:
AI_SetWeHaveSpellsEffect(GlobalHasFoxesCunningSpell);
break;
case SPELL_HOLY_AURA:
case SPELL_MAGIC_CIRCLE_AGAINST_EVIL:
case SPELL_PROTECTION_FROM_EVIL:
AI_SetWeHaveSpellsEffect(GlobalHasProtectionEvilSpell);
break;
case SPELL_UNHOLY_AURA:
case SPELL_MAGIC_CIRCLE_AGAINST_GOOD:
case SPELL_PROTECTION_FROM_GOOD:
AI_SetWeHaveSpellsEffect(GlobalHasProtectionGoodSpell);
break;
case SPELL_LIGHT:
case SPELL_CONTINUAL_FLAME:
AI_SetWeHaveSpellsEffect(GlobalHasLightSpell);
break;
case SPELL_OWLS_WISDOM:
case SPELL_GREATER_OWLS_WISDOM:
case AI_SPELL_OWLS_INSIGHT:// Missed spell
AI_SetWeHaveSpellsEffect(GlobalHasOwlsWisdomSpell);
break;
case SPELL_PROTECTION_FROM_SPELLS:
AI_SetWeHaveSpellsEffect(GlobalHasProtectionSpellsSpell);
break;
case SPELL_REGENERATE:
AI_SetWeHaveSpellsEffect(GlobalHasRegenerateSpell);
break;
case SPELL_SPELL_RESISTANCE:
AI_SetWeHaveSpellsEffect(GlobalHasSpellResistanceSpell);
break;
case SPELL_WAR_CRY:
AI_SetWeHaveSpellsEffect(GlobalHasSpellWarCrySpell);
break;
case SPELLABILITY_DIVINE_PROTECTION:
case SPELLABILITY_DIVINE_STRENGTH:
case SPELLABILITY_DIVINE_TRICKERY:
case SPELLABILITY_BATTLE_MASTERY:
AI_SetWeHaveSpellsEffect(GlobalHasDomainSpells);
break;
case SPELLABILITY_RAGE_3:
case SPELLABILITY_RAGE_4:
case SPELLABILITY_RAGE_5:
case SPELLABILITY_BARBARIAN_RAGE:
case SPELLABILITY_INTENSITY_1:
case SPELLABILITY_INTENSITY_2:
case SPELLABILITY_INTENSITY_3:
case SPELLABILITY_FEROCITY_1:
case SPELLABILITY_FEROCITY_2:
case SPELLABILITY_FEROCITY_3:
case SPELL_BLOOD_FRENZY:
AI_SetWeHaveSpellsEffect(GlobalHasRageSpells);
break;
}
}
}
break;
}
eCheck = GetNextEffect(oTarget);
}
// If undead, set some immunities by default
if(MyPRCGetRacialType(oTarget) == RACIAL_TYPE_UNDEAD)
{
AI_SetWeHaveSpellsEffect(GlobalHasDeathWardSpell);
}
DeleteLocalInt(oTarget, AI_ABILITY_DECREASE);
DeleteLocalInt(oTarget, AI_EFFECT_HEX);
// Special - only we set spell hexs on ourselves.
if(oTarget == OBJECT_SELF)
{
DeleteLocalInt(oTarget, AI_SPELL_HEX);
SetLocalInt(oTarget, AI_SPELL_HEX, TempSpellHex);
}
// Set final ones from temp integers
SetLocalInt(oTarget, AI_ABILITY_DECREASE, nEffectAbilityDecrease);
SetLocalInt(oTarget, AI_EFFECT_HEX, TempEffectHex);
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,917 +0,0 @@
/*/////////////////////// [Include - Spawn In] /////////////////////////////////
Filename: J_Inc_SpawnIn
///////////////////////// [Include - Spawn In] /////////////////////////////////
This contains all the functions used in the spawning process, in one easy
and very long file.
It also importantly sets up spells we have, or at least talents, so we
know if we have any spells from category X.
///////////////////////// [History] ////////////////////////////////////////////
1.3 - Changed, added a lot of new things (such as constants file)
1.4 - No more setting talent categories On Spawn. This is too much hassel.
See the On rest script for ideas (remove this when complete!).
Perhaps set "Items" the first time we enter combat, and reset each time
combat stops. Can be more efficeint maybe.
- Skills set to "use" should have, say, 3 or more skill points to be
used automatically, especially true for hiding.
///////////////////////// [Workings] ///////////////////////////////////////////
This doesn't call anything to run the rest, except AI_SetUpEndOfSpawn has
a lot of things that the generic AI requires (SetListeningPatterns and skills
and waypoints ETC)
See the spawn in script for all the actual uses.
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: N/A see spawn in script
///////////////////////// [Include - Spawn In] ///////////////////////////////*/
// All constants.
#include "J_INC_SETWEAPONS"
#include "prc_inc_racial"
// Set weapons
// - Constants file is in this
// Special: Bioware SoU Waypoints/Animations constants
// - Here so I know where they are :-P
const string sAnimCondVarname = "NW_ANIM_CONDITION";
// If set, the NPC is civilized
const int NW_ANIM_FLAG_IS_CIVILIZED = 0x00000400;
// If set, the NPC will use voicechats
const int NW_ANIM_FLAG_CHATTER = 0x00000004;
// If set, the NPC is mobile in a close-range
const int NW_ANIM_FLAG_IS_MOBILE_CLOSE_RANGE = 0x00000200;
/******************************************************************************/
// Functions:
/******************************************************************************/
// This will activate one aura, very quickly.
// If we have more than one...oh well.
void AI_AdvancedAuras();
// Activate the aura number (IE: Spell number), if it is possible.
void AI_ActivateAura(int nAuraNumber);
// Base for moving round thier waypoints
// - Uses ExectuteScript to run the waypoint walking.
// * If bRun is TRUE, we run all the waypoint.
// * fPause is the time delay between walking to the next waypoint (default 1.0)
void SpawnWalkWayPoints(int bRun = FALSE, float fPause = 1.0);
// Sets up what we will listen to (everything!)
void AI_SetListeningPatterns();
// This will set what creature to create OnDeath.
void AI_SetDeathResRef(string sResRef);
// This will set the string, sNameOfValue, to sValue. Array size of 1.
// - Use nPercentToSay to determine what % out of 100 it is said.
void AI_SetSpawnInSpeakValue(string sNameOfValue, string sValue, int nPercentToSay = 100);
// This will choose a random string, using iAmountOfValues, which is
// the amount of non-empty strings given. The size of the array is therefore 1.
// - Use nPercentToSay to determine what % out of 100 it is said.
void AI_SetSpawnInSpeakRandomValue(string sNameOfValue, int nPercentToSay, int nAmountOfValues, string sValue1, string sValue2, string sValue3 = "", string sValue4 = "", string sValue5 = "", string sValue6 = "", string sValue7 = "", string sValue8 = "", string sValue9 = "", string sValue10 = "", string sValue11 = "", string sValue12 = "");
// This will set an array of values, to sNameOfValue, for one to be chosen to
// be said at the right time :-)
// - sNameOfValue must be a valid name.
// - Use iPercentToSay to determine what % out of 100 it is said.
// NOTE: If the sNameOfValue is any combat one, we make that 1/100 to 1/1000.
void AI_SetSpawnInSpeakArray(string sNameOfValue, int nPercentToSay, int nSize, string sValue1, string sValue2, string sValue3 = "", string sValue4 = "", string sValue5 = "", string sValue6 = "", string sValue7 = "", string sValue8 = "", string sValue9 = "", string sValue10 = "", string sValue11 = "", string sValue12 = "");
// This applies an increase, decrease or no change to the intended stat.
// * Applies the effects INSTANTLY. These CANNOT be removed easily!
void AI_ApplyStatChange(int nStat, int nAmount);
// This will alter (magically) an ammount of random stats - nAmount
// by a value within iLowest and nHighest.
// * Applies the effects INSTANTLY. These CANNOT be removed easily!
void AI_CreateRandomStats(int nLowest, int nHighest, int nAmount);
// This will randomise other stats. Put both numbers to 0 to ignore some.
// nHPMin, nHPMax = HP changes.
// nReflexSaveMin, nReflexSaveMax = Reflex Save changes
// nWillSaveMin, nWillSaveMax = Will Save changes
// nFortSaveMin, nFortSaveMax = Fortitude Save changes
// nACMin, nACMax = AC change.
// Use nACType to define the AC type - default AC_DODGE_BONUS
// * Applies the effects INSTANTLY. These CANNOT be removed easily!
void AI_CreateRandomOther(int nHPMin, int nHPMax, int nReflexSaveMin = 0, int nReflexSaveMax = 0, int nWillSaveMin = 0, int nWillSaveMax = 0, int nFortSaveMin = 0, int nFortSaveMax = 0, int nACMin = 0, int nACMax = 0, int nACType = AC_DODGE_BONUS);
// Sets up thier selection of skills, to integers, if they would ever use them.
// NOTE: it also triggers "hide" if they have enough skill and not stopped.
// * 1.4 Changes: Some skills are turned off automatically when they have very
// low points in that skill (IE: No possibility of doing it sucessfully). Also
// edited other parts of the AI to take this into account.
void AI_SetUpSkillToUse();
// Sets the turning level if we have FEAT_TURN_UNDEAD.
// - Called from AI_SetUpEndOfSpawn.
void AI_SetTurningLevel();
// This MUST be called. It fires these events:
// SetUpSpells, SetUpSkillToUse, SetListeningPatterns, SetWeapons, AdvancedAuras.
// These MUST be called! the AI might fail to work correctly if they don't fire!
void AI_SetUpEndOfSpawn();
// This will make the visual effect passed play INSTANTLY at the creatures location.
// * nVFX - The visual effect constant number
void AI_SpawnInInstantVisual(int nVFX);
// This will make the visual effect passed play PERMAMENTLY.
// * nVFX - The visual effect constant number
// NOTE: They will be made to be SUPERNATUAL, so are not dispelled!
void AI_SpawnInPermamentVisual(int nVFX);
// This should not be used!
// * called from SetUpEndOfSpawn.
void AI_SetMaybeFearless();
// This will set the MAXIMUM and MINIMUM targets to pass this stage (under sName)
// of the targeting system. IE:
// - If we set it to min of 5, max of 10, for AC, if we cancled 5 targets on having
// AC higher then wanted, we will take the highest 5 minimum.
// If there are over 10, we take a max of 10 to choose from.
// * nType - must be TARGET_HIGHER or TARGET_LOWER. Defaults to the lowest, so it
// targets the lowest value for sName.
void AI_SetAITargetingValues(string sName, int nType, int nMinimum, int nMaximum);
// Levels up us.
// * nLevel - Levels to this number (doesn't do anything if already GetHitDice >= nLevel).
// * nClass, nClass2, nClass3 - the 3 classes to level up in. Only needs 1 minimum
// Spreads equally if there is more then 1 nClass.
// Sets up spells to use automatically, but DOES NOT CHANGE CHALLENGE RATING!
void AI_LevelUpCreature(int nLevel, int nClass, int nClass2 = CLASS_TYPE_INVALID, int nClass3 = CLASS_TYPE_INVALID);
// Used in AI_LevelUpCreature.
// - Levels up OBJECT_SELF, in nClass for nLevels
void AI_LevelLoop(int nClass, int nLevels);
// Sets up what random spells to cheat-cast at the end of all known spells.
// it does NOT check for immunities, barriers, or anything else.
// - You can set spells to more then one of the imputs to have a higher % to cast that one.
void SetAICheatCastSpells(int nSpell1, int nSpell2, int nSpell3, int nSpell4, int nSpell5, int nSpell6);
// Mark that the given creature has the given condition set for anitmations
// * Bioware SoU animations thing.
void SetAnimationCondition(int nCondition, int bValid = TRUE, object oCreature = OBJECT_SELF);
// Sets we are a Beholder and use Ray attacks, and Animagic Ray.
void SetBeholderAI();
// Set we are a mindflayer, and uses some special AI for them.
void SetMindflayerAI();
// This will set a spell trigger up. Under cirtain conditions, spells are released
// and cast on the caster.
// Once fired, a spell trigger is only reset by resting. Only 1 of each max is fired at once!
// * sType - is specifically:
// SPELLTRIGGER_DAMAGED_AT_PERCENT - When damaged, the trigger fires. Use iValue for the %. One at a time is fired.
// SPELLTRIGGER_IMMOBILE - Fired when held/paralyzed/sleeping ETC. One at a time is fired.
// SPELLTRIGGER_NOT_GOT_FIRST_SPELL - Makes sure !GetHasSpellEffect(iSpell1) already,
// then fires. Checks all in this category each round (first one fires!)
// SPELLTRIGGER_START_OF_COMBAT - Triggered always, at the start of DetermineCombatRound.
// * nNumber - can be 1-9, in sequential order of when you want them to fire.
// * nValue - is only required with DAMAGED_AT_PERCENT.
// * nSpellX - Cannot be 0. It should only really be defensive spells.
void SetSpellTrigger(string sType, int nValue, int nNumber, int nSpell1, int nSpell2 = 0, int nSpell3 = 0, int nSpell4 = 0, int nSpell5 = 0, int nSpell6 = 0, int nSpell7 = 0, int nSpell8 = 0, int nSpell9 = 0);
// Mark that the given creature has the given condition set
void SetAnimationCondition(int nCondition, int bValid = TRUE, object oCreature = OBJECT_SELF)
{
int nCurrentCond = GetLocalInt(oCreature, sAnimCondVarname);
if (bValid) {
SetLocalInt(oCreature, sAnimCondVarname, nCurrentCond | nCondition);
} else {
SetLocalInt(oCreature, sAnimCondVarname, nCurrentCond & ~nCondition);
}
}
// Sets up what random spells to cheat-cast at the end of all known spells.
// it does NOT check for immunities, barriers, or anything else.
// - You can set spells to more then one of the imputs to have a higher % to cast that one.
void SetAICheatCastSpells(int nSpell1, int nSpell2, int nSpell3, int nSpell4, int nSpell5, int nSpell6)
{
SetAIConstant(AI_CHEAT_CAST_SPELL + IntToString(1), nSpell1);
SetAIConstant(AI_CHEAT_CAST_SPELL + IntToString(2), nSpell2);
SetAIConstant(AI_CHEAT_CAST_SPELL + IntToString(3), nSpell3);
SetAIConstant(AI_CHEAT_CAST_SPELL + IntToString(4), nSpell4);
SetAIConstant(AI_CHEAT_CAST_SPELL + IntToString(5), nSpell5);
SetAIConstant(AI_CHEAT_CAST_SPELL + IntToString(6), nSpell6);
}
// Levels up us.
// * nLevel - Levels to this number (doesn't do anything if already GetHitDice >= nLevel).
// * nClass, nClass2, nClass3 - the 3 classes to level up in. Only needs 1 minimum
// - Spreads equally if there is more then 1 nClass.
// - Sets up spells to use automatically, but DOES NOT CHANGE CHALLENGE RATING!
// - Does NOT check for validness, or report any information.
void AI_LevelUpCreature(int nLevel, int nClass, int nClass2 = CLASS_TYPE_INVALID, int nClass3 = CLASS_TYPE_INVALID)
{
// Divide by 1, 2 or 3 (100%, 50%, 33%)
int nDivideBy = (nClass >= 0) + (nClass2 >= 0) + (nClass3 >= 0);
int nTotalPerClass = nLevel / nDivideBy;
// Limit and loop - Class 1.
AI_LevelLoop(nClass, nTotalPerClass);
// 2
AI_LevelLoop(nClass2, nTotalPerClass);
// 3
AI_LevelLoop(nClass3, nTotalPerClass);
}
// Used in AI_LevelUpCreature.
// - Levels up OBJECT_SELF, in iClass for nLevels
void AI_LevelLoop(int nClass, int nLevels)
{
// Limit and loop
while(nLevels > FALSE)
{
LevelUpHenchman(OBJECT_SELF, nClass, TRUE);
nLevels--;
}
}
// This will set what creature to create OnDeath.
void AI_SetDeathResRef(string sResRef)
{
SetLocalString(OBJECT_SELF, AI_WE_WILL_CREATE_ON_DEATH, sResRef);
}
// This will set the string, sNameOfValue, to sValue. Array size of 1.
// - Use iPercentToSay to determine what % out of 100 it is said.
void AI_SetSpawnInSpeakValue(string sNameOfValue, string sValue, int iPercentToSay)
{
SetLocalString(OBJECT_SELF, sNameOfValue + "1", sValue);
// The array is 1 big!
SetLocalInt(OBJECT_SELF, ARRAY_SIZE + sNameOfValue, 1);
SetLocalInt(OBJECT_SELF, ARRAY_PERCENT + sNameOfValue, iPercentToSay);
}
// This will choose a random string, using iAmountOfValues, which is
// the amount of non-empty strings given. The size of the array is therefore 1.
// - Use iPercentToSay to determine what % out of 100 it is said.
void AI_SetSpawnInSpeakRandomValue(string sNameOfValue, int nPercentToSay, int nAmountOfValues, string sValue1, string sValue2, string sValue3, string sValue4, string sValue5, string sValue6, string sValue7, string sValue8, string sValue9, string sValue10, string sValue11, string sValue12)
{
// Need a value amount of values!
if(nAmountOfValues)
{
int nRandomNum = Random(nAmountOfValues) - 1; // take one, as it is 0 - X, not 1 - X
string sValueToUse;
switch(nRandomNum)
{
case 0:{sValueToUse = sValue1;}break;
case 1:{sValueToUse = sValue2;}break;
case 2:{sValueToUse = sValue3;}break;
case 3:{sValueToUse = sValue4;}break;
case 4:{sValueToUse = sValue5;}break;
case 5:{sValueToUse = sValue6;}break;
case 6:{sValueToUse = sValue7;}break;
case 7:{sValueToUse = sValue8;}break;
case 8:{sValueToUse = sValue9;}break;
case 9:{sValueToUse = sValue10;}break;
case 10:{sValueToUse = sValue11;}break;
case 11:{sValueToUse = sValue12;}break;
}
SetLocalString(OBJECT_SELF, sNameOfValue + "1", sValueToUse);
// The array is 1 big!
SetLocalInt(OBJECT_SELF, ARRAY_SIZE + sNameOfValue, 1);
SetLocalInt(OBJECT_SELF, ARRAY_PERCENT + sNameOfValue, nPercentToSay);
}
}
void AI_SetSpawnInSpeakArray(string sNameOfValue, int nPercentToSay, int nSize, string sValue1, string sValue2, string sValue3 = "", string sValue4 = "", string sValue5 = "", string sValue6 = "", string sValue7 = "", string sValue8 = "", string sValue9 = "", string sValue10 = "", string sValue11 = "", string sValue12 = "")
{
if(nSize >= 1)
{
SetLocalString(OBJECT_SELF, sNameOfValue + "1", sValue1);
if(nSize >= 2)
{
SetLocalString(OBJECT_SELF, sNameOfValue + "2", sValue2);
if(nSize >= 3)
{
SetLocalString(OBJECT_SELF, sNameOfValue + "3", sValue3);
if(nSize >= 4)
{
SetLocalString(OBJECT_SELF, sNameOfValue + "4", sValue4);
if(nSize >= 5)
{
SetLocalString(OBJECT_SELF, sNameOfValue + "5", sValue5);
if(nSize >= 6)
{
SetLocalString(OBJECT_SELF, sNameOfValue + "6", sValue6);
if(nSize >= 7)
{
SetLocalString(OBJECT_SELF, sNameOfValue + "7", sValue7);
if(nSize >= 8)
{
SetLocalString(OBJECT_SELF, sNameOfValue + "8", sValue8);
if(nSize >= 9)
{
SetLocalString(OBJECT_SELF, sNameOfValue + "9", sValue9);
if(nSize >= 10)
{
SetLocalString(OBJECT_SELF, sNameOfValue + "10", sValue10);
if(nSize >= 11)
{
SetLocalString(OBJECT_SELF, sNameOfValue + "11", sValue11);
if(nSize >= 12)
{
SetLocalString(OBJECT_SELF, sNameOfValue + "12", sValue12);
// Hehe, this looks not stright if you stare at it! :-P
} } } } } } } } } } } }
// The array is so big...
SetLocalInt(OBJECT_SELF, ARRAY_SIZE + sNameOfValue, nSize);
SetLocalInt(OBJECT_SELF, ARRAY_PERCENT + sNameOfValue, nPercentToSay);
}
// This applies an increase, decrease or no change to the intended stat.
// * Applies the effects INSTANTLY. These CANNOT be removed easily!
void AI_ApplyStatChange(int nStat, int nAmount)
{
if(nAmount != 0)
{
effect eChange;
if(nAmount < 0)
{
nAmount = abs(nAmount);
eChange = SupernaturalEffect(EffectAbilityDecrease(nStat, nAmount));
ApplyEffectToObject(DURATION_TYPE_INSTANT, eChange, OBJECT_SELF);
}
else
{
eChange = SupernaturalEffect(EffectAbilityIncrease(nStat, nAmount));
ApplyEffectToObject(DURATION_TYPE_INSTANT, eChange, OBJECT_SELF);
}
}
}
// This will, eventually, choose X number of stats, and change them within the
// range given.
void AI_CreateRandomStats(int nLowest, int nHighest, int nAmount)
{
if(nAmount > 0 && nHighest != 0 && nLowest != 0 && nHighest >= nLowest)
{
int nRange = nHighest - nLowest;
int nNumSlots = nAmount;
if(nNumSlots > 6) nNumSlots = 6;
int nNumLeft = 6;
// Walk through each stat and figure out what it's chance of being
// modified is. As an example, suppose we wanted to have 4 randomized
// abilities. We'd look at the first ability and it would have a 4 in 6
// chance of being picked. Let's suppose it was, the next ability would
// have a 3 in 5 chance of being picked. If this next ability wasn't
// picked to be changed, the 3rd ability woud have a 3 in 4 chance of
// being picked and so on.
int nCnt;
int nChange;
for(nCnt = 0; (nNumSlots > 0 && nCnt < 6); nCnt++)
{
if((nNumSlots == nNumLeft) || (Random(nNumLeft) < nNumSlots))
{
nChange = Random(nRange) + nLowest;
AI_ApplyStatChange(nCnt, nChange);
nNumSlots--;
}
nNumLeft--;
}
}
}
// This will randomise other stats. Put both numbers to 0 to ignore some.
// nHPMin, nHPMax = HP changes.
// nReflexSaveMin, nReflexSaveMax = Reflex Save changes
// nWillSaveMin, nWillSaveMax = Will Save changes
// nFortSaveMin, nFortSaveMax = Fortitude Save changes
// nACMin, nACMax = AC change.
// Use nACType to define the AC type - default AC_DODGE_BONUS
// * Applies the effects INSTANTLY. These CANNOT be removed easily!
void AI_CreateRandomOther(int nHPMin, int nHPMax, int nReflexSaveMin = 0, int nReflexSaveMax = 0, int nWillSaveMin = 0, int nWillSaveMax = 0, int nFortSaveMin = 0, int nFortSaveMax = 0, int nACMin = 0, int nACMax = 0, int nACType = AC_DODGE_BONUS)
{
int nRange, nChange, nNewChange;
effect eChange;
if(!(nHPMin == 0 && nHPMax == 0) && nHPMax >= nHPMin)
{
nRange = nHPMax - nHPMin;
nChange = Random(nRange) + nHPMin;
if(nChange > 0)
{
eChange = SupernaturalEffect(EffectTemporaryHitpoints(nChange));
ApplyEffectToObject(DURATION_TYPE_INSTANT, eChange, OBJECT_SELF);
}
// * Must have 1HP remaining at least.
else if(nChange < 0 && GetMaxHitPoints() > nChange)
{
eChange = EffectDamage(nChange, DAMAGE_TYPE_DIVINE, DAMAGE_POWER_PLUS_TWENTY);
ApplyEffectToObject(DURATION_TYPE_INSTANT, eChange, OBJECT_SELF);
}
}
if(!(nReflexSaveMin == 0 && nReflexSaveMax == 0) && nReflexSaveMax >= nReflexSaveMin)
{
nRange = nReflexSaveMax - nReflexSaveMin;
nChange = Random(nRange) + nReflexSaveMin;
if(nChange > 0)
{
eChange = SupernaturalEffect(EffectSavingThrowIncrease(SAVING_THROW_REFLEX, nChange));
ApplyEffectToObject(DURATION_TYPE_INSTANT, eChange, OBJECT_SELF);
}
// Cannot apply 0 change, but can make our saves negative
else if(nChange < 0)
{
nNewChange = abs(nChange);
eChange = SupernaturalEffect(EffectSavingThrowDecrease(SAVING_THROW_REFLEX, nNewChange));
ApplyEffectToObject(DURATION_TYPE_INSTANT, eChange, OBJECT_SELF);
}
}
if(!(nWillSaveMin == 0 && nWillSaveMax == 0) && nWillSaveMax >= nWillSaveMin)
{
nRange = nWillSaveMax - nWillSaveMin;
nChange = Random(nRange) + nWillSaveMin;
if(nChange > 0)
{
eChange = SupernaturalEffect(EffectSavingThrowIncrease(SAVING_THROW_WILL, nChange));
ApplyEffectToObject(DURATION_TYPE_INSTANT, eChange, OBJECT_SELF);
}
// Cannot apply 0 change, but can make our saves negative
else if(nChange < 0)
{
nNewChange = abs(nChange);
eChange = SupernaturalEffect(EffectSavingThrowDecrease(SAVING_THROW_WILL, nNewChange));
ApplyEffectToObject(DURATION_TYPE_INSTANT, eChange, OBJECT_SELF);
}
}
if(!(nFortSaveMin == 0 && nFortSaveMax == 0) && nFortSaveMax >= nFortSaveMin)
{
nRange = nFortSaveMax - nFortSaveMin;
nChange = Random(nRange) + nFortSaveMin;
if(nChange > 0)
{
eChange = SupernaturalEffect(EffectSavingThrowIncrease(SAVING_THROW_FORT, nChange));
ApplyEffectToObject(DURATION_TYPE_INSTANT, eChange, OBJECT_SELF);
}
// Cannot apply 0 change, but can make our saves negative
else if(nChange < 0)
{
nNewChange = abs(nChange);
eChange = SupernaturalEffect(EffectSavingThrowDecrease(SAVING_THROW_FORT, nNewChange));
ApplyEffectToObject(DURATION_TYPE_INSTANT, eChange, OBJECT_SELF);
}
}
if(!(nACMin == 0 && nACMax == 0) && nACMax >= nACMin)
{
nRange = nACMax - nACMin;
nChange = Random(nRange) + nACMin;
if(nChange > 0)
{
eChange = SupernaturalEffect(EffectACIncrease(nChange, nACType));
ApplyEffectToObject(DURATION_TYPE_INSTANT, eChange, OBJECT_SELF);
}
else if(nChange < 0)
{
nNewChange = abs(nChange);
eChange = SupernaturalEffect(EffectACDecrease(nNewChange, nACType));
ApplyEffectToObject(DURATION_TYPE_INSTANT, eChange, OBJECT_SELF);
}
}
}
/*::///////////////////////////////////////////////
//:: SetListeningPatterns
//:://////////////////////////////////////////////
Changed a lot. added in "**" (all) listening, for hearing enemies.
//::////////////////////////////////////////////*/
void AI_SetListeningPatterns()
{
// Lag check
if(GetSpawnInCondition(AI_FLAG_OTHER_LAG_NO_LISTENING, AI_OTHER_MASTER)) return;
SetListening(OBJECT_SELF, TRUE);
// Anyone that can hear it, and is not fighting, comes and helps
SetListenPattern(OBJECT_SELF, AI_SHOUT_I_WAS_ATTACKED, AI_SHOUT_I_WAS_ATTACKED_CONSTANT);
//Set a custom listening pattern for the creature so that placables with
//"NW_BLOCKER" + Blocker NPC Tag will correctly call to their blockers.
string sBlocker = "NW_BLOCKER_BLK_" + GetTag(OBJECT_SELF);
SetListenPattern(OBJECT_SELF, sBlocker, AI_SHOUT_BLOCKER_CONSTANT);
// Determines combat round, if not fighting
SetListenPattern(OBJECT_SELF, AI_SHOUT_CALL_TO_ARMS, AI_SHOUT_CALL_TO_ARMS_CONSTANT);
// These call to allies, to move them to a battle.
SetListenPattern(OBJECT_SELF, AI_SHOUT_HELP_MY_FRIEND, AI_SHOUT_HELP_MY_FRIEND_CONSTANT);
SetListenPattern(OBJECT_SELF, AI_SHOUT_LEADER_FLEE_NOW, AI_SHOUT_LEADER_FLEE_NOW_CONSTANT);
SetListenPattern(OBJECT_SELF, AI_SHOUT_LEADER_ATTACK_TARGET, AI_SHOUT_LEADER_ATTACK_TARGET_CONSTANT);
// 1.3 - Need a killed one.
SetListenPattern(OBJECT_SELF, AI_SHOUT_I_WAS_KILLED, AI_SHOUT_I_WAS_KILLED_CONSTANT);
// 1.3 - PLaceables/doors which shout this get responded to!
SetListenPattern(OBJECT_SELF, AI_SHOUT_I_WAS_OPENED, AI_SHOUT_I_WAS_OPENED_CONSTANT);
// This will make the listener hear anything, used to react to enemy talking.
SetListenPattern(OBJECT_SELF, "**", AI_SHOUT_ANYTHING_SAID_CONSTANT);
}
// Base for moving round thier waypoints
// - Uses ExectuteScript to run the waypoint walking.
// * If bRun is TRUE, we run all the waypoint.
// * fPause is the time delay between walking to the next waypoint (default 1.0)
void SpawnWalkWayPoints(int bRun = FALSE, float fPause = 1.0)
{
SetLocalInt(OBJECT_SELF, WAYPOINT_RUN, bRun);
SetLocalFloat(OBJECT_SELF, WAYPOINT_PAUSE, fPause);
ExecuteScript(FILE_WALK_WAYPOINTS, OBJECT_SELF);
}
// This MUST be called. It fires these events:
// SetUpSpells, SetUpSkillToUse, SetListeningPatterns, SetWeapons, AdvancedAuras.
// These MUST be called! the AI might fail to work correctly if they don't fire!
void AI_SetUpEndOfSpawn()
{
if(GetSpawnInCondition(AI_FLAG_OTHER_RETURN_TO_SPAWN_LOCATION, AI_OTHER_MASTER))
{
// This will store thier starting location, and then move back there after combat
// Will turn off if there are waypoints. It is set in SetUpEndOfSpawn.
SetAILocation(AI_RETURN_TO_POINT, GetLocation(OBJECT_SELF));
}
// Set up if we are immune to cirtain levels of spells naturally for better
// AI spellcasters.
object oHide = GetItemInSlot(INVENTORY_SLOT_CARMOUR, OBJECT_SELF);
// Get if immune is on
if(GetItemHasItemProperty(oHide, ITEM_PROPERTY_IMMUNITY_SPELLS_BY_LEVEL))
{
itemproperty eCheck = GetFirstItemProperty(oHide);
int nAmount;
// Check for item properties until we find the level.
while(GetIsItemPropertyValid(eCheck) && nAmount == FALSE)
{
// Check subtype.
if(GetItemPropertyType(eCheck) == ITEM_PROPERTY_IMMUNITY_SPELLS_BY_LEVEL)
{
// Get the amount
nAmount = GetItemPropertyCostTableValue(eCheck);
}
eCheck = GetNextItemProperty(oHide);
}
// Set it
if(nAmount)
{
SetLocalInt(OBJECT_SELF, AI_SPELL_IMMUNE_LEVEL, nAmount);
}
}
// All things only used by my personal AI.
// * If we are not using a custom AI file, we do these things.
if(GetCustomAIFileName() == "")
{
// If we are a commoner of any sort, and under 10 hit dice, we are
// panicy - IE: We set to -1 morale, which triggers the "commoner" fleeing
if(GetLevelByClass(CLASS_TYPE_COMMONER) && GetHitDice(OBJECT_SELF) < 10)
{
SetAIInteger(AI_MORALE, -1);
}
// If we are not set already to fearless, we might be set to fearless
if(!GetSpawnInCondition(AI_FLAG_FLEEING_FEARLESS, AI_TARGETING_FLEE_MASTER))
{
AI_SetMaybeFearless();
}
// Set if we are a beholder or mindflayer
switch(GetAppearanceType(OBJECT_SELF))
{
// Sets we are a Beholder and use Ray attacks, and Animagic Ray.
case APPEARANCE_TYPE_BEHOLDER: // beholder, 401
case APPEARANCE_TYPE_BEHOLDER_EYEBALL: // beholder, 402
case APPEARANCE_TYPE_BEHOLDER_MAGE: // beholder, 403
case APPEARANCE_TYPE_BEHOLDER_MOTHER: // Hive mother, 472
{
// 1 = beholder
SetAIInteger(AI_SPECIAL_AI, AI_SPECIAL_AI_BEHOLDER);
}
break;
// Set we are a mindflayer, and uses some special AI for them, IE:
// brain sucking.
case APPEARANCE_TYPE_MINDFLAYER: // Mindflayer, 413
case APPEARANCE_TYPE_MINDFLAYER_2: // Mindflayer2, 414
case APPEARANCE_TYPE_MINDFLAYER_ALHOON: // Mindflayer_Alhoon, 415
{
// 2 = mindflayer
SetAIInteger(AI_SPECIAL_AI, AI_SPECIAL_AI_MINDFLAYER);
}
break;
}
// This will turn OFF skills we cannot use, so will never attempt them
// at low skill levels anywhere in the AI.
AI_SetUpSkillToUse();
// Sets the turning level if we have FEAT_TURN_UNDEAD.
AI_SetTurningLevel();
// This sets what weapons the creature will use. They will use the best, according to a "value"
// Giving a creature the feat Two-weapon-fighting makes them deul wield if appropriate weapons.
SetWeapons();
}
// We don't set up corpses if set not to...else set to resurrect
if(!GetSpawnInCondition(AI_FLAG_OTHER_TURN_OFF_CORPSES, AI_OTHER_MASTER))
{
// Note: Here, if we can, we set Bioware's lootable on.
if(GetSpawnInCondition(AI_FLAG_OTHER_USE_BIOWARE_LOOTING, AI_OTHER_MASTER))
{
// Set to lootable
SetLootable(OBJECT_SELF, TRUE);
}
// Just handling corpse raising/resurrection/removal
// - Undestroyable, Raiseable and Selectable
SetIsDestroyable(FALSE, TRUE, TRUE);
}
// Goes through and sets up which shouts the NPC will listen to.
// - Custom AI uses this also, or should take advantage of it
AI_SetListeningPatterns();
// This activates the creatures aura's.
if(GetCommandable()) AI_AdvancedAuras();
}
// Sets the turning level if we have FEAT_TURN_UNDEAD.
void AI_SetTurningLevel()
{
// Most taken directly from NW_S2_TURNDEAD which is used with FEAT_TURN_UNDEAD
if(GetHasFeat(FEAT_TURN_UNDEAD))
{
// By default, it is clerical levels which provide turn undead power.
// We can turn HD up to nTurnLevel (HD = GetHitDice + GetTurnREsistsnceHD of undead)
int nTurnLevel = GetLevelByClass(CLASS_TYPE_CLERIC);
// Paladins turn at -2 the level of clerics
if(GetLevelByClass(CLASS_TYPE_PALADIN) - 2 > nTurnLevel)
{
nTurnLevel = GetLevelByClass(CLASS_TYPE_PALADIN) - 2;
}
// Blackguard gets to turn at HITDICE -2 level, not character level,
// as it says in NW_S2_TURNDEAD.
if(GetLevelByClass(CLASS_TYPE_BLACKGUARD) > 0 &&
(GetHitDice(OBJECT_SELF) - 2 > nTurnLevel))
{
nTurnLevel = GetHitDice(OBJECT_SELF) - 2;
}
// BTW, the number of undead turned is at least nTurnLevel, so we
// can always turn one :-D
SetAIInteger(AI_TURNING_LEVEL, nTurnLevel);
// Note: Turn undead could be used for FEAT_DIVINE_MIGHT and
// FEAT_DIVINE_SHIELD
}
}
// This should not be used!
// * called from SetUpEndOfSpawn.
void AI_SetMaybeFearless()
{
// Cirtain races are immune to fear
switch(MyPRCGetRacialType(OBJECT_SELF))
{
case RACIAL_TYPE_CONSTRUCT:
case RACIAL_TYPE_DRAGON:
case RACIAL_TYPE_UNDEAD:
case RACIAL_TYPE_OUTSIDER:
{
SetSpawnInCondition(AI_FLAG_FLEEING_FEARLESS, AI_TARGETING_FLEE_MASTER);
return;
}
break;
}
// If we are immune to fear anyway, we don't care
if(GetHasFeat(FEAT_AURA_OF_COURAGE) ||
GetHasFeat(FEAT_RESIST_NATURES_LURE) ||
GetIsImmune(OBJECT_SELF, IMMUNITY_TYPE_FEAR))
{
SetSpawnInCondition(AI_FLAG_FLEEING_FEARLESS, AI_TARGETING_FLEE_MASTER);
}
}
// Activate all auras.
void AI_ActivateAura(int nAuraNumber)
{
// Just ActionCast - cheat cast, as then we can use it unlmimted times, as books say.
if(GetHasSpell(nAuraNumber))
{
ActionCastSpellAtObject(nAuraNumber, OBJECT_SELF, METAMAGIC_NONE, TRUE, 20, PROJECTILE_PATH_TYPE_DEFAULT, TRUE);
}
}
// This will activate one aura, very quickly.
// If we have more than one...oh well.
void AI_AdvancedAuras()
{
// Do aura's
// NOTE:
// - All cheat cast. As DMG, they should be always on OR free action to reapply.
ClearAllActions();
AI_ActivateAura(SPELLABILITY_DRAGON_FEAR);
AI_ActivateAura(SPELLABILITY_AURA_UNEARTHLY_VISAGE);
AI_ActivateAura(SPELLABILITY_AURA_BLINDING);
AI_ActivateAura(SPELLABILITY_AURA_OF_COURAGE);
AI_ActivateAura(SPELLABILITY_AURA_PROTECTION);
AI_ActivateAura(SPELLABILITY_AURA_STUN);
AI_ActivateAura(SPELLABILITY_AURA_FIRE);
AI_ActivateAura(SPELLABILITY_AURA_COLD);
AI_ActivateAura(SPELLABILITY_AURA_ELECTRICITY);
AI_ActivateAura(SPELLABILITY_AURA_UNNATURAL);
AI_ActivateAura(SPELLABILITY_AURA_FEAR);
AI_ActivateAura(SPELLABILITY_AURA_UNNATURAL);
AI_ActivateAura(SPELLABILITY_AURA_MENACE);
AI_ActivateAura(SPELLABILITY_TYRANT_FOG_MIST);
AI_ActivateAura(AI_SPELLABILITY_AURA_OF_HELLFIRE);
AI_ActivateAura(SPELLABILITY_AURA_HORRIFICAPPEARANCE);
}
// Sets up thier selection of skills, to integers, if they would ever use them.
// NOTE: it also triggers "hide" if they have enough skill and not stopped.
void AI_SetUpSkillToUse()
{
// Get our hitdice
int nHitDice = GetHitDice(OBJECT_SELF);
int nRank;
// Hiding. We turn off if we have no skill or under 1 skill in it
// * Note: For the AI to decide "oh, we should hide", it requires a minimum
// of 7 points in hide, and Rank - 4 must be >= our HD too. Can be forced.
if(!GetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_HIDING, AI_OTHER_COMBAT_MASTER))
{
if(!GetHasSkill(SKILL_HIDE) ||
GetSkillRank(SKILL_HIDE) < 1)
{
SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_HIDING, AI_OTHER_COMBAT_MASTER);
DeleteSpawnInCondition(AI_FLAG_OTHER_COMBAT_FORCE_HIDING, AI_OTHER_COMBAT_MASTER);
}
}
// Pickpocketing...we only turn it OFF here if low skill
// (or none) Needs 1/2 HD or 10 minimum - 10 is probably needed for the DC35
// check for this skill at all.
if(!GetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_PICKPOCKETING, AI_OTHER_COMBAT_MASTER))
{
nRank = GetSkillRank(SKILL_PICK_POCKET);
if(!GetHasSkill(SKILL_PICK_POCKET) ||
nRank < nHitDice/2 || nRank < 10)
{
SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_PICKPOCKETING, AI_OTHER_COMBAT_MASTER);
DeleteSpawnInCondition(AI_FLAG_OTHER_COMBAT_FORCE_PICKPOCKETING, AI_OTHER_COMBAT_MASTER);
}
}
// Taunting. Again, only off if low skill. Needs half of HD, or 3 minimum
if(!GetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_TAUNTING, AI_OTHER_COMBAT_MASTER))
{
nRank = GetSkillRank(SKILL_TAUNT);
if(!GetHasSkill(SKILL_TAUNT) ||
nRank < nHitDice/2 || nRank < 3)
{
SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_TAUNTING, AI_OTHER_COMBAT_MASTER);
DeleteSpawnInCondition(AI_FLAG_OTHER_COMBAT_FORCE_TAUNTING, AI_OTHER_COMBAT_MASTER);
}
}
// Empathy. Again, only off if low skill. Needs any, checked futher in game.
if(!GetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_EMPATHY, AI_OTHER_COMBAT_MASTER))
{
if(!GetHasSkill(SKILL_ANIMAL_EMPATHY))
{
SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_EMPATHY, AI_OTHER_COMBAT_MASTER);
DeleteSpawnInCondition(AI_FLAG_OTHER_COMBAT_FORCE_EMPATHY, AI_OTHER_COMBAT_MASTER);
}
}
// Unlocking doors. Again, only off if low skill. Needs any, checked futher in game.
if(!GetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_OPENING_LOCKED_DOORS, AI_OTHER_COMBAT_MASTER))
{
if(!GetHasSkill(SKILL_OPEN_LOCK))
{
SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_OPENING_LOCKED_DOORS, AI_OTHER_COMBAT_MASTER);
DeleteSpawnInCondition(AI_FLAG_OTHER_COMBAT_FORCE_OPENING_LOCKED_DOORS, AI_OTHER_COMBAT_MASTER);
}
}
// Healing kits.
if(!GetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_USING_HEALING_KITS, AI_OTHER_COMBAT_MASTER))
{
if(!GetHasSkill(SKILL_HEAL))
{
SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_USING_HEALING_KITS, AI_OTHER_COMBAT_MASTER);
DeleteSpawnInCondition(AI_FLAG_OTHER_COMBAT_FORCE_USING_HEALING_KITS, AI_OTHER_COMBAT_MASTER);
}
}
// Parrying
// Only on if we have some skill in it :-)
if(!GetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_PARRYING, AI_OTHER_COMBAT_MASTER))
{
if(!GetHasSkill(SKILL_PARRY))
{
SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_PARRYING, AI_OTHER_COMBAT_MASTER);
DeleteSpawnInCondition(AI_FLAG_OTHER_COMBAT_FORCE_PARRYING, AI_OTHER_COMBAT_MASTER);
}
}
}
// This will make the visual effect passed play INSTANTLY at the creatures location.
// * nVFX - The visual effect constant number
void AI_SpawnInInstantVisual(int nVFX)
{
// Beta 3 change: Made to at location.
ApplyEffectAtLocation(DURATION_TYPE_INSTANT,
EffectVisualEffect(nVFX),
GetLocation(OBJECT_SELF));
}
// This will make the visual effect passed play PERMAMENTLY.
// * nVFX - The visual effect constant number
// NOTE: They will be made to be SUPERNATUAL, so are not dispelled!
void AI_SpawnInPermamentVisual(int nVFX)
{
ApplyEffectToObject(DURATION_TYPE_INSTANT,
SupernaturalEffect(EffectVisualEffect(nVFX)),
OBJECT_SELF);
}
// This will set the MAXIMUM and MINIMUM targets to pass this stage (under sName)
// of the targeting system. IE:
// - If we set it to min of 5, max of 10, for AC, if we cancled 5 targets on having
// AC higher then wanted, we will take the highest 5 minimum.
// If there are over 10, we take a max of 10 to choose from.
// * nType - must be TARGET_HIGHER or TARGET_LOWER. Defaults to the lowest, so it
// targets the lowest value for sName.
void AI_SetAITargetingValues(string sName, int nType, int nMinimum, int nMaximum)
{
// Error checking
if((nType == TARGET_HIGHER || nType == TARGET_LOWER) &&
nMinimum >= 1 && nMaximum >= 1 && nMaximum >= nMinimum)
{
// Set the type to sName.
// - It is TARGET_HIGHER (1) or TARGET_LOWER (0).
SetAIInteger(sName, nType);
// Minimum amount of targets for this?
SetAIInteger(sName + MINIMUM, nMinimum);
// Maximum targets for this?
SetAIInteger(sName + MAXIMUM, nMaximum);
}
}
// This will set a spell trigger up. Under cirtain conditions, spells are released
// and cast on the caster.
// Once fired, a spell trigger is only reset by resting. Only 1 of each max is fired at once!
// * sType - is specifically:
// SPELLTRIGGER_DAMAGED_AT_PERCENT - When damaged, the trigger fires. Use iValue for the %. One at a time is fired.
// SPELLTRIGGER_IMMOBILE - Fired when held/paralyzed/sleeping ETC. One at a time is fired.
// SPELLTRIGGER_NOT_GOT_FIRST_SPELL - Makes sure !GetHasSpellEffect(iSpell1) already,
// then fires. Checks all in this category each round (first one fires!)
// SPELLTRIGGER_START_OF_COMBAT - Triggered always, at the start of DetermineCombatRound.
// * nNumber - can be 1-9, in sequential order of when you want them to fire.
// * nValue - is only required with DAMAGED_AT_PERCENT.
// * nSpellX - Cannot be 0. It should only really be defensive spells.
void SetSpellTrigger(string sType, int nValue, int nNumber, int nSpell1, int nSpell2 = 0, int nSpell3 = 0, int nSpell4 = 0, int nSpell5 = 0, int nSpell6 = 0, int nSpell7 = 0, int nSpell8 = 0, int nSpell9 = 0)
{
// Either get our spell trigger (creature) or create one
object oTrigger = GetAIObject(AI_SPELL_TRIGGER_CREATURE);
// Is it valid?
if(!GetIsObjectValid(oTrigger))
{
// Create it
oTrigger = CreateObject(OBJECT_TYPE_CREATURE, "jass_spelltrig", GetLocation(OBJECT_SELF));
// Set local on them for the target
AddHenchman(OBJECT_SELF, oTrigger);
// Local for us to get our spell trigger (should be our henchmen)
SetAIObject(AI_SPELL_TRIGGER_CREATURE, oTrigger);
}
int nSize = 1;
string sTotalID = sType + IntToString(nNumber);
SetLocalInt(oTrigger, sTotalID + "1", nSpell1);
if(nSpell2 != FALSE)
{ nSize = 2;
SetLocalInt(oTrigger, sTotalID + "2", nSpell2); }
if(nSpell3 != FALSE)
{ nSize = 3;
SetLocalInt(oTrigger, sTotalID + "3", nSpell3); }
if(nSpell4 != FALSE)
{ nSize = 4;
SetLocalInt(oTrigger, sTotalID + "4", nSpell4); }
if(nSpell5 != FALSE)
{ nSize = 5;
SetLocalInt(oTrigger, sTotalID + "5", nSpell5); }
if(nSpell6 != FALSE)
{ nSize = 6;
SetLocalInt(oTrigger, sTotalID + "6", nSpell6); }
if(nSpell7 != FALSE)
{ nSize = 7;
SetLocalInt(oTrigger, sTotalID + "7", nSpell7); }
if(nSpell8 != FALSE)
{ nSize = 8;
SetLocalInt(oTrigger, sTotalID + "8", nSpell8); }
if(nSpell9 != FALSE)
{ nSize = 9;
SetLocalInt(oTrigger, sTotalID + "9", nSpell9); }
// Set final sizes ETC.
SetLocalInt(oTrigger, MAXINT_ + sTotalID, nSize);
SetLocalInt(oTrigger, sTotalID + USED, FALSE);
// Check value
if(nValue > GetLocalInt(oTrigger, VALUE + sType))
{
SetLocalInt(oTrigger, VALUE + sType, nValue);
}
// Set how many spell triggers we have too
if(nNumber > GetLocalInt(oTrigger, MAXIMUM + sType))
{
SetLocalInt(oTrigger, MAXIMUM + sType, nNumber);
}
}
// Debug: To compile this script, uncomment all of the below.
/* - Add two "/"'s at the start of this line
void main()
{
return;
}
//*/

View File

@@ -1,333 +0,0 @@
// Walk waypoints include.
int NW_FLAG_STEALTH = 0x00000004;
int NW_FLAG_SEARCH = 0x00000008;
int NW_FLAG_DAY_NIGHT_POSTING = 0x00100000;
// Animations:
// Randomwalk normally, or move to nearest ally.
int AMBIENT_ANIMATIONS = 1;
// These will face nearest ally, and talk or laugh. If no ally then look right/left.
int IMMOBILE_AMBIENT_ANIMATIONS = 2;
// This is the bird animations.
int AMBIENT_ANIMATIONS_AVIAN = 3;
// This will make the creatures "group" and sit, and normally talk.
int AMBIENT_GROUP_ANIMATIONS = 4;
// This will make the creature talk with nearby allies, as to not look dead.
// Also, if alone, it will take drinks, and things like that.
int IMMOBILE_ANIMATIONS_AND_SOLO = 5;
// This is a consitution for just random walking, nothing else.
int AMBIENT_ANIMAL_WALKING = 6;
// Run the circuit.
void RunCircuit(int nTens, int nNum, int nRun = FALSE, float fPause = 1.0);
// Base for moving round thier waypoints
void WalkWayPoints(int nRun = FALSE, float fPause = 1.0);
// Used in walk waypoints
void RunNextCircuit(int nRun = FALSE, float fPause = 1.0);
// Checks which waypoint they are on, if any valid. TRUE if got any waypoints in range.
int CheckWayPoints(object oWalker = OBJECT_SELF);
//Returns true if the object is walking any waypoints.
int GetIsPostOrWalking(object oWalker = OBJECT_SELF);
// Returns the string to use - depending on day or night.
string GetStringPrefix(string sPrefix, object oWalker = OBJECT_SELF);
// This sets a spawn in condition.
void SetSpawnInCondition(int nCondition, int bValid = TRUE, string sName = "NW_GENERIC_MASTER");
//Gets the spawn in condition.Can set things to different ints if you like.
int GetSpawnInCondition(int nCondition, string sName = "NW_GENERIC_MASTER");
//::///////////////////////////////////////////////
//:: Master Local Set
//:: FileName
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
All On Spawn in conditions in the game are now
being stored within one local. The get and set
changed or checks the condition of this one
Hex local. The NW_FLAG_XXX variables above
allow for the user of these functions throughout
the generic scripts.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 14, 2001
//:://////////////////////////////////////////////
void SetSpawnInCondition(int nCondition, int bValid, string sName)
{
int nPlot = GetLocalInt(OBJECT_SELF, sName);
if(bValid == TRUE)
{
nPlot = nPlot | nCondition;
SetLocalInt(OBJECT_SELF, sName, nPlot);
}
else if (bValid == FALSE)
{
nPlot = nPlot & ~nCondition;
SetLocalInt(OBJECT_SELF, sName, nPlot);
}
}
int GetSpawnInCondition(int nCondition, string sName)
{
int nPlot = GetLocalInt(OBJECT_SELF, sName);
if(nPlot & nCondition)
{
return TRUE;
}
return FALSE;
}
//***************************
//***************************
//
//WAY POINT WALK FUNCTIONS
//
//***************************
//***************************
//::///////////////////////////////////////////////
//:: Walk Way Point Path
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
Allows specified person walk a waypoint path
*/
//:://////////////////////////////////////////////
//:: Created By: Aidan Scanlan
//:: Created On: July 10, 2001
//:://////////////////////////////////////////////
void WalkWayPoints(int nRun = FALSE, float fPause = 1.0) //Run first circuit
{
if(CheckWayPoints())
{
ClearAllActions();
}
string NightWayString;
string NightPostString;
string sWay;
string sPost;
//The block of code below deals with night and day cycle for postings and walkway points.
if(GetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING))
{
NightWayString = "WN_";
NightPostString = "NIGHT_";
}
else
{
NightWayString = "WP_";
NightPostString = "POST_";
}
// We will set what strings to use.
SetLocalString(OBJECT_SELF, "NW_GENERIC_WALKWAYS_DAY", "WP_");
SetLocalString(OBJECT_SELF, "NW_GENERIC_WALKWAYS_NIGHT", NightWayString);
SetLocalString(OBJECT_SELF, "NW_GENERIC_POSTING_DAY", "POST_");
SetLocalString(OBJECT_SELF, "NW_GENERIC_POSTING_NIGHT", NightPostString);
// Which shall we use? Day or night?
sWay = GetStringPrefix("NW_GENERIC_WALKWAYS");
sPost = GetStringPrefix("NW_GENERIC_POSTING");
//I have now determined what the prefixs for the current walkways and postings are and will use them instead
// of POST_ and WP_
if(GetSpawnInCondition(NW_FLAG_STEALTH))
{
// Will hide all the time, when they walk
ActionUseSkill(SKILL_HIDE, OBJECT_SELF);
}
else if(GetSpawnInCondition(NW_FLAG_SEARCH) || GetLocalInt(OBJECT_SELF, "ANIMATIONS") == IMMOBILE_AMBIENT_ANIMATIONS)
{
// Will search all the time, when they walk, or if we are not going to move.
ActionUseSkill(SKILL_SEARCH, OBJECT_SELF);
}
//Test if OBJECT_SELF has waypoints to walk
string sWayTag = GetTag(OBJECT_SELF);
sWayTag = sWay + sWayTag + "_01";
object oWay1 = GetNearestObjectByTag(sWayTag);
// Get the object, if nearest (IE in area one) is not valid.
if(!GetIsObjectValid(oWay1))
{
oWay1 = GetObjectByTag(sWayTag);
}
if(GetIsObjectValid(oWay1))
{
int nNth = 1;
int nTens;
int nNum;
object oNearest = GetNearestObject(OBJECT_TYPE_WAYPOINT, OBJECT_SELF, nNth);
while (GetIsObjectValid(oNearest))
{
string sNearestTag = GetTag(oNearest);
//removes the first 3 and last three characters from the waypoint's tag
//and checks it against his own tag. Waypoint tag format is WP_MyTag_XX.
if(GetSubString(sNearestTag, 3, GetStringLength(sNearestTag) - 6) == GetTag(OBJECT_SELF))
{
string sTens = GetStringRight(GetTag(oNearest), 2);
nTens = StringToInt(sTens)/10;
nNum= StringToInt(GetStringRight(GetTag(oNearest), 1));
oNearest = OBJECT_INVALID;
}
else
{
nNth++;
oNearest = GetNearestObject(OBJECT_TYPE_WAYPOINT,OBJECT_SELF,nNth);
}
}
RunCircuit(nTens, nNum, nRun, fPause); //***************************************
ActionWait(fPause);
ActionDoCommand(RunNextCircuit(nRun, fPause));
}
else // Else go to the post we have set.
{
sWayTag = GetTag(OBJECT_SELF);
sWayTag = sPost + sWayTag;
oWay1 = GetNearestObjectByTag(sWayTag);
if(!GetIsObjectValid(oWay1))
{
oWay1 = GetObjectByTag(sWayTag);
}
if(GetIsObjectValid(oWay1))
{
ActionForceMoveToObject(oWay1, nRun, 1.0, 60.0);
float fFacing = GetFacing(oWay1);
ActionDoCommand(SetFacing(fFacing));
}
}
}
void RunNextCircuit(int nRun = FALSE, float fPause = 1.0)
{
RunCircuit(0, 1, nRun, fPause);
ActionWait(fPause);
ActionDoCommand(RunNextCircuit(nRun, fPause));
}
//::///////////////////////////////////////////////
//:: Run Circuit
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
Calculates the proper path to follow along a
predetermined set of way points
*/
//:://////////////////////////////////////////////
//:: Created By: Aidan Scanlan
//:: Created On: July 10, 2001
//:://////////////////////////////////////////////
void RunCircuit(int nTens, int nNum, int nRun = FALSE, float fPause = 1.0)
{
// starting at a given way point, move sequentialy through incrementally
// increasing points until there are no more valid ones.
// We will check for day/night in these instead of heartbeats.
string sWay = GetStringPrefix("NW_GENERIC_WALKWAYS");
string sNewString;
object oTargetPoint = GetWaypointByTag(sWay + GetTag(OBJECT_SELF) + "_" + IntToString(nTens) + IntToString(nNum));
while(GetIsObjectValid(oTargetPoint))
{
ActionWait(fPause);
ActionMoveToObject(oTargetPoint, nRun);
nNum++;
if (nNum > 9)
{
nTens++;
nNum = 0;
}
// Maybe change string prefix to use.
sNewString = GetStringPrefix("NW_GENERIC_WALKWAYS");
if(sNewString != sWay)
{
WalkWayPoints(nRun, fPause);
return;
}
oTargetPoint = GetWaypointByTag(sWay + GetTag(OBJECT_SELF) + "_" + IntToString(nTens) + IntToString(nNum));
}
// once there are no more waypoints available, decriment back to the last
// valid point.
nNum--;
if (nNum < 0)
{
nTens--;
nNum = 9;
}
// start the cycle again going back to point 01
oTargetPoint = GetWaypointByTag(sWay + GetTag(OBJECT_SELF) + "_" + IntToString(nTens) + IntToString(nNum));
while(GetIsObjectValid(oTargetPoint))
{
ActionWait(fPause);
ActionMoveToObject(oTargetPoint, nRun);
nNum--;
if (nNum < 0)
{
nTens--;
nNum = 9;
}
// Maybe change string prefix to use.
sNewString = GetStringPrefix("NW_GENERIC_WALKWAYS");
if(sNewString != sWay)
{
WalkWayPoints(nRun, fPause);
return;
}
oTargetPoint = GetWaypointByTag(sWay + GetTag(OBJECT_SELF) + "_" + IntToString(nTens) + IntToString(nNum));
}
}
//::///////////////////////////////////////////////
//:: Check Walkways
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
This function checks the passed in object to
see if they are supposed to be walking to
day or night postings.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Feb 26, 2002
//:://////////////////////////////////////////////
int CheckWayPoints(object oWalker)
{
object oWay1;
object oWay2;
object oWay3;
object oWay4;
string sTag = GetTag(oWalker);
if(GetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING))
{
oWay2 = GetWaypointByTag("NIGHT_" + sTag);
oWay4 = GetWaypointByTag("WN_" + sTag + "_01");
}
oWay1 = GetWaypointByTag("POST_" + sTag);
oWay3 = GetWaypointByTag("WP_" + sTag + "_01");
if(GetIsObjectValid(oWay2) || GetIsObjectValid(oWay4) || GetIsObjectValid(oWay1) || GetIsObjectValid(oWay3))
{
return TRUE;
}
return FALSE;
}
// Returns the string to use - depending on day or night.
string GetStringPrefix(string sPrefix, object oWalker)
{
if(GetIsDay() || GetIsDawn())
{
return GetLocalString(OBJECT_SELF, sPrefix + "_DAY");
}
else
{
return GetLocalString(OBJECT_SELF, sPrefix + "_NIGHT");
}
}

View File

@@ -1,50 +0,0 @@
/************************ [On Spawn: Archer] ***********************************
Filename: j_sp_archer
************************* [On Spawn: Archer] ***********************************
Any-level archer. This man is pretty basic, and has really only the special
archery stuff on.
************************* [On Spawn: Archer] **********************************/
// This is required for all spawn in options!
#include "j_inc_spawnin"
void main()
{
// Random intelligence, 4-6.
SetAIInteger(AI_INTELLIGENCE, 3 + d3());
// Random morale
SetAIInteger(AI_MORALE, 7 + d6());
AI_SetAITargetingValues(TARGETING_RANGE, TARGET_HIGHER, 2, 9);
// Range - very imporant! Basis for all ranged/spell attacks.
SetSpawnInCondition(AI_FLAG_COMBAT_PICK_UP_DISARMED_WEAPONS, AI_COMBAT_MASTER);
// This sets to pick up weapons which are disarmed.
SetAIInteger(AI_RANGED_WEAPON_RANGE, 2);
// This is the range at which they go into melee (from using a ranged weapon). Default is 3 or 5.
SetSpawnInCondition(AI_FLAG_COMBAT_ARCHER_ATTACKING, AI_COMBAT_MASTER);
// For archers. If they have ally support, they'd rather move back & shoot then go into HTH.
SetSpawnInCondition(AI_FLAG_COMBAT_ARCHER_ALWAYS_MOVE_BACK, AI_COMBAT_MASTER);
// This forces the move back from attackers, and shoot bows. Very small chance to go melee.
//SetSpawnInCondition(AI_FLAG_COMBAT_ARCHER_ALWAYS_USE_BOW, AI_COMBAT_MASTER);
// This will make the creature ALWAYs use any bows it has. ALWAYS.
SetSpawnInCondition(AI_FLAG_OTHER_NO_POLYMORPHING, AI_OTHER_MASTER);
// This will stop all polymorphing spells feats from being used.
SetSpawnInCondition(AI_FLAG_OTHER_DONT_RESPOND_TO_EMOTES, AI_OTHER_MASTER);
// This will ignore ALL chat by PC's (Enemies) who speak actions in Stars - *Bow*
// no spells or items.
SetSpawnInCondition(AI_FLAG_OTHER_LAG_NO_ITEMS, AI_OTHER_MASTER);
SetSpawnInCondition(AI_FLAG_OTHER_LAG_NO_SPELLS, AI_OTHER_MASTER);
// Ambient animations
if(GetIsEncounterCreature())
{
SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS, NW_GENERIC_MASTER);
}
AI_SetUpEndOfSpawn();
DelayCommand(2.0f, SpawnWalkWayPoints());
}

View File

@@ -1,38 +0,0 @@
/************************ [On Spawn: Dragon] ***********************************
Filename: j_sp_dragon
************************* [On Spawn: Dragon] ***********************************
Dragons are highly intelligent, and can...fly!
They do have a few improved spellcasting bits, and like to target lower AC
more then anything.
Flying is also on, so they can jump to enemies far away.
************************* [On Spawn: Dragon] **********************************/
// This is required for all spawn in options!
#include "j_inc_spawnin"
void main()
{
// Maximum "intelligence"
SetAIInteger(AI_INTELLIGENCE, 10);
SetAIInteger(AI_MORALE, 10);
AI_SetAITargetingValues(TARGETING_RANGE, TARGET_HIGHER, 2, 9);
AI_SetAITargetingValues(TARGETING_AC, TARGET_LOWER, 1, 6);
SetSpawnInCondition(AI_FLAG_COMBAT_FLAG_FAST_BUFF_ENEMY, AI_COMBAT_MASTER);
SetSpawnInCondition(AI_FLAG_COMBAT_IMPROVED_INSTANT_DEATH_SPELLS, AI_COMBAT_MASTER);
SetSpawnInCondition(AI_FLAG_COMBAT_IMPROVED_IMMUNITY_CHECKING, AI_COMBAT_MASTER);
SetSpawnInCondition(AI_FLAG_COMBAT_IMPROVED_SPECIFIC_SPELL_IMMUNITY, AI_COMBAT_MASTER);
SetSpawnInCondition(AI_FLAG_COMBAT_LONGER_RANGED_SPELLS_FIRST, AI_COMBAT_MASTER);
SetSpawnInCondition(AI_FLAG_OTHER_DONT_RESPOND_TO_EMOTES, AI_OTHER_MASTER);
// This will ignore ALL chat by PC's (Enemies) who speak actions in Stars - *Bow*
// Dragon stuff
SetSpawnInCondition(AI_FLAG_COMBAT_FLYING, AI_COMBAT_MASTER);
AI_SetUpEndOfSpawn();
DelayCommand(2.0f, SpawnWalkWayPoints());
}

View File

@@ -1,51 +0,0 @@
/************************ [On Spawn: High-Level Mage] **************************
Filename: j_sp_highmage
************************* [On Spawn: High-Level Mage] **************************
A mage who is higher level - ok, so it has many stuff from the default spawn
file, but this one has some of the mage behaviours set, such as long range
attacking and fast buffing, but no spell triggers.
************************* [On Spawn: High-Level Mage] *************************/
// This is required for all spawn in options!
#include "j_inc_spawnin"
void main()
{
// Random intelligence, 7-9.
SetAIInteger(AI_INTELLIGENCE, 6 + d3());
SetAIInteger(AI_MORALE, 10);
// Less mantals, and less saves is all we target
AI_SetAITargetingValues(TARGETING_MANTALS, TARGET_LOWER, 1, 4);
AI_SetAITargetingValues(TARGETING_SAVES, TARGET_LOWER, 1, 2);
SetSpawnInCondition(AI_FLAG_COMBAT_PICK_UP_DISARMED_WEAPONS, AI_COMBAT_MASTER);
// This sets to pick up weapons which are disarmed.
SetAIInteger(AI_RANGED_WEAPON_RANGE, 2);
// This is the range at which they go into melee (from using a ranged weapon). Default is 3 or 5.
SetSpawnInCondition(AI_FLAG_COMBAT_DISPEL_IN_ORDER, AI_COMBAT_MASTER);
SetSpawnInCondition(AI_FLAG_COMBAT_IMPROVED_INSTANT_DEATH_SPELLS, AI_COMBAT_MASTER);
SetSpawnInCondition(AI_FLAG_COMBAT_FLAG_FAST_BUFF_ENEMY, AI_COMBAT_MASTER);
SetSpawnInCondition(AI_FLAG_COMBAT_IMPROVED_SUMMON_TARGETING, AI_COMBAT_MASTER);
SetSpawnInCondition(AI_FLAG_COMBAT_IMPROVED_IMMUNITY_CHECKING, AI_COMBAT_MASTER);
SetSpawnInCondition(AI_FLAG_COMBAT_IMPROVED_SPECIFIC_SPELL_IMMUNITY, AI_COMBAT_MASTER);
SetSpawnInCondition(AI_FLAG_COMBAT_LONGER_RANGED_SPELLS_FIRST, AI_COMBAT_MASTER);
SetSpawnInCondition(AI_FLAG_OTHER_DONT_RESPOND_TO_EMOTES, AI_OTHER_MASTER);
// This will ignore ALL chat by PC's (Enemies) who speak actions in Stars - *Bow*
// no spells or items.
SetSpawnInCondition(AI_FLAG_OTHER_LAG_NO_ITEMS, AI_OTHER_MASTER);
SetSpawnInCondition(AI_FLAG_OTHER_LAG_NO_SPELLS, AI_OTHER_MASTER);
// Ambient animations
if(GetIsEncounterCreature())
{
SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS, NW_GENERIC_MASTER);
}
AI_SetUpEndOfSpawn();
DelayCommand(2.0f, SpawnWalkWayPoints());
}

View File

@@ -1,87 +0,0 @@
/************************ [On Spawn: Human Leader] *****************************
Filename: j_sp_humleader
************************* [On Spawn: Human Leader] *****************************
A human leader sample spawn script.
Maximum intelligence, some sample shouts/taunts and the leader settings are
on. He does, however, never run, and always likes melee.
Shouldn't be a spellcaster, should only be a fighter primarily geared for HTH
fighting.
************************* [On Spawn: Human Leader] ****************************/
// This is required for all spawn in options!
#include "j_inc_spawnin"
void main()
{
// Maximum "intelligence"
SetAIInteger(AI_INTELLIGENCE, 10);
// We are fearless
SetAIInteger(AI_MORALE, 10);
AI_SetAITargetingValues(TARGETING_RANGE, TARGET_HIGHER, 2, 9);
// Range - very imporant! Basis for all ranged/spell attacks.
AI_SetAITargetingValues(TARGETING_AC, TARGET_LOWER, 2, 6);
// AC is used for all phisical attacks. Lower targets lower (By default).
// Fighter/Clerics (It is over a mages BAB + 1 (IE 0.5 BAB/Level) target lower
AI_SetAITargetingValues(TARGETING_PHISICALS, TARGET_LOWER, 2, 6);
// Base attack bonus. Used for spells and phisical attacks. Checked with GetBaseAttackBonus.
AI_SetAITargetingValues(TARGETING_BAB, TARGET_LOWER, 1, 4);
SetSpawnInCondition(AI_FLAG_FLEEING_FEARLESS, AI_TARGETING_FLEE_MASTER);
// Forces them to not flee. This may be set with AI_SetMaybeFearless at the end.
SetSpawnInCondition(AI_FLAG_COMBAT_PICK_UP_DISARMED_WEAPONS, AI_COMBAT_MASTER);
// This sets to pick up weapons which are disarmed.
SetAIInteger(AI_RANGED_WEAPON_RANGE, 6);
// This is the range at which they go into melee (from using a ranged weapon). Default is 3 or 5.
SetSpawnInCondition(AI_FLAG_COMBAT_BETTER_AT_HAND_TO_HAND, AI_COMBAT_MASTER);
// Set if you want them to move forwards into HTH sooner. Will always
// if the enemy is a mage/archer, else % based on range.
// Set all leader variables
SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_GROUP_LEADER, AI_OTHER_COMBAT_MASTER);
// Special leader. Can issuse some orders. See readme for details.
SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_BOSS_MONSTER_SHOUT, AI_OTHER_COMBAT_MASTER);
// Boss shout. 1 time use - calls all creatures in X meters (below) for battle!
//SetAIInteger(AI_BOSS_MONSTER_SHOUT_RANGE, 60);
// Defaults to a 60 M range. This can change it. Note: 1 toolset square = 10M.
SetSpawnInCondition(AI_FLAG_OTHER_NO_POLYMORPHING, AI_OTHER_MASTER);
// This will stop all polymorphing spells feats from being used.
SetSpawnInCondition(AI_FLAG_OTHER_DONT_RESPOND_TO_EMOTES, AI_OTHER_MASTER);
// This will ignore ALL chat by PC's (Enemies) who speak actions in Stars - *Bow*
SetSpawnInCondition(AI_FLAG_OTHER_REST_AFTER_COMBAT, AI_OTHER_MASTER);
// When combat is over, creature rests. Useful for replenising health.
SetSpawnInCondition(AI_FLAG_OTHER_NO_PLAYING_VOICE_CHAT, AI_OTHER_MASTER);
// Can uncomment these if the leader has no spells or items.
//SetSpawnInCondition(AI_FLAG_OTHER_LAG_NO_ITEMS, AI_OTHER_MASTER);
// The creature doesn't check for, or use any items that cast spells.
//SetSpawnInCondition(AI_FLAG_OTHER_LAG_NO_SPELLS, AI_OTHER_MASTER);
//The creature doesn't ever cast spells (and never checks them)
// Combat
AI_SetSpawnInSpeakArray(AI_TALK_ON_COMBAT_ROUND_EQUAL, 10, 4, "You don't stand a chance!", "Men, Attack!", "For Glory!!", "Eat steel!");
AI_SetSpawnInSpeakArray(AI_TALK_ON_COMBAT_ROUND_THEM_OVER_US, 10, 4, "Your might is no match for my brains!", "Tough man, are we?", "You won't kill me!", "Pah! I am no coward! I fight on!");
AI_SetSpawnInSpeakArray(AI_TALK_ON_COMBAT_ROUND_US_OVER_THEM, 10, 4, "No mercy!", "Hope for a quick death!", "Men! Kill the lot!", "There is no chance!");
// Our leader shouts!
// - As this is a human, very orderly
AI_SetSpawnInSpeakValue(AI_TALK_ON_LEADER_SEND_RUNNER, "Soldier! Go find help!");
AI_SetSpawnInSpeakValue(AI_TALK_ON_LEADER_ATTACK_TARGET, "Direct your attacks here, men!");
// Ambient animations
if(GetIsEncounterCreature())
{
SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS, NW_GENERIC_MASTER);
}
AI_SetUpEndOfSpawn();
DelayCommand(2.0f, SpawnWalkWayPoints());
}

View File

@@ -1,76 +0,0 @@
/************************ [On Spawn: Lich] *************************************
Filename: j_sp_lichboss
************************* [On Spawn: Lich] *************************************
A high-powered lich, who takes advantage of spell triggers!
He should be geared towards higher level spells, and once he runs out, he
does cheat-cast several 1-3 level spells.
The spell triggers stop quite a bit of damage, with Premonition, greater
spell mantal and Energy Buffer. He also has some taunts he uses most combat
rounds, as well as using longer ranged spells first.
As he is a boss, he is a leader status, and also gets a free harm at 30% HP.
************************* [On Spawn: Lich] ************************************/
// This is required for all spawn in options!
#include "j_inc_spawnin"
void main()
{
// Maximum intelligence
SetAIInteger(AI_INTELLIGENCE, 10);
SetAIInteger(AI_MORALE, 10);
SetSpawnInCondition(AI_FLAG_FLEEING_FEARLESS, AI_TARGETING_FLEE_MASTER);
SetSpawnInCondition(AI_FLAG_OTHER_DONT_RESPOND_TO_EMOTES, AI_OTHER_MASTER);
AI_SetAITargetingValues(TARGETING_MANTALS, TARGET_LOWER, 1, 12);
AI_SetAITargetingValues(TARGETING_RANGE, TARGET_HIGHER, 2, 9);
AI_SetAITargetingValues(TARGETING_AC, TARGET_LOWER, 3, 6);
AI_SetAITargetingValues(TARGETING_SAVES, TARGET_LOWER, 3, 4);
// Mages target higher. (the lowest BAB, under half our hit dice in BAB)
AI_SetAITargetingValues(TARGETING_PHISICALS, TARGET_HIGHER, 1, 5);
AI_SetAITargetingValues(TARGETING_BAB, TARGET_LOWER, 1, 4);
AI_SetAITargetingValues(TARGETING_HITDICE, TARGET_LOWER, 1, 3);
SetSpawnInCondition(AI_FLAG_COMBAT_DISPEL_IN_ORDER, AI_COMBAT_MASTER);
SetSpawnInCondition(AI_FLAG_COMBAT_IMPROVED_INSTANT_DEATH_SPELLS, AI_COMBAT_MASTER);
SetSpawnInCondition(AI_FLAG_COMBAT_IMPROVED_SUMMON_TARGETING, AI_COMBAT_MASTER);
SetSpawnInCondition(AI_FLAG_COMBAT_IMPROVED_IMMUNITY_CHECKING, AI_COMBAT_MASTER);
SetSpawnInCondition(AI_FLAG_COMBAT_IMPROVED_SPECIFIC_SPELL_IMMUNITY, AI_COMBAT_MASTER);
SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_WILL_RAISE_ALLIES_IN_BATTLE, AI_OTHER_COMBAT_MASTER);
SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_GROUP_LEADER, AI_OTHER_COMBAT_MASTER);
SetSpawnInCondition(AI_FLAG_COMBAT_LONGER_RANGED_SPELLS_FIRST, AI_COMBAT_MASTER);
AI_SetSpawnInSpeakArray(AI_TALK_ON_COMBAT_ROUND_EQUAL, 900, 4, "Curse your life!", "Nothing can kill the undead!", "MUhahaHaHahahha!!", "Prepare to DIE!");
AI_SetSpawnInSpeakArray(AI_TALK_ON_COMBAT_ROUND_THEM_OVER_US, 900, 4, "Curse your life!", "Nothing can kill the undead!", "MUhahaHaHahahha!!", "Prepare to DIE!");
AI_SetSpawnInSpeakArray(AI_TALK_ON_COMBAT_ROUND_US_OVER_THEM, 900, 4, "Curse your life!", "Nothing can kill the undead!", "MUhahaHaHahahha!!", "Prepare to DIE!");
// Spell triggers
SetSpellTrigger(SPELLTRIGGER_START_OF_COMBAT, FALSE, 1, SPELL_DEATH_ARMOR, SPELL_FOXS_CUNNING, SPELL_SHADOW_SHIELD);
// Damamged
SetSpellTrigger(SPELLTRIGGER_DAMAGED_AT_PERCENT, 30, 1, SPELL_HARM);
// Immobile
SetSpellTrigger(SPELLTRIGGER_IMMOBILE, FALSE, 1, SPELL_FREEDOM_OF_MOVEMENT);
// Normal defensive
SetSpellTrigger(SPELLTRIGGER_NOT_GOT_FIRST_SPELL, FALSE, 1, SPELL_PREMONITION);
SetSpellTrigger(SPELLTRIGGER_NOT_GOT_FIRST_SPELL, FALSE, 2, SPELL_PREMONITION);
SetSpellTrigger(SPELLTRIGGER_NOT_GOT_FIRST_SPELL, FALSE, 3, SPELL_GREATER_SPELL_MANTLE);
SetSpellTrigger(SPELLTRIGGER_NOT_GOT_FIRST_SPELL, FALSE, 4, SPELL_GREATER_SPELL_MANTLE);
SetSpellTrigger(SPELLTRIGGER_NOT_GOT_FIRST_SPELL, FALSE, 5, SPELL_ENERGY_BUFFER);
SetSpellTrigger(SPELLTRIGGER_NOT_GOT_FIRST_SPELL, FALSE, 6, SPELL_ENERGY_BUFFER);
// Cheat spells
SetAICheatCastSpells(SPELL_MAGIC_MISSILE, SPELL_MAGIC_MISSILE, SPELL_MAGIC_MISSILE, SPELL_FIREBALL, SPELL_MELFS_ACID_ARROW, SPELL_MELFS_ACID_ARROW);
AI_SetUpEndOfSpawn();
DelayCommand(2.0, SpawnWalkWayPoints());
}

View File

@@ -1,29 +0,0 @@
/************************ [On Spawn: Low Intelligence] *************************
Filename: j_sp_lowintel
************************* [On Spawn: Low Intelligence] *************************
Low intelligence creatures, such as Goblins, might not have an advanced a
way of picking who to best attack, nor as much AI intelligence.
************************* [On Spawn: Low Intelligence] ************************/
// This is required for all spawn in options!
#include "j_inc_spawnin"
void main()
{
// 1 or 2 intelligence.
SetAIInteger(AI_INTELLIGENCE, d2());
SetAIInteger(AI_MORALE, 10);
// Probably worse for the AI to have these set - acts less intelligently.
SetSpawnInCondition(AI_FLAG_OTHER_LAG_EQUIP_MOST_DAMAGING, AI_OTHER_MASTER);
SetSpawnInCondition(AI_FLAG_OTHER_LAG_TARGET_NEAREST_ENEMY, AI_OTHER_MASTER);
// Lots of other stuff is affected by having 1 or 2 intelligence anyway.
// Removed a few of the immunity-checking bits, to lower effectivness.
SetSpawnInCondition(AI_FLAG_OTHER_DONT_RESPOND_TO_EMOTES, AI_OTHER_MASTER);
// This will ignore ALL chat by PC's (Enemies) who speak actions in Stars - *Bow*
AI_SetUpEndOfSpawn();
DelayCommand(2.0f, SpawnWalkWayPoints());
}

38
_module/nss/no_ai_atk.nss Normal file
View File

@@ -0,0 +1,38 @@
//::///////////////////////////////////////////////
//:: On Attacked
//:: NW_C2_DEFAULT5
//:://////////////////////////////////////////////
/*
Set attacker as an enemy if they are not a friend
or enemy (ie/ neutral), and initiate combat AI if
it is not already running.
*/
//:://////////////////////////////////////////////
//:://////////////////////////////////////////////
#include "no_lib_data"
#include "no_inc"
void main()
{
object oA = GetLastAttacker();
if ( GetIsObjectValid( oA ) )
{
/*
if ( GetIsFriend( oA ) )
{
PrintString( GetName( OBJECT_SELF ) + " attacked by friend " + GetName( oA ) );
}
*/
if ( !GetIsFriend( oA ) && !GetIsEnemy( oA ) && GetMaster( OBJECT_SELF ) != oA )
{
//neutrals
SetIsTemporaryEnemy( oA, OBJECT_SELF, TRUE, 300.0 );
}
//DoQueueCombat( 8.0, 8.0 );
InitCombat();
SignalEvent(OBJECT_SELF, EventUserDefined(1005));
}
}

36
_module/nss/no_ai_blk.nss Normal file
View File

@@ -0,0 +1,36 @@
//::///////////////////////////////////////////////
//:: Default On Heartbeat
//:: NW_C2_DEFAULTE
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
This will cause blocked creatures to open
or smash down doors depending on int and
str.
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Nov 23, 2001
//:://////////////////////////////////////////////
/*
NOTE: Unmodified except for this comment. Makes this
script show up as a script for this module for completeness.
*/
void main()
{
object oDoor = GetBlockingDoor();
if(GetAbilityScore(OBJECT_SELF, ABILITY_INTELLIGENCE) >= 5)
{
if(GetIsDoorActionPossible(oDoor, DOOR_ACTION_OPEN) && GetAbilityScore(OBJECT_SELF, ABILITY_INTELLIGENCE) >= 7 )
{
DoDoorAction(oDoor, DOOR_ACTION_OPEN);
}
else if(GetIsDoorActionPossible(oDoor, DOOR_ACTION_BASH))
{
DoDoorAction(oDoor, DOOR_ACTION_BASH);
}
}
}

20
_module/nss/no_ai_cmb.nss Normal file
View File

@@ -0,0 +1,20 @@
//::///////////////////////////////////////////////
//:: End of Combat Round
//::
//:://////////////////////////////////////////////
/*
Calls the end of combat script every round
*/
//:://////////////////////////////////////////////
#include "no_lib_data"
#include "no_inc"
void main()
{
//SetReadyStatus();
//DoCombat();
InitCombat();
//signal combat to userdef
SignalEvent( OBJECT_SELF, EventUserDefined( 1003 ) );
}

162
_module/nss/no_ai_cnv.nss Normal file
View File

@@ -0,0 +1,162 @@
//::///////////////////////////////////////////////
//:: On Conversation
//::
//:://////////////////////////////////////////////
/*
Determines the course of action to be taken
by the generic script after dialogue or a
shout is initiated.
*/
//:://////////////////////////////////////////////
#include "no_lib_data"
#include "no_inc"
void main()
{
object oT = OBJECT_INVALID;
object oM = GetMaster( OBJECT_SELF );
object oBroadcaster = GetLastSpeaker();
int iBroadcast = GetListenPatternNumber();
int iR = 0;
if ( iBroadcast == -1 )
{
ClearAllActions();
//SetLocalInt( OBJECT_SELF, "#ACTIVE", 1 );
//ActionStartConversation( oBroadcaster );
BeginConversation();
//DoQueueShutdown( 6.0 );
}
else
{
if ( GetIsObjectValid( oM ) && oBroadcaster == oM )
{
if ( iBroadcast == ASSOCIATE_COMMAND_STANDGROUND )
{
//stand ground
SetLocalLocation( OBJECT_SELF, "#SGLOC", GetLocation( OBJECT_SELF ) );
SetLocalInt( OBJECT_SELF, "#STANDGROUND", 1 );
ClearAllActions();
PlayVoiceChat( VOICE_CHAT_TASKCOMPLETE );
ActionMoveToLocation( GetLocation( OBJECT_SELF ) ); //stop here
}
else if ( iBroadcast == ASSOCIATE_COMMAND_ATTACKNEAREST )
{
//attack nearest
DeleteLocalInt( OBJECT_SELF, "#STANDGROUND" );
oT = GetTarget();
if ( GetIsObjectValid( oT ) )
{
PlayVoiceChat( VOICE_CHAT_GOODIDEA );
//DoQueueCombat( 8.0, 8.0 );
InitCombat();
SignalEvent( OBJECT_SELF, EventUserDefined( 1003 ) );
}
else
{
PlayVoiceChat( VOICE_CHAT_CANTDO );
}
}
else if ( iBroadcast == ASSOCIATE_COMMAND_HEALMASTER )
{
//heal master
DeleteLocalInt( OBJECT_SELF, "#STANDGROUND" );
if ( DoSpellHeal( oM ) )
{
PlayVoiceChat( VOICE_CHAT_CANDO );
}
else
{
PlayVoiceChat( VOICE_CHAT_CANTDO );
}
}
else if ( iBroadcast == ASSOCIATE_COMMAND_FOLLOWMASTER )
{
//follow master
DeleteLocalLocation( OBJECT_SELF, "#STANDGROUND" );
ClearAllActions();
ActionForceFollowObject( oM, 3.0 );
}
else if ( iBroadcast == ASSOCIATE_COMMAND_GUARDMASTER )
{
//guard master
DeleteLocalInt( OBJECT_SELF, "#STANDGROUND" );
if ( !GetIsObjectValid( oT = GetLastHostileActor( oM ) ) )
{
if ( !GetIsObjectValid( oT = GetLastAttacker( oM ) ) )
{
PlayVoiceChat( VOICE_CHAT_CANTDO );
}
}
//list of actions to try against oT
if ( GetIsObjectValid( oT ) && ( GetObjectSeen( oT ) || GetObjectHeard( oT ) ) )
{
if ( !( iR = DoSpellDirect( oT ) ) )
{
if ( !( iR = DoTouch( oT ) ) )
{
if ( !( iR = DoAttackRanged( oT ) ) )
{
if ( !( iR = DoAttackMelee( oT ) ) )
{
PlayVoiceChat( VOICE_CHAT_CANTDO );
}
}
}
}
if ( iR )
{
PlayVoiceChat( VOICE_CHAT_CANDO );
}
}
}
}
if ( iBroadcast == 699 ) //COMBAT going on nearby
{
//respond
if ( GetArea( oBroadcaster ) == GetArea( OBJECT_SELF ) && GetDistanceBetween( oBroadcaster, OBJECT_SELF ) <= GetResponseRange( BC_FIGHTING ) )
{
object oE = GetTarget();
if ( !GetIsObjectValid( oE ) )
{
//I've heard combat but I can't see the combat or any enemies
//PrintString( "CHM: " + GetName( OBJECT_SELF ) + " moving to support " + GetName( oBroadcaster ) );
DoMoveToObject( oBroadcaster, TRUE, 5.0 );
DoFightBroadcast();
}
else
{
//DoQueueCombat( 8.0, 8.0 );
InitCombat();
}
}
else
{
//hearing something from another area or from out of our response range
//SpeakString( "Ignoring combat sounds" );
}
}
else if ( iBroadcast == 691 ) //DEAD
{
//if ( GetIsFriend( oBroadcaster ) )
if ( GetFactionEqual( oBroadcaster ) )
{
DoVoiceChat( VOICE_CHAT_CUSS );
}
else if ( GetIsEnemy( oBroadcaster ) )
{
if ( Random( 2 ) )
{
DoVoiceChat( VOICE_CHAT_CHEER );
}
else
{
DoVoiceChat( VOICE_CHAT_LAUGH );
}
}
}
}
//signal conversation to userdef
SignalEvent( OBJECT_SELF, EventUserDefined( 1004 ) );
}

54
_module/nss/no_ai_dam.nss Normal file
View File

@@ -0,0 +1,54 @@
//::///////////////////////////////////////////////
//:: On Damaged
//::
//:://////////////////////////////////////////////
/*
Set damager as an enemy if they are not a friend
or enemy (ie/ neutral), and initiate combat AI if
it is not already running.
*/
//:://////////////////////////////////////////////
#include "no_lib_data"
#include "no_inc"
void main()
{
float fHP;
object oDam = GetLastDamager();
object oT = OBJECT_INVALID;
//if timestamp has elapsed and there is a friendly nearby
if ( !GetLocalInt( OBJECT_SELF, "#HEALDEL" ) &&
GetIsObjectValid( GetNearestCreature( CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_FRIEND, OBJECT_SELF, 1, CREATURE_TYPE_IS_ALIVE, TRUE ) ) )
{
fHP = IntToFloat( GetCurrentHitPoints( OBJECT_SELF ) ) / GetMaxHitPoints( OBJECT_SELF );
//only start calling for healing once we've taken 50%
if ( fHP < 0.51 )
{
//broadcast request for healing for display purposes
DoVoiceChat( VOICE_CHAT_HEALME );
//do not broadcast again until next combat round event when this int is cleared
SetLocalInt( OBJECT_SELF, "#HEALDEL", 1 );
DelayCommand( 3.0, DeleteLocalInt( OBJECT_SELF, "#HEALDEL" ) );
}
}
if ( GetIsObjectValid( oDam ) )
{
/*
if ( GetIsFriend( oDam ) )
{
PrintString( GetName( OBJECT_SELF ) + " damaged by friend " + GetName( oDam ) );
}
*/
if ( !GetIsFriend( oDam ) && !GetIsEnemy( oDam ) && GetMaster( OBJECT_SELF ) != oDam )
{
//neutrals
SetIsTemporaryEnemy( oDam, OBJECT_SELF, TRUE, 300.0 );
}
//DoQueueCombat( 8.0, 8.0 );
InitCombat();
//signal damage to userdef
SignalEvent( OBJECT_SELF, EventUserDefined( 1006 ) );
}
}

38
_module/nss/no_ai_dis.nss Normal file
View File

@@ -0,0 +1,38 @@
//::///////////////////////////////////////////////
//:: Default: On Disturbed
//:: NW_C2_DEFAULT8
//:: Copyright (c) 2001 Bioware Corp.
//:://////////////////////////////////////////////
/*
Calls the end of combat script every round
*/
//:://////////////////////////////////////////////
//:: Created By: Preston Watamaniuk
//:: Created On: Oct 16, 2001
//::///////////////////////////////////////////
// * Make me hostile the faction of my last attacker (TEMP)
// AdjustReputation(OBJECT_SELF,GetFaction(GetLastAttacker()),-100);
// * Determined Combat Round
/*
NOTE: Blocked to stop interference.
Update coming in next version.
*/
//#include "NW_I0_GENERIC"
#include "no_lib_data"
#include "no_inc"
void main()
{
object oT = GetLastDisturbed();
if ( GetIsObjectValid( oT ) )
{
SetIsTemporaryEnemy( oT, OBJECT_SELF, TRUE, 300.0 );
//DoQueueCombat( 8.0, 8.0 );
InitCombat();
SignalEvent(OBJECT_SELF, EventUserDefined(1008));
}
}

32
_module/nss/no_ai_dth.nss Normal file
View File

@@ -0,0 +1,32 @@
//::///////////////////////////////////////////////
//:: On Death
//::
//:://////////////////////////////////////////////
/*
Shouts to allies that they have been killed
*/
//:://////////////////////////////////////////////
#include "no_lib_data"
#include "no_inc"
void main()
{
//float fDieDelay = GetLocalFloat( OBJECT_SELF, "#DECAYDELAY" );
//corpse decay deactivated for Murray module
float fDieDelay = 10.0;
ClearAllActions();
//broadcast death
SpeakString( "BC_DEAD", TALKVOLUME_SILENT_TALK );
//PrintString( GetName( OBJECT_SELF ) + " killed by " + GetName( GetLastKiller() ) );
if ( GetName( GetItemInSlot( INVENTORY_SLOT_CARMOUR, OBJECT_SELF ) ) == "Balor Properties" )
{
ExecuteScript( "nw_s3_balordeth", OBJECT_SELF );
}
DelayCommand( fDieDelay, ExecuteScript( "no_scr_cleanvars", OBJECT_SELF ) );
DelayCommand( fDieDelay + 0.5, ExecuteScript( "no_scr_excorpse", OBJECT_SELF ) );
//signal death to userdef
SignalEvent( OBJECT_SELF, EventUserDefined( 1007 ) );
}

121
_module/nss/no_ai_hrt.nss Normal file
View File

@@ -0,0 +1,121 @@
//::///////////////////////////////////////////////
//:: On Heartbeat
//::
//:://////////////////////////////////////////////
/*
This script will have people perform default
animations.
*/
//:://////////////////////////////////////////////
#include "no_lib_data"
#include "no_inc"
void main()
{
//if the AI level is very low and the combat AI is not active do nothing
//need this change so that combat AI can shut itself down properly before ignoring heartbeats
if ( GetAILevel() == AI_LEVEL_VERY_LOW && !IsActive() )
{
return;
}
if ( IsActive() )
{
//if combat AI is active this is the only segment of the heartbeat that will run
int iE = GetHostileCount( 50.0 );
if ( iE == 0 )
{
object oA = GetFurthestActiveAlly( 50.0 );
if ( GetIsObjectValid( oA ) && GetDistanceBetween( OBJECT_SELF, oA ) > 20.0 && !GetIsPerceived( oA ) )
{
DoMoveToObject( oA, TRUE );
}
else
{
ExecuteScript( "no_scr_shutdown", OBJECT_SELF );
}
}
}
else
{
//combat AI isn't active
if( GetSpawnInCondition( NW_FLAG_DAY_NIGHT_POSTING ) )
{
int nDay = FALSE;
if( GetIsDay() || GetIsDawn() )
{
nDay = TRUE;
}
if( GetLocalInt( OBJECT_SELF, "NW_GENERIC_DAY_NIGHT" ) != nDay )
{
if( nDay == TRUE )
{
SetLocalInt( OBJECT_SELF, "NW_GENERIC_DAY_NIGHT", TRUE );
}
else
{
SetLocalInt( OBJECT_SELF, "NW_GENERIC_DAY_NIGHT", FALSE );
}
WalkWayPoints();
}
}
if( CanAct() )
{
object oE = GetTarget();
if( !GetIsPostOrWalking() )
{
if( !GetIsObjectValid( GetAttemptedAttackTarget() ) && !GetIsObjectValid( GetAttemptedSpellTarget() ) )
{
//if( !GetIsObjectValid( GetNearestCreature( CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN) ) )
if ( !GetIsObjectValid( oE ) )
{
if( /*!GetBehaviorState( NW_FLAG_BEHAVIOR_SPECIAL ) &&*/ !IsInConversation( OBJECT_SELF ) )
{
if( GetSpawnInCondition( NW_FLAG_AMBIENT_ANIMATIONS ) || GetSpawnInCondition( NW_FLAG_AMBIENT_ANIMATIONS_AVIAN ) )
{
PlayMobileAmbientAnimations();
}
else if( GetIsEncounterCreature() )
//won't be here unless this next condition is true so it is redundant to check it
//!GetIsObjectValid( GetNearestCreature( CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN ) ) )
{
PlayMobileAmbientAnimations();
}
else if( GetSpawnInCondition( NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS ) )
//won't be in here unless this next condition is true so it is redundant to check it
//!GetIsObjectValid( GetNearestCreature( CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN ) ) )
{
PlayImmobileAmbientAnimations();
}
}
else
{
DetermineSpecialBehavior();
}
}
else
{
//DetermineCombatRound()
InitCombat();
}
}
}
}
else
{
if( GetSpawnInCondition( NW_FLAG_SLEEPING_AT_NIGHT ) )
{
effect eVis = EffectVisualEffect( VFX_IMP_SLEEP );
if( d10() > 6 )
{
ApplyEffectToObject( DURATION_TYPE_INSTANT, eVis, OBJECT_SELF );
}
}
}
}
//Signal heart beat event to userdef
SignalEvent( OBJECT_SELF, EventUserDefined( 1001 ) );
}

98
_module/nss/no_ai_per.nss Normal file
View File

@@ -0,0 +1,98 @@
//::///////////////////////////////////////////////
//:: On Percieve
//::
//:://////////////////////////////////////////////
/*
Checks to see if the perceived target is an
enemy and if so fires the Determine Combat
Round function
*/
//:://////////////////////////////////////////////
#include "no_lib_data"
#include "no_inc"
void main()
{
object oPer = GetLastPerceived();
if ( !GetIsObjectValid( oPer ) )
{
//invalid object, do nothing
return;
}
//for associates
if ( !GetLocalInt( OBJECT_SELF, "#ACTIVE" ) && GetIsMaster( oPer ) )
{
ActionForceFollowObject( oPer, GetFollowDist() );
}
//main
if ( GetLastPerceptionSeen() && GetIsPerceived( oPer, NO_PERCEPTION_SEEN ) )
{
if ( GetIsEnemy( oPer ) && !GetIsDead( oPer ) )
{
//trigger combat
//PrintString( "ENEMY: " + GetName( OBJECT_SELF ) + " -> " + GetName( oPer ) );
DoVoiceChat( VOICE_CHAT_ENEMIES );
if ( GetIsFastBuffer() == TRUE && GetIsFastBuffed() == FALSE )
{
//only to this once per start up
ClearAllActions();
if ( DoFastBuffs() )
{
//PrintString( "FASTBUFF: " + GetName( OBJECT_SELF ) );
}
SetIsFastBuffed( TRUE );
}
//DoQueueCombat( 8.0, 8.0 );
DelayCommand( 0.5, InitCombat() );
}
else if ( !GetLocalInt( OBJECT_SELF, "#ACTIVE" ) )
{
if ( GetIsFriend( oPer ) && GetIsDead( oPer ) && GetHasRaisingAbility() )
{
ClearAllActions();
if ( DoSpellRaise( oPer ) )
{
SetLocalInt( OBJECT_SELF, "#ACTIVE", 1 );
DoQueueShutdown( 12.0 );
}
}
}
}
else if ( GetLastPerceptionHeard() && GetIsPerceived( oPer, NO_PERCEPTION_HEARD ) )
{
if ( !GetIsObjectValid( GetNearestCreature( CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN, CREATURE_TYPE_IS_ALIVE, TRUE ) ) )
{
if ( GetIsEnemy( oPer ) && GetObjectType( oPer ) == OBJECT_TYPE_CREATURE && !GetIsDead( oPer ) )
{
//check perceptions
if ( !GetIsPerceived( oPer, NO_PERCEPTION_SEEN ) )
{
//heard something that is not visible, no visible enemies, respond
//SetLocalInt( OBJECT_SELF, "#VANISHED", 1 );
//DoQueueCombat( 8.0, 8.0 );
DelayCommand( 0.5, InitCombat() );
}
}
}
}
else if ( GetLastPerceptionVanished() && GetIsPerceived( oPer, NO_PERCEPTION_VANISHED ) )
{
//make sure it isn't a corpse that just faded out
//report vanished enemies who have not just died
if ( GetIsEnemy( oPer ) )
{
if( !GetIsDead( oPer ) )
{
DoVoiceChat( VOICE_CHAT_CUSS );
SetLocalInt( OBJECT_SELF, "#VANISHED", 1 );
}
}
}
//signal perception to userdef
SignalEvent( OBJECT_SELF, EventUserDefined( 1002 ) );
}

26
_module/nss/no_ai_rst.nss Normal file
View File

@@ -0,0 +1,26 @@
//::///////////////////////////////////////////////
//:: Default: On Rested
//:: NW_C2_DEFAULTA
//:: Copyright (c) 2002 Bioware Corp.
//:://////////////////////////////////////////////
/*
Determines the course of action to be taken
after having just rested.
*/
//:://////////////////////////////////////////////
//:: Created By: Don Moar
//:: Created On: April 28, 2002
//:://////////////////////////////////////////////
/*
NOTE: Unmodified except for this comment. Makes this
script show up as a script for this module for completeness.
*/
void main()
{
// enter desired behaviour here
return;
}

70
_module/nss/no_ai_spt.nss Normal file
View File

@@ -0,0 +1,70 @@
//::///////////////////////////////////////////////
//:: On Spell Cast At
//::
//:://////////////////////////////////////////////
/*
This determines if the spell just cast at the
target is harmful or not.
*/
//:://////////////////////////////////////////////
#include "no_lib_data"
#include "no_inc"
void main()
{
int iS = GetLastSpell();
int iH = GetLastSpellHarmful();
object oC = GetLastSpellCaster();
if ( !iH )
{
if ( iS == SPELL_RAISE_DEAD || iS == SPELL_RESURRECTION )
{
SetCommandable( TRUE, OBJECT_SELF );
DeleteLocalObject( OBJECT_SELF, "#RAISER" );
}
else if ( iS == SPELL_HEAL || iS == SPELL_CURE_CRITICAL_WOUNDS ||
iS == SPELL_CURE_SERIOUS_WOUNDS || iS == SPELL_CURE_MODERATE_WOUNDS ||
iS == SPELL_CURE_LIGHT_WOUNDS || iS == SPELL_CURE_MINOR_WOUNDS )
{
if ( oC != OBJECT_SELF && GetIsFriend( oC ) )
{
DoVoiceChat( VOICE_CHAT_THANKS );
}
DeleteLocalObject( OBJECT_SELF, "#HEALER" );
}
else if ( iS == SPELL_DARKVISION )
{
DeleteLocalInt( OBJECT_SELF, "#DARKNESS" );
DeleteLocalObject( OBJECT_SELF, "#VISION" );
}
else if ( iS == SPELL_SEE_INVISIBILITY )
{
DeleteLocalInt( OBJECT_SELF, "#VANISHED" );
DeleteLocalObject( OBJECT_SELF, "#VISION" );
}
else if ( iS == SPELL_TRUE_SEEING )
{
DeleteLocalInt( OBJECT_SELF, "#DARKNESS" );
DeleteLocalInt( OBJECT_SELF, "#VANISHED" );
DeleteLocalObject( OBJECT_SELF, "#VISION" );
}
}
if ( iS == SPELL_DARKNESS )
{
SetLocalInt( OBJECT_SELF, "#DARKNESS", 1 );
}
if ( iH )
{
if ( !GetIsFriend( oC ) && !GetIsEnemy( oC ) && GetMaster( OBJECT_SELF ) != oC )
{
//neutrals
SetIsTemporaryEnemy( oC, OBJECT_SELF, TRUE, 300.0 );
}
//DoQueueCombat( 8.0, 8.0 );
InitCombat();
}
//signal spell at to userdef
SignalEvent( OBJECT_SELF, EventUserDefined( 1011 ) );
}

10
_module/nss/no_inc.nss Normal file
View File

@@ -0,0 +1,10 @@
//#include "no_lib_data"
#include "no_inc_ptypes"
#include "no_lib_bio"
#include "no_lib_priority"
#include "no_lib_magic"
#include "no_lib_analysis"
#include "no_lib_feat"
#include "no_lib_melee"
#include "no_lib_ranged"
#include "no_lib_actions"

View File

@@ -0,0 +1,408 @@
//constants
//can broadcasting use DM channel
const int NO_CAN_USE_DM_CHANNEL = 1;
//broadcast constants
const int BC_FIGHTING = 699;
//effect weights
const int NO_EFFECT_GENERIC = 1;
const int NO_EFFECT_DISEASE = 2;
const int NO_EFFECT_CURSE = 4;
const int NO_EFFECT_POISON = 8;
const int NO_EFFECT_DEAF = 16;
const int NO_EFFECT_BLINDNESS = 32;
const int NO_EFFECT_SILENCE = 64;
const int NO_EFFECT_NEGATIVELEVEL = 128;
const int NO_EFFECT_DAZED = 256;
const int NO_EFFECT_FRIGHTENED = 512;
const int NO_EFFECT_CONFUSED = 1024;
const int NO_EFFECT_CHARMED = 2048;
const int NO_EFFECT_SLEEP = 4096;
const int NO_EFFECT_STUNNED = 8192;
const int NO_EFFECT_DOMINATED = 16384;
const int NO_EFFECT_PETRIFY = 32768;
const int NO_EFFECT_PARALYZE = 65536;
//spell level cut offs
const int NO_LVL8_MIN_LVL = 24;
const int NO_LVL7_MIN_LVL = 21;
const int NO_LVL6_MIN_LVL = 18;
const int NO_LVL5_MIN_LVL = 15;
const int NO_LVL4_MIN_LVL = 12;
const int NO_LVL3_MIN_LVL = 9;
const int NO_LVL2_MIN_LVL = 6;
const int NO_LVL1_MIN_LVL = 3;
//associate orders
const int NO_ORDER_ATTACK = 1;
const int NO_ORDER_FOLLOW = 2;
const int NO_ORDER_GUARD = 4;
const int NO_ORDER_HEAL = 8;
const int NO_ORDER_STANDGROUND = 16;
//voice chat defines
const int NO_VC_DEFAULT = 1000;
const int NO_VC_MELEE = 1001;
const int NO_VC_RANGED = 1003;
const int NO_VC_MELEEASSIST = 1004;
//perception types
const int NO_PERCEPTION_SEEN = 1;
const int NO_PERCEPTION_HEARD = 2;
const int NO_PERCEPTION_VANISHED = 4;
//special attack minimum hit dice ratios
const float NO_THRESH_SMITE = 0.75;
const float NO_THRESH_STUNNING_FIST = 0.5;
const float NO_THRESH_QUIVERING_PALM = 0.75;
const float NO_THRESH_ARROW_SLAYING = 0.75;
const float NO_THRESH_KI_DAMAGE = 0.5;
//illithid abilities
const int CODI_MIND_BLAST = 1522;
const int CODI_BRAIN_EXTRACT = 1523;
//beholder constants
const int BEHOLDER_MAX_RAYS = 10;
const int SPELL_BEHRAY_FINGER_OF_DEATH = 776;
const int SPELL_BEHRAY_TELEKINESIS = 777;
const int SPELL_BEHRAY_FLESH_TO_STONE = 778;
const int SPELL_BEHRAY_CHARM = 779;
const int SPELL_BEHRAY_SLOW = 780;
const int SPELL_BEHRAY_INFLICT_WOUNDS = 783;
const int SPELL_BEHRAY_FEAR = 784;
const int SPELL_BEH_ANTIMAGIC_CONE = 727;
//missing epic spell definition
const int SPELL_EPIC_WARDING = 695;
//miscellaneous missing constants
const int SPELLABILITY_DRAGON_BREATH_RDD = 690;
const int SPELLABILITY_DRAGON_BREATH_PRISMATIC = 771;
const int SPELLABILITY_DEFLECTING_FORCE = 774;
//string constants
const string s_BEHOLDER_CENTRAL_EYE_FLAG = "#BEHCENEYE";
#include "no_lib_data"
//Master prototype list
// NO_LIB_ACTIONS
// support functions
void NO_ActionCastSpellAtLocation( int iSpell, location lTargetLocation, int iMetaMagic=METAMAGIC_ANY, int iCheat=FALSE, int iProjectilePathType=PROJECTILE_PATH_TYPE_DEFAULT, int iInstantSpell=FALSE, int iDefensive=TRUE );
void NO_ActionCastSpellAtObject( int iSpell, object oTarget, int iMetaMagic=METAMAGIC_ANY, int iCheat=FALSE, int iDomainLevel=0, int iProjectilePathType=PROJECTILE_PATH_TYPE_DEFAULT, int iInstantSpell=FALSE, int iDefensive=TRUE );
void NO_ActionUseTalentAtLocation( talent tChosenTalent, location lTargetLocation, int iDefensive=TRUE );
void NO_ActionUseTalentOnObject( talent tChosenTalent, object oTarget, int iDefensive=TRUE );
void ActivateCombatMode( int iMode=0, object oE=OBJECT_SELF );
void DeactivateCombatModes( int iException=0, object oE=OBJECT_SELF );
int DoHideInPlainSight( object oE=OBJECT_SELF );
void DoFireBeholderRay( int iS, object oT );
void DoMoveToLocation( location lDest, int bRun=FALSE );
void DoMoveToObject( object oDest, int bRun=FALSE, float fDist=1.0f );
void DoTeleport( location lLoc );
object GetTarget();
float DotProduct( vector v1, vector v2 );
location GetFlankLoc( object oT, location lL );
void DoEquipMelee( object oT );
talent GetTalentSpell( int iCat, int iD );
void DoFightBroadcast();
int GetTimeSinceLastCombat();
void DoConditionalRestart( float fT=6.0 );
void DoQueueShutdown( float fT=0.0 );
void DoQueueCombat( float fD=6.0, float fT=6.0 );
void InitCombat( object oE=OBJECT_INVALID );
void DoVoiceChat( int iV=-1 );
void DoMainCombatLoop();
void DoCombat();
// action functions
int DoAttackMelee( object oT=OBJECT_INVALID );
int DoAttackRanged( object oT=OBJECT_INVALID );
int DoCounterSpell( object oT=OBJECT_INVALID );
int DoEvacAOE();
int DoRegroup( object oT=OBJECT_INVALID );
int DoDefendSelf();
int DoDefendSingle( object oT=OBJECT_INVALID );
int DoEnhanceSelf();
int DoEnhanceSingle( object oT=OBJECT_INVALID );
int DoSpellHelp( object oT=OBJECT_INVALID );
int DoSpellHeal( object oT=OBJECT_INVALID );
int DoSpellRaise( object oT=OBJECT_INVALID );
int DoSpellBreach( object oT=OBJECT_INVALID );
int DoSpellDirect( object oT=OBJECT_INVALID );
int DoTouch( object oT=OBJECT_INVALID );
int DoSpellArea();
int DoSpellSummon();
int DoSpellCharm();
int DoFeatEnhance();
int DoAvoidMelee();
int DoTimeStop();
int DoVision();
int DoBreathWeapon();
int DoTurning();
int DoSpellCone();
int DoHealSelf();
int DoSpellGroupEnhance();
int DoSpellGroupHeal();
int DoDispelPersAOE();
int DoDispelSingle();
int DoDismissal();
int DoFastBuffs();
int DoMeleeAssist();
int DoFlank( object oE=OBJECT_INVALID );
int DoMindBlast();
int DoBrainExtraction();
int DoAvoidEnemies();
int DoGrenade();
int DoBeholderRays();
int DoBeholderCentralEye();
// NO_LIB_ANALYSIS
int GetAOEThreat( object oArea, object oEnt=OBJECT_SELF );
int GetAOECount( float fRad=10.0f, object oEnt=OBJECT_SELF );
vector GetAOEVector( float fRad=10.0f, object oEnt=OBJECT_SELF );
int GetHostileAOECount( float fRad=10.0f, object oEnt=OBJECT_SELF );
vector GetHostileAOEVector( float fRad=10.0f, object oEnt=OBJECT_SELF );
vector GetAOEEvacVector( vector vS, object oEnt=OBJECT_SELF );
object GetMostDamagedAlly( float fRad=15.0f, object oEnt=OBJECT_SELF, int iSee=FALSE );
object GetLowestHPAlly( float fRad=15.0, int iLim=0, object oEnt=OBJECT_SELF, int iSee=FALSE );
object GetLowestHPAllyNoHealer( float fRad=15.0, int iLim=0, object oEnt=OBJECT_SELF, int iSee=FALSE, int iLive=TRUE );
object GetNearestDeadAlly( float fRad=15.0f, object oEnt=OBJECT_SELF, int iSee=FALSE );
object GetNearestDeadAllyNoRaiser( float fRad=15.0f, object oEnt=OBJECT_SELF, int iSee=FALSE );
object GetNearestPetrifiedAllyNoHelper( float fRad=15.0f, object oEnt=OBJECT_SELF, int iSee=FALSE );
int GetEffectsOnObject( object oEnt=OBJECT_SELF );
object GetMostHamperedAlly( float fRad=15.0f, object oEnt=OBJECT_SELF, int iSee=FALSE );
vector GetAreaTarget( int iS, float fRad, float fMinRad=7.5, float fMaxRad=30.0, int iEffChk=TRUE, object oCaster=OBJECT_SELF );
vector GetFriendlyAreaTarget( float fRad, int iSpell=0, int iType=0, object oCaster=OBJECT_SELF );
int CanAct( object oSelf=OBJECT_SELF );
int GetIsWeapon( object oWeapon );
int GetIsLightWeapon( object oWeapon, int iCanBeInvalid=FALSE );
int GetIsDoubleWeapon( object oWeapon );
int GetCasterCount( float fRad=5.0, object oEnt=OBJECT_SELF );
int GetAttackerCount( float fRad=5.0, object oEnt=OBJECT_SELF, object oS=OBJECT_SELF );
int GetHostileCount( float fRad=5.0, object oEnt=OBJECT_SELF, object oS=OBJECT_SELF );
int GetOmniscientHostileCount( float fRad=5.0, object oEnt=OBJECT_SELF, object oS=OBJECT_SELF );
int GetAllyCount( float fRad=5.0, object oEnt=OBJECT_SELF, object oS=OBJECT_SELF );
int GetAttackerHD( float fRad=5.0, object oEnt=OBJECT_SELF, object oS=OBJECT_SELF );
int GetHostileHD( float fRad=5.0, object oEnt=OBJECT_SELF, object oS=OBJECT_SELF );
int GetAllyHD( float fRad=5.0, object oEnt=OBJECT_SELF, object oS=OBJECT_SELF );
vector GetHostileVector( float fRad=10.0f, object oEnt=OBJECT_SELF );
vector GetHostileEvacVector( vector vS, object oEnt=OBJECT_SELF );
int GetIsCaster( object oEnt=OBJECT_SELF );
int DoAbilityCheck( int iAbil, int iDC, object oEnt=OBJECT_SELF );
int DoCombatKnowledgeCheck( int iBAB=FALSE, int iDC=10, object oE=OBJECT_SELF );
float GetFriendFoeRatio( location lLoc, float fRad, object oEnt=OBJECT_SELF );
float GetFriendFoeTolerance( object oEnt=OBJECT_SELF );
object GetNearestEnemyCaster( int iMaxLvl=20, int iMinLvl=1, object oEnt=OBJECT_SELF );
int GetAverageEnemyLevel( float fRad=60.0, object oEnt=OBJECT_SELF );
int GetSafeAverageEnemyLevel( float fRad=40.0, object oEnt=OBJECT_SELF );
object GetLeastMagicDefendedEnemy( float fRad=5.0, object oEnt=OBJECT_SELF );
vector GetTurningVector( object oEnt=OBJECT_SELF );
int GetIsValidTurnTarget( object oT, int iL=0, object oEnt=OBJECT_SELF );
int GetPotionHealAmount( object oP );
int GetTalentPotionHealAmount( talent tP );
vector GetAreaHealTarget( float fRad=0.0, int iH=0, object oEnt=OBJECT_SELF );
float GetAllyDamageStats( location lT, float fRad=0.0, object oEnt=OBJECT_SELF );
object GetMostBuffedEnemy( float fRad=10.0, object oEnt=OBJECT_SELF );
object GetLeastBuffedAlly( float fRad=10.0, int iMelee=FALSE, object oEnt=OBJECT_SELF );
int GetIsBuffEffect( effect eT );
int GetAverageEffectCasterLevel( object oT=OBJECT_SELF );
object GetStrongestEnemySummonedAssociateOwner( float fRad=10.0, object oEnt=OBJECT_SELF );
vector GetEnemySummonedAssociatesVector( float fRad=10.0, object oEnt=OBJECT_SELF );
vector GetEnemyPlanarVector( float fRad=10.0, object oEnt=OBJECT_SELF );
object GetVisionDeprived( float fRad=10.0, object oT=OBJECT_SELF );
object GetLeastDefendedAlly( float fRad=10.0, object oC=OBJECT_SELF );
int GetHasRangedCapability( object oEnt=OBJECT_SELF );
int GetIsRangedWeapon( object oW=OBJECT_INVALID );
object GetMostDistantEnemy( float fR=30.0, int iS=TRUE, object oC=OBJECT_SELF );
vector GetSaves( object oT=OBJECT_SELF );
vector GetBaseSavesByClass( int iC, int iL );
vector GetAverageEnemySaveInArea( vector vP, float fR=5.0, object oC=OBJECT_SELF );
int IsImmuneToPetrification(object oCreature);
object GetNearestAddledEnemy( float fRange=10.0, object oE=OBJECT_SELF );
object GetNearestAddledEnemyNoExtractor( float fRange=10.0, object oE=OBJECT_SELF );
int IsBrainExtractable( object oT );
int GetCreatureAttackBonus( object oC=OBJECT_SELF );
int GetGrappleBonus( object oC=OBJECT_SELF );
int GetIsMaster( object oM, object oE=OBJECT_SELF );
int GetIsPerceived( object oP, int iP=0, object oE=OBJECT_SELF );
object GetNearestPerceivedCreature( int iP=NO_PERCEPTION_SEEN, object oE=OBJECT_SELF );
object GetNearestActiveAlly( object oE=OBJECT_SELF );
object GetFurthestActiveAlly( float fD=50.0, object oE=OBJECT_SELF );
int EstimateAttackBonus( object oC=OBJECT_SELF );
int GetDualWieldingPenalty( object oC=OBJECT_SELF, object oR=OBJECT_INVALID, object oL=OBJECT_INVALID );
int GetHasWeaponFocus( object oR, object oC=OBJECT_SELF );
int GetIsArmed( object oEnt=OBJECT_SELF );
int GetRelativeEnemyWeaponSize( object oT, object oEnt=OBJECT_SELF );
int GetWeaponSize( object oEnt=OBJECT_SELF );
float GetAverageDistanceToEnemy( float fRad=60.0, object oEnt=OBJECT_SELF );
int GetCombatModeModifier( int iMode=0 );
int GetCombatConcentration( object oE=OBJECT_SELF );
int GetTurningLevel( object oC=OBJECT_SELF );
void SetIsCentralEyeOpen( int iS=FALSE, object oB=OBJECT_SELF );
int GetIsCentralEyeOpen( object oB=OBJECT_SELF );
// NO_LIB_FEAT
int GetEnhanceFeat( object oEnt=OBJECT_SELF );
int GetGroupEnhanceFeat( object oEnt=OBJECT_SELF );
float GetGroupEnhanceFeatRadius( int iFeat );
// NO_LIB_MAGIC
int GetBestMagicDefenseSelf( object oEnt=OBJECT_SELF );
int GetBestMagicDefenseSingle( object oEnt=OBJECT_SELF, object oC=OBJECT_SELF );
int GetBestPhysDefenseSelf( object oEnt=OBJECT_SELF );
int GetBestPhysDefenseSingle( object oEnt=OBJECT_SELF, object oC=OBJECT_SELF );
int GetBestGenericProtection( object oEnt=OBJECT_SELF );
struct sSpellDefStatus EvaluateSpellDefenses( object oTarget=OBJECT_SELF );
struct sPhysDefStatus EvaluatePhysicalDefenses( object oTarget=OBJECT_SELF );
int GetBestHeal( object oEnt=OBJECT_SELF, int iMin=10 );
int GetGroupHealSpell( int iMinLvl=0, object oCaster=OBJECT_SELF );
int GetGroupHealSpellAmount( int iH=0, object oCaster=OBJECT_SELF );
float GetGroupHealSpellRadius( int iH=0 );
int GetBestRaise( int iCombat=FALSE );
int GetHasHealingAbility( object oCaster=OBJECT_SELF );
int GetHasRaisingAbility( object oCaster=OBJECT_SELF );
int GetHasHelpingAbility( object oCaster=OBJECT_SELF );
int GetBestHelp( object oEnt, object oCaster=OBJECT_SELF );
int GetAreaSpell( vector vS, int iDisc=FALSE, int iMinLvl=0, float fR=40.0, object oCaster=OBJECT_SELF );
float GetAreaSpellRadius( int iSpell );
int GetDirectSpell( object oT, int iDisc=FALSE, int iMinLvl=0, object oCaster=OBJECT_SELF );
int GetTouchSpell( object oT, int iMinLvl=0, object oCaster=OBJECT_SELF );
int GetSummonSpell( int iMinLvl=1, object oCaster=OBJECT_SELF );
int GetEnhanceSpellSelf( int iMinLvl=1, object oCaster=OBJECT_SELF );
int GetEnhanceSpellSingle( int iMinLvl=1, object oEnt=OBJECT_SELF, object oCaster=OBJECT_SELF );
int GetBestBreach( int iLim=30, object oEnt=OBJECT_SELF );
int GetBestDispel( int iCLvl=20, int iDLvl=20, object oEnt=OBJECT_SELF );
int GetIsDiscriminantSpell( int iSpell );
int GetBreathWeapon( object oEnt=OBJECT_SELF );
int GetConeSpell( int iMinLvl = 1, object oCaster=OBJECT_SELF );
int GetGroupEnhanceSpell( int iMinLvl = 1, object oCaster=OBJECT_SELF );
float GetGroupEnhanceSpellRadius( int iSpell );
int GetDispelSpell( object oEnt=OBJECT_SELF );
int GetMaxDispelCasterLevel( object oEnt=OBJECT_SELF );
int GetVisionSpellNeeded( object oS=OBJECT_SELF, object oC=OBJECT_SELF );
int GetHasVisionSpells( object oC=OBJECT_SELF );
int GenerateFastBuffList( object oC=OBJECT_SELF );
float GetSpellRange( int iS );
int IsCone( int iS=0 );
int IsDragonBreath( int iS=0 );
int IsHowl( int iS=0 );
int IsPulse( int iS=0 );
void InitializeBeholderRaySelection( object oB=OBJECT_SELF );
void ClearBeholderRaySelection( object oB=OBJECT_SELF );
void RemoveBeholderRayFromSelection( int iS=0, object oB=OBJECT_SELF );
int MatchRayToTarget( object oT, object oB=OBJECT_SELF );
// NO_LIB_MELEE
int GetBestMeleeSpecial( object oTarget, int iPenalty=0, int iChance=50, object oEnt=OBJECT_SELF );
int SelectMeleeCombatModes( object oT, int iC=50, object oEnt=OBJECT_SELF );
// NO_LIB_RANGED
int GetBestRangedSpecial( object oTarget, int iPenalty=0, int iChance=50, object oEnt=OBJECT_SELF );
int SelectRangedCombatModes( object oT, int iC=50, object oEnt=OBJECT_SELF );
// NO_LIB_PRIORITY
void AddBehaviour( string sB, int iC, object oEnt=OBJECT_SELF );
string GetPriority( int iP=1, object oEnt=OBJECT_SELF );
int GetPriorityChance( int iP=1, object oEnt=OBJECT_SELF );
void SetVoiceChat( int iV, int iC, object oE=OBJECT_SELF );
float GetFollowDist( object oE=OBJECT_SELF );
void SetPerceptionRange( int iP, float fP=50.0, object oE=OBJECT_SELF );
void SetPerceptionRanges( float fS=50.0, float fH=50.0, float fV=50.0, object oE=OBJECT_SELF );
float GetPerceptionRange( int iP, object oE=OBJECT_SELF );
void SetReadyStatus( int iS=1, object oE=OBJECT_SELF );
int IsReadyToAct( object oE=OBJECT_SELF );
int ShortAction( object oE=OBJECT_SELF );
int IsActive( object oE=OBJECT_SELF );
void SetActive( object oE=OBJECT_SELF );
void SetIsActive( int iA=TRUE, object oE=OBJECT_SELF );
float GetResponseRange( int iT, object oE=OBJECT_SELF );
void SetResponseRange( int iT, float fR=50.0, object oE=OBJECT_SELF );
void SetIsTeleporter( object oE=OBJECT_SELF );
int GetIsTeleporter( object oE=OBJECT_SELF );
void SetIsFastBuffer( int iS, object oE=OBJECT_SELF );
int GetIsFastBuffer( object oE=OBJECT_SELF );
void SetIsFastBuffed( int iS, object oE=OBJECT_SELF );
int GetIsFastBuffed( object oE=OBJECT_SELF );
void AddFastBuff( int iS, object oE=OBJECT_SELF );
int CountFastBuffs( object oE=OBJECT_SELF );
void SetLastAction( string sA, object oE=OBJECT_SELF );
string GetLastAction( object oE=OBJECT_SELF );
void SetLastActionTimestamp( object oE=OBJECT_SELF );
int GetLastActionTimestamp( object oE=OBJECT_SELF );
void SetCorpseDelay( int iT=60, object oC=OBJECT_SELF );
void SetIsFlier( int iF=FALSE, object oF=OBJECT_SELF );
int GetIsFlier( object oF=OBJECT_SELF );
// NO_LIB_BIO
void SetSpawnInCondition(int nCondition, int bValid = TRUE);
int GetSpawnInCondition(int nCondition);
void SetSpawnInLocals(int nCondition);
void SetListeningPatterns();
void WalkWayPoints(int nRun = FALSE, float fPause = 1.0);
void RunNextCircuit(int nRun = FALSE, float fPause = 1.0);
void RunCircuit(int nTens, int nNum, int nRun = FALSE, float fPause = 1.0);
int CheckWayPoints(object oWalker = OBJECT_SELF);
int GetIsPostOrWalking(object oWalker = OBJECT_SELF);
//void SetBehaviorState(int nCondition, int bValid = TRUE);
//int GetBehaviorState(int nCondition);
void PlayMobileAmbientAnimations();
//void PlayImmobileAmbientAnimations();
void DetermineSpecialBehavior(object oIntruder = OBJECT_INVALID);
void ClearActions(int nClearConstant=0, int bClearCombat=FALSE);
//SoU animation craziness
void AnimDebug(string sMsg);
int GetAnimationCondition(int nCondition, object oCreature=OBJECT_SELF);
void SetAnimationCondition(int nCondition, int bValid=TRUE, object oCreature=OBJECT_SELF);
int GetIsBusyWithAnimation(object oCreature);
object GetRandomFriend(float fMaxDistance);
object GetRandomObjectByTag(string sTag, float fMaxDistance);
object GetRandomObjectByType(int nObjType, float fMaxDistance);
object GetRandomStop(float fMaxDistance);
void SetCreatureHomeWaypoint();
object GetCreatureHomeWaypoint();
void SetCurrentFriend(object oFriend);
object GetCurrentFriend();
void SetCurrentInteractionTarget(object oTarget);
object GetCurrentInteractionTarget();
void CheckIsCivilized();
void CheckCurrentModes();
int CheckIsAnimActive(object oCreature);
int CheckCurrentAction();
void AnimInitialization();
void PlayMobileAmbientAnimations_NonAvian();
void PlayMobileAmbientAnimations_Avian();
void PlayImmobileAmbientAnimations();
void AnimActionPlayRandomImmobile();
void AnimActionPlayRandomCloseRange();
void AnimActionPlayRandomMobile();
void AnimActionPlayRandomUncivilized();
void AnimActionStartInteracting(object oPlaceable);
void AnimActionStopInteracting();
void AnimActionStartTalking(object oFriend, int nHDiff=0);
void AnimActionStopTalking(object oFriend, int nHDiff=0);
void AnimActionPlayRandomGreeting(int nHDiff=0);
void AnimActionPlayRandomGoodbye(int nHDiff);
void AnimActionRandomMoveAway(object oSource, float fDistance);
void AnimActionShakeHead();
void AnimActionLookAround();
void AnimActionTurnAround();
void AnimActionGoThroughDoor(object oDoor);
int AnimActionCloseRandomDoor();
int AnimActionSitInChair(float fMaxDistance);
int AnimActionGetUpFromChair();
int AnimActionGoInside();
int AnimActionGoOutside();
int AnimActionGoToStop(float fMaxDistance);
int AnimActionFindFriend(float fMaxDistance);
int AnimActionFindPlaceable(float fMaxDistance);
int AnimActionRest();
int AnimActionGoHome();
int AnimActionLeaveHome();
int AnimActionChallengeIntruder();
void AnimActionPlayRandomInteractAnimation(object oPlaceable);
void AnimActionPlayRandomTalkAnimation(int nHDiff);
void AnimActionPlayRandomBasicAnimation();
void AnimActionPlayRandomAnimation();

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

2173
_module/nss/no_lib_bio.nss Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,15 @@
struct sSpellDefStatus {
int iTotal;
int iMantle;
int iElem;
int iDeath;
int iMind;
int iInvis;
int iBlocker;
};
struct sPhysDefStatus {
int iTotal;
int iDamred;
int iConceal;
};

View File

@@ -0,0 +1,95 @@
#include "no_inc_ptypes"
//functions
int GetEnhanceFeat( object oEnt=OBJECT_SELF )
{
int iCnt = 0;
int iFeat = 0;
if ( GetHasFeat( FEAT_EMPTY_BODY, oEnt ) && !GetHasFeatEffect( FEAT_EMPTY_BODY, oEnt ) )
{
SetLocalInt( oEnt, "#FEAT_" + IntToString( ++iCnt ), FEAT_EMPTY_BODY );
}
if ( GetHasFeat( FEAT_MIGHTY_RAGE, oEnt ) )
{
if ( !GetHasFeatEffect( FEAT_MIGHTY_RAGE, oEnt ) )
{
SetLocalInt( oEnt, "#FEAT_" + IntToString( ++iCnt ), FEAT_MIGHTY_RAGE );
}
}
else if ( GetHasFeat( FEAT_BARBARIAN_RAGE, oEnt ) && !GetHasFeatEffect( FEAT_BARBARIAN_RAGE, oEnt ) )
{
SetLocalInt( oEnt, "#FEAT_" + IntToString( ++iCnt ), FEAT_BARBARIAN_RAGE );
}
if ( GetHasFeat( FEAT_BARD_SONGS, oEnt ) && !GetHasFeatEffect( FEAT_BARD_SONGS, oEnt ) )
{
SetLocalInt( oEnt, "#FEAT_" + IntToString( ++iCnt ), FEAT_BARD_SONGS );
}
if ( GetHasFeat( FEAT_CURSE_SONG, oEnt ) && !GetHasFeatEffect( FEAT_CURSE_SONG, oEnt ) )
{
SetLocalInt( oEnt, "#FEAT_" + IntToString( ++iCnt ), FEAT_CURSE_SONG );
}
if ( GetHasFeat( FEAT_DIVINE_WRATH, oEnt ) && GetAbilityModifier( ABILITY_CHARISMA, oEnt ) > 0 && !GetHasFeatEffect( FEAT_DIVINE_WRATH, oEnt ) )
{
SetLocalInt( oEnt, "#FEAT_" + IntToString( ++iCnt ), FEAT_DIVINE_WRATH );
}
if ( GetHasFeat( FEAT_DWARVEN_DEFENDER_DEFENSIVE_STANCE, oEnt ) && !GetHasFeatEffect( FEAT_DWARVEN_DEFENDER_DEFENSIVE_STANCE, oEnt ) )
{
SetLocalInt( oEnt, "#FEAT_" + IntToString( ++iCnt ), FEAT_DWARVEN_DEFENDER_DEFENSIVE_STANCE );
}
if ( GetHasFeat( FEAT_EPIC_BLINDING_SPEED, oEnt ) && !GetHasFeatEffect( FEAT_EPIC_BLINDING_SPEED, oEnt ) &&
!GetHasSpellEffect( SPELL_HASTE, oEnt ) && !GetHasSpellEffect( SPELL_MASS_HASTE, oEnt ) )
{
SetLocalInt( oEnt, "#FEAT_" + IntToString( ++iCnt ), FEAT_EPIC_BLINDING_SPEED );
}
if ( GetHasFeat( FEAT_SHADOW_EVADE, oEnt ) && !GetHasFeatEffect( FEAT_SHADOW_EVADE, oEnt ) )
{
SetLocalInt( oEnt, "#FEAT_" + IntToString( ++iCnt ), FEAT_SHADOW_EVADE );
}
if ( GetHasFeat( FEAT_DIVINE_MIGHT, oEnt ) && GetHasFeat( FEAT_TURN_UNDEAD, oEnt ) && !GetHasFeatEffect( FEAT_DIVINE_MIGHT, oEnt ) )
{
SetLocalInt( oEnt, "#FEAT_" + IntToString( ++iCnt ), FEAT_DIVINE_MIGHT );
}
if ( GetHasFeat( FEAT_DIVINE_SHIELD, oEnt ) && GetHasFeat( FEAT_TURN_UNDEAD, oEnt ) && !GetHasFeatEffect( FEAT_DIVINE_SHIELD, oEnt ) )
{
SetLocalInt( oEnt, "#FEAT_" + IntToString( ++iCnt ), FEAT_DIVINE_SHIELD );
}
if ( GetHasFeat( FEAT_TYMORAS_SMILE, oEnt ) && !GetHasFeatEffect( FEAT_TYMORAS_SMILE, oEnt ) )
{
SetLocalInt( oEnt, "#FEAT_" + IntToString( ++iCnt ), FEAT_TYMORAS_SMILE );
}
iFeat = GetLocalInt( oEnt, "#FEAT_" + IntToString( Random( iCnt ) + 1 ) );
while ( iCnt )
{
DeleteLocalInt( oEnt, "#FEAT_" + IntToString( iCnt-- ) );
}
return iFeat;
}
int GetGroupEnhanceFeat( object oEnt=OBJECT_SELF )
{
int iCnt = 0;
int iFeat = 0;
if ( GetHasFeat( FEAT_BARD_SONGS, oEnt ) && !GetHasFeatEffect( FEAT_BARD_SONGS, oEnt ) )
{
SetLocalInt( oEnt, "#FEAT_" + IntToString( ++iCnt ), FEAT_BARD_SONGS );
}
iFeat = GetLocalInt( oEnt, "#FEAT_" + IntToString( Random( iCnt ) + 1 ) );
while ( iCnt )
{
DeleteLocalInt( oEnt, "#FEAT_" + IntToString( iCnt-- ) );
}
return iFeat;
}
float GetGroupEnhanceFeatRadius( int iFeat )
{
if ( iFeat == FEAT_BARD_SONGS )
{
return RADIUS_SIZE_COLOSSAL;
}
return 0.0;
}

3982
_module/nss/no_lib_magic.nss Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,300 @@
#include "no_inc_ptypes"
//functions
int GetBestMeleeSpecial( object oTarget, int iPenalty=0, int iChance=50, object oEnt=OBJECT_SELF )
{
int iCnt = 0;
int iFeat;
int iMyAtk;
int iEnemyAtk;
int iMyAC;
int iEnemyAC;
int iF1;
int iF2;
int iD;
int iT;
if ( !GetIsObjectValid( oTarget ) || Random( 100 ) > iChance )
{
return 0;
}
//get target's discipline skill as it opposes some melee specials
iD = GetSkillRank( SKILL_DISCIPLINE, oTarget ) + GetAbilityModifier( ABILITY_STRENGTH, oTarget ) + 3 * GetHasFeat( FEAT_SKILL_FOCUS_DISCIPLINE, oTarget );
//use either my intelligence or BAB to check for creature knowledge on some of these, whichever is better
//if iT == TRUE we will use BAB, otherwise use intelligence modifier
iT = GetBaseAttackBonus( OBJECT_SELF ) < GetAbilityModifier( ABILITY_INTELLIGENCE ) ? FALSE : TRUE;
iMyAtk = EstimateAttackBonus( oEnt ) + iPenalty; //include penalty from active combat mode if any
//iEnemyAtk = EstimateAttackBonus( oTarget );
//iMyAC = GetAC( oEnt ) - 10;
iEnemyAC = GetAC( oTarget ) - 10;
//KNOCKDOWN
iF1 = GetHasFeat( FEAT_KNOCKDOWN, oEnt );
iF2 = GetHasFeat( FEAT_IMPROVED_KNOCKDOWN, oEnt );
if ( iF1 || iF2 )
{
iFeat = 0;
if ( !GetHasFeatEffect( FEAT_KNOCKDOWN, oTarget ) && !GetHasFeatEffect( FEAT_IMPROVED_KNOCKDOWN, oTarget ) )
{
//figure out target's discipline
if ( iF2 ) //improved knockdown
{
//compare my improved knockdown attack roll to target's AC and Discipline check
if ( iMyAtk >= iEnemyAC && iMyAtk > iD )
{
iFeat = FEAT_IMPROVED_KNOCKDOWN;
}
}
else //no iF2 means we must have iF1
{
//compare my knockdown attack roll to target's AC and Discipline check
if ( DoCombatKnowledgeCheck( iT, 10 ) == FALSE || ( iMyAtk - 4 >= iEnemyAC && iMyAtk - 4 > iD ) )
{
iFeat = FEAT_KNOCKDOWN;
}
}
}
if ( iFeat )
{
SetLocalInt( oEnt, "#FEAT" + IntToString( ++iCnt ), iFeat );
}
}
//CALLED SHOT
if ( GetHasFeat( FEAT_CALLED_SHOT, oEnt ) )
{
iFeat = 0;
if ( DoCombatKnowledgeCheck( iT, 10 ) == FALSE || ( iMyAtk - 4 >= iEnemyAC && iMyAtk - 4 > iD ) )
{
iFeat = FEAT_CALLED_SHOT;
}
if ( iFeat )
{
SetLocalInt( oEnt, "#FEAT" + IntToString( ++iCnt ), iFeat );
}
}
//DISARM
iF1 = GetHasFeat( FEAT_DISARM, oEnt );
iF2 = GetHasFeat( FEAT_IMPROVED_DISARM, oEnt );
if ( iF1 || iF2 )
{
int iMod = 4 * GetRelativeEnemyWeaponSize( oTarget );
iFeat = 0;
if ( GetIsArmed( oTarget) )
{
if ( iF2 ) //improved disarm
{
if ( DoCombatKnowledgeCheck( iT, 10 ) == FALSE || ( iMyAtk - 4 + iMod >= iEnemyAC && iMyAtk - 4 + iMod > iD ) )
{
iFeat = FEAT_IMPROVED_DISARM;
}
}
else //disarm
{
if ( DoCombatKnowledgeCheck( iT, 10 ) == FALSE || ( iMyAtk - 6 + iMod >= iEnemyAC && iMyAtk - 6 + iMod > iD ) )
{
iFeat = FEAT_DISARM;
}
}
}
if ( iFeat )
{
SetLocalInt( oEnt, "#FEAT" + IntToString( ++iCnt ), iFeat );
}
}
//STUNNING FIST
if ( GetHasFeat( FEAT_STUNNING_FIST, oEnt ) && !GetHasFeatEffect( FEAT_STUNNING_FIST, oTarget ) &&
FloatToInt( NO_THRESH_STUNNING_FIST * GetHitDice( oEnt ) ) < GetHitDice( oTarget ) &&
( DoAbilityCheck( ABILITY_INTELLIGENCE, 10 ) == FALSE || !GetIsImmune( oTarget, IMMUNITY_TYPE_STUN ) ) )
{
iFeat = 0;
if ( DoCombatKnowledgeCheck( iT, 10 ) == FALSE || iMyAtk - 4 >= iEnemyAC )
{
iFeat = FEAT_STUNNING_FIST;
}
if ( iFeat )
{
SetLocalInt( oEnt, "#FEAT" + IntToString( ++iCnt ), iFeat );
}
}
//QUIVERING PALM
if ( GetHasFeat( FEAT_QUIVERING_PALM, oEnt ) &&
FloatToInt( NO_THRESH_QUIVERING_PALM * GetHitDice( oEnt ) ) < GetHitDice( oTarget ) &&
( DoAbilityCheck( ABILITY_INTELLIGENCE, 10 ) == FALSE || !GetIsImmune( oTarget, IMMUNITY_TYPE_DEATH ) ) )
{
iFeat = FEAT_QUIVERING_PALM;
SetLocalInt( oEnt, "#FEAT" + IntToString( ++iCnt ), iFeat );
}
//SMITE EVIL
if ( GetHasFeat( FEAT_SMITE_EVIL, oEnt ) && FloatToInt( NO_THRESH_SMITE * GetHitDice( oEnt ) ) < GetHitDice( oTarget ) &&
( DoAbilityCheck( ABILITY_INTELLIGENCE, 2 ) == FALSE || GetAlignmentGoodEvil( oTarget ) == ALIGNMENT_EVIL ) )
{
iFeat = FEAT_SMITE_EVIL;
SetLocalInt( oEnt, "#FEAT" + IntToString( ++iCnt ), iFeat );
}
//SMITE GOOD
//This feat definition was missing in nwscript pre-HotU, now it's in, uncommenting this block
if ( GetHasFeat( FEAT_SMITE_GOOD, oEnt ) && FloatToInt( NO_THRESH_SMITE * GetHitDice( oEnt ) ) < GetHitDice( oTarget ) &&
( DoAbilityCheck( ABILITY_INTELLIGENCE, 2 ) == FALSE || GetAlignmentGoodEvil( oTarget ) == ALIGNMENT_GOOD ) )
{
iFeat = FEAT_SMITE_GOOD;
SetLocalInt( oEnt, "#FEAT" + IntToString( ++iCnt ), iFeat );
}
//WHIRLWIND
iF1 = GetHasFeat( FEAT_WHIRLWIND_ATTACK, oEnt );
iF2 = GetHasFeat( FEAT_IMPROVED_WHIRLWIND, oEnt );
if ( iF1 || iF2 )
{
iFeat = 0;
if ( iF2 ) //improved whirlwind
{
//check to see if there are multiple enemies in melee range
//if so, check to see if there are at least as many as our number of attacks divided by 2
//tail end attacks probably miss anyway, so only count the top end of the attack sequence
//if there are enough, use whirlwind as we get full BAB on every attack with whirlwind
if ( GetHostileCount( 3.0 ) > GetBaseAttackBonus( oEnt ) / 10 )
{
iFeat = FEAT_IMPROVED_WHIRLWIND;
}
}
else //whirlwind
{
if ( GetHostileCount( 3.0 ) > GetBaseAttackBonus( oEnt ) / 10 )
{
iFeat = FEAT_WHIRLWIND_ATTACK;
}
}
if ( iFeat )
{
SetLocalInt( oEnt, "#FEAT" + IntToString( ++iCnt ), iFeat );
}
}
//KI DAMAGE
if ( GetHasFeat( FEAT_KI_DAMAGE, oEnt ) && FloatToInt( NO_THRESH_KI_DAMAGE * GetHitDice( oEnt ) ) < GetHitDice( oTarget ) )
{
iFeat = FEAT_KI_DAMAGE;
SetLocalInt( oEnt, "#FEAT" + IntToString( ++iCnt ), iFeat );
}
iFeat = GetLocalInt( oEnt, "#FEAT" + IntToString( Random( iCnt ) + 1 ) );
while ( iCnt )
{
DeleteLocalInt( oEnt, "#FEAT" + IntToString( iCnt-- ) );
}
return iFeat;
}
int SelectMeleeCombatModes( object oT, int iC=50, object oEnt=OBJECT_SELF )
{
int iPenalty = 0; //accumulate penalty from attack modes
int iMyAtk;
int iEnemyAtk;
int iMyAC;
int iEnemyAC;
int iF1;
int iF2;
int iCnt = 0;
int iMode;
int iT;
if ( !GetIsObjectValid( oT ) || Random( 100 ) > iC )
{
return 0;
}
iMyAtk = EstimateAttackBonus( oEnt );
iEnemyAtk = EstimateAttackBonus( oT );
iMyAC = GetAC( oEnt ) - 10;
iEnemyAC = GetAC( oT ) - 10;
//use either my intelligence or BAB to check for creature knowledge on some of these, whichever is better
//if iT == TRUE we will use BAB, otherwise use intelligence modifier
iT = GetBaseAttackBonus( OBJECT_SELF ) < GetAbilityModifier( ABILITY_INTELLIGENCE ) ? FALSE : TRUE;
//POWER ATTACK, IMPROVED POWER ATTACK
iF1 = GetHasFeat( FEAT_POWER_ATTACK, oEnt );
iF2 = GetHasFeat( FEAT_IMPROVED_POWER_ATTACK, oEnt );
if ( iF1 || iF2 )
{
iMode = 0;
if ( iF2 ) //improved power attack
{
if ( DoCombatKnowledgeCheck( iT, 10 ) == FALSE || iMyAtk - 10 >= iEnemyAC )
{
iMode = FEAT_IMPROVED_POWER_ATTACK;
}
}
if ( iF1 && iMode == 0 ) //we don't have or didn't choose improved power attack
{
if ( DoCombatKnowledgeCheck( iT, 10 ) == FALSE || iMyAtk - 5 >= iEnemyAC )
{
iMode = FEAT_POWER_ATTACK;
}
}
if ( iMode )
{
SetLocalInt( oEnt, "#COMBATMODE" + IntToString( ++iCnt ), iMode );
}
}
//FLURRY OF BLOWS
if ( GetHasFeat( FEAT_FLURRY_OF_BLOWS, oEnt ) )
{
iMode = 0;
if ( DoCombatKnowledgeCheck( iT, 10 ) == FALSE || iMyAtk - 2 >= iEnemyAC )
{
iMode = FEAT_FLURRY_OF_BLOWS;
}
if ( iMode )
{
SetLocalInt( oEnt, "#COMBATMODE" + IntToString( ++iCnt ), iMode );
}
}
//EXPERTISE, IMPROVED EXPERTISE
iF1 = GetHasFeat( FEAT_EXPERTISE, oEnt );
iF2 = GetHasFeat( FEAT_IMPROVED_EXPERTISE, oEnt );
if ( iF1 || iF2 )
{
iMode = 0;
if ( iF2 ) //improved expertise
{
//check if I can afford a -10 on attack, and if my enemy has a high enough attack to bother
if ( DoCombatKnowledgeCheck( iT, 10 ) == FALSE || ( iMyAtk - 10 >= iEnemyAC && iEnemyAtk >= iMyAC ) )
{
iMode = FEAT_IMPROVED_EXPERTISE;
}
}
if ( iF1 && iMode == 0 ) //we don't have or didn't choose improved expertise
{
//check if I can afford a -5 on attack, and if my enemy has a high enough attack to bother
if ( DoCombatKnowledgeCheck( iT, 10 ) == FALSE || ( iMyAtk - 5 >= iEnemyAC && iEnemyAtk >= iMyAC ) )
{
iMode = FEAT_EXPERTISE;
}
}
if ( iMode )
{
SetLocalInt( oEnt, "#COMBATMODE" + IntToString( ++iCnt ), iMode );
}
}
iMode = GetLocalInt( oEnt, "#COMBATMODE" + IntToString( Random( iCnt ) + 1 ) );
while ( iCnt )
{
DeleteLocalInt( oEnt, "#COMBATMODE" + IntToString( iCnt-- ) );
}
return iMode;
}

View File

@@ -0,0 +1,320 @@
#include "no_inc_ptypes"
//functions
void AddBehaviour( string sB, int iC, object oEnt=OBJECT_SELF )
{
int iL = GetLocalInt( oEnt, "PRITOTAL" ) + 1;
//update count
SetLocalInt( oEnt, "PRITOTAL", iL );
//make sure the chance is valid
iC = iC < 0 ? 0 : iC;
iC = iC > 100 ? 100 : iC;
//set up the behaviour
SetLocalString( oEnt, "PRID_" + IntToString( iL ), sB );
SetLocalInt( oEnt, "PRIC_" + IntToString( iL ), iC );
}
string GetPriority( int iP=1, object oEnt=OBJECT_SELF )
{
//retrieve priority iP
return GetLocalString( oEnt, "PRID_" + IntToString( iP ) );
}
int GetPriorityChance( int iP=1, object oEnt=OBJECT_SELF )
{
//retrieve priority chance iP
return GetLocalInt( oEnt, "PRIC_" + IntToString( iP ) );
}
void SetVoiceChat( int iV, int iC, object oE=OBJECT_SELF )
{
if ( iC < 0 )
{
iC = -1;
}
else if ( iC > 100 )
{
iC = 100;
}
if ( iV == NO_VC_DEFAULT )
{
if ( iC == 0 )
{
//delete the config for default voicechat chance
DeleteLocalInt( oE, "#VCC" );
}
else
{
//set the config for default voicechat chance
SetLocalInt( oE, "#VCC", iC );
}
}
else
{
if ( iC == 0 )
{
//delete the config for this voicechat chance
DeleteLocalInt( oE, "#VCC_" + IntToString( iV ) );
}
else
{
//set the config for this voicechat chance
SetLocalInt( oE, "#VCC_" + IntToString( iV ), iC );
}
}
}
float GetFollowDist( object oE=OBJECT_SELF )
{
float fF = -1.0;
if ( GetIsObjectValid( oE ) )
{
fF = GetLocalFloat( OBJECT_SELF, "#FOLLOWDIST" );
if ( fF == 0.0 )
{
//default distance if none is set
fF = 3.0;
}
}
return fF;
}
void SetPerceptionRange( int iP, float fP=50.0, object oE=OBJECT_SELF )
{
if ( iP == NO_PERCEPTION_SEEN )
{
SetLocalFloat( oE, "#PER_SEEN_RANGE", fP );
}
else if ( iP == NO_PERCEPTION_HEARD )
{
SetLocalFloat( oE, "#PER_HEARD_RANGE", fP );
}
else if ( iP == NO_PERCEPTION_VANISHED )
{
SetLocalFloat( oE, "#PER_VANISHED_RANGE", fP );
}
}
void SetPerceptionRanges( float fS=50.0, float fH=50.0, float fV=50.0, object oE=OBJECT_SELF )
{
if ( fS != -1.0 )
{
SetLocalFloat( oE, "#PER_SEEN_RANGE", fS );
}
if ( fH != -1.0 )
{
SetLocalFloat( oE, "#PER_HEARD_RANGE", fH );
}
if ( fV != -1.0 )
{
SetLocalFloat( oE, "#PER_VANISHED_RANGE", fV );
}
}
float GetPerceptionRange( int iP, object oE=OBJECT_SELF )
{
float fP = 0.0;
if ( iP == NO_PERCEPTION_SEEN )
{
fP = GetLocalFloat( oE, "#PER_SEEN_RANGE" );
}
else if ( iP == NO_PERCEPTION_HEARD )
{
fP = GetLocalFloat( oE, "#PER_HEARD_RANGE" );
}
else if ( iP == NO_PERCEPTION_VANISHED )
{
fP = GetLocalFloat( oE, "#PER_VANISHED_RANGE" );
}
//set max range if no setting found
if ( fP == 0.0 )
{
fP = 50.0;
}
return fP;
}
void SetReadyStatus( int iS=1, object oE=OBJECT_SELF )
{
SetLocalInt( oE, "#READYTOACT", iS );
}
int IsReadyToAct( object oE=OBJECT_SELF )
{
return GetLocalInt( oE, "#READYTOACT" );
}
int ShortAction( object oE=OBJECT_SELF )
{
string sAct = GetLastAction( oE );
if ( sAct == "+EVACAOE" || sAct == "+REGROUP" || sAct == "+AVOIDMELEE" || sAct == "+FLANK" || sAct == "+AVOIDENEMY" )
//|| sAct == "+EYERAYS" )
{
return TRUE;
}
return FALSE;
}
int IsActive( object oE=OBJECT_SELF )
{
return GetLocalInt( oE, "#ACTIVE" );
}
void SetActive( object oE=OBJECT_SELF )
{
SetLocalInt( OBJECT_SELF, "#ACTIVE", 1 );
}
void SetIsActive( int iA=TRUE, object oE=OBJECT_SELF )
{
if ( iA == TRUE )
{
SetLocalInt( oE, "#ACTIVE", 1 );
}
else
{
DeleteLocalInt( oE, "#ACTIVE" );
}
}
float GetResponseRange( int iT, object oE=OBJECT_SELF )
{
float fR = GetLocalFloat( oE, "#RESPOND_RANGE_" + IntToString( iT ) );
if ( fR == 0.0 )
{
//default range
fR = 50.0;
}
return fR;
}
void SetResponseRange( int iT, float fR=50.0, object oE=OBJECT_SELF )
{
float fRange = fR > 0.0 ? fR : 0.0;
SetLocalFloat( oE, "#RESPOND_RANGE_" + IntToString( iT ), fRange );
}
void SetIsTeleporter( object oE=OBJECT_SELF )
{
SetLocalInt( OBJECT_SELF, "TELEPORTER", 1 );
}
int GetIsTeleporter( object oE=OBJECT_SELF )
{
return GetLocalInt( OBJECT_SELF, "TELEPORTER" );
}
void SetIsFastBuffer( int iS, object oE=OBJECT_SELF )
{
if ( iS == 1 )
{
SetLocalInt( oE, "#FASTBUFFER", 1 );
}
else
{
DeleteLocalInt( oE, "#FASTBUFFER" );
}
}
int GetIsFastBuffer( object oE=OBJECT_SELF )
{
return GetLocalInt( oE, "#FASTBUFFER" );
}
void SetIsFastBuffed( int iS, object oE=OBJECT_SELF )
{
if ( iS == 1 )
{
SetLocalInt( oE, "#FASTBUFFED", 1 );
}
else
{
DeleteLocalInt( oE, "#FASTBUFFED" );
}
}
int GetIsFastBuffed( object oE=OBJECT_SELF )
{
return GetLocalInt( oE, "#FASTBUFFED" );
}
void AddFastBuff( int iS, object oE=OBJECT_SELF )
{
int iC = CountFastBuffs( oE ) + 1;
SetLocalInt( oE, "#SPN_FB" + IntToString( iC ), iS );
}
int CountFastBuffs( object oE=OBJECT_SELF )
{
int iC = 0;
int iS = 1;
while ( GetLocalInt( oE, "#SPN_FB" + IntToString( iS++ ) ) != 0 )
{
iC++;
}
return iC;
}
void SetLastAction( string sA, object oE=OBJECT_SELF )
{
SetLocalString( oE, "#LASTACTION", sA );
}
string GetLastAction( object oE=OBJECT_SELF )
{
return GetLocalString( oE, "#LASTACTION" );
}
void SetLastActionTimestamp( object oE=OBJECT_SELF )
{
SetLocalInt( oE, "#LASTACTIONTIME", GetTimeSecond() );
}
int GetLastActionTimestamp( object oE=OBJECT_SELF )
{
int iS = GetLocalInt( oE, "#LASTACTIONTIME" );
int iT = GetTimeSecond();
int iL = iT < iS ? iT + 60 : iT;
return iL - iS;
}
void SetCorpseDelay( int iT=60, object oC=OBJECT_SELF )
{
if ( GetRacialType( oC ) != RACIAL_TYPE_UNDEAD && GetStringLeft( GetTag( oC ), 6 ) != "NO_AI_" &&
GetName( GetItemInSlot( INVENTORY_SLOT_CARMOUR, oC ) ) != "Gargoyle Properties" )
{
//not summoned, not undead, default decay time
AssignCommand( oC, SetIsDestroyable( FALSE, TRUE, TRUE ) );
SetLocalFloat( oC, "#DECAYDELAY", 60.0 ); //default corpse decay time
}
}
void SetIsFlier( int iF=FALSE, object oF=OBJECT_SELF )
{
if ( iF == TRUE || GetRacialType( oF ) == RACIAL_TYPE_DRAGON )
{
SetLocalInt( oF, "FLIER", 1 );
}
else
{
DeleteLocalInt( oF, "FLIER" );
}
}
int GetIsFlier( object oF=OBJECT_SELF )
{
return GetLocalInt( oF, "FLIER" );
}

View File

@@ -0,0 +1,172 @@
#include "no_inc_ptypes"
//functions
int GetBestRangedSpecial( object oTarget, int iPenalty=0, int iChance=50, object oEnt=OBJECT_SELF )
{
int iCnt = 0;
int iFeat;
int iMyAtk;
int iEnemyAtk;
int iMyAC;
int iEnemyAC;
int iF1;
int iF2;
int iD;
int iT;
if ( !GetIsObjectValid( oTarget ) || Random( 100 ) > iChance )
{
return 0;
}
iD = GetSkillRank( SKILL_DISCIPLINE, oTarget ) + GetAbilityModifier( ABILITY_STRENGTH, oTarget ) + 3 * GetHasFeat( FEAT_SKILL_FOCUS_DISCIPLINE, oTarget );
iMyAtk = EstimateAttackBonus( oEnt ) + iPenalty; //include penalty from active combat mode if any
//iEnemyAtk = EstimateAttackBonus( oTarget );
//iMyAC = GetAC( oEnt ) - 10;
iEnemyAC = GetAC( oTarget ) - 10;
//use either my intelligence or BAB to check for creature knowledge on some of these, whichever is better
//if iT == TRUE we will use BAB, otherwise use intelligence modifier
iT = GetBaseAttackBonus( OBJECT_SELF ) < GetAbilityModifier( ABILITY_INTELLIGENCE ) ? FALSE : TRUE;
//CALLED SHOT
if ( GetHasFeat( FEAT_CALLED_SHOT, oEnt ) )
{
iFeat = 0;
if ( DoCombatKnowledgeCheck( iT, 10 ) == FALSE || ( iMyAtk - 4 >= iEnemyAC && iMyAtk - 4 > iD ) )
{
iFeat = FEAT_CALLED_SHOT;
}
if ( iFeat )
{
SetLocalInt( oEnt, "#FEAT" + IntToString( ++iCnt ), iFeat );
}
}
//SEEKER ARROW
// Arcane Archer feats are not defined in nwscript?
// FIX: They are in HotU but not SoU. When updating these for HotU update this block and add the rest.
iF1 = GetHasFeat( FEAT_PRESTIGE_SEEKER_ARROW_1, oEnt );
iF2 = GetHasFeat( FEAT_PRESTIGE_SEEKER_ARROW_2, oEnt );
if ( iF1 || iF2 )
{
iFeat = 0;
if ( iMyAtk + 8 < iEnemyAC ) //if I can't hit even with a high roll use a seeker arrow
{
if ( iF2 )
{
iFeat = FEAT_PRESTIGE_SEEKER_ARROW_2;
}
else
{
iFeat = FEAT_PRESTIGE_SEEKER_ARROW_1;
}
}
if ( iFeat )
{
SetLocalInt( oEnt, "#FEAT" + IntToString( ++iCnt ), iFeat );
}
}
//IMBUE ARROW
if ( GetHasFeat( FEAT_PRESTIGE_IMBUE_ARROW, oEnt ) )
{
iFeat = 0;
if ( GetAllyCount( RADIUS_SIZE_HUGE, oTarget, oEnt ) > GetHostileCount( RADIUS_SIZE_HUGE, oTarget, oEnt ) )
{
iFeat = FEAT_PRESTIGE_IMBUE_ARROW;
}
if ( iFeat )
{
SetLocalInt( oEnt, "#FEAT" + IntToString( ++iCnt ), iFeat );
}
}
//HAIL OF ARROWS
if ( GetHasFeat( FEAT_PRESTIGE_HAIL_OF_ARROWS, oEnt ) )
{
iFeat = 0;
if ( GetHostileCount( 30.0 ) > GetBaseAttackBonus( oEnt ) / 10 )
{
iFeat = FEAT_PRESTIGE_HAIL_OF_ARROWS;
}
if ( iFeat )
{
SetLocalInt( oEnt, "#FEAT" + IntToString( ++iCnt ), iFeat );
}
}
//ARROW OF SLAYING
if ( GetHasFeat( FEAT_PRESTIGE_ARROW_OF_DEATH, oEnt ) )
{
iFeat = 0;
if ( FloatToInt( NO_THRESH_ARROW_SLAYING * GetHitDice( oEnt ) ) < GetHitDice( oTarget ) &&
( DoAbilityCheck( ABILITY_INTELLIGENCE, 10 ) == FALSE || GetIsImmune( oTarget, IMMUNITY_TYPE_DEATH ) == FALSE ) )
{
//target has sufficient hit dice to warrant use of an arrow of death
//either oEnt failed its intelligence check or it passed and determined that target is not immune to death effects
iFeat = FEAT_PRESTIGE_ARROW_OF_DEATH;
}
if ( iFeat )
{
SetLocalInt( oEnt, "#FEAT" + IntToString( ++iCnt ), iFeat );
}
}
//randomly select one of the feats that was deemed suitable for use
iFeat = GetLocalInt( oEnt, "#FEAT" + IntToString( Random( iCnt ) + 1 ) );
while ( iCnt )
{
DeleteLocalInt( oEnt, "#FEAT" + IntToString( iCnt-- ) );
}
return iFeat;
}
int SelectRangedCombatModes( object oT, int iC=50, object oEnt=OBJECT_SELF )
{
int iPenalty = 0; //accumulate penalty from attack modes
int iMyAtk;
//int iEnemyAtk;
//int iMyAC;
int iEnemyAC;
int iF1;
int iF2;
int iCnt = 0;
int iMode;
int iT;
if ( !GetIsObjectValid( oT ) || Random( 100 ) > iC )
{
return 0;
}
iMyAtk = EstimateAttackBonus( oEnt );
//iEnemyAtk = EstimateAttackBonus( oT );
//iMyAC = GetAC( oEnt ) - 10;
iEnemyAC = GetAC( oT ) - 10;
//use either my intelligence or BAB to check for creature knowledge on some of these, whichever is better
//if iT == TRUE we will use BAB, otherwise use intelligence modifier
iT = GetBaseAttackBonus( OBJECT_SELF ) < GetAbilityModifier( ABILITY_INTELLIGENCE ) ? FALSE : TRUE;
//RAPID SHOT
if ( GetHasFeat( FEAT_RAPID_SHOT, oEnt ) )
{
iMode = 0;
if ( DoCombatKnowledgeCheck( iT, 10 ) == FALSE || ( iMyAtk - 2 >= iEnemyAC ) )
{
iMode = FEAT_RAPID_SHOT;
}
if ( iMode )
{
SetLocalInt( oEnt, "#COMBATMODE" + IntToString( ++iCnt ), iMode );
}
}
iMode = GetLocalInt( oEnt, "#COMBATMODE" + IntToString( Random( iCnt ) + 1 ) );
while ( iCnt )
{
DeleteLocalInt( oEnt, "#COMBATMODE" + IntToString( iCnt-- ) );
}
return iMode;
}

View File

@@ -0,0 +1,5 @@
void main()
{
SetListening( OBJECT_SELF, TRUE );
SetAssociateListenPatterns( OBJECT_SELF );
}

View File

@@ -0,0 +1,108 @@
#include "no_lib_priority"
void main()
{
//clean up variables on dying creature
int iCnt;
//don't proceed if we're alive again
if ( GetIsDead( OBJECT_SELF ) || GetLocalInt( OBJECT_SELF, "TEMPDIE" ) )
{
//clear teleporter status variable
DeleteLocalInt( OBJECT_SELF, "TELEPORTER" );
//clear balor death throes variable
DeleteLocalInt( OBJECT_SELF, "BALORDEATH" );
//clear dragon flight variables
DeleteLocalInt( OBJECT_SELF, "FLIER" );
DeleteLocalInt( OBJECT_SELF, "DRAGONFLIGHTDEL" );
//dragon fear variable
DeleteLocalInt( OBJECT_SELF, "#DRAGFEAR" );
//clear caster flag
DeleteLocalInt( OBJECT_SELF, "#CASTER" );
//clear avoid melee trackers
DeleteLocalLocation( OBJECT_SELF, "#LASTHOTSPOT" );
DeleteLocalFloat( OBJECT_SELF, "#LASTAMANGLE" );
DeleteLocalInt( OBJECT_SELF, "#LASTHSRETRIES" );
DeleteLocalInt( OBJECT_SELF, "#LASTDEST" );
DeleteLocalLocation( OBJECT_SELF, "#LASTDEST" );
//clear dragon breath weapon delay flag
DeleteLocalInt( OBJECT_SELF, "#BDEL" );
//clear BC_HEAL anti-spam flag
DeleteLocalInt( OBJECT_SELF, "#HEALDEL" );
//delete combat setting
DeleteLocalInt( OBJECT_SELF, "#INCOMBAT" );
//delete last combat round end broadcast timestamp
DeleteLocalInt( OBJECT_SELF, "#LASTCREBC" );
//clear tail of summon chain variable
DeleteLocalObject( OBJECT_SELF, "MASTCHAIN" );
//clear vision flags
DeleteLocalInt( OBJECT_SELF, "#DARKNESS" );
DeleteLocalInt( OBJECT_SELF, "#VANISHED" );
DeleteLocalObject( OBJECT_SELF, "#VISION" );
//clear last rest marker
DeleteLocalInt( OBJECT_SELF, "#LASTREST" );
//clear fast buffer markers
DeleteLocalInt( OBJECT_SELF, "#FASTBUFFER" );
DeleteLocalInt( OBJECT_SELF, "#FASTBUFFED" );
//delete activity marker
DeleteLocalInt( OBJECT_SELF, "#ACTIVE" );
DeleteLocalInt( OBJECT_SELF, "#QUEUESHUTDOWN" );
//delete logged spawn point
DeleteLocalInt( OBJECT_SELF, "#RETSPNLOC" );
DeleteLocalLocation( OBJECT_SELF, "#SPAWNLOC" );
//delete stand ground variables
DeleteLocalInt( OBJECT_SELF, "#STANDGROUND" );
DeleteLocalLocation( OBJECT_SELF, "#SGLOC" );
//delete corpse decay delay variable
DeleteLocalFloat( OBJECT_SELF, "#DECAYDELAY" );
//clear spell list and fastbuff list
//these shouldn't be necessary, but just in case there is an interruption
iCnt = 1;
while ( GetLocalInt( OBJECT_SELF, "#SPL_" + IntToString( iCnt ) ) )
{
DeleteLocalInt( OBJECT_SELF, "#SPL_" + IntToString( iCnt++ ) );
}
iCnt = 1;
while ( GetLocalInt( OBJECT_SELF, "#SPL_FB" + IntToString( iCnt ) ) )
{
DeleteLocalInt( OBJECT_SELF, "#SPL_FB" + IntToString( iCnt++ ) );
}
iCnt = 1;
while ( GetLocalInt( OBJECT_SELF, "#SPN_FB" + IntToString( iCnt ) ) )
{
DeleteLocalInt( OBJECT_SELF, "#SPN_FB" + IntToString( iCnt++ ) );
}
iCnt = 1;
while ( GetLocalInt( OBJECT_SELF, "#FEAT_" + IntToString( iCnt ) ) )
{
DeleteLocalInt( OBJECT_SELF, "#FEAT_" + IntToString( iCnt++ ) );
}
//clear priority lists
DeleteLocalInt( OBJECT_SELF, "PRITOTAL" );
iCnt = 1;
while ( GetLocalInt( OBJECT_SELF, "PRIC_" + IntToString( iCnt ) ) )
{
DeleteLocalString( OBJECT_SELF, "PRID_" + IntToString( iCnt ) );
DeleteLocalInt( OBJECT_SELF, "PRIC_" + IntToString( iCnt++ ) );
}
}
}

View File

@@ -0,0 +1,13 @@
void main()
{
//don't proceed if we're alive again
if ( GetIsDead( OBJECT_SELF ) || GetLocalInt( OBJECT_SELF, "TEMPDIE" ) )
{
//clear death marker
DeleteLocalInt( OBJECT_SELF, "TEMPDIE" );
//time to die
SetIsDestroyable( TRUE, FALSE, FALSE );
DestroyObject( OBJECT_SELF );
}
}

View File

@@ -0,0 +1,14 @@
void main()
{
object oL = GetItemInSlot( INVENTORY_SLOT_LEFTHAND );
object oR = GetItemInSlot( INVENTORY_SLOT_RIGHTHAND );
if ( GetIsObjectValid( oL ) )
{
SetLocalObject( OBJECT_SELF, "LHAND", oL );
}
if ( GetIsObjectValid( oR ) )
{
SetLocalObject( OBJECT_SELF, "RHAND", oR );
}
}

View File

@@ -0,0 +1,5 @@
void main()
{
SetLocalInt( OBJECT_SELF, "#RETSPNLOC", 1 );
SetLocalLocation( OBJECT_SELF, "#SPAWNLOC", GetLocation( OBJECT_SELF ) );
}

View File

@@ -0,0 +1,72 @@
//::///////////////////////////////////////////////
//:: Shutdown
//::
//:://////////////////////////////////////////////
/*
This script will shutdown the combat AI.
*/
//:://////////////////////////////////////////////
#include "no_lib_data"
#include "no_inc"
void main()
{
int iCnt = GetLocalInt( OBJECT_SELF, "#QUEUESHUTDOWN" );
int iCombat = 0;
//object oEnemy;
int iRestWait = 30;
//delete queue marker
DeleteLocalInt( OBJECT_SELF, "#QUEUESHUTDOWN" );
//SpeakString( "CFS" );
//if ( !GetIsInCombat() && GetLocalInt( OBJECT_SELF, "#ACTIVE" ) && !IsInConversation( OBJECT_SELF ) )
if ( !IsInConversation( OBJECT_SELF ) )
{
//oEnemy = GetNearestCreature( CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_IS_ALIVE, TRUE );
int iE = GetHostileCount( 50.0 );
if ( iE )
{
InitCombat();
}
else
{
if ( GetIsObjectValid( GetMaster( OBJECT_SELF ) ) )
{
DeleteLocalInt( OBJECT_SELF, "#FASTBUFFED" );
DeleteLocalInt( OBJECT_SELF, "#QUEUESHUTDOWN" );
DeleteLocalInt( OBJECT_SELF, "#ACTIVE" );
DeleteLocalInt( OBJECT_SELF, "#VANISHED" );
//SetReadyStatus();
ActionForceFollowObject( GetMaster( OBJECT_SELF ), 3.0 );
return;
}
//else if ( !GetLocalInt( OBJECT_SELF, "#LASTREST" ) && GetTimeSinceLastCombat() > iRestWait )
else if ( GetTimeSinceLastCombat() > iRestWait )
{
//PrintString( "RESTING: " + GetName( OBJECT_SELF ) );
DeleteLocalInt( OBJECT_SELF, "#FASTBUFFED" );
DeleteLocalInt( OBJECT_SELF, "#QUEUESHUTDOWN" );
DeleteLocalInt( OBJECT_SELF, "#ACTIVE" ); //shutdown AI heartbeats until an opponent shows up
DeleteLocalInt( OBJECT_SELF, "#VANISHED" );
//SetReadyStatus();
if ( !GetLocalInt( OBJECT_SELF, "#LASTREST" ) )
{
ActionRest(); //no enemies seen for 30 seconds, rest
SetLocalInt( OBJECT_SELF, "#LASTREST", 1 );
}
ActionDoCommand( WalkWayPoints() ); //start walking waypoints if applicable
return;
}
if ( !GetLocalInt( OBJECT_SELF, "#QUEUESHUTDOWN" ) && GetLocalInt( OBJECT_SELF, "#ACTIVE" ) )
{
//DelayCommand( 12.0, ExecuteScript( "no_scr_shutdown", OBJECT_SELF ) );
DoQueueShutdown( 12.0 );
return;
}
}
}
}

121
_module/nss/no_spn_beh.nss Normal file
View File

@@ -0,0 +1,121 @@
//::///////////////////////////////////////////////
//:: On Spawn In
//::
//:://////////////////////////////////////////////
/*
Determines the course of action to be taken
after having just been spawned in
*/
//:://////////////////////////////////////////////
#include "no_lib_data"
#include "no_inc"
#include "nw_o2_coninclude"
#include "x0_i0_treasure"
void main()
{
//Behaviour config
AddBehaviour( "+AVOIDMELEE", 50 ); //avoid melee
AddBehaviour( "+EVACAOE", 80 ); //evac AOEs
AddBehaviour( "+HEALSELF", 100 ); //heal self
AddBehaviour( "+REGROUP", 20 ); //regroup
AddBehaviour( "+FEATENHANCE", 10 ); //enhance self via feats
AddBehaviour( "+CENTRALEYE", 10 ); //beholder antimagic cone
AddBehaviour( "+EYERAYS", 100 ); //beholder eye rays
AddBehaviour( "+ATKMELEE", 100 ); //melee attack
//Other config
//Corpse decay set up and exclusions
SetCorpseDelay();
//Set whether the creature can use EffectDisappearAppear when moving
SetIsFlier();
if ( GetIsObjectValid( GetMaster( OBJECT_SELF ) ) )
{
//I am probably a summoned creature, possibly a henchman
SetAssociateListenPatterns();
}
//set voice chat config
SetVoiceChat( NO_VC_DEFAULT, 10 );
//configure perception ranges
SetPerceptionRanges();
//set response range for fighting broadcast
SetResponseRange( BC_FIGHTING, 50.0 );
//tell creature it is ready to act
//SetReadyStatus();
//set fastbuffer status, should always be left on
SetIsFastBuffer( TRUE );
//SetLocalInt( OBJECT_SELF, "#FASTBUFFER", 1 );
//SetLocalInt( OBJECT_SELF, "#ACTIVE", 1 );
//log starting location
ExecuteScript( "no_scr_logspnloc", OBJECT_SELF );
//log loaded melee weapons
ExecuteScript( "no_scr_logeq", OBJECT_SELF );
// OPTIONAL BEHAVIORS (Comment In or Out to Activate ) ****************************************************************************
//SetSpawnInCondition(NW_FLAG_SPECIAL_CONVERSATION);
//SetSpawnInCondition(NW_FLAG_SPECIAL_COMBAT_CONVERSATION);
// This causes the creature to say a special greeting in their conversation file
// upon Perceiving the player. Attach the [NW_D2_GenCheck.nss] script to the desired
// greeting in order to designate it. As the creature is actually saying this to
// himself, don't attach any player responses to the greeting.
//SetSpawnInCondition(NW_FLAG_SHOUT_ATTACK_MY_TARGET);
// This will set the listening pattern on the NPC to attack when allies call
//SetSpawnInCondition(NW_FLAG_STEALTH);
// If the NPC has stealth and they are a rogue go into stealth mode
//SetSpawnInCondition(NW_FLAG_SEARCH);
// If the NPC has Search go into Search Mode
//SetSpawnInCondition(NW_FLAG_SET_WARNINGS);
// This will set the NPC to give a warning to non-enemies before attacking
//SetSpawnInCondition(NW_FLAG_SLEEP);
//Creatures that spawn in during the night will be asleep.
//SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING);
//SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION);
//SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS);
SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS);
// SetAnimationCondition(NW_ANIM_FLAG_IS_CIVILIZED);
SetAnimationCondition(NW_ANIM_FLAG_CONSTANT);
// SetAnimationCondition(NW_ANIM_FLAG_CHATTER);
// SetAnimationCondition(NW_ANIM_FLAG_IS_MOBILE_CLOSE_RANGE);
//This will play Ambient Animations until the NPC sees an enemy or is cleared.
//NOTE that these animations will play automatically for Encounter Creatures.
// NOTE: ONLY ONE OF THE FOLOOWING ESCAPE COMMANDS SHOULD EVER BE ACTIVATED AT ANY ONE TIME.
//SetSpawnInCondition(NW_FLAG_ESCAPE_RETURN); // OPTIONAL BEHAVIOR (Flee to a way point and return a short time later.)
//SetSpawnInCondition(NW_FLAG_ESCAPE_LEAVE); // OPTIONAL BEHAVIOR (Flee to a way point and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_LEAVE); // OPTIONAL BEHAVIOR (Teleport to safety and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_RETURN); // OPTIONAL BEHAVIOR (Teleport to safety and return a short time later.)
// CUSTOM USER DEFINED EVENTS
/*
The following settings will allow the user to fire one of the blank user defined events in the NW_D2_DefaultD. Like the
On Spawn In script this script is meant to be customized by the end user to allow for unique behaviors. The user defined
events user 1000 - 1010
*/
//SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1001
//SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1002
//SetSpawnInCondition(NW_FLAG_ATTACK_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1005
//SetSpawnInCondition(NW_FLAG_DAMAGED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1006
//SetSpawnInCondition(NW_FLAG_DISTURBED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1008
//SetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1003
//SetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1004
//SetSpawnInCondition(NW_FLAG_DEATH_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1007
SetListeningPatterns(); // Goes through and sets up which shouts the NPC will listen to.
WalkWayPoints(); // Optional Parameter: void WalkWayPoints(int nRun = FALSE, float fPause = 1.0)
// 1. Looks to see if any Way Points in the module have the tag "WP_" + NPC TAG + "_0X", if so walk them
// 2. If the tag of the Way Point is "POST_" + NPC TAG the creature will return this way point after
// combat.
CTG_GenerateNPCTreasure(TREASURE_TYPE_MONSTER, OBJECT_SELF); //* Use this to create a small amount of treasure on the creature
}

157
_module/nss/no_spn_clr.nss Normal file
View File

@@ -0,0 +1,157 @@
//::///////////////////////////////////////////////
//:: On Spawn In
//::
//:://////////////////////////////////////////////
/*
Determines the course of action to be taken
after having just been spawned in
*/
//:://////////////////////////////////////////////
#include "no_lib_data"
#include "no_inc"
#include "nw_o2_coninclude"
void main()
{
//Behaviour config
AddBehaviour( "+HEALSELF", 100 );
AddBehaviour( "+REGROUP", 80 );
AddBehaviour( "+FLANK", 20 );
AddBehaviour( "+SUMMON", 40 );
AddBehaviour( "+RAISE", 60 );
AddBehaviour( "+GROUPHEAL", 60 );
AddBehaviour( "+HELP", 60 );
AddBehaviour( "+HEAL", 60 );
AddBehaviour( "+VIS", 60 );
AddBehaviour( "+DEFSELF", 40 );
AddBehaviour( "+DEFSING", 40 );
AddBehaviour( "+GROUPENHANCE", 40 );
AddBehaviour( "+ENHANCESING", 40 );
AddBehaviour( "+ENHANCESELF", 40 );
AddBehaviour( "+FEATENHANCE", 40 );
AddBehaviour( "+DISPEL", 40 );
AddBehaviour( "+DISPELAOE", 40 );
AddBehaviour( "+DISMISSAL", 40 );
AddBehaviour( "+TURN", 40 );
AddBehaviour( "+AREA", 40 );
AddBehaviour( "+DIRECT", 40 );
AddBehaviour( "+TOUCH", 40 );
AddBehaviour( "+EVACAOE", 50 );
AddBehaviour( "+ATKMELEE", 100 );
//Other config
//Corpse decay set up and exclusions
SetCorpseDelay();
/*
if ( GetRacialType( OBJECT_SELF ) != RACIAL_TYPE_UNDEAD && GetStringLeft( GetTag( OBJECT_SELF ), 6 ) != "NO_AI_" &&
GetName( GetItemInSlot( INVENTORY_SLOT_CARMOUR, OBJECT_SELF ) ) != "Gargoyle Properties" )
{
//not summoned, not undead, default decay time
SetIsDestroyable( FALSE, TRUE, TRUE );
SetLocalFloat( OBJECT_SELF, "#DECAYDELAY", 60.0 ); //default corpse decay time
}
*/
/*
SetListening( OBJECT_SELF, TRUE );
SetListenPattern( OBJECT_SELF, "BC_DEAD", 691 );
SetListenPattern( OBJECT_SELF, "BC_FIGHTING", 699 );
*/
if ( GetName( GetItemInSlot( INVENTORY_SLOT_CARMOUR, OBJECT_SELF ) ) == "Balor Properties" )
{
SetLocalInt( OBJECT_SELF, "BALORDEATH", 1 );
}
if ( GetRacialType( OBJECT_SELF ) == RACIAL_TYPE_DRAGON )
{
SetLocalInt( OBJECT_SELF, "FLIER", 1 );
}
if ( GetIsObjectValid( GetMaster( OBJECT_SELF ) ) )
{
//I am probably a summoned creature, possibly a henchman
SetAssociateListenPatterns();
}
//set voice chat config
SetVoiceChat( NO_VC_DEFAULT, 10 );
//configure perception ranges
SetPerceptionRanges();
//set response range for fighting broadcast
SetResponseRange( BC_FIGHTING, 50.0 );
//tell creature it is ready to act
//SetReadyStatus();
//set fastbuffer status, should always be left on
SetIsFastBuffer( TRUE );
//SetLocalInt( OBJECT_SELF, "#FASTBUFFER", 1 );
//log starting location
ExecuteScript( "no_scr_logspnloc", OBJECT_SELF );
//log loaded melee weapons
ExecuteScript( "no_scr_logeq", OBJECT_SELF );
// OPTIONAL BEHAVIORS (Comment In or Out to Activate ) ****************************************************************************
//SetSpawnInCondition(NW_FLAG_SPECIAL_CONVERSATION);
//SetSpawnInCondition(NW_FLAG_SPECIAL_COMBAT_CONVERSATION);
// This causes the creature to say a special greeting in their conversation file
// upon Perceiving the player. Attach the [NW_D2_GenCheck.nss] script to the desired
// greeting in order to designate it. As the creature is actually saying this to
// himself, don't attach any player responses to the greeting.
//SetSpawnInCondition(NW_FLAG_SHOUT_ATTACK_MY_TARGET);
// This will set the listening pattern on the NPC to attack when allies call
//SetSpawnInCondition(NW_FLAG_STEALTH);
// If the NPC has stealth and they are a rogue go into stealth mode
//SetSpawnInCondition(NW_FLAG_SEARCH);
// If the NPC has Search go into Search Mode
//SetSpawnInCondition(NW_FLAG_SET_WARNINGS);
// This will set the NPC to give a warning to non-enemies before attacking
//SetSpawnInCondition(NW_FLAG_SLEEP);
//Creatures that spawn in during the night will be asleep.
//SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING);
//SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION);
//SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS);
SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS);
// SetAnimationCondition(NW_ANIM_FLAG_IS_CIVILIZED);
SetAnimationCondition(NW_ANIM_FLAG_CONSTANT);
// SetAnimationCondition(NW_ANIM_FLAG_CHATTER);
// SetAnimationCondition(NW_ANIM_FLAG_IS_MOBILE_CLOSE_RANGE);
//This will play Ambient Animations until the NPC sees an enemy or is cleared.
//NOTE that these animations will play automatically for Encounter Creatures.
// NOTE: ONLY ONE OF THE FOLOOWING ESCAPE COMMANDS SHOULD EVER BE ACTIVATED AT ANY ONE TIME.
//SetSpawnInCondition(NW_FLAG_ESCAPE_RETURN); // OPTIONAL BEHAVIOR (Flee to a way point and return a short time later.)
//SetSpawnInCondition(NW_FLAG_ESCAPE_LEAVE); // OPTIONAL BEHAVIOR (Flee to a way point and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_LEAVE); // OPTIONAL BEHAVIOR (Teleport to safety and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_RETURN); // OPTIONAL BEHAVIOR (Teleport to safety and return a short time later.)
// CUSTOM USER DEFINED EVENTS
/*
The following settings will allow the user to fire one of the blank user defined events in the NW_D2_DefaultD. Like the
On Spawn In script this script is meant to be customized by the end user to allow for unique behaviors. The user defined
events user 1000 - 1010
*/
//SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1001
//SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1002
//SetSpawnInCondition(NW_FLAG_ATTACK_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1005
//SetSpawnInCondition(NW_FLAG_DAMAGED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1006
//SetSpawnInCondition(NW_FLAG_DISTURBED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1008
//SetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1003
//SetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1004
//SetSpawnInCondition(NW_FLAG_DEATH_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1007
SetListeningPatterns(); // Goes through and sets up which shouts the NPC will listen to.
WalkWayPoints(); // Optional Parameter: void WalkWayPoints(int nRun = FALSE, float fPause = 1.0)
// 1. Looks to see if any Way Points in the module have the tag "WP_" + NPC TAG + "_0X", if so walk them
// 2. If the tag of the Way Point is "POST_" + NPC TAG the creature will return this way point after
// combat.
GenerateNPCTreasure(); //* Use this to create a small amount of treasure on the creature
}

View File

@@ -0,0 +1,135 @@
//::///////////////////////////////////////////////
//:: On Spawn In
//::
//:://////////////////////////////////////////////
/*
Determines the course of action to be taken
after having just been spawned in
*/
//:://////////////////////////////////////////////
#include "no_lib_data"
#include "no_inc"
#include "nw_o2_coninclude"
#include "x0_i0_treasure"
void main()
{
//Behaviour config
AddBehaviour( "+HEALSELF", 100 ); //heal self
AddBehaviour( "+REGROUP", 40 ); //regroup
AddBehaviour( "+FLANK", 10 ); //flank
AddBehaviour( "+AVOIDMELEE", 10 ); //avoid melee
AddBehaviour( "+EVACAOE", 20 ); //evac AOEs
AddBehaviour( "+SUMMON", 20 ); //summon spells
AddBehaviour( "+HELP", 40 ); //help
AddBehaviour( "+VIS", 40 ); //vision
AddBehaviour( "+DEFSING", 10 ); //defend single
AddBehaviour( "+DEFSELF", 10 ); //defend self
AddBehaviour( "+GROUPENHANCE", 10 ); //enhance group
AddBehaviour( "+ENHANCESING", 10 ); //enhance single
AddBehaviour( "+ENHANCESELF", 10 ); //enhance self
AddBehaviour( "+FEATENHANCE", 10 ); //enhance self via feats
AddBehaviour( "+DISPEL", 10 ); //dispel single
AddBehaviour( "+DISPELAOE", 10 ); //dispel AOEs
AddBehaviour( "+DISMISSAL", 10 ); //dismiss summons
AddBehaviour( "+BREACH", 10 ); //breach
AddBehaviour( "+TIMESTOP", 10 ); //time stop
AddBehaviour( "+AREA", 25 ); //area attack spells
AddBehaviour( "+DIRECT", 20 ); //direct attack spells
AddBehaviour( "+TOUCH", 20 ); //touch attack spells
//AddBehaviour( "+MELEEASSIST", 50 ); //assist allies in melee
//AddBehaviour( "+ATKRANGED", 100 ); //ranged attack
AddBehaviour( "+ATKMELEE", 100 ); //melee attack
//Other config
//Corpse decay set up and exclusions
SetCorpseDelay();
//Set whether the creature can use EffectDisappearAppear when moving
SetIsFlier();
if ( GetIsObjectValid( GetMaster( OBJECT_SELF ) ) )
{
//I am probably a summoned creature, possibly a henchman
SetAssociateListenPatterns();
}
//set voice chat config
SetVoiceChat( NO_VC_DEFAULT, 10 );
//configure perception ranges
SetPerceptionRanges();
//tell creature it is ready to act
//SetReadyStatus();
//set fastbuffer status, should always be left on
SetIsFastBuffer( TRUE );
//SetLocalInt( OBJECT_SELF, "#FASTBUFFER", 1 );
//SetLocalInt( OBJECT_SELF, "#ACTIVE", 1 );
//log starting location
ExecuteScript( "no_scr_logspnloc", OBJECT_SELF );
//log loaded melee weapons
ExecuteScript( "no_scr_logeq", OBJECT_SELF );
// OPTIONAL BEHAVIORS (Comment In or Out to Activate ) ****************************************************************************
//SetSpawnInCondition(NW_FLAG_SPECIAL_CONVERSATION);
//SetSpawnInCondition(NW_FLAG_SPECIAL_COMBAT_CONVERSATION);
// This causes the creature to say a special greeting in their conversation file
// upon Perceiving the player. Attach the [NW_D2_GenCheck.nss] script to the desired
// greeting in order to designate it. As the creature is actually saying this to
// himself, don't attach any player responses to the greeting.
//SetSpawnInCondition(NW_FLAG_SHOUT_ATTACK_MY_TARGET);
// This will set the listening pattern on the NPC to attack when allies call
//SetSpawnInCondition(NW_FLAG_STEALTH);
// If the NPC has stealth and they are a rogue go into stealth mode
//SetSpawnInCondition(NW_FLAG_SEARCH);
// If the NPC has Search go into Search Mode
//SetSpawnInCondition(NW_FLAG_SET_WARNINGS);
// This will set the NPC to give a warning to non-enemies before attacking
//SetSpawnInCondition(NW_FLAG_SLEEP);
//Creatures that spawn in during the night will be asleep.
//SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING);
//SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION);
//SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS);
SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS);
// SetAnimationCondition(NW_ANIM_FLAG_IS_CIVILIZED);
SetAnimationCondition(NW_ANIM_FLAG_CONSTANT);
// SetAnimationCondition(NW_ANIM_FLAG_CHATTER);
// SetAnimationCondition(NW_ANIM_FLAG_IS_MOBILE_CLOSE_RANGE);
//This will play Ambient Animations until the NPC sees an enemy or is cleared.
//NOTE that these animations will play automatically for Encounter Creatures.
// NOTE: ONLY ONE OF THE FOLOOWING ESCAPE COMMANDS SHOULD EVER BE ACTIVATED AT ANY ONE TIME.
//SetSpawnInCondition(NW_FLAG_ESCAPE_RETURN); // OPTIONAL BEHAVIOR (Flee to a way point and return a short time later.)
//SetSpawnInCondition(NW_FLAG_ESCAPE_LEAVE); // OPTIONAL BEHAVIOR (Flee to a way point and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_LEAVE); // OPTIONAL BEHAVIOR (Teleport to safety and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_RETURN); // OPTIONAL BEHAVIOR (Teleport to safety and return a short time later.)
// CUSTOM USER DEFINED EVENTS
/*
The following settings will allow the user to fire one of the blank user defined events in the NW_D2_DefaultD. Like the
On Spawn In script this script is meant to be customized by the end user to allow for unique behaviors. The user defined
events user 1000 - 1010
*/
//SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1001
//SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1002
//SetSpawnInCondition(NW_FLAG_ATTACK_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1005
//SetSpawnInCondition(NW_FLAG_DAMAGED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1006
//SetSpawnInCondition(NW_FLAG_DISTURBED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1008
//SetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1003
//SetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1004
//SetSpawnInCondition(NW_FLAG_DEATH_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1007
SetListeningPatterns(); // Goes through and sets up which shouts the NPC will listen to.
WalkWayPoints(); // Optional Parameter: void WalkWayPoints(int nRun = FALSE, float fPause = 1.0)
// 1. Looks to see if any Way Points in the module have the tag "WP_" + NPC TAG + "_0X", if so walk them
// 2. If the tag of the Way Point is "POST_" + NPC TAG the creature will return this way point after
// combat.
CTG_GenerateNPCTreasure(TREASURE_TYPE_MONSTER, OBJECT_SELF); //* Use this to create a small amount of treasure on the creature
}

121
_module/nss/no_spn_ftr.nss Normal file
View File

@@ -0,0 +1,121 @@
//::///////////////////////////////////////////////
//:: On Spawn In
//::
//:://////////////////////////////////////////////
/*
Determines the course of action to be taken
after having just been spawned in
*/
//:://////////////////////////////////////////////
#include "no_lib_data"
#include "no_inc"
#include "nw_o2_coninclude"
#include "x0_i0_treasure"
void main()
{
//Behaviour config
AddBehaviour( "+HEALSELF", 100 ); //heal self
AddBehaviour( "+FEATENHANCE", 80 ); //enhance self via feats
AddBehaviour( "+REGROUP", 80 ); //regroup
AddBehaviour( "+FLANK", 20 ); //flank
AddBehaviour( "+EVACAOE", 50 ); //evac AOEs
AddBehaviour( "+MELEEASSIST", 100 ); //assist allies in melee
AddBehaviour( "+ATKRANGED", 100 ); //ranged attack
AddBehaviour( "+ATKMELEE", 100 ); //melee attack
//Other config
//Corpse decay set up and exclusions
SetCorpseDelay();
//Set whether the creature can use EffectDisappearAppear when moving
SetIsFlier();
if ( GetIsObjectValid( GetMaster( OBJECT_SELF ) ) )
{
//I am probably a summoned creature, possibly a henchman
SetAssociateListenPatterns();
}
//set voice chat config
SetVoiceChat( NO_VC_DEFAULT, 10 );
//configure perception ranges
SetPerceptionRanges();
//set response range for fighting broadcast
SetResponseRange( BC_FIGHTING, 50.0 );
//tell creature it is ready to act
//SetReadyStatus();
//set fastbuffer status, should always be left on
SetIsFastBuffer( TRUE );
//SetLocalInt( OBJECT_SELF, "#FASTBUFFER", 1 );
//SetLocalInt( OBJECT_SELF, "#ACTIVE", 1 );
//log starting location
ExecuteScript( "no_scr_logspnloc", OBJECT_SELF );
//log loaded melee weapons
ExecuteScript( "no_scr_logeq", OBJECT_SELF );
// OPTIONAL BEHAVIORS (Comment In or Out to Activate ) ****************************************************************************
//SetSpawnInCondition(NW_FLAG_SPECIAL_CONVERSATION);
//SetSpawnInCondition(NW_FLAG_SPECIAL_COMBAT_CONVERSATION);
// This causes the creature to say a special greeting in their conversation file
// upon Perceiving the player. Attach the [NW_D2_GenCheck.nss] script to the desired
// greeting in order to designate it. As the creature is actually saying this to
// himself, don't attach any player responses to the greeting.
//SetSpawnInCondition(NW_FLAG_SHOUT_ATTACK_MY_TARGET);
// This will set the listening pattern on the NPC to attack when allies call
//SetSpawnInCondition(NW_FLAG_STEALTH);
// If the NPC has stealth and they are a rogue go into stealth mode
//SetSpawnInCondition(NW_FLAG_SEARCH);
// If the NPC has Search go into Search Mode
//SetSpawnInCondition(NW_FLAG_SET_WARNINGS);
// This will set the NPC to give a warning to non-enemies before attacking
//SetSpawnInCondition(NW_FLAG_SLEEP);
//Creatures that spawn in during the night will be asleep.
//SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING);
//SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION);
//SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS);
SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS);
// SetAnimationCondition(NW_ANIM_FLAG_IS_CIVILIZED);
SetAnimationCondition(NW_ANIM_FLAG_CONSTANT);
// SetAnimationCondition(NW_ANIM_FLAG_CHATTER);
// SetAnimationCondition(NW_ANIM_FLAG_IS_MOBILE_CLOSE_RANGE);
//This will play Ambient Animations until the NPC sees an enemy or is cleared.
//NOTE that these animations will play automatically for Encounter Creatures.
// NOTE: ONLY ONE OF THE FOLOOWING ESCAPE COMMANDS SHOULD EVER BE ACTIVATED AT ANY ONE TIME.
//SetSpawnInCondition(NW_FLAG_ESCAPE_RETURN); // OPTIONAL BEHAVIOR (Flee to a way point and return a short time later.)
//SetSpawnInCondition(NW_FLAG_ESCAPE_LEAVE); // OPTIONAL BEHAVIOR (Flee to a way point and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_LEAVE); // OPTIONAL BEHAVIOR (Teleport to safety and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_RETURN); // OPTIONAL BEHAVIOR (Teleport to safety and return a short time later.)
// CUSTOM USER DEFINED EVENTS
/*
The following settings will allow the user to fire one of the blank user defined events in the NW_D2_DefaultD. Like the
On Spawn In script this script is meant to be customized by the end user to allow for unique behaviors. The user defined
events user 1000 - 1010
*/
//SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1001
//SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1002
//SetSpawnInCondition(NW_FLAG_ATTACK_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1005
//SetSpawnInCondition(NW_FLAG_DAMAGED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1006
//SetSpawnInCondition(NW_FLAG_DISTURBED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1008
//SetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1003
//SetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1004
//SetSpawnInCondition(NW_FLAG_DEATH_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1007
SetListeningPatterns(); // Goes through and sets up which shouts the NPC will listen to.
WalkWayPoints(); // Optional Parameter: void WalkWayPoints(int nRun = FALSE, float fPause = 1.0)
// 1. Looks to see if any Way Points in the module have the tag "WP_" + NPC TAG + "_0X", if so walk them
// 2. If the tag of the Way Point is "POST_" + NPC TAG the creature will return this way point after
// combat.
CTG_GenerateNPCTreasure(TREASURE_TYPE_MONSTER, OBJECT_SELF); //* Use this to create a small amount of treasure on the creature
}

View File

@@ -0,0 +1,136 @@
//::///////////////////////////////////////////////
//:: On Spawn In
//::
//:://////////////////////////////////////////////
/*
Determines the course of action to be taken
after having just been spawned in
*/
//:://////////////////////////////////////////////
#include "no_lib_data"
#include "no_inc"
#include "nw_o2_coninclude"
#include "x0_i0_treasure"
void main()
{
//Behaviour config
AddBehaviour( "+HEALSELF", 100 ); //heal self
AddBehaviour( "+REGROUP", 40 ); //regroup
AddBehaviour( "+FLANK", 20 ); //flank
//AddBehaviour( "+AVOIDMELEE", 20 ); //avoid melee
AddBehaviour( "+EVACAOE", 50 ); //evac AOEs
//AddBehaviour( "+SUMMON", 60 ); //summon spells
AddBehaviour( "+HELP", 40 ); //help
AddBehaviour( "+VIS", 40 ); //vision
AddBehaviour( "+DEFSING", 20 ); //defend single
AddBehaviour( "+DEFSELF", 20 ); //defend self
AddBehaviour( "+GROUPENHANCE", 20 ); //enhance group
AddBehaviour( "+ENHANCESING", 20 ); //enhance single
AddBehaviour( "+ENHANCESELF", 20 ); //enhance self
AddBehaviour( "+FEATENHANCE", 20 ); //enhance self via feats
//AddBehaviour( "+DISPEL", 40 ); //dispel single
//AddBehaviour( "+DISPELAOE", 40 ); //dispel AOEs
//AddBehaviour( "+DISMISSAL", 40 ); //dismiss summons
//AddBehaviour( "+BREACH", 40 ); //breach
//AddBehaviour( "+TIMESTOP", 20 ); //time stop
AddBehaviour( "+AREA", 20 ); //area attack spells
AddBehaviour( "+BREATH", 40 ); //area attack spells
AddBehaviour( "+DIRECT", 20 ); //direct attack spells
AddBehaviour( "+TOUCH", 20 ); //touch attack spells
AddBehaviour( "+MELEEASSIST", 50 ); //assist allies in melee
//AddBehaviour( "+ATKRANGED", 100 ); //ranged attack
AddBehaviour( "+ATKMELEE", 100 ); //melee attack
//Other config
//Corpse decay set up and exclusions
SetCorpseDelay();
//Set whether the creature can use EffectDisappearAppear when moving
SetIsFlier();
if ( GetIsObjectValid( GetMaster( OBJECT_SELF ) ) )
{
//I am probably a summoned creature, possibly a henchman
SetAssociateListenPatterns();
}
//set voice chat config
SetVoiceChat( NO_VC_DEFAULT, 10 );
//configure perception ranges
SetPerceptionRanges();
//tell creature it is ready to act
//SetReadyStatus();
//set fastbuffer status, should always be left on
SetIsFastBuffer( TRUE );
//SetLocalInt( OBJECT_SELF, "#FASTBUFFER", 1 );
//SetLocalInt( OBJECT_SELF, "#ACTIVE", 1 );
//log starting location
ExecuteScript( "no_scr_logspnloc", OBJECT_SELF );
//log loaded melee weapons
ExecuteScript( "no_scr_logeq", OBJECT_SELF );
// OPTIONAL BEHAVIORS (Comment In or Out to Activate ) ****************************************************************************
//SetSpawnInCondition(NW_FLAG_SPECIAL_CONVERSATION);
//SetSpawnInCondition(NW_FLAG_SPECIAL_COMBAT_CONVERSATION);
// This causes the creature to say a special greeting in their conversation file
// upon Perceiving the player. Attach the [NW_D2_GenCheck.nss] script to the desired
// greeting in order to designate it. As the creature is actually saying this to
// himself, don't attach any player responses to the greeting.
//SetSpawnInCondition(NW_FLAG_SHOUT_ATTACK_MY_TARGET);
// This will set the listening pattern on the NPC to attack when allies call
//SetSpawnInCondition(NW_FLAG_STEALTH);
// If the NPC has stealth and they are a rogue go into stealth mode
//SetSpawnInCondition(NW_FLAG_SEARCH);
// If the NPC has Search go into Search Mode
//SetSpawnInCondition(NW_FLAG_SET_WARNINGS);
// This will set the NPC to give a warning to non-enemies before attacking
//SetSpawnInCondition(NW_FLAG_SLEEP);
//Creatures that spawn in during the night will be asleep.
//SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING);
//SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION);
//SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS);
SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS);
// SetAnimationCondition(NW_ANIM_FLAG_IS_CIVILIZED);
SetAnimationCondition(NW_ANIM_FLAG_CONSTANT);
// SetAnimationCondition(NW_ANIM_FLAG_CHATTER);
// SetAnimationCondition(NW_ANIM_FLAG_IS_MOBILE_CLOSE_RANGE);
//This will play Ambient Animations until the NPC sees an enemy or is cleared.
//NOTE that these animations will play automatically for Encounter Creatures.
// NOTE: ONLY ONE OF THE FOLOOWING ESCAPE COMMANDS SHOULD EVER BE ACTIVATED AT ANY ONE TIME.
//SetSpawnInCondition(NW_FLAG_ESCAPE_RETURN); // OPTIONAL BEHAVIOR (Flee to a way point and return a short time later.)
//SetSpawnInCondition(NW_FLAG_ESCAPE_LEAVE); // OPTIONAL BEHAVIOR (Flee to a way point and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_LEAVE); // OPTIONAL BEHAVIOR (Teleport to safety and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_RETURN); // OPTIONAL BEHAVIOR (Teleport to safety and return a short time later.)
// CUSTOM USER DEFINED EVENTS
/*
The following settings will allow the user to fire one of the blank user defined events in the NW_D2_DefaultD. Like the
On Spawn In script this script is meant to be customized by the end user to allow for unique behaviors. The user defined
events user 1000 - 1010
*/
//SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1001
//SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1002
//SetSpawnInCondition(NW_FLAG_ATTACK_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1005
//SetSpawnInCondition(NW_FLAG_DAMAGED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1006
//SetSpawnInCondition(NW_FLAG_DISTURBED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1008
//SetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1003
//SetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1004
//SetSpawnInCondition(NW_FLAG_DEATH_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1007
SetListeningPatterns(); // Goes through and sets up which shouts the NPC will listen to.
WalkWayPoints(); // Optional Parameter: void WalkWayPoints(int nRun = FALSE, float fPause = 1.0)
// 1. Looks to see if any Way Points in the module have the tag "WP_" + NPC TAG + "_0X", if so walk them
// 2. If the tag of the Way Point is "POST_" + NPC TAG the creature will return this way point after
// combat.
CTG_GenerateNPCTreasure(TREASURE_TYPE_MONSTER, OBJECT_SELF); //* Use this to create a small amount of treasure on the creature
}

View File

@@ -0,0 +1,136 @@
//::///////////////////////////////////////////////
//:: On Spawn In
//::
//:://////////////////////////////////////////////
/*
Determines the course of action to be taken
after having just been spawned in
*/
//:://////////////////////////////////////////////
#include "no_lib_data"
#include "no_inc"
#include "nw_o2_coninclude"
#include "x0_i0_treasure"
void main()
{
//Behaviour config
AddBehaviour( "+HEALSELF", 100 ); //heal self
AddBehaviour( "+REGROUP", 40 ); //regroup
AddBehaviour( "+FLANK", 20 ); //flank
//AddBehaviour( "+AVOIDMELEE", 20 ); //avoid melee
AddBehaviour( "+EVACAOE", 50 ); //evac AOEs
//AddBehaviour( "+SUMMON", 60 ); //summon spells
AddBehaviour( "+HELP", 40 ); //help
AddBehaviour( "+VIS", 40 ); //vision
AddBehaviour( "+DEFSING", 20 ); //defend single
AddBehaviour( "+DEFSELF", 20 ); //defend self
AddBehaviour( "+GROUPENHANCE", 20 ); //enhance group
AddBehaviour( "+ENHANCESING", 20 ); //enhance single
AddBehaviour( "+ENHANCESELF", 20 ); //enhance self
AddBehaviour( "+FEATENHANCE", 20 ); //enhance self via feats
AddBehaviour( "+DISPEL", 20 ); //dispel single
AddBehaviour( "+DISPELAOE", 20 ); //dispel AOEs
//AddBehaviour( "+DISMISSAL", 40 ); //dismiss summons
//AddBehaviour( "+BREACH", 40 ); //breach
//AddBehaviour( "+TIMESTOP", 20 ); //time stop
AddBehaviour( "+AREA", 20 ); //area attack spells
AddBehaviour( "+BREATH", 40 ); //area attack spells
AddBehaviour( "+DIRECT", 20 ); //direct attack spells
AddBehaviour( "+TOUCH", 20 ); //touch attack spells
AddBehaviour( "+MELEEASSIST", 50 ); //assist allies in melee
//AddBehaviour( "+ATKRANGED", 100 ); //ranged attack
AddBehaviour( "+ATKMELEE", 100 ); //melee attack
//Other config
//Corpse decay set up and exclusions
SetCorpseDelay();
//Set whether the creature can use EffectDisappearAppear when moving
SetIsFlier();
if ( GetIsObjectValid( GetMaster( OBJECT_SELF ) ) )
{
//I am probably a summoned creature, possibly a henchman
SetAssociateListenPatterns();
}
//set voice chat config
SetVoiceChat( NO_VC_DEFAULT, 10 );
//configure perception ranges
SetPerceptionRanges();
//tell creature it is ready to act
//SetReadyStatus();
//set fastbuffer status, should always be left on
SetIsFastBuffer( TRUE );
//SetLocalInt( OBJECT_SELF, "#FASTBUFFER", 1 );
//SetLocalInt( OBJECT_SELF, "#ACTIVE", 1 );
//log starting location
ExecuteScript( "no_scr_logspnloc", OBJECT_SELF );
//log loaded melee weapons
ExecuteScript( "no_scr_logeq", OBJECT_SELF );
// OPTIONAL BEHAVIORS (Comment In or Out to Activate ) ****************************************************************************
//SetSpawnInCondition(NW_FLAG_SPECIAL_CONVERSATION);
//SetSpawnInCondition(NW_FLAG_SPECIAL_COMBAT_CONVERSATION);
// This causes the creature to say a special greeting in their conversation file
// upon Perceiving the player. Attach the [NW_D2_GenCheck.nss] script to the desired
// greeting in order to designate it. As the creature is actually saying this to
// himself, don't attach any player responses to the greeting.
//SetSpawnInCondition(NW_FLAG_SHOUT_ATTACK_MY_TARGET);
// This will set the listening pattern on the NPC to attack when allies call
//SetSpawnInCondition(NW_FLAG_STEALTH);
// If the NPC has stealth and they are a rogue go into stealth mode
//SetSpawnInCondition(NW_FLAG_SEARCH);
// If the NPC has Search go into Search Mode
//SetSpawnInCondition(NW_FLAG_SET_WARNINGS);
// This will set the NPC to give a warning to non-enemies before attacking
//SetSpawnInCondition(NW_FLAG_SLEEP);
//Creatures that spawn in during the night will be asleep.
//SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING);
//SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION);
//SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS);
SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS);
// SetAnimationCondition(NW_ANIM_FLAG_IS_CIVILIZED);
SetAnimationCondition(NW_ANIM_FLAG_CONSTANT);
// SetAnimationCondition(NW_ANIM_FLAG_CHATTER);
// SetAnimationCondition(NW_ANIM_FLAG_IS_MOBILE_CLOSE_RANGE);
//This will play Ambient Animations until the NPC sees an enemy or is cleared.
//NOTE that these animations will play automatically for Encounter Creatures.
// NOTE: ONLY ONE OF THE FOLOOWING ESCAPE COMMANDS SHOULD EVER BE ACTIVATED AT ANY ONE TIME.
//SetSpawnInCondition(NW_FLAG_ESCAPE_RETURN); // OPTIONAL BEHAVIOR (Flee to a way point and return a short time later.)
//SetSpawnInCondition(NW_FLAG_ESCAPE_LEAVE); // OPTIONAL BEHAVIOR (Flee to a way point and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_LEAVE); // OPTIONAL BEHAVIOR (Teleport to safety and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_RETURN); // OPTIONAL BEHAVIOR (Teleport to safety and return a short time later.)
// CUSTOM USER DEFINED EVENTS
/*
The following settings will allow the user to fire one of the blank user defined events in the NW_D2_DefaultD. Like the
On Spawn In script this script is meant to be customized by the end user to allow for unique behaviors. The user defined
events user 1000 - 1010
*/
//SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1001
//SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1002
//SetSpawnInCondition(NW_FLAG_ATTACK_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1005
//SetSpawnInCondition(NW_FLAG_DAMAGED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1006
//SetSpawnInCondition(NW_FLAG_DISTURBED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1008
//SetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1003
//SetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1004
//SetSpawnInCondition(NW_FLAG_DEATH_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1007
SetListeningPatterns(); // Goes through and sets up which shouts the NPC will listen to.
WalkWayPoints(); // Optional Parameter: void WalkWayPoints(int nRun = FALSE, float fPause = 1.0)
// 1. Looks to see if any Way Points in the module have the tag "WP_" + NPC TAG + "_0X", if so walk them
// 2. If the tag of the Way Point is "POST_" + NPC TAG the creature will return this way point after
// combat.
CTG_GenerateNPCTreasure(TREASURE_TYPE_MONSTER, OBJECT_SELF); //* Use this to create a small amount of treasure on the creature
}

View File

@@ -0,0 +1,136 @@
//::///////////////////////////////////////////////
//:: On Spawn In
//::
//:://////////////////////////////////////////////
/*
Determines the course of action to be taken
after having just been spawned in
*/
//:://////////////////////////////////////////////
#include "no_lib_data"
#include "no_inc"
#include "nw_o2_coninclude"
#include "x0_i0_treasure"
void main()
{
//Behaviour config
AddBehaviour( "+HEALSELF", 100 ); //heal self
AddBehaviour( "+REGROUP", 40 ); //regroup
AddBehaviour( "+FLANK", 20 ); //flank
//AddBehaviour( "+AVOIDMELEE", 20 ); //avoid melee
AddBehaviour( "+EVACAOE", 50 ); //evac AOEs
AddBehaviour( "+SUMMON", 60 ); //summon spells
AddBehaviour( "+HELP", 40 ); //help
AddBehaviour( "+VIS", 40 ); //vision
AddBehaviour( "+DEFSING", 20 ); //defend single
AddBehaviour( "+DEFSELF", 20 ); //defend self
AddBehaviour( "+GROUPENHANCE", 20 ); //enhance group
AddBehaviour( "+ENHANCESING", 20 ); //enhance single
AddBehaviour( "+ENHANCESELF", 20 ); //enhance self
AddBehaviour( "+FEATENHANCE", 20 ); //enhance self via feats
AddBehaviour( "+DISPEL", 20 ); //dispel single
AddBehaviour( "+DISPELAOE", 20 ); //dispel AOEs
AddBehaviour( "+DISMISSAL", 20 ); //dismiss summons
AddBehaviour( "+BREACH", 20 ); //breach
AddBehaviour( "+TIMESTOP", 20 ); //time stop
AddBehaviour( "+AREA", 20 ); //area attack spells
AddBehaviour( "+BREATH", 40 ); //area attack spells
AddBehaviour( "+DIRECT", 20 ); //direct attack spells
AddBehaviour( "+TOUCH", 20 ); //touch attack spells
AddBehaviour( "+MELEEASSIST", 50 ); //assist allies in melee
//AddBehaviour( "+ATKRANGED", 100 ); //ranged attack
AddBehaviour( "+ATKMELEE", 100 ); //melee attack
//Other config
//Corpse decay set up and exclusions
SetCorpseDelay();
//Set whether the creature can use EffectDisappearAppear when moving
SetIsFlier();
if ( GetIsObjectValid( GetMaster( OBJECT_SELF ) ) )
{
//I am probably a summoned creature, possibly a henchman
SetAssociateListenPatterns();
}
//set voice chat config
SetVoiceChat( NO_VC_DEFAULT, 10 );
//configure perception ranges
SetPerceptionRanges();
//tell creature it is ready to act
//SetReadyStatus();
//set fastbuffer status, should always be left on
SetIsFastBuffer( TRUE );
//SetLocalInt( OBJECT_SELF, "#FASTBUFFER", 1 );
//SetLocalInt( OBJECT_SELF, "#ACTIVE", 1 );
//log starting location
ExecuteScript( "no_scr_logspnloc", OBJECT_SELF );
//log loaded melee weapons
ExecuteScript( "no_scr_logeq", OBJECT_SELF );
// OPTIONAL BEHAVIORS (Comment In or Out to Activate ) ****************************************************************************
//SetSpawnInCondition(NW_FLAG_SPECIAL_CONVERSATION);
//SetSpawnInCondition(NW_FLAG_SPECIAL_COMBAT_CONVERSATION);
// This causes the creature to say a special greeting in their conversation file
// upon Perceiving the player. Attach the [NW_D2_GenCheck.nss] script to the desired
// greeting in order to designate it. As the creature is actually saying this to
// himself, don't attach any player responses to the greeting.
//SetSpawnInCondition(NW_FLAG_SHOUT_ATTACK_MY_TARGET);
// This will set the listening pattern on the NPC to attack when allies call
//SetSpawnInCondition(NW_FLAG_STEALTH);
// If the NPC has stealth and they are a rogue go into stealth mode
//SetSpawnInCondition(NW_FLAG_SEARCH);
// If the NPC has Search go into Search Mode
//SetSpawnInCondition(NW_FLAG_SET_WARNINGS);
// This will set the NPC to give a warning to non-enemies before attacking
//SetSpawnInCondition(NW_FLAG_SLEEP);
//Creatures that spawn in during the night will be asleep.
//SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING);
//SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION);
//SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS);
SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS);
// SetAnimationCondition(NW_ANIM_FLAG_IS_CIVILIZED);
SetAnimationCondition(NW_ANIM_FLAG_CONSTANT);
// SetAnimationCondition(NW_ANIM_FLAG_CHATTER);
// SetAnimationCondition(NW_ANIM_FLAG_IS_MOBILE_CLOSE_RANGE);
//This will play Ambient Animations until the NPC sees an enemy or is cleared.
//NOTE that these animations will play automatically for Encounter Creatures.
// NOTE: ONLY ONE OF THE FOLOOWING ESCAPE COMMANDS SHOULD EVER BE ACTIVATED AT ANY ONE TIME.
//SetSpawnInCondition(NW_FLAG_ESCAPE_RETURN); // OPTIONAL BEHAVIOR (Flee to a way point and return a short time later.)
//SetSpawnInCondition(NW_FLAG_ESCAPE_LEAVE); // OPTIONAL BEHAVIOR (Flee to a way point and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_LEAVE); // OPTIONAL BEHAVIOR (Teleport to safety and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_RETURN); // OPTIONAL BEHAVIOR (Teleport to safety and return a short time later.)
// CUSTOM USER DEFINED EVENTS
/*
The following settings will allow the user to fire one of the blank user defined events in the NW_D2_DefaultD. Like the
On Spawn In script this script is meant to be customized by the end user to allow for unique behaviors. The user defined
events user 1000 - 1010
*/
//SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1001
//SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1002
//SetSpawnInCondition(NW_FLAG_ATTACK_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1005
//SetSpawnInCondition(NW_FLAG_DAMAGED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1006
//SetSpawnInCondition(NW_FLAG_DISTURBED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1008
//SetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1003
//SetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1004
//SetSpawnInCondition(NW_FLAG_DEATH_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1007
SetListeningPatterns(); // Goes through and sets up which shouts the NPC will listen to.
WalkWayPoints(); // Optional Parameter: void WalkWayPoints(int nRun = FALSE, float fPause = 1.0)
// 1. Looks to see if any Way Points in the module have the tag "WP_" + NPC TAG + "_0X", if so walk them
// 2. If the tag of the Way Point is "POST_" + NPC TAG the creature will return this way point after
// combat.
CTG_GenerateNPCTreasure(TREASURE_TYPE_MONSTER, OBJECT_SELF); //* Use this to create a small amount of treasure on the creature
}

View File

@@ -0,0 +1,136 @@
//::///////////////////////////////////////////////
//:: On Spawn In
//::
//:://////////////////////////////////////////////
/*
Determines the course of action to be taken
after having just been spawned in
*/
//:://////////////////////////////////////////////
#include "no_lib_data"
#include "no_inc"
#include "nw_o2_coninclude"
#include "x0_i0_treasure"
void main()
{
//Behaviour config
AddBehaviour( "+HEALSELF", 100 ); //heal self
AddBehaviour( "+REGROUP", 40 ); //regroup
AddBehaviour( "+FLANK", 20 ); //flank
//AddBehaviour( "+AVOIDMELEE", 20 ); //avoid melee
AddBehaviour( "+EVACAOE", 50 ); //evac AOEs
//AddBehaviour( "+SUMMON", 60 ); //summon spells
//AddBehaviour( "+HELP", 40 ); //help
AddBehaviour( "+VIS", 40 ); //vision
AddBehaviour( "+DEFSING", 40 ); //defend single
AddBehaviour( "+DEFSELF", 40 ); //defend self
AddBehaviour( "+GROUPENHANCE", 40 ); //enhance group
AddBehaviour( "+ENHANCESING", 40 ); //enhance single
AddBehaviour( "+ENHANCESELF", 40 ); //enhance self
AddBehaviour( "+FEATENHANCE", 40 ); //enhance self via feats
//AddBehaviour( "+DISPEL", 40 ); //dispel single
//AddBehaviour( "+DISPELAOE", 40 ); //dispel AOEs
//AddBehaviour( "+DISMISSAL", 40 ); //dismiss summons
//AddBehaviour( "+BREACH", 40 ); //breach
//AddBehaviour( "+TIMESTOP", 20 ); //time stop
//AddBehaviour( "+AREA", 80 ); //area attack spells
//AddBehaviour( "+BREATH", 40 ); //area attack spells
//AddBehaviour( "+DIRECT", 80 ); //direct attack spells
//AddBehaviour( "+TOUCH", 80 ); //touch attack spells
AddBehaviour( "+MELEEASSIST", 50 ); //assist allies in melee
//AddBehaviour( "+ATKRANGED", 100 ); //ranged attack
AddBehaviour( "+ATKMELEE", 100 ); //melee attack
//Other config
//Corpse decay set up and exclusions
SetCorpseDelay();
//Set whether the creature can use EffectDisappearAppear when moving
SetIsFlier();
if ( GetIsObjectValid( GetMaster( OBJECT_SELF ) ) )
{
//I am probably a summoned creature, possibly a henchman
SetAssociateListenPatterns();
}
//set voice chat config
SetVoiceChat( NO_VC_DEFAULT, 10 );
//configure perception ranges
SetPerceptionRanges();
//tell creature it is ready to act
//SetReadyStatus();
//set fastbuffer status, should always be left on
SetIsFastBuffer( TRUE );
//SetLocalInt( OBJECT_SELF, "#FASTBUFFER", 1 );
//SetLocalInt( OBJECT_SELF, "#ACTIVE", 1 );
//log starting location
ExecuteScript( "no_scr_logspnloc", OBJECT_SELF );
//log loaded melee weapons
ExecuteScript( "no_scr_logeq", OBJECT_SELF );
// OPTIONAL BEHAVIORS (Comment In or Out to Activate ) ****************************************************************************
//SetSpawnInCondition(NW_FLAG_SPECIAL_CONVERSATION);
//SetSpawnInCondition(NW_FLAG_SPECIAL_COMBAT_CONVERSATION);
// This causes the creature to say a special greeting in their conversation file
// upon Perceiving the player. Attach the [NW_D2_GenCheck.nss] script to the desired
// greeting in order to designate it. As the creature is actually saying this to
// himself, don't attach any player responses to the greeting.
//SetSpawnInCondition(NW_FLAG_SHOUT_ATTACK_MY_TARGET);
// This will set the listening pattern on the NPC to attack when allies call
//SetSpawnInCondition(NW_FLAG_STEALTH);
// If the NPC has stealth and they are a rogue go into stealth mode
//SetSpawnInCondition(NW_FLAG_SEARCH);
// If the NPC has Search go into Search Mode
//SetSpawnInCondition(NW_FLAG_SET_WARNINGS);
// This will set the NPC to give a warning to non-enemies before attacking
//SetSpawnInCondition(NW_FLAG_SLEEP);
//Creatures that spawn in during the night will be asleep.
//SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING);
//SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION);
//SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS);
SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS);
// SetAnimationCondition(NW_ANIM_FLAG_IS_CIVILIZED);
SetAnimationCondition(NW_ANIM_FLAG_CONSTANT);
// SetAnimationCondition(NW_ANIM_FLAG_CHATTER);
// SetAnimationCondition(NW_ANIM_FLAG_IS_MOBILE_CLOSE_RANGE);
//This will play Ambient Animations until the NPC sees an enemy or is cleared.
//NOTE that these animations will play automatically for Encounter Creatures.
// NOTE: ONLY ONE OF THE FOLOOWING ESCAPE COMMANDS SHOULD EVER BE ACTIVATED AT ANY ONE TIME.
//SetSpawnInCondition(NW_FLAG_ESCAPE_RETURN); // OPTIONAL BEHAVIOR (Flee to a way point and return a short time later.)
//SetSpawnInCondition(NW_FLAG_ESCAPE_LEAVE); // OPTIONAL BEHAVIOR (Flee to a way point and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_LEAVE); // OPTIONAL BEHAVIOR (Teleport to safety and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_RETURN); // OPTIONAL BEHAVIOR (Teleport to safety and return a short time later.)
// CUSTOM USER DEFINED EVENTS
/*
The following settings will allow the user to fire one of the blank user defined events in the NW_D2_DefaultD. Like the
On Spawn In script this script is meant to be customized by the end user to allow for unique behaviors. The user defined
events user 1000 - 1010
*/
//SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1001
//SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1002
//SetSpawnInCondition(NW_FLAG_ATTACK_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1005
//SetSpawnInCondition(NW_FLAG_DAMAGED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1006
//SetSpawnInCondition(NW_FLAG_DISTURBED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1008
//SetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1003
//SetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1004
//SetSpawnInCondition(NW_FLAG_DEATH_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1007
SetListeningPatterns(); // Goes through and sets up which shouts the NPC will listen to.
WalkWayPoints(); // Optional Parameter: void WalkWayPoints(int nRun = FALSE, float fPause = 1.0)
// 1. Looks to see if any Way Points in the module have the tag "WP_" + NPC TAG + "_0X", if so walk them
// 2. If the tag of the Way Point is "POST_" + NPC TAG the creature will return this way point after
// combat.
CTG_GenerateNPCTreasure(TREASURE_TYPE_MONSTER, OBJECT_SELF); //* Use this to create a small amount of treasure on the creature
}

121
_module/nss/no_spn_rftr.nss Normal file
View File

@@ -0,0 +1,121 @@
//::///////////////////////////////////////////////
//:: On Spawn In
//::
//:://////////////////////////////////////////////
/*
Determines the course of action to be taken
after having just been spawned in
*/
//:://////////////////////////////////////////////
#include "no_lib_data"
#include "no_inc"
#include "nw_o2_coninclude"
#include "x0_i0_treasure"
void main()
{
//Behaviour config
AddBehaviour( "+HEALSELF", 100 ); //heal self
AddBehaviour( "+FEATENHANCE", 80 ); //enhance self via feats
AddBehaviour( "+REGROUP", 80 ); //regroup
AddBehaviour( "+FLANK", 20 ); //flank
AddBehaviour( "+EVACAOE", 50 ); //evac AOEs
AddBehaviour( "+MELEEASSIST", 100 ); //assist allies in melee
AddBehaviour( "+ATKRANGED", 100 ); //ranged attack
AddBehaviour( "+ATKMELEE", 100 ); //melee attack
//Other config
//Corpse decay set up and exclusions
SetCorpseDelay();
//Set whether the creature can use EffectDisappearAppear when moving
SetIsFlier();
if ( GetIsObjectValid( GetMaster( OBJECT_SELF ) ) )
{
//I am probably a summoned creature, possibly a henchman
SetAssociateListenPatterns();
}
//set voice chat config
SetVoiceChat( NO_VC_DEFAULT, 10 );
//configure perception ranges
SetPerceptionRanges();
//set response range for fighting broadcast
SetResponseRange( BC_FIGHTING, 50.0 );
//tell creature it is ready to act
//SetReadyStatus();
//set fastbuffer status, should always be left on
SetIsFastBuffer( TRUE );
//SetLocalInt( OBJECT_SELF, "#FASTBUFFER", 1 );
//SetLocalInt( OBJECT_SELF, "#ACTIVE", 1 );
//log starting location
ExecuteScript( "no_scr_logspnloc", OBJECT_SELF );
//log loaded melee weapons
ExecuteScript( "no_scr_logeq", OBJECT_SELF );
// OPTIONAL BEHAVIORS (Comment In or Out to Activate ) ****************************************************************************
//SetSpawnInCondition(NW_FLAG_SPECIAL_CONVERSATION);
//SetSpawnInCondition(NW_FLAG_SPECIAL_COMBAT_CONVERSATION);
// This causes the creature to say a special greeting in their conversation file
// upon Perceiving the player. Attach the [NW_D2_GenCheck.nss] script to the desired
// greeting in order to designate it. As the creature is actually saying this to
// himself, don't attach any player responses to the greeting.
//SetSpawnInCondition(NW_FLAG_SHOUT_ATTACK_MY_TARGET);
// This will set the listening pattern on the NPC to attack when allies call
//SetSpawnInCondition(NW_FLAG_STEALTH);
// If the NPC has stealth and they are a rogue go into stealth mode
//SetSpawnInCondition(NW_FLAG_SEARCH);
// If the NPC has Search go into Search Mode
//SetSpawnInCondition(NW_FLAG_SET_WARNINGS);
// This will set the NPC to give a warning to non-enemies before attacking
//SetSpawnInCondition(NW_FLAG_SLEEP);
//Creatures that spawn in during the night will be asleep.
//SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING);
//SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION);
//SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS);
SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS);
// SetAnimationCondition(NW_ANIM_FLAG_IS_CIVILIZED);
SetAnimationCondition(NW_ANIM_FLAG_CONSTANT);
// SetAnimationCondition(NW_ANIM_FLAG_CHATTER);
// SetAnimationCondition(NW_ANIM_FLAG_IS_MOBILE_CLOSE_RANGE);
//This will play Ambient Animations until the NPC sees an enemy or is cleared.
//NOTE that these animations will play automatically for Encounter Creatures.
// NOTE: ONLY ONE OF THE FOLOOWING ESCAPE COMMANDS SHOULD EVER BE ACTIVATED AT ANY ONE TIME.
//SetSpawnInCondition(NW_FLAG_ESCAPE_RETURN); // OPTIONAL BEHAVIOR (Flee to a way point and return a short time later.)
//SetSpawnInCondition(NW_FLAG_ESCAPE_LEAVE); // OPTIONAL BEHAVIOR (Flee to a way point and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_LEAVE); // OPTIONAL BEHAVIOR (Teleport to safety and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_RETURN); // OPTIONAL BEHAVIOR (Teleport to safety and return a short time later.)
// CUSTOM USER DEFINED EVENTS
/*
The following settings will allow the user to fire one of the blank user defined events in the NW_D2_DefaultD. Like the
On Spawn In script this script is meant to be customized by the end user to allow for unique behaviors. The user defined
events user 1000 - 1010
*/
//SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1001
//SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1002
//SetSpawnInCondition(NW_FLAG_ATTACK_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1005
//SetSpawnInCondition(NW_FLAG_DAMAGED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1006
//SetSpawnInCondition(NW_FLAG_DISTURBED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1008
//SetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1003
//SetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1004
//SetSpawnInCondition(NW_FLAG_DEATH_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1007
SetListeningPatterns(); // Goes through and sets up which shouts the NPC will listen to.
WalkWayPoints(); // Optional Parameter: void WalkWayPoints(int nRun = FALSE, float fPause = 1.0)
// 1. Looks to see if any Way Points in the module have the tag "WP_" + NPC TAG + "_0X", if so walk them
// 2. If the tag of the Way Point is "POST_" + NPC TAG the creature will return this way point after
// combat.
CTG_GenerateNPCTreasure(TREASURE_TYPE_MONSTER, OBJECT_SELF); //* Use this to create a small amount of treasure on the creature
}

View File

@@ -0,0 +1,136 @@
//::///////////////////////////////////////////////
//:: On Spawn In
//::
//:://////////////////////////////////////////////
/*
Determines the course of action to be taken
after having just been spawned in
*/
//:://////////////////////////////////////////////
#include "no_lib_data"
#include "no_inc"
#include "nw_o2_coninclude"
#include "x0_i0_treasure"
void main()
{
//Behaviour config
AddBehaviour( "+HEALSELF", 100 ); //heal self
AddBehaviour( "+REGROUP", 40 ); //regroup
AddBehaviour( "+FLANK", 20 ); //flank
//AddBehaviour( "+AVOIDMELEE", 20 ); //avoid melee
AddBehaviour( "+EVACAOE", 50 ); //evac AOEs
//AddBehaviour( "+SUMMON", 60 ); //summon spells
AddBehaviour( "+HELP", 40 ); //help
AddBehaviour( "+VIS", 40 ); //vision
AddBehaviour( "+DEFSING", 40 ); //defend single
AddBehaviour( "+DEFSELF", 40 ); //defend self
AddBehaviour( "+GROUPENHANCE", 40 ); //enhance group
AddBehaviour( "+ENHANCESING", 40 ); //enhance single
AddBehaviour( "+ENHANCESELF", 40 ); //enhance self
AddBehaviour( "+FEATENHANCE", 40 ); //enhance self via feats
//AddBehaviour( "+DISPEL", 40 ); //dispel single
//AddBehaviour( "+DISPELAOE", 40 ); //dispel AOEs
//AddBehaviour( "+DISMISSAL", 40 ); //dismiss summons
//AddBehaviour( "+BREACH", 40 ); //breach
//AddBehaviour( "+TIMESTOP", 20 ); //time stop
AddBehaviour( "+AREA", 80 ); //area attack spells
AddBehaviour( "+BREATH", 40 ); //area attack spells
AddBehaviour( "+DIRECT", 80 ); //direct attack spells
AddBehaviour( "+TOUCH", 80 ); //touch attack spells
AddBehaviour( "+MELEEASSIST", 50 ); //assist allies in melee
AddBehaviour( "+ATKRANGED", 100 ); //ranged attack
AddBehaviour( "+ATKMELEE", 100 ); //melee attack
//Other config
//Corpse decay set up and exclusions
SetCorpseDelay();
//Set whether the creature can use EffectDisappearAppear when moving
SetIsFlier();
if ( GetIsObjectValid( GetMaster( OBJECT_SELF ) ) )
{
//I am probably a summoned creature, possibly a henchman
SetAssociateListenPatterns();
}
//set voice chat config
SetVoiceChat( NO_VC_DEFAULT, 10 );
//configure perception ranges
SetPerceptionRanges();
//tell creature it is ready to act
//SetReadyStatus();
//set fastbuffer status, should always be left on
SetIsFastBuffer( TRUE );
//SetLocalInt( OBJECT_SELF, "#FASTBUFFER", 1 );
//SetLocalInt( OBJECT_SELF, "#ACTIVE", 1 );
//log starting location
ExecuteScript( "no_scr_logspnloc", OBJECT_SELF );
//log loaded melee weapons
ExecuteScript( "no_scr_logeq", OBJECT_SELF );
// OPTIONAL BEHAVIORS (Comment In or Out to Activate ) ****************************************************************************
//SetSpawnInCondition(NW_FLAG_SPECIAL_CONVERSATION);
//SetSpawnInCondition(NW_FLAG_SPECIAL_COMBAT_CONVERSATION);
// This causes the creature to say a special greeting in their conversation file
// upon Perceiving the player. Attach the [NW_D2_GenCheck.nss] script to the desired
// greeting in order to designate it. As the creature is actually saying this to
// himself, don't attach any player responses to the greeting.
//SetSpawnInCondition(NW_FLAG_SHOUT_ATTACK_MY_TARGET);
// This will set the listening pattern on the NPC to attack when allies call
//SetSpawnInCondition(NW_FLAG_STEALTH);
// If the NPC has stealth and they are a rogue go into stealth mode
//SetSpawnInCondition(NW_FLAG_SEARCH);
// If the NPC has Search go into Search Mode
//SetSpawnInCondition(NW_FLAG_SET_WARNINGS);
// This will set the NPC to give a warning to non-enemies before attacking
//SetSpawnInCondition(NW_FLAG_SLEEP);
//Creatures that spawn in during the night will be asleep.
//SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING);
//SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION);
//SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS);
SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS);
// SetAnimationCondition(NW_ANIM_FLAG_IS_CIVILIZED);
SetAnimationCondition(NW_ANIM_FLAG_CONSTANT);
// SetAnimationCondition(NW_ANIM_FLAG_CHATTER);
// SetAnimationCondition(NW_ANIM_FLAG_IS_MOBILE_CLOSE_RANGE);
//This will play Ambient Animations until the NPC sees an enemy or is cleared.
//NOTE that these animations will play automatically for Encounter Creatures.
// NOTE: ONLY ONE OF THE FOLOOWING ESCAPE COMMANDS SHOULD EVER BE ACTIVATED AT ANY ONE TIME.
//SetSpawnInCondition(NW_FLAG_ESCAPE_RETURN); // OPTIONAL BEHAVIOR (Flee to a way point and return a short time later.)
//SetSpawnInCondition(NW_FLAG_ESCAPE_LEAVE); // OPTIONAL BEHAVIOR (Flee to a way point and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_LEAVE); // OPTIONAL BEHAVIOR (Teleport to safety and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_RETURN); // OPTIONAL BEHAVIOR (Teleport to safety and return a short time later.)
// CUSTOM USER DEFINED EVENTS
/*
The following settings will allow the user to fire one of the blank user defined events in the NW_D2_DefaultD. Like the
On Spawn In script this script is meant to be customized by the end user to allow for unique behaviors. The user defined
events user 1000 - 1010
*/
//SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1001
//SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1002
//SetSpawnInCondition(NW_FLAG_ATTACK_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1005
//SetSpawnInCondition(NW_FLAG_DAMAGED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1006
//SetSpawnInCondition(NW_FLAG_DISTURBED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1008
//SetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1003
//SetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1004
//SetSpawnInCondition(NW_FLAG_DEATH_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1007
SetListeningPatterns(); // Goes through and sets up which shouts the NPC will listen to.
WalkWayPoints(); // Optional Parameter: void WalkWayPoints(int nRun = FALSE, float fPause = 1.0)
// 1. Looks to see if any Way Points in the module have the tag "WP_" + NPC TAG + "_0X", if so walk them
// 2. If the tag of the Way Point is "POST_" + NPC TAG the creature will return this way point after
// combat.
CTG_GenerateNPCTreasure(TREASURE_TYPE_MONSTER, OBJECT_SELF); //* Use this to create a small amount of treasure on the creature
}

View File

@@ -0,0 +1,136 @@
//::///////////////////////////////////////////////
//:: On Spawn In
//::
//:://////////////////////////////////////////////
/*
Determines the course of action to be taken
after having just been spawned in
*/
//:://////////////////////////////////////////////
#include "no_lib_data"
#include "no_inc"
#include "nw_o2_coninclude"
#include "x0_i0_treasure"
void main()
{
//Behaviour config
AddBehaviour( "+HEALSELF", 100 ); //heal self
AddBehaviour( "+AVOIDMELEE", 80 ); //avoid melee
AddBehaviour( "+REGROUP", 40 ); //regroup
AddBehaviour( "+FLANK", 20 ); //flank
AddBehaviour( "+EVACAOE", 50 ); //evac AOEs
AddBehaviour( "+SUMMON", 60 ); //summon spells
AddBehaviour( "+HELP", 40 ); //help
AddBehaviour( "+VIS", 40 ); //vision
AddBehaviour( "+DEFSING", 20 ); //defend single
AddBehaviour( "+DEFSELF", 20 ); //defend self
AddBehaviour( "+GROUPENHANCE", 20 ); //enhance group
AddBehaviour( "+ENHANCESING", 20 ); //enhance single
AddBehaviour( "+ENHANCESELF", 20 ); //enhance self
AddBehaviour( "+FEATENHANCE", 20 ); //enhance self via feats
AddBehaviour( "+DISPEL", 20 ); //dispel single
AddBehaviour( "+DISPELAOE", 20 ); //dispel AOEs
AddBehaviour( "+DISMISSAL", 20 ); //dismiss summons
AddBehaviour( "+BREACH", 20 ); //breach
AddBehaviour( "+TIMESTOP", 20 ); //time stop
AddBehaviour( "+AREA", 20 ); //area attack spells
AddBehaviour( "+BREATH", 40 ); //area attack spells
AddBehaviour( "+DIRECT", 20 ); //direct attack spells
AddBehaviour( "+TOUCH", 20 ); //touch attack spells
//AddBehaviour( "+MELEEASSIST", 50 ); //assist allies in melee
AddBehaviour( "+ATKRANGED", 100 ); //ranged attack
AddBehaviour( "+ATKMELEE", 100 ); //melee attack
//Other config
//Corpse decay set up and exclusions
SetCorpseDelay();
//Set whether the creature can use EffectDisappearAppear when moving
SetIsFlier();
if ( GetIsObjectValid( GetMaster( OBJECT_SELF ) ) )
{
//I am probably a summoned creature, possibly a henchman
SetAssociateListenPatterns();
}
//set voice chat config
SetVoiceChat( NO_VC_DEFAULT, 10 );
//configure perception ranges
SetPerceptionRanges();
//tell creature it is ready to act
//SetReadyStatus();
//set fastbuffer status, should always be left on
SetIsFastBuffer( TRUE );
//SetLocalInt( OBJECT_SELF, "#FASTBUFFER", 1 );
//SetLocalInt( OBJECT_SELF, "#ACTIVE", 1 );
//log starting location
ExecuteScript( "no_scr_logspnloc", OBJECT_SELF );
//log loaded melee weapons
ExecuteScript( "no_scr_logeq", OBJECT_SELF );
// OPTIONAL BEHAVIORS (Comment In or Out to Activate ) ****************************************************************************
//SetSpawnInCondition(NW_FLAG_SPECIAL_CONVERSATION);
//SetSpawnInCondition(NW_FLAG_SPECIAL_COMBAT_CONVERSATION);
// This causes the creature to say a special greeting in their conversation file
// upon Perceiving the player. Attach the [NW_D2_GenCheck.nss] script to the desired
// greeting in order to designate it. As the creature is actually saying this to
// himself, don't attach any player responses to the greeting.
//SetSpawnInCondition(NW_FLAG_SHOUT_ATTACK_MY_TARGET);
// This will set the listening pattern on the NPC to attack when allies call
//SetSpawnInCondition(NW_FLAG_STEALTH);
// If the NPC has stealth and they are a rogue go into stealth mode
//SetSpawnInCondition(NW_FLAG_SEARCH);
// If the NPC has Search go into Search Mode
//SetSpawnInCondition(NW_FLAG_SET_WARNINGS);
// This will set the NPC to give a warning to non-enemies before attacking
//SetSpawnInCondition(NW_FLAG_SLEEP);
//Creatures that spawn in during the night will be asleep.
//SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING);
//SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION);
//SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS);
SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS);
// SetAnimationCondition(NW_ANIM_FLAG_IS_CIVILIZED);
SetAnimationCondition(NW_ANIM_FLAG_CONSTANT);
// SetAnimationCondition(NW_ANIM_FLAG_CHATTER);
// SetAnimationCondition(NW_ANIM_FLAG_IS_MOBILE_CLOSE_RANGE);
//This will play Ambient Animations until the NPC sees an enemy or is cleared.
//NOTE that these animations will play automatically for Encounter Creatures.
// NOTE: ONLY ONE OF THE FOLOOWING ESCAPE COMMANDS SHOULD EVER BE ACTIVATED AT ANY ONE TIME.
//SetSpawnInCondition(NW_FLAG_ESCAPE_RETURN); // OPTIONAL BEHAVIOR (Flee to a way point and return a short time later.)
//SetSpawnInCondition(NW_FLAG_ESCAPE_LEAVE); // OPTIONAL BEHAVIOR (Flee to a way point and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_LEAVE); // OPTIONAL BEHAVIOR (Teleport to safety and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_RETURN); // OPTIONAL BEHAVIOR (Teleport to safety and return a short time later.)
// CUSTOM USER DEFINED EVENTS
/*
The following settings will allow the user to fire one of the blank user defined events in the NW_D2_DefaultD. Like the
On Spawn In script this script is meant to be customized by the end user to allow for unique behaviors. The user defined
events user 1000 - 1010
*/
//SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1001
//SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1002
//SetSpawnInCondition(NW_FLAG_ATTACK_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1005
//SetSpawnInCondition(NW_FLAG_DAMAGED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1006
//SetSpawnInCondition(NW_FLAG_DISTURBED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1008
//SetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1003
//SetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1004
//SetSpawnInCondition(NW_FLAG_DEATH_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1007
SetListeningPatterns(); // Goes through and sets up which shouts the NPC will listen to.
WalkWayPoints(); // Optional Parameter: void WalkWayPoints(int nRun = FALSE, float fPause = 1.0)
// 1. Looks to see if any Way Points in the module have the tag "WP_" + NPC TAG + "_0X", if so walk them
// 2. If the tag of the Way Point is "POST_" + NPC TAG the creature will return this way point after
// combat.
CTG_GenerateNPCTreasure(TREASURE_TYPE_MONSTER, OBJECT_SELF); //* Use this to create a small amount of treasure on the creature
}

122
_module/nss/no_spn_rog.nss Normal file
View File

@@ -0,0 +1,122 @@
//::///////////////////////////////////////////////
//:: On Spawn In
//::
//:://////////////////////////////////////////////
/*
Determines the course of action to be taken
after having just been spawned in
*/
//:://////////////////////////////////////////////
#include "no_lib_data"
#include "no_inc"
#include "nw_o2_coninclude"
#include "x0_i0_treasure"
void main()
{
//Behaviour config
AddBehaviour( "+HEALSELF", 100 ); //heal self
AddBehaviour( "+FEATENHANCE", 80 ); //enhance self via feats
AddBehaviour( "+REGROUP", 80 ); //regroup
AddBehaviour( "+FLANK", 20 ); //flank
AddBehaviour( "+AREA", 60 ); //area attack spells
AddBehaviour( "+EVACAOE", 50 ); //evac AOEs
AddBehaviour( "+MELEEASSIST", 100 ); //assist allies in melee
AddBehaviour( "+ATKRANGED", 100 ); //ranged attack
AddBehaviour( "+ATKMELEE", 100 ); //melee attack
//Other config
//Corpse decay set up and exclusions
SetCorpseDelay();
//Set whether the creature can use EffectDisappearAppear when moving
SetIsFlier();
if ( GetIsObjectValid( GetMaster( OBJECT_SELF ) ) )
{
//I am probably a summoned creature, possibly a henchman
SetAssociateListenPatterns();
}
//set voice chat config
SetVoiceChat( NO_VC_DEFAULT, 10 );
//configure perception ranges
SetPerceptionRanges();
//set response range for fighting broadcast
SetResponseRange( BC_FIGHTING, 50.0 );
//tell creature it is ready to act
//SetReadyStatus();
//set fastbuffer status, should always be left on
SetIsFastBuffer( TRUE );
//SetLocalInt( OBJECT_SELF, "#FASTBUFFER", 1 );
//SetLocalInt( OBJECT_SELF, "#ACTIVE", 1 );
//log starting location
ExecuteScript( "no_scr_logspnloc", OBJECT_SELF );
//log loaded melee weapons
ExecuteScript( "no_scr_logeq", OBJECT_SELF );
// OPTIONAL BEHAVIORS (Comment In or Out to Activate ) ****************************************************************************
//SetSpawnInCondition(NW_FLAG_SPECIAL_CONVERSATION);
//SetSpawnInCondition(NW_FLAG_SPECIAL_COMBAT_CONVERSATION);
// This causes the creature to say a special greeting in their conversation file
// upon Perceiving the player. Attach the [NW_D2_GenCheck.nss] script to the desired
// greeting in order to designate it. As the creature is actually saying this to
// himself, don't attach any player responses to the greeting.
//SetSpawnInCondition(NW_FLAG_SHOUT_ATTACK_MY_TARGET);
// This will set the listening pattern on the NPC to attack when allies call
SetSpawnInCondition(NW_FLAG_STEALTH);
// If the NPC has stealth and they are a rogue go into stealth mode
//SetSpawnInCondition(NW_FLAG_SEARCH);
// If the NPC has Search go into Search Mode
//SetSpawnInCondition(NW_FLAG_SET_WARNINGS);
// This will set the NPC to give a warning to non-enemies before attacking
//SetSpawnInCondition(NW_FLAG_SLEEP);
//Creatures that spawn in during the night will be asleep.
//SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING);
//SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION);
//SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS);
SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS);
// SetAnimationCondition(NW_ANIM_FLAG_IS_CIVILIZED);
SetAnimationCondition(NW_ANIM_FLAG_CONSTANT);
// SetAnimationCondition(NW_ANIM_FLAG_CHATTER);
// SetAnimationCondition(NW_ANIM_FLAG_IS_MOBILE_CLOSE_RANGE);
//This will play Ambient Animations until the NPC sees an enemy or is cleared.
//NOTE that these animations will play automatically for Encounter Creatures.
// NOTE: ONLY ONE OF THE FOLOOWING ESCAPE COMMANDS SHOULD EVER BE ACTIVATED AT ANY ONE TIME.
//SetSpawnInCondition(NW_FLAG_ESCAPE_RETURN); // OPTIONAL BEHAVIOR (Flee to a way point and return a short time later.)
//SetSpawnInCondition(NW_FLAG_ESCAPE_LEAVE); // OPTIONAL BEHAVIOR (Flee to a way point and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_LEAVE); // OPTIONAL BEHAVIOR (Teleport to safety and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_RETURN); // OPTIONAL BEHAVIOR (Teleport to safety and return a short time later.)
// CUSTOM USER DEFINED EVENTS
/*
The following settings will allow the user to fire one of the blank user defined events in the NW_D2_DefaultD. Like the
On Spawn In script this script is meant to be customized by the end user to allow for unique behaviors. The user defined
events user 1000 - 1010
*/
//SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1001
//SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1002
//SetSpawnInCondition(NW_FLAG_ATTACK_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1005
//SetSpawnInCondition(NW_FLAG_DAMAGED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1006
//SetSpawnInCondition(NW_FLAG_DISTURBED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1008
//SetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1003
//SetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1004
//SetSpawnInCondition(NW_FLAG_DEATH_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1007
SetListeningPatterns(); // Goes through and sets up which shouts the NPC will listen to.
WalkWayPoints(); // Optional Parameter: void WalkWayPoints(int nRun = FALSE, float fPause = 1.0)
// 1. Looks to see if any Way Points in the module have the tag "WP_" + NPC TAG + "_0X", if so walk them
// 2. If the tag of the Way Point is "POST_" + NPC TAG the creature will return this way point after
// combat.
CTG_GenerateNPCTreasure(TREASURE_TYPE_MONSTER, OBJECT_SELF); //* Use this to create a small amount of treasure on the creature
}

View File

@@ -0,0 +1,136 @@
//::///////////////////////////////////////////////
//:: On Spawn In
//::
//:://////////////////////////////////////////////
/*
Determines the course of action to be taken
after having just been spawned in
*/
//:://////////////////////////////////////////////
#include "no_lib_data"
#include "no_inc"
#include "nw_o2_coninclude"
#include "x0_i0_treasure"
void main()
{
//Behaviour config
AddBehaviour( "+HEALSELF", 100 ); //heal self
AddBehaviour( "+REGROUP", 40 ); //regroup
AddBehaviour( "+FLANK", 20 ); //flank
//AddBehaviour( "+AVOIDMELEE", 20 ); //avoid melee
AddBehaviour( "+EVACAOE", 50 ); //evac AOEs
//AddBehaviour( "+SUMMON", 60 ); //summon spells
AddBehaviour( "+HELP", 40 ); //help
AddBehaviour( "+VIS", 40 ); //vision
AddBehaviour( "+DEFSING", 40 ); //defend single
AddBehaviour( "+DEFSELF", 40 ); //defend self
AddBehaviour( "+GROUPENHANCE", 40 ); //enhance group
AddBehaviour( "+ENHANCESING", 40 ); //enhance single
AddBehaviour( "+ENHANCESELF", 40 ); //enhance self
AddBehaviour( "+FEATENHANCE", 40 ); //enhance self via feats
//AddBehaviour( "+DISPEL", 40 ); //dispel single
//AddBehaviour( "+DISPELAOE", 40 ); //dispel AOEs
//AddBehaviour( "+DISMISSAL", 40 ); //dismiss summons
//AddBehaviour( "+BREACH", 40 ); //breach
//AddBehaviour( "+TIMESTOP", 20 ); //time stop
AddBehaviour( "+AREA", 80 ); //area attack spells
AddBehaviour( "+BREATH", 40 ); //area attack spells
AddBehaviour( "+DIRECT", 80 ); //direct attack spells
AddBehaviour( "+TOUCH", 80 ); //touch attack spells
AddBehaviour( "+MELEEASSIST", 50 ); //assist allies in melee
AddBehaviour( "+ATKRANGED", 100 ); //ranged attack
AddBehaviour( "+ATKMELEE", 100 ); //melee attack
//Other config
//Corpse decay set up and exclusions
SetCorpseDelay();
//Set whether the creature can use EffectDisappearAppear when moving
SetIsFlier();
if ( GetIsObjectValid( GetMaster( OBJECT_SELF ) ) )
{
//I am probably a summoned creature, possibly a henchman
SetAssociateListenPatterns();
}
//set voice chat config
SetVoiceChat( NO_VC_DEFAULT, 10 );
//configure perception ranges
SetPerceptionRanges();
//tell creature it is ready to act
//SetReadyStatus();
//set fastbuffer status, should always be left on
SetIsFastBuffer( TRUE );
//SetLocalInt( OBJECT_SELF, "#FASTBUFFER", 1 );
//SetLocalInt( OBJECT_SELF, "#ACTIVE", 1 );
//log starting location
ExecuteScript( "no_scr_logspnloc", OBJECT_SELF );
//log loaded melee weapons
ExecuteScript( "no_scr_logeq", OBJECT_SELF );
// OPTIONAL BEHAVIORS (Comment In or Out to Activate ) ****************************************************************************
//SetSpawnInCondition(NW_FLAG_SPECIAL_CONVERSATION);
//SetSpawnInCondition(NW_FLAG_SPECIAL_COMBAT_CONVERSATION);
// This causes the creature to say a special greeting in their conversation file
// upon Perceiving the player. Attach the [NW_D2_GenCheck.nss] script to the desired
// greeting in order to designate it. As the creature is actually saying this to
// himself, don't attach any player responses to the greeting.
//SetSpawnInCondition(NW_FLAG_SHOUT_ATTACK_MY_TARGET);
// This will set the listening pattern on the NPC to attack when allies call
SetSpawnInCondition(NW_FLAG_STEALTH);
// If the NPC has stealth and they are a rogue go into stealth mode
//SetSpawnInCondition(NW_FLAG_SEARCH);
// If the NPC has Search go into Search Mode
//SetSpawnInCondition(NW_FLAG_SET_WARNINGS);
// This will set the NPC to give a warning to non-enemies before attacking
//SetSpawnInCondition(NW_FLAG_SLEEP);
//Creatures that spawn in during the night will be asleep.
//SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING);
//SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION);
//SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS);
SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS);
// SetAnimationCondition(NW_ANIM_FLAG_IS_CIVILIZED);
SetAnimationCondition(NW_ANIM_FLAG_CONSTANT);
// SetAnimationCondition(NW_ANIM_FLAG_CHATTER);
// SetAnimationCondition(NW_ANIM_FLAG_IS_MOBILE_CLOSE_RANGE);
//This will play Ambient Animations until the NPC sees an enemy or is cleared.
//NOTE that these animations will play automatically for Encounter Creatures.
// NOTE: ONLY ONE OF THE FOLOOWING ESCAPE COMMANDS SHOULD EVER BE ACTIVATED AT ANY ONE TIME.
//SetSpawnInCondition(NW_FLAG_ESCAPE_RETURN); // OPTIONAL BEHAVIOR (Flee to a way point and return a short time later.)
//SetSpawnInCondition(NW_FLAG_ESCAPE_LEAVE); // OPTIONAL BEHAVIOR (Flee to a way point and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_LEAVE); // OPTIONAL BEHAVIOR (Teleport to safety and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_RETURN); // OPTIONAL BEHAVIOR (Teleport to safety and return a short time later.)
// CUSTOM USER DEFINED EVENTS
/*
The following settings will allow the user to fire one of the blank user defined events in the NW_D2_DefaultD. Like the
On Spawn In script this script is meant to be customized by the end user to allow for unique behaviors. The user defined
events user 1000 - 1010
*/
//SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1001
//SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1002
//SetSpawnInCondition(NW_FLAG_ATTACK_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1005
//SetSpawnInCondition(NW_FLAG_DAMAGED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1006
//SetSpawnInCondition(NW_FLAG_DISTURBED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1008
//SetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1003
//SetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1004
//SetSpawnInCondition(NW_FLAG_DEATH_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1007
SetListeningPatterns(); // Goes through and sets up which shouts the NPC will listen to.
WalkWayPoints(); // Optional Parameter: void WalkWayPoints(int nRun = FALSE, float fPause = 1.0)
// 1. Looks to see if any Way Points in the module have the tag "WP_" + NPC TAG + "_0X", if so walk them
// 2. If the tag of the Way Point is "POST_" + NPC TAG the creature will return this way point after
// combat.
CTG_GenerateNPCTreasure(TREASURE_TYPE_MONSTER, OBJECT_SELF); //* Use this to create a small amount of treasure on the creature
}

View File

@@ -0,0 +1,136 @@
//::///////////////////////////////////////////////
//:: On Spawn In
//::
//:://////////////////////////////////////////////
/*
Determines the course of action to be taken
after having just been spawned in
*/
//:://////////////////////////////////////////////
#include "no_lib_data"
#include "no_inc"
#include "nw_o2_coninclude"
#include "x0_i0_treasure"
void main()
{
//Behaviour config
AddBehaviour( "+HEALSELF", 100 ); //heal self
AddBehaviour( "+REGROUP", 40 ); //regroup
AddBehaviour( "+FLANK", 20 ); //flank
//AddBehaviour( "+AVOIDMELEE", 20 ); //avoid melee
AddBehaviour( "+EVACAOE", 50 ); //evac AOEs
AddBehaviour( "+SUMMON", 60 ); //summon spells
AddBehaviour( "+HELP", 40 ); //help
AddBehaviour( "+VIS", 40 ); //vision
AddBehaviour( "+DEFSING", 20 ); //defend single
AddBehaviour( "+DEFSELF", 20 ); //defend self
AddBehaviour( "+GROUPENHANCE", 20 ); //enhance group
AddBehaviour( "+ENHANCESING", 20 ); //enhance single
AddBehaviour( "+ENHANCESELF", 20 ); //enhance self
AddBehaviour( "+FEATENHANCE", 20 ); //enhance self via feats
AddBehaviour( "+DISPEL", 20 ); //dispel single
AddBehaviour( "+DISPELAOE", 20 ); //dispel AOEs
AddBehaviour( "+DISMISSAL", 20 ); //dismiss summons
AddBehaviour( "+BREACH", 20 ); //breach
AddBehaviour( "+TIMESTOP", 20 ); //time stop
AddBehaviour( "+AREA", 20 ); //area attack spells
AddBehaviour( "+BREATH", 40 ); //area attack spells
AddBehaviour( "+DIRECT", 20 ); //direct attack spells
AddBehaviour( "+TOUCH", 20 ); //touch attack spells
AddBehaviour( "+MELEEASSIST", 50 ); //assist allies in melee
AddBehaviour( "+ATKRANGED", 100 ); //ranged attack
AddBehaviour( "+ATKMELEE", 100 ); //melee attack
//Other config
//Corpse decay set up and exclusions
SetCorpseDelay();
//Set whether the creature can use EffectDisappearAppear when moving
SetIsFlier();
if ( GetIsObjectValid( GetMaster( OBJECT_SELF ) ) )
{
//I am probably a summoned creature, possibly a henchman
SetAssociateListenPatterns();
}
//set voice chat config
SetVoiceChat( NO_VC_DEFAULT, 10 );
//configure perception ranges
SetPerceptionRanges();
//tell creature it is ready to act
//SetReadyStatus();
//set fastbuffer status, should always be left on
SetIsFastBuffer( TRUE );
//SetLocalInt( OBJECT_SELF, "#FASTBUFFER", 1 );
//SetLocalInt( OBJECT_SELF, "#ACTIVE", 1 );
//log starting location
ExecuteScript( "no_scr_logspnloc", OBJECT_SELF );
//log loaded melee weapons
ExecuteScript( "no_scr_logeq", OBJECT_SELF );
// OPTIONAL BEHAVIORS (Comment In or Out to Activate ) ****************************************************************************
//SetSpawnInCondition(NW_FLAG_SPECIAL_CONVERSATION);
//SetSpawnInCondition(NW_FLAG_SPECIAL_COMBAT_CONVERSATION);
// This causes the creature to say a special greeting in their conversation file
// upon Perceiving the player. Attach the [NW_D2_GenCheck.nss] script to the desired
// greeting in order to designate it. As the creature is actually saying this to
// himself, don't attach any player responses to the greeting.
//SetSpawnInCondition(NW_FLAG_SHOUT_ATTACK_MY_TARGET);
// This will set the listening pattern on the NPC to attack when allies call
SetSpawnInCondition(NW_FLAG_STEALTH);
// If the NPC has stealth and they are a rogue go into stealth mode
//SetSpawnInCondition(NW_FLAG_SEARCH);
// If the NPC has Search go into Search Mode
//SetSpawnInCondition(NW_FLAG_SET_WARNINGS);
// This will set the NPC to give a warning to non-enemies before attacking
//SetSpawnInCondition(NW_FLAG_SLEEP);
//Creatures that spawn in during the night will be asleep.
//SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING);
//SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION);
//SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS);
SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS);
// SetAnimationCondition(NW_ANIM_FLAG_IS_CIVILIZED);
SetAnimationCondition(NW_ANIM_FLAG_CONSTANT);
// SetAnimationCondition(NW_ANIM_FLAG_CHATTER);
// SetAnimationCondition(NW_ANIM_FLAG_IS_MOBILE_CLOSE_RANGE);
//This will play Ambient Animations until the NPC sees an enemy or is cleared.
//NOTE that these animations will play automatically for Encounter Creatures.
// NOTE: ONLY ONE OF THE FOLOOWING ESCAPE COMMANDS SHOULD EVER BE ACTIVATED AT ANY ONE TIME.
//SetSpawnInCondition(NW_FLAG_ESCAPE_RETURN); // OPTIONAL BEHAVIOR (Flee to a way point and return a short time later.)
//SetSpawnInCondition(NW_FLAG_ESCAPE_LEAVE); // OPTIONAL BEHAVIOR (Flee to a way point and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_LEAVE); // OPTIONAL BEHAVIOR (Teleport to safety and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_RETURN); // OPTIONAL BEHAVIOR (Teleport to safety and return a short time later.)
// CUSTOM USER DEFINED EVENTS
/*
The following settings will allow the user to fire one of the blank user defined events in the NW_D2_DefaultD. Like the
On Spawn In script this script is meant to be customized by the end user to allow for unique behaviors. The user defined
events user 1000 - 1010
*/
//SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1001
//SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1002
//SetSpawnInCondition(NW_FLAG_ATTACK_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1005
//SetSpawnInCondition(NW_FLAG_DAMAGED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1006
//SetSpawnInCondition(NW_FLAG_DISTURBED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1008
//SetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1003
//SetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1004
//SetSpawnInCondition(NW_FLAG_DEATH_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1007
SetListeningPatterns(); // Goes through and sets up which shouts the NPC will listen to.
WalkWayPoints(); // Optional Parameter: void WalkWayPoints(int nRun = FALSE, float fPause = 1.0)
// 1. Looks to see if any Way Points in the module have the tag "WP_" + NPC TAG + "_0X", if so walk them
// 2. If the tag of the Way Point is "POST_" + NPC TAG the creature will return this way point after
// combat.
CTG_GenerateNPCTreasure(TREASURE_TYPE_MONSTER, OBJECT_SELF); //* Use this to create a small amount of treasure on the creature
}

View File

@@ -0,0 +1,136 @@
//::///////////////////////////////////////////////
//:: On Spawn In
//::
//:://////////////////////////////////////////////
/*
Determines the course of action to be taken
after having just been spawned in
*/
//:://////////////////////////////////////////////
#include "no_lib_data"
#include "no_inc"
#include "nw_o2_coninclude"
#include "x0_i0_treasure"
void main()
{
//Behaviour config
AddBehaviour( "+HEALSELF", 100 ); //heal self
AddBehaviour( "+REGROUP", 40 ); //regroup
AddBehaviour( "+FLANK", 20 ); //flank
//AddBehaviour( "+AVOIDMELEE", 20 ); //avoid melee
AddBehaviour( "+EVACAOE", 50 ); //evac AOEs
//AddBehaviour( "+SUMMON", 60 ); //summon spells
//AddBehaviour( "+HELP", 40 ); //help
AddBehaviour( "+VIS", 40 ); //vision
AddBehaviour( "+DEFSING", 40 ); //defend single
AddBehaviour( "+DEFSELF", 40 ); //defend self
AddBehaviour( "+GROUPENHANCE", 40 ); //enhance group
AddBehaviour( "+ENHANCESING", 40 ); //enhance single
AddBehaviour( "+ENHANCESELF", 40 ); //enhance self
AddBehaviour( "+FEATENHANCE", 40 ); //enhance self via feats
//AddBehaviour( "+DISPEL", 40 ); //dispel single
//AddBehaviour( "+DISPELAOE", 40 ); //dispel AOEs
//AddBehaviour( "+DISMISSAL", 40 ); //dismiss summons
//AddBehaviour( "+BREACH", 40 ); //breach
//AddBehaviour( "+TIMESTOP", 20 ); //time stop
//AddBehaviour( "+AREA", 80 ); //area attack spells
//AddBehaviour( "+BREATH", 40 ); //area attack spells
//AddBehaviour( "+DIRECT", 80 ); //direct attack spells
//AddBehaviour( "+TOUCH", 80 ); //touch attack spells
AddBehaviour( "+MELEEASSIST", 50 ); //assist allies in melee
//AddBehaviour( "+ATKRANGED", 100 ); //ranged attack
AddBehaviour( "+ATKMELEE", 100 ); //melee attack
//Other config
//Corpse decay set up and exclusions
SetCorpseDelay();
//Set whether the creature can use EffectDisappearAppear when moving
SetIsFlier();
if ( GetIsObjectValid( GetMaster( OBJECT_SELF ) ) )
{
//I am probably a summoned creature, possibly a henchman
SetAssociateListenPatterns();
}
//set voice chat config
SetVoiceChat( NO_VC_DEFAULT, 10 );
//configure perception ranges
SetPerceptionRanges();
//tell creature it is ready to act
//SetReadyStatus();
//set fastbuffer status, should always be left on
SetIsFastBuffer( TRUE );
//SetLocalInt( OBJECT_SELF, "#FASTBUFFER", 1 );
//SetLocalInt( OBJECT_SELF, "#ACTIVE", 1 );
//log starting location
ExecuteScript( "no_scr_logspnloc", OBJECT_SELF );
//log loaded melee weapons
ExecuteScript( "no_scr_logeq", OBJECT_SELF );
// OPTIONAL BEHAVIORS (Comment In or Out to Activate ) ****************************************************************************
//SetSpawnInCondition(NW_FLAG_SPECIAL_CONVERSATION);
//SetSpawnInCondition(NW_FLAG_SPECIAL_COMBAT_CONVERSATION);
// This causes the creature to say a special greeting in their conversation file
// upon Perceiving the player. Attach the [NW_D2_GenCheck.nss] script to the desired
// greeting in order to designate it. As the creature is actually saying this to
// himself, don't attach any player responses to the greeting.
//SetSpawnInCondition(NW_FLAG_SHOUT_ATTACK_MY_TARGET);
// This will set the listening pattern on the NPC to attack when allies call
SetSpawnInCondition(NW_FLAG_STEALTH);
// If the NPC has stealth and they are a rogue go into stealth mode
//SetSpawnInCondition(NW_FLAG_SEARCH);
// If the NPC has Search go into Search Mode
//SetSpawnInCondition(NW_FLAG_SET_WARNINGS);
// This will set the NPC to give a warning to non-enemies before attacking
//SetSpawnInCondition(NW_FLAG_SLEEP);
//Creatures that spawn in during the night will be asleep.
//SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING);
//SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION);
//SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS);
SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS);
// SetAnimationCondition(NW_ANIM_FLAG_IS_CIVILIZED);
SetAnimationCondition(NW_ANIM_FLAG_CONSTANT);
// SetAnimationCondition(NW_ANIM_FLAG_CHATTER);
// SetAnimationCondition(NW_ANIM_FLAG_IS_MOBILE_CLOSE_RANGE);
//This will play Ambient Animations until the NPC sees an enemy or is cleared.
//NOTE that these animations will play automatically for Encounter Creatures.
// NOTE: ONLY ONE OF THE FOLOOWING ESCAPE COMMANDS SHOULD EVER BE ACTIVATED AT ANY ONE TIME.
//SetSpawnInCondition(NW_FLAG_ESCAPE_RETURN); // OPTIONAL BEHAVIOR (Flee to a way point and return a short time later.)
//SetSpawnInCondition(NW_FLAG_ESCAPE_LEAVE); // OPTIONAL BEHAVIOR (Flee to a way point and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_LEAVE); // OPTIONAL BEHAVIOR (Teleport to safety and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_RETURN); // OPTIONAL BEHAVIOR (Teleport to safety and return a short time later.)
// CUSTOM USER DEFINED EVENTS
/*
The following settings will allow the user to fire one of the blank user defined events in the NW_D2_DefaultD. Like the
On Spawn In script this script is meant to be customized by the end user to allow for unique behaviors. The user defined
events user 1000 - 1010
*/
//SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1001
//SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1002
//SetSpawnInCondition(NW_FLAG_ATTACK_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1005
//SetSpawnInCondition(NW_FLAG_DAMAGED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1006
//SetSpawnInCondition(NW_FLAG_DISTURBED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1008
//SetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1003
//SetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1004
//SetSpawnInCondition(NW_FLAG_DEATH_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1007
SetListeningPatterns(); // Goes through and sets up which shouts the NPC will listen to.
WalkWayPoints(); // Optional Parameter: void WalkWayPoints(int nRun = FALSE, float fPause = 1.0)
// 1. Looks to see if any Way Points in the module have the tag "WP_" + NPC TAG + "_0X", if so walk them
// 2. If the tag of the Way Point is "POST_" + NPC TAG the creature will return this way point after
// combat.
CTG_GenerateNPCTreasure(TREASURE_TYPE_MONSTER, OBJECT_SELF); //* Use this to create a small amount of treasure on the creatureed Event 1007
}

View File

@@ -0,0 +1,125 @@
//::///////////////////////////////////////////////
//:: On Spawn In
//::
//:://////////////////////////////////////////////
/*
Determines the course of action to be taken
after having just been spawned in
*/
//:://////////////////////////////////////////////
#include "no_lib_data"
#include "no_inc"
#include "nw_o2_coninclude"
#include "x0_i0_treasure"
void main()
{
//Behaviour config
AddBehaviour( "+HEALSELF", 100 ); //heal self
AddBehaviour( "+FEATENHANCE", 80 ); //enhance self via feats
AddBehaviour( "+REGROUP", 80 ); //regroup
AddBehaviour( "+FLANK", 20 ); //flank
AddBehaviour( "+AREA", 60 ); //area attack spells
AddBehaviour( "+EVACAOE", 50 ); //evac AOEs
AddBehaviour( "+MELEEASSIST", 100 ); //assist allies in melee
AddBehaviour( "+ATKRANGED", 100 ); //ranged attack
AddBehaviour( "+ATKMELEE", 100 ); //melee attack
//Other config
//Corpse decay set up and exclusions
SetCorpseDelay();
//Set whether the creature can use EffectDisappearAppear when moving
SetIsFlier();
if ( GetIsObjectValid( GetMaster( OBJECT_SELF ) ) )
{
//I am probably a summoned creature, possibly a henchman
SetAssociateListenPatterns();
}
//set voice chat config
SetVoiceChat( NO_VC_DEFAULT, 10 );
//configure perception ranges
SetPerceptionRanges();
//set response range for fighting broadcast
SetResponseRange( BC_FIGHTING, 50.0 );
//tell creature it is ready to act
//SetReadyStatus();
//flag as a teleport capable creature
SetIsTeleporter();
//set fastbuffer status, should always be left on
SetIsFastBuffer( TRUE );
//SetLocalInt( OBJECT_SELF, "#FASTBUFFER", 1 );
//SetLocalInt( OBJECT_SELF, "#ACTIVE", 1 );
//log starting location
ExecuteScript( "no_scr_logspnloc", OBJECT_SELF );
//log loaded melee weapons
ExecuteScript( "no_scr_logeq", OBJECT_SELF );
// OPTIONAL BEHAVIORS (Comment In or Out to Activate ) ****************************************************************************
//SetSpawnInCondition(NW_FLAG_SPECIAL_CONVERSATION);
//SetSpawnInCondition(NW_FLAG_SPECIAL_COMBAT_CONVERSATION);
// This causes the creature to say a special greeting in their conversation file
// upon Perceiving the player. Attach the [NW_D2_GenCheck.nss] script to the desired
// greeting in order to designate it. As the creature is actually saying this to
// himself, don't attach any player responses to the greeting.
//SetSpawnInCondition(NW_FLAG_SHOUT_ATTACK_MY_TARGET);
// This will set the listening pattern on the NPC to attack when allies call
SetSpawnInCondition(NW_FLAG_STEALTH);
// If the NPC has stealth and they are a rogue go into stealth mode
//SetSpawnInCondition(NW_FLAG_SEARCH);
// If the NPC has Search go into Search Mode
//SetSpawnInCondition(NW_FLAG_SET_WARNINGS);
// This will set the NPC to give a warning to non-enemies before attacking
//SetSpawnInCondition(NW_FLAG_SLEEP);
//Creatures that spawn in during the night will be asleep.
//SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING);
//SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION);
//SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS);
SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS);
// SetAnimationCondition(NW_ANIM_FLAG_IS_CIVILIZED);
SetAnimationCondition(NW_ANIM_FLAG_CONSTANT);
// SetAnimationCondition(NW_ANIM_FLAG_CHATTER);
// SetAnimationCondition(NW_ANIM_FLAG_IS_MOBILE_CLOSE_RANGE);
//This will play Ambient Animations until the NPC sees an enemy or is cleared.
//NOTE that these animations will play automatically for Encounter Creatures.
// NOTE: ONLY ONE OF THE FOLOOWING ESCAPE COMMANDS SHOULD EVER BE ACTIVATED AT ANY ONE TIME.
//SetSpawnInCondition(NW_FLAG_ESCAPE_RETURN); // OPTIONAL BEHAVIOR (Flee to a way point and return a short time later.)
//SetSpawnInCondition(NW_FLAG_ESCAPE_LEAVE); // OPTIONAL BEHAVIOR (Flee to a way point and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_LEAVE); // OPTIONAL BEHAVIOR (Teleport to safety and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_RETURN); // OPTIONAL BEHAVIOR (Teleport to safety and return a short time later.)
// CUSTOM USER DEFINED EVENTS
/*
The following settings will allow the user to fire one of the blank user defined events in the NW_D2_DefaultD. Like the
On Spawn In script this script is meant to be customized by the end user to allow for unique behaviors. The user defined
events user 1000 - 1010
*/
//SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1001
//SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1002
//SetSpawnInCondition(NW_FLAG_ATTACK_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1005
//SetSpawnInCondition(NW_FLAG_DAMAGED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1006
//SetSpawnInCondition(NW_FLAG_DISTURBED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1008
//SetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1003
//SetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1004
//SetSpawnInCondition(NW_FLAG_DEATH_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1007
SetListeningPatterns(); // Goes through and sets up which shouts the NPC will listen to.
WalkWayPoints(); // Optional Parameter: void WalkWayPoints(int nRun = FALSE, float fPause = 1.0)
// 1. Looks to see if any Way Points in the module have the tag "WP_" + NPC TAG + "_0X", if so walk them
// 2. If the tag of the Way Point is "POST_" + NPC TAG the creature will return this way point after
// combat.
CTG_GenerateNPCTreasure(TREASURE_TYPE_MONSTER, OBJECT_SELF); //* Use this to create a small amount of treasure on the creature
}

136
_module/nss/no_spn_summ.nss Normal file
View File

@@ -0,0 +1,136 @@
//::///////////////////////////////////////////////
//:: On Spawn In
//::
//:://////////////////////////////////////////////
/*
Determines the course of action to be taken
after having just been spawned in
*/
//:://////////////////////////////////////////////
#include "no_lib_data"
#include "no_inc"
#include "nw_o2_coninclude"
#include "x0_i0_treasure"
void main()
{
//Behaviour config
AddBehaviour( "+HEALSELF", 100 ); //heal self
AddBehaviour( "+REGROUP", 40 ); //regroup
AddBehaviour( "+FLANK", 20 ); //flank
AddBehaviour( "+AVOIDMELEE", 20 ); //avoid melee
AddBehaviour( "+EVACAOE", 50 ); //evac AOEs
AddBehaviour( "+SUMMON", 60 ); //summon spells
AddBehaviour( "+HELP", 40 ); //help
AddBehaviour( "+VIS", 40 ); //vision
AddBehaviour( "+DEFSING", 40 ); //defend single
AddBehaviour( "+DEFSELF", 40 ); //defend self
AddBehaviour( "+GROUPENHANCE", 40 ); //enhance group
AddBehaviour( "+ENHANCESING", 40 ); //enhance single
AddBehaviour( "+ENHANCESELF", 40 ); //enhance self
AddBehaviour( "+FEATENHANCE", 40 ); //enhance self via feats
AddBehaviour( "+DISPEL", 40 ); //dispel single
AddBehaviour( "+DISPELAOE", 40 ); //dispel AOEs
AddBehaviour( "+DISMISSAL", 40 ); //dismiss summons
AddBehaviour( "+BREACH", 40 ); //breach
AddBehaviour( "+TIMESTOP", 20 ); //time stop
AddBehaviour( "+AREA", 80 ); //area attack spells
AddBehaviour( "+BREATH", 40 ); //area attack spells
AddBehaviour( "+DIRECT", 80 ); //direct attack spells
AddBehaviour( "+TOUCH", 80 ); //touch attack spells
AddBehaviour( "+MELEEASSIST", 50 ); //assist allies in melee
AddBehaviour( "+ATKRANGED", 100 ); //ranged attack
AddBehaviour( "+ATKMELEE", 100 ); //melee attack
//Other config
//Corpse decay set up and exclusions
SetCorpseDelay();
//Set whether the creature can use EffectDisappearAppear when moving
SetIsFlier();
if ( GetIsObjectValid( GetMaster( OBJECT_SELF ) ) )
{
//I am probably a summoned creature, possibly a henchman
SetAssociateListenPatterns();
}
//set voice chat config
SetVoiceChat( NO_VC_DEFAULT, 10 );
//configure perception ranges
SetPerceptionRanges();
//tell creature it is ready to act
//SetReadyStatus();
//set fastbuffer status, should always be left on
SetIsFastBuffer( TRUE );
//SetLocalInt( OBJECT_SELF, "#FASTBUFFER", 1 );
//SetLocalInt( OBJECT_SELF, "#ACTIVE", 1 );
//log starting location
ExecuteScript( "no_scr_logspnloc", OBJECT_SELF );
//log loaded melee weapons
ExecuteScript( "no_scr_logeq", OBJECT_SELF );
// OPTIONAL BEHAVIORS (Comment In or Out to Activate ) ****************************************************************************
//SetSpawnInCondition(NW_FLAG_SPECIAL_CONVERSATION);
//SetSpawnInCondition(NW_FLAG_SPECIAL_COMBAT_CONVERSATION);
// This causes the creature to say a special greeting in their conversation file
// upon Perceiving the player. Attach the [NW_D2_GenCheck.nss] script to the desired
// greeting in order to designate it. As the creature is actually saying this to
// himself, don't attach any player responses to the greeting.
//SetSpawnInCondition(NW_FLAG_SHOUT_ATTACK_MY_TARGET);
// This will set the listening pattern on the NPC to attack when allies call
//SetSpawnInCondition(NW_FLAG_STEALTH);
// If the NPC has stealth and they are a rogue go into stealth mode
//SetSpawnInCondition(NW_FLAG_SEARCH);
// If the NPC has Search go into Search Mode
//SetSpawnInCondition(NW_FLAG_SET_WARNINGS);
// This will set the NPC to give a warning to non-enemies before attacking
//SetSpawnInCondition(NW_FLAG_SLEEP);
//Creatures that spawn in during the night will be asleep.
//SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING);
//SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION);
//SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS);
SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS);
// SetAnimationCondition(NW_ANIM_FLAG_IS_CIVILIZED);
SetAnimationCondition(NW_ANIM_FLAG_CONSTANT);
// SetAnimationCondition(NW_ANIM_FLAG_CHATTER);
// SetAnimationCondition(NW_ANIM_FLAG_IS_MOBILE_CLOSE_RANGE);
//This will play Ambient Animations until the NPC sees an enemy or is cleared.
//NOTE that these animations will play automatically for Encounter Creatures.
// NOTE: ONLY ONE OF THE FOLOOWING ESCAPE COMMANDS SHOULD EVER BE ACTIVATED AT ANY ONE TIME.
//SetSpawnInCondition(NW_FLAG_ESCAPE_RETURN); // OPTIONAL BEHAVIOR (Flee to a way point and return a short time later.)
//SetSpawnInCondition(NW_FLAG_ESCAPE_LEAVE); // OPTIONAL BEHAVIOR (Flee to a way point and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_LEAVE); // OPTIONAL BEHAVIOR (Teleport to safety and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_RETURN); // OPTIONAL BEHAVIOR (Teleport to safety and return a short time later.)
// CUSTOM USER DEFINED EVENTS
/*
The following settings will allow the user to fire one of the blank user defined events in the NW_D2_DefaultD. Like the
On Spawn In script this script is meant to be customized by the end user to allow for unique behaviors. The user defined
events user 1000 - 1010
*/
//SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1001
//SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1002
//SetSpawnInCondition(NW_FLAG_ATTACK_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1005
//SetSpawnInCondition(NW_FLAG_DAMAGED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1006
//SetSpawnInCondition(NW_FLAG_DISTURBED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1008
//SetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1003
//SetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1004
//SetSpawnInCondition(NW_FLAG_DEATH_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1007
SetListeningPatterns(); // Goes through and sets up which shouts the NPC will listen to.
WalkWayPoints(); // Optional Parameter: void WalkWayPoints(int nRun = FALSE, float fPause = 1.0)
// 1. Looks to see if any Way Points in the module have the tag "WP_" + NPC TAG + "_0X", if so walk them
// 2. If the tag of the Way Point is "POST_" + NPC TAG the creature will return this way point after
// combat.
CTG_GenerateNPCTreasure(TREASURE_TYPE_MONSTER, OBJECT_SELF); //* Use this to create a small amount of treasure on the creature
}

135
_module/nss/no_spn_wiz.nss Normal file
View File

@@ -0,0 +1,135 @@
//::///////////////////////////////////////////////
//:: On Spawn In
//::
//:://////////////////////////////////////////////
/*
Determines the course of action to be taken
after having just been spawned in
*/
//:://////////////////////////////////////////////
#include "no_lib_data"
#include "no_inc"
#include "nw_o2_coninclude"
#include "x0_i0_treasure"
void main()
{
//Behaviour config
AddBehaviour( "+AVOIDMELEE", 50 ); //avoid melee
AddBehaviour( "+EVACAOE", 80 ); //evac AOEs
AddBehaviour( "+HEALSELF", 100 ); //heal self
AddBehaviour( "+REGROUP", 20 ); //regroup
AddBehaviour( "+SUMMON", 50 ); //summon spells
AddBehaviour( "+HELP", 50 ); //help
AddBehaviour( "+VIS", 50 ); //vision
AddBehaviour( "+DEFSELF", 10 ); //defend self
AddBehaviour( "+DEFSING", 5 ); //defend single
AddBehaviour( "+ENHANCESELF", 10 ); //enhance self
AddBehaviour( "+GROUPENHANCE", 5 ); //enhance group
AddBehaviour( "+ENHANCESING", 5 ); //enhance single
AddBehaviour( "+FEATENHANCE", 10 ); //enhance self via feats
AddBehaviour( "+DISPEL", 10 ); //dispel single
AddBehaviour( "+DISPELAOE", 10 ); //dispel AOEs
AddBehaviour( "+DISMISSAL", 10 ); //dismiss summons
AddBehaviour( "+BREACH", 10 ); //breach
AddBehaviour( "+TIMESTOP", 20 ); //time stop
AddBehaviour( "+AREA", 80 ); //area attack spells
AddBehaviour( "+DIRECT", 80 ); //direct attack spells
AddBehaviour( "+TOUCH", 80 ); //touch attack spells
AddBehaviour( "+ATKRANGED", 100 ); //ranged attack
//Other config
//Corpse decay set up and exclusions
SetCorpseDelay();
//Set whether the creature can use EffectDisappearAppear when moving
SetIsFlier();
if ( GetIsObjectValid( GetMaster( OBJECT_SELF ) ) )
{
//I am probably a summoned creature, possibly a henchman
SetAssociateListenPatterns();
}
//set voice chat config
SetVoiceChat( NO_VC_DEFAULT, 10 );
//configure perception ranges
SetPerceptionRanges();
//set response range for fighting broadcast
SetResponseRange( BC_FIGHTING, 50.0 );
//tell creature it is ready to act
//SetReadyStatus();
//set fastbuffer status, should always be left on
SetIsFastBuffer( TRUE );
//SetLocalInt( OBJECT_SELF, "#FASTBUFFER", 1 );
//SetLocalInt( OBJECT_SELF, "#ACTIVE", 1 );
//log starting location
ExecuteScript( "no_scr_logspnloc", OBJECT_SELF );
//log loaded melee weapons
ExecuteScript( "no_scr_logeq", OBJECT_SELF );
// OPTIONAL BEHAVIORS (Comment In or Out to Activate ) ****************************************************************************
//SetSpawnInCondition(NW_FLAG_SPECIAL_CONVERSATION);
//SetSpawnInCondition(NW_FLAG_SPECIAL_COMBAT_CONVERSATION);
// This causes the creature to say a special greeting in their conversation file
// upon Perceiving the player. Attach the [NW_D2_GenCheck.nss] script to the desired
// greeting in order to designate it. As the creature is actually saying this to
// himself, don't attach any player responses to the greeting.
//SetSpawnInCondition(NW_FLAG_SHOUT_ATTACK_MY_TARGET);
// This will set the listening pattern on the NPC to attack when allies call
//SetSpawnInCondition(NW_FLAG_STEALTH);
// If the NPC has stealth and they are a rogue go into stealth mode
//SetSpawnInCondition(NW_FLAG_SEARCH);
// If the NPC has Search go into Search Mode
//SetSpawnInCondition(NW_FLAG_SET_WARNINGS);
// This will set the NPC to give a warning to non-enemies before attacking
//SetSpawnInCondition(NW_FLAG_SLEEP);
//Creatures that spawn in during the night will be asleep.
//SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING);
//SetSpawnInCondition(NW_FLAG_APPEAR_SPAWN_IN_ANIMATION);
//SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS);
SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS);
// SetAnimationCondition(NW_ANIM_FLAG_IS_CIVILIZED);
SetAnimationCondition(NW_ANIM_FLAG_CONSTANT);
// SetAnimationCondition(NW_ANIM_FLAG_CHATTER);
// SetAnimationCondition(NW_ANIM_FLAG_IS_MOBILE_CLOSE_RANGE);
//This will play Ambient Animations until the NPC sees an enemy or is cleared.
//NOTE that these animations will play automatically for Encounter Creatures.
// NOTE: ONLY ONE OF THE FOLOOWING ESCAPE COMMANDS SHOULD EVER BE ACTIVATED AT ANY ONE TIME.
//SetSpawnInCondition(NW_FLAG_ESCAPE_RETURN); // OPTIONAL BEHAVIOR (Flee to a way point and return a short time later.)
//SetSpawnInCondition(NW_FLAG_ESCAPE_LEAVE); // OPTIONAL BEHAVIOR (Flee to a way point and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_LEAVE); // OPTIONAL BEHAVIOR (Teleport to safety and do not return.)
//SetSpawnInCondition(NW_FLAG_TELEPORT_RETURN); // OPTIONAL BEHAVIOR (Teleport to safety and return a short time later.)
// CUSTOM USER DEFINED EVENTS
/*
The following settings will allow the user to fire one of the blank user defined events in the NW_D2_DefaultD. Like the
On Spawn In script this script is meant to be customized by the end user to allow for unique behaviors. The user defined
events user 1000 - 1010
*/
//SetSpawnInCondition(NW_FLAG_HEARTBEAT_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1001
//SetSpawnInCondition(NW_FLAG_PERCIEVE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1002
//SetSpawnInCondition(NW_FLAG_ATTACK_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1005
//SetSpawnInCondition(NW_FLAG_DAMAGED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1006
//SetSpawnInCondition(NW_FLAG_DISTURBED_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1008
//SetSpawnInCondition(NW_FLAG_END_COMBAT_ROUND_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1003
//SetSpawnInCondition(NW_FLAG_ON_DIALOGUE_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1004
//SetSpawnInCondition(NW_FLAG_DEATH_EVENT); //OPTIONAL BEHAVIOR - Fire User Defined Event 1007
SetListeningPatterns(); // Goes through and sets up which shouts the NPC will listen to.
WalkWayPoints(); // Optional Parameter: void WalkWayPoints(int nRun = FALSE, float fPause = 1.0)
// 1. Looks to see if any Way Points in the module have the tag "WP_" + NPC TAG + "_0X", if so walk them
// 2. If the tag of the Way Point is "POST_" + NPC TAG the creature will return this way point after
// combat.
CTG_GenerateNPCTreasure(TREASURE_TYPE_MONSTER, OBJECT_SELF); //* Use this to create a small amount of treasure on the creature
}

View File

@@ -1,114 +0,0 @@
/*/////////////////////// [On Heartbeat] ///////////////////////////////////////
Filename: nw_c2_default1 or J_AI_OnHeartbeat
///////////////////////// [On Heartbeat] ///////////////////////////////////////
Removed stupid stuff, special behaviour, sleep.
Also, note please, I removed waypoints and day/night posting from this.
It can be re-added if you like, but it does reduce heartbeats.
Added in better checks to see if we should fire this script. Stops early if
some conditions (like we can't move, low AI settings) are set.
Hint: If nothing is used within this script, either remove it from creatures
or create one witch is blank, with just a "void main(){}" at the top.
Hint 2: You could add this very small file to your catche of scripts in the
module properties, as it runs on every creature every 6 seconds (ow!)
This also uses a system of Execute Script :-D This means the heartbeat, when
compiled, should be very tiny.
Note: NO Debug strings!
Note 2: Remember, I use default SoU Animations/normal animations. As it is
executed, we can check the prerequisists here, and then do it VIA
execute script.
-Working- Best possible, fast compile.
///////////////////////// [History] ////////////////////////////////////////////
1.3 - Added more "buffs" to fast buff.
- Fixed animations (they both WORK and looping ones do loop right!)
- Loot behaviour!
- Randomly moving nearer a PC in 25M if set.
- Removed silly day/night optional setting. Anything we can remove, is a good idea.
1.4 - Removed AI level setting. Not good to use, I mistakenly added it.
///////////////////////// [Workings] ///////////////////////////////////////////
This fires off every 6 seconds (with PCs in the area, or AI_LEVEL_HIGH without)
and therefore is intensive.
It fires of ExecutesScript things for the different parts - saves CPU stuff
if the bits are not used.
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: Basically, none. Nothing activates this script. Fires every 6 seconds.
///////////////////////// [On Heartbeat] /////////////////////////////////////*/
// - This includes J_Inc_Constants
#include "J_INC_HEARTBEAT"
void main()
{
// Special - Runner from the leader shouts, each heartbeat, to others to get thier
// attention that they are being attacked.
// - Includes fleeing making sure (so it resets the ActionMoveTo each 6 seconds -
// this is not too bad)
// - Includes door bashing stop heartbeat
if(PerformSpecialAction()) return;
// Pre-heartbeat-event. Returns TRUE if we interrupt this script call.
if(FirePreUserEvent(AI_FLAG_UDE_HEARTBEAT_PRE_EVENT, EVENT_HEARTBEAT_PRE_EVENT)) return;
// AI status check. Is the AI on?
if(GetAIOff() || GetSpawnInCondition(AI_FLAG_OTHER_LAG_IGNORE_HEARTBEAT, AI_OTHER_MASTER)) return;
// Define the enemy and player to use.
object oEnemy = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY);
object oPlayer = GetNearestCreature(CREATURE_TYPE_PLAYER_CHAR, PLAYER_CHAR_IS_PC);
// We can skip to the end if we are in combat, or something...
if(!JumpOutOfHeartBeat() && // We don't stop due to effects.
!GetIsInCombat() && // We are not in combat.
!GetIsObjectValid(GetAttackTarget()) && // Second combat check.
!GetObjectSeen(oEnemy)) // Nearest enemy is not seen.
{
// Fast buffing...if we have the spawn in condition...
if(GetSpawnInCondition(AI_FLAG_COMBAT_FLAG_FAST_BUFF_ENEMY, AI_COMBAT_MASTER) &&
GetIsObjectValid(oEnemy) && GetDistanceToObject(oEnemy) <= 40.0)
{
// ...we may do an advanced buff. If we cannot see/hear oEnemy, but oEnemy
// is within 40M, we cast many defensive spells instantly...
ExecuteScript(FILE_HEARTBEAT_TALENT_BUFF, OBJECT_SELF);
//...if TRUE (IE it does something) we turn of future calls.
DeleteSpawnInCondition(AI_FLAG_COMBAT_FLAG_FAST_BUFF_ENEMY, AI_COMBAT_MASTER);
// This MUST STOP the heartbeat event - else, the actions may be interrupted.
return;
}
// Execute waypoints file if we have waypoints set up.
if(GetWalkCondition(NW_WALK_FLAG_CONSTANT))
{
ExecuteScript(FILE_WALK_WAYPOINTS, OBJECT_SELF);
}
// We can't have any waypoints for the other things
else
{
// We must have animations set, and not be "paused", so doing a
// longer looping one
// - Need a valid player.
if(GetIsObjectValid(oPlayer) && !IsInConversation(OBJECT_SELF))
{
// We may search for PC enemies, 25% chance to move closer to PC's
if(GetSpawnInCondition(AI_FLAG_OTHER_SEARCH_IF_ENEMIES_NEAR, AI_OTHER_MASTER) &&
!GetLocalTimer(AI_TIMER_SEARCHING) && d4() == 1)
{
ExecuteScript(FILE_HEARTBEAT_WALK_TO_PC, OBJECT_SELF);
}
// Else, Do we have any animations to speak of?
// If we have a nearby PC, we do animations.
else if(GetHasValidAnimations())
{
ExecuteScript(FILE_HEARTBEAT_ANIMATIONS, OBJECT_SELF);
}
}
}
}
// Fire End-heartbeat-UDE
FireUserEvent(AI_FLAG_UDE_HEARTBEAT_EVENT, EVENT_HEARTBEAT_EVENT);
}

View File

@@ -1,225 +0,0 @@
/*/////////////////////// [On Percieve] ////////////////////////////////////////
Filename: J_AI_OnPercieve or nw_c2_default2
///////////////////////// [On Percieve] ////////////////////////////////////////
If the target is an enemy, attack
Will determine combat round on that person, is an enemy, basically.
Includes shouting for a big radius - if the spawn in condition is set to this.
NOTE: Debug strings in this file will be uncommented for speed by default.
- It is one of the most intensive scripts as it runs so often.
- Attempted to optimise as much as possible.
///////////////////////// [History] ////////////////////////////////////////////
1.3 - We include j_inc_other_ai to initiate combat (or go into combat again)
- j_inc_other_ai holds all other needed functions/integers ETC.
- Turn off hide things.
- Added "Only attack if attacked"
- Removed special conversation things. Almost no one uses them, and the taunt system is easier.
- Should now search around if they move to a dead body, and only once they get there.
1.4 - TO DO:
1. Perception needs checking - attacking outside perception ranges!
2. Vanishing targets, etc. test, improve.
3. Problems with dispelling invisibility. Maybe either do change the line to create placable, or, of course, cast at location (dispells cannot be metamagiked or whatever) Source
4. No Effect Type Ethereal. Source
///////////////////////// [Workings] ///////////////////////////////////////////
It fires:
- When a creature enters it perception range (Set in creature properties) and
is seen or heard.
* Tests show (and in general) it fires HEARD first, then immediantly SEEN if,
of course, they are visible. Odd really, but true.
- When a creature uses invisiblity/leaves the area in the creatures perception
range
- When a creature appears suddenly, already in the perception range (not
the other way round, normally)
- When a creature moves out of the creatures perception range, and therefore
becomes unseen.
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: GetLastPerceived, GetLastPerceptionSeen, GetLastPerceptionHeard,
GetLastPerceptionVanished, GetLastPerceptionInaudible.
///////////////////////// [On Percieve] //////////////////////////////////////*/
#include "J_INC_OTHER_AI"
void main()
{
// Pre-percieve-event. Returns TRUE if we interrupt this script call.
if(FirePreUserEvent(AI_FLAG_UDE_PERCIEVE_PRE_EVENT, EVENT_PERCIEVE_PRE_EVENT)) return;
// AI status check. Is the AI on?
if(GetAIOff()) return;
//:: Skip commoners unless the are beign attacked
string sCommoner = GetTag(OBJECT_SELF);
if (!GetIsInCombat() && FindSubString(sCommoner, "NPC_COM_")) return;
// Declare main things.
// - We declare OUTSIDE if's JUST IN CASE!
object oPerceived = GetLastPerceived();
object oAttackTarget = GetAttackTarget();
// 1.4: Very rarely is our attack target valid, so we will set it to
// what we would have melee attacked when DCR was called.
if(GetIgnoreNoFriend(oAttackTarget) || oAttackTarget == OBJECT_SELF)
{
oAttackTarget = GetAIObject(AI_LAST_MELEE_TARGET);
}
int bSeen = GetLastPerceptionSeen();
int bHeard = GetLastPerceptionHeard();
int bVanished = GetLastPerceptionVanished();
int bInaudiable = GetLastPerceptionInaudible();
// Debug
DebugActionSpeak("*** PER ***: " + GetName(oPerceived) + "| SEEN: " + IntToString(bSeen) +
"| HEARD: " + IntToString(bHeard) + "| VANISHED: " + IntToString(bVanished) +
"| INAUDIABLE: " + IntToString(bInaudiable));
// Need to be valid and not ignorable.
if(GetIsObjectValid(oPerceived) &&
!GetIsDM(oPerceived) &&
!GetIgnore(oPerceived))
{
// First, easy enemy checks.
if(GetIsEnemy(oPerceived) && !GetFactionEqual(oPerceived))
{
DebugActionSpeak("*** PER *** ENEMY");
// Turn of hiding, a timer to activate Hiding in the main file. This is
// done in each of the events, with the opposition checking seen/heard.
TurnOffHiding(oPerceived);
// Well, are we both inaudible and vanished?
// * the GetLastPerception should only say what specific event has fired!
if(bVanished || bInaudiable)
{
DebugActionSpeak("*** PER *** VANISHED OR INAUDIBLE");
// If they just became invisible because of the spell
// invisiblity, or improved invisiblity...we set a local object.
// - Beta: Added in ethereal as well.
if(GetHasEffect(EFFECT_TYPE_INVISIBILITY, oPerceived) ||
GetHasEffect(EFFECT_TYPE_SANCTUARY, oPerceived) ||
GetStealthMode(oPerceived) == STEALTH_MODE_ACTIVATED)
{
// Set object, AND the location they went invisible!
SetAIObject(AI_LAST_TO_GO_INVISIBLE, oPerceived);
// We also set thier location for AOE dispelling - same name
SetAILocation(AI_LAST_TO_GO_INVISIBLE, GetLocation(oPerceived));
}
// If they were our target, follow! >:-D
// - Optional, on spawn option, for following through areas.
if(oAttackTarget == oPerceived)
{
DebugActionSpeak("*** PER *** VANISHED OR INAUDIBLE AND IS CURRENT TARGET");
// This means they have exited the area! follow!
if(GetArea(oPerceived) != GetArea(OBJECT_SELF))
{
ClearAllActions();
// 51: "[Perception] Our Enemy Target changed areas. Stopping, moving too...and attack... [Percieved] " + GetName(oPerceived)
DebugActionSpeakByInt(51, oPerceived);
// Call to stop silly moving to enemies if we are fleeing
ActionMoveToEnemy(oPerceived);
}
// - Added check for not casting a spell. If we are, we finnish
// (EG: AOE spell) and automatically carry on.
// 1.4: If we are using a targetted spell, we do cancle our
// spellcasting if it is them.
else if(GetCurrentAction() != ACTION_CASTSPELL ||
GetAttackTarget() == oPerceived)
{
ClearAllActions();
// 52: "[Perception] Enemy Vanished (Same area) Retargeting/Searching [Percieved] " + GetName(oPerceived)
DebugActionSpeakByInt(52, oPerceived);
DetermineCombatRound(oPerceived);
}
}
}// End if just gone out of perception
// ELSE they have been SEEN or HEARD. We don't check specifics.
else //if(bSeen || bHeard)
{
// If they have been made seen, and they are our attack target,
// we must re-do combat round - unless we are casting a spell.
if(bSeen && GetCurrentAction() != ACTION_CASTSPELL &&
(oAttackTarget == oPerceived || !GetObjectSeen(oAttackTarget)))
{
// 53: "[Perception] Enemy seen, and was old enemy/cannot see current. Re-evaluating (no spell) [Percieved] " + GetName(oPerceived)
DebugActionSpeakByInt(53, oPerceived);
DetermineCombatRound(oPerceived);
// Shout to allies to attack oPerceived
AISpeakString(AI_SHOUT_I_WAS_ATTACKED);
}
// Else We check if we are already attacking.
else if(!CannotPerformCombatRound() &&
!GetSpawnInCondition(AI_FLAG_OTHER_ONLY_ATTACK_IF_ATTACKED, AI_OTHER_MASTER))
{
// * Don't speak when dead. 1.4 change (an obvious one to make)
if(CanSpeak())
{
// Special shout, d1000 though!
SpeakArrayString(AI_TALK_ON_PERCIEVE_ENEMY, TRUE);
}
// Stop stuff because of facing point - New enemy
HideOrClear();
// Get all allies in 60M to come to thier aid. Talkvolume silent
// shout does not seem to work well.
// - void function. Checks for the spawn int. in it.
// - Turns it off in it too (5 minutes - 1.4)
// - Variable range On Spawn
ShoutBossShout(oPerceived);
// 54: "[Perception] Enemy Seen. Not in combat, attacking. [Percieved] " + GetName(oPerceived)
DebugActionSpeakByInt(54, oPerceived);
// 1.4 change: SetFacingPoint(GetPosition(oPerceived));
// Is now part of DetermineCombatRound().
// * This means other events will work similarily.
DetermineCombatRound(oPerceived);
// Warn others
AISpeakString(AI_SHOUT_I_WAS_ATTACKED);
}
}
}
// Else, they are an equal faction, or not an enemy (or both)
else
{
// If they are dead, or fighting, eg: we saw something on
// waypoints, we charge in to investigate.
// * Higher intelligence will buff somewhat as well!
if((GetIsDead(oPerceived) || GetIsInCombat(oPerceived)) &&
(bSeen || bHeard))
{
if(GetIsDead(oPerceived))
{
// 55: "[Perception] Percieved Dead Friend! Moving into investigate [Percieved] " + GetName(oPerceived)
DebugActionSpeakByInt(55, oPerceived);
}
else
{
// 56: "[Perception] Percieved Alive Fighting Friend! Moving to and attacking. [Percieved] " + GetName(oPerceived)
DebugActionSpeakByInt(56, oPerceived);
}
// Check if we can attack
if(!CannotPerformCombatRound())
{
// Hide or clear actions
HideOrClear();
// If we were called to arms, react
CallToArmsResponse(oPerceived);
}
else
{
// Warn others even if we don't, or cannot, attack
AISpeakString(AI_SHOUT_CALL_TO_ARMS);
}
}
}
}
// Fire End of Percieve event
FireUserEvent(AI_FLAG_UDE_PERCIEVE_EVENT, EVENT_PERCIEVE_EVENT);
}

View File

@@ -1,37 +0,0 @@
/*/////////////////////// [On Combat Round End] ////////////////////////////////
Filename: nw_c2_default3 or J_AI_OnCombatrou
///////////////////////// [On Combat Round End] ////////////////////////////////
This is run every 3 or 6 seconds, if the creature is in combat. It is
executed only in combat automatically.
It runs what the AI should do, bascially.
///////////////////////// [History] ////////////////////////////////////////////
1.3 - Executes same script as the other parts of the AI to cuase a new action
1.4 -
///////////////////////// [Workings] ///////////////////////////////////////////
Calls the combat AI file using the J_INC_OTHER_AI include function,
DetermineCombatRound.
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: GetAttackTarget, GetLastHostileActor, GetAttemptedAttackTarget,
GetAttemptedSpellTarget (Or these are useful at least!)
///////////////////////// [On Combat Round End] //////////////////////////////*/
#include "J_INC_OTHER_AI"
void main()
{
// Pre-combat-round-event. Returns TRUE if we interrupt this script call.
if(FirePreUserEvent(AI_FLAG_UDE_END_COMBAT_ROUND_PRE_EVENT, EVENT_END_COMBAT_ROUND_PRE_EVENT)) return;
// AI status check. Is the AI on?
if(GetAIOff()) return;
// It is our normal call (every 3 or 6 seconds, when we can change actions)
// so no need to delete, and we fire the UDE's.
// Determine combat round against an invalid target (as default)
DetermineCombatRound();
// Fire End of end combat round event
FireUserEvent(AI_FLAG_UDE_END_COMBAT_ROUND_EVENT, EVENT_END_COMBAT_ROUND_EVENT);
}

View File

@@ -1,160 +0,0 @@
/*/////////////////////// [On Conversation] ////////////////////////////////////
Filename: J_AI_OnConversat or nw_c2_default4
///////////////////////// [On Conversation] ////////////////////////////////////
OnConversation/ Listen to shouts.
Documented, and checked. -Working-
Added spawn in condition - Never clear actions when talking.
///////////////////////// [History] ////////////////////////////////////////////
1.3 - Added in conversation thing - IE we can set speakstrings, no need for conversation file.
- Sorted more shouts out.
- Should work right, and not cause too many actions (as we ignore
shouts for normally 12 or so seconds before letting them affect us again).
1.4 - Deafness incorpreated.
///////////////////////// [Workings] ///////////////////////////////////////////
Uses RespondToShout to react to allies' shouts, and just attacks any enemy
who speaks, or at least moves to them. (OK, dumb if they are invisible, but
oh well, they shouldn't talk so loud!)
Remember, whispers are never heard if too far away, speakstrings don't go
through walls, and shouts are always heard (so we don't go off to anyone
not in our area, remember)
Deafness causes us to never hear battle, so unless we see the target speaking
we do not react. Doesn't apply to normal conversations - although if we cannot
talk (also restricted by deafness) then so be it.
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: GetListenPatternNumber, GetLastSpeaker, TestStringAgainstPattern,
GetMatchedSubstring
///////////////////////// [On Conversation] //////////////////////////////////*/
#include "J_INC_OTHER_AI"
void main()
{
// Pre-conversation-event. Returns TRUE if we interrupt this script call.
if(FirePreUserEvent(AI_FLAG_UDE_ON_DIALOGUE_PRE_EVENT, EVENT_ON_DIALOGUE_PRE_EVENT)) return;
// AI status check. Is the AI on?
if(GetAIOff()) return;
// Declarations
int nMatch = GetListenPatternNumber();
object oShouter = GetLastSpeaker();
string sSpoken = GetMatchedSubstring(0);
// We can ignore everything under special cases - EG no valid shouter,
// we are fleeing, its us, or we are not in the same area.
// - We break out of the script if this happens.
if(!GetIsObjectValid(oShouter) || /* Must be a valid speaker! */
oShouter == OBJECT_SELF || /* Not us! */
GetIsPerformingSpecialAction() || /* Not fleeing */
GetIgnore(oShouter) || /* Not ignoring the shouter */
GetArea(oShouter) != GetArea(OBJECT_SELF))/* Same area (Stops loud yellow shouts getting NPCs) */
{
// Fire End of Dialogue event
FireUserEvent(AI_FLAG_UDE_ON_DIALOGUE_EVENT, EVENT_ON_DIALOGUE_EVENT);
return;
}
// Conversation if not a shout.
if(nMatch == -1)
{
// * Don't speak when dead. 1.4 change (an obvious one to make)
if(CanSpeak())
{
// Make sure it is a PC and we are not fighting.
if(!GetIsFighting() && (GetIsPC(oShouter) || GetIsDMPossessed(oShouter)))
{
// If we have something random (or not) to say instead of
// the conversation, we will say that.
if(GetLocalInt(OBJECT_SELF, ARRAY_SIZE + AI_TALK_ON_CONVERSATION))
{
ClearAllActions();// Stop
SetFacingPoint(GetPosition(oShouter));// Face
SpeakArrayString(AI_TALK_ON_CONVERSATION);// Speak string
PlayAnimation(ANIMATION_LOOPING_TALK_NORMAL, 1.0, 3.0);// "Talk", then resume potitions.
ActionDoCommand(ExecuteScript(FILE_WALK_WAYPOINTS, OBJECT_SELF));
}
else
{
// If we are set to NOT clear all actions, we won't.
if(!GetSpawnInCondition(AI_FLAG_OTHER_NO_CLEAR_ACTIONS_BEFORE_CONVERSATION, AI_OTHER_MASTER))
{
ClearAllActions();
}
BeginConversation();
}
}
}
}
// If it is a valid shout...and a valid shouter.
// - Not a DM. Not ignoring shouting. Not a Debug String.
else if(!GetLocalTimer(AI_TIMER_SHOUT_IGNORE_ANYTHING_SAID) &&// Not listening (IE heard already)
!GetIsDM(oShouter) && FindSubString(sSpoken, "[Debug]") == -1 &&
// 1.4 - Deafness (or they are seen) check, for fun.
(!GetHasEffect(EFFECT_TYPE_DEAF) || GetObjectSeen(oShouter)))
{
if(GetIsFriend(oShouter) || GetFactionEqual(oShouter))
{
// If they are a friend, not a PC, and a valid number, react.
// In the actual RespondToShout call, we do check to see if we bother.
// - Is PC - or is...master?
// - Shouts which are not negative, and not AI_ANYTHING_SAID_CONSTANT.
if(nMatch >= 0 && nMatch != AI_SHOUT_ANYTHING_SAID_CONSTANT &&
!GetIsPC(oShouter) && !GetIsPC(GetMaster(oShouter)))
{
// Respond to the shout
RespondToShout(oShouter, nMatch);
}
// Else either is PC or is shout 0 (everything!)
// - not if we are in combat, or they are not.
else if(!CannotPerformCombatRound() &&
GetIsInCombat(oShouter) &&
GetObjectType(oShouter) == OBJECT_TYPE_CREATURE)
{
// 57: "[Shout] Friend (may be PC) in combat. Attacking! [Friend] " + GetName(oShouter)
DebugActionSpeakByInt(57, oShouter);
// Respond to oShouter
IWasAttackedResponse(oShouter);
}
}
else if(GetIsEnemy(oShouter) && GetObjectType(oShouter) == OBJECT_TYPE_CREATURE)
{
// If we hear anything said by an enemy, and are not fighting, attack them!
if(!CannotPerformCombatRound())
// the negatives are associate shouts, Normally (!)
// 0+ are my shouts. 0 is anything
{
// We make sure it isn't an emote (set by default)
if(nMatch == AI_SHOUT_ANYTHING_SAID_CONSTANT &&
GetSpawnInCondition(AI_FLAG_OTHER_DONT_RESPOND_TO_EMOTES, AI_OTHER_MASTER))
{
// Jump out if its an emote - "*Nods*"
if(GetStringLeft(sSpoken, 1) == EMOTE_STAR &&
GetStringRight(sSpoken, 1) == EMOTE_STAR)
{
// Fire End of Dialogue event
FireUserEvent(AI_FLAG_UDE_ON_DIALOGUE_EVENT, EVENT_ON_DIALOGUE_EVENT);
return;
}
}
// 58: "[Shout] Responding to shout [Enemy] " + GetName(oShouter) + " Who has spoken!"
DebugActionSpeakByInt(58, oShouter);
// Short non-respond
SetLocalTimer(AI_TIMER_SHOUT_IGNORE_ANYTHING_SAID, 6.0);
// Attack the enemy!
ClearAllActions();
DetermineCombatRound(oShouter);
// Shout to allies to attack the shouter
AISpeakString(AI_SHOUT_I_WAS_ATTACKED);
}
}
}
// Fire End of Dialogue event
FireUserEvent(AI_FLAG_UDE_ON_DIALOGUE_EVENT, EVENT_ON_DIALOGUE_EVENT);
}

View File

@@ -1,136 +0,0 @@
/*/////////////////////// [On Phisical Attacked] ///////////////////////////////
Filename: J_AI_OnPhiAttack or nw_c2_default5
///////////////////////// [On Phisical Attacked] ///////////////////////////////
On Attacked
No checking for fleeing or warnings.
Very boring really!
///////////////////////// [History] ////////////////////////////////////////////
1.3 - Added hiding things
1.4 - Missing Silent Shouts have been added.
///////////////////////// [Workings] ///////////////////////////////////////////
Got some simple Knockdown timer, so that we use heal sooner if we keep getting
a creature who is attempting to knock us down.
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: GetLastAttacker, GetLastWeaponUsed, GetLastAttackMode, GetLastAttackType
///////////////////////// [On Phisical Attacked] /////////////////////////////*/
#include "J_INC_OTHER_AI"
void main()
{
// Pre-attacked-event. Returns TRUE if we interrupt this script call.
if(FirePreUserEvent(AI_FLAG_UDE_ATTACK_PRE_EVENT, EVENT_ATTACK_PRE_EVENT)) return;
// AI status check. Is the AI on?
if(GetAIOff()) return;
// Set up objects.
object oAttacker = GetLastAttacker();
object oWeapon = GetLastWeaponUsed(oAttacker);
//int nMode = GetLastAttackMode(oAttacker); // Currently unused
int nAttackType = GetLastAttackType(oAttacker);
// Check if they are valid, a DM, we are ignoring them, they are dead now, or invalid
if(!GetIgnoreNoFriend(oAttacker))
{
// Adjust automatically if set.
if(GetSpawnInCondition(AI_FLAG_OTHER_CHANGE_FACTIONS_TO_HOSTILE_ON_ATTACK, AI_OTHER_MASTER))
{
if(!GetIsEnemy(oAttacker))
{
AdjustReputation(oAttacker, OBJECT_SELF, -100);
}
}
// If we were attacked by knockdown, for a timer of X seconds, we make
// sure we attempt healing at a higher level.
if(!GetLocalTimer(AI_TIMER_KNOCKDOWN) &&
(nAttackType == SPECIAL_ATTACK_IMPROVED_KNOCKDOWN ||
nAttackType == SPECIAL_ATTACK_KNOCKDOWN) &&
!GetIsImmune(OBJECT_SELF, IMMUNITY_TYPE_KNOCKDOWN) &&
GetBaseAttackBonus(oAttacker) + 20 >= GetAC(OBJECT_SELF))
{
SetLocalTimer(AI_TIMER_KNOCKDOWN, 30.0);
}
// Set last hostile, valid attacker (Used in the On Damaged event)
SetAIObject(AI_STORED_LAST_ATTACKER, oAttacker);
// * Don't speak when dead. 1.4 change (an obvious one to make)
if(CanSpeak())
{
// Speak the phisically attacked string, if applicable.
// Speak the damaged string, if applicable.
SpeakArrayString(AI_TALK_ON_PHISICALLY_ATTACKED);
}
// Turn of hiding, a timer to activate Hiding in the main file. This is
// done in each of the events, with the opposition checking seen/heard.
TurnOffHiding(oAttacker);
// We set if we are attacked in HTH onto a low-delay timer.
// - Not currently used
/*if(!GetLocalTimer(AI_TIMER_ATTACKED_IN_HTH))
{
// If the weapon is not ranged, or is not valid, set the timer.
if(!GetIsObjectValid(oWeapon) ||
!GetWeaponRanged(oWeapon))
{
SetLocalTimer(AI_TIMER_ATTACKED_IN_HTH, f18);
}
}*/
// If we are not fighting, and they are in the area, attack. Else, determine anyway.
if(!CannotPerformCombatRound())
{
// Must be in our area to go after now.
if(GetArea(oAttacker) == GetArea(OBJECT_SELF))
{
// 59: "[Phisically Attacked] Attacking back. [Attacker(enemy)] " + GetName(oAttacker)
DebugActionSpeakByInt(59, oAttacker);
// Attack the attacker
DetermineCombatRound(oAttacker);
// Shout to allies to attack the enemy who attacked me
AISpeakString(AI_SHOUT_I_WAS_ATTACKED);
}
else
{
// Shout to allies to attack, or be prepared.
AISpeakString(AI_SHOUT_CALL_TO_ARMS);
// 60: "[Phisically Attacked] Not same area. [Attacker(enemy)] " + GetName(oAttacker)
DebugActionSpeakByInt(60, oAttacker);
// May find another hostile to attack...
DetermineCombatRound();
}
}
else
{
// Shout to allies to attack, or be prepared.
AISpeakString(AI_SHOUT_CALL_TO_ARMS);
}
}
// Else, invalid, DM, ally, etc...must be prepared at least (could be
// they are charmed or something!)
else
{
// If we are not fighting, prepare for battle. Something bad must have
// happened.
if(!CannotPerformCombatRound())
{
// Respond to oAttacker as if they shouted for help.
IWasAttackedResponse(oAttacker);
}
else
{
// Shout to allies to attack, or be prepared.
AISpeakString(AI_SHOUT_CALL_TO_ARMS);
}
}
// Fire End of Attacked event
FireUserEvent(AI_FLAG_UDE_ATTACK_EVENT, EVENT_ATTACK_EVENT);
}

View File

@@ -1,241 +0,0 @@
/*/////////////////////// [On Damaged] /////////////////////////////////////////
Filename: nw_c2_default6 or J_AI_OnDamaged
///////////////////////// [On Damaged] /////////////////////////////////////////
We attack any damager if same area (and not already fighting
then search for enemies (defaults to searching if there are no enemies left).
///////////////////////// [History] ////////////////////////////////////////////
1.3 - If we have a damager, not equal faction, and not a DM...
- We set Max Elemental damage.
- Sets the highest damager and amount (if the new damager is seen/heard)
- Polymorph improved a little
- Hide check
- Morale penalty (if set)
1.4 - Elemental damage fixed with bugfixed introduced in later patches.
- Moved things around, more documentation, a little more ordered.
- Added the missing silent shout strings to get allies to attack.
- Damaged taunting will not happen if we are dead.
///////////////////////// [Workings] ///////////////////////////////////////////
Now with fixes, we can correctly set physical damage done (and elemental
damage).
Otherwise, this acts like a hositile spell, or a normal attack or pickpocket
attempt would - and attack the damn person who dares damage us!
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: GetTotalDamageDealt, GetLastDamager, GetCurrentHitPoints (and max),
GetDamageDealtByType (must be done seperatly for each, doesn't count melee damage)
///////////////////////// [On Damaged] ///////////////////////////////////////*/
#include "J_INC_OTHER_AI"
void main()
{
// Pre-damaged-event. Returns TRUE if we interrupt this script call.
if(FirePreUserEvent(AI_FLAG_UDE_DAMAGED_PRE_EVENT, EVENT_DAMAGED_PRE_EVENT)) return;
// AI status check. Is the AI on?
if(GetAIOff()) return;
// Define Objects/Integers.
int nDamage = GetTotalDamageDealt();
object oDamager = GetLastDamager();
// Check to see if we will polymorph.
int nPolymorph = GetAIConstant(AI_POLYMORPH_INTO);
// Total up the physical damage
// Polymorph check.
if(nPolymorph >= 0)
{
// We won't polymorph if already so
if(!GetHasEffect(EFFECT_TYPE_POLYMORPH))
{
// Polymorph into the requested shape. Cannot be dispelled.
effect eShape = SupernaturalEffect(EffectPolymorph(nPolymorph));
effect eVis = EffectVisualEffect(VFX_FNF_SUMMON_UNDEAD);
DelayCommand(1.0, ApplyEffectToObject(DURATION_TYPE_PERMANENT, eShape, OBJECT_SELF));
DelayCommand(1.0, ApplyEffectToObject(DURATION_TYPE_INSTANT, eVis, OBJECT_SELF));
}
DeleteAIConstant(AI_POLYMORPH_INTO);// We set it to invalid (sets to 0).
}
// First, we check AOE spells...
if(GetObjectType(oDamager) == OBJECT_TYPE_AREA_OF_EFFECT)
{
// Set the damage done by it (the last damage)
// Set to the tag of the AOE, prefixed AI style to be sure.
// - Note, doesn't matter about things like
if(nDamage > 0)
{
// Set it to object to string, which we will delete later anywho.
SetAIInteger(ObjectToString(oDamager), nDamage);
}
}
// Hostile attacker...but it doesn't matter (at the moment) if they even
// did damage.
// * GetIgnoreNoFriend() wrappers DM, Validity, Faction Equal and Dead checks in one
else if(!GetIgnoreNoFriend(oDamager))
{
// Adjust automatically if set. (and not an AOE)
if(GetSpawnInCondition(AI_FLAG_OTHER_CHANGE_FACTIONS_TO_HOSTILE_ON_ATTACK, AI_OTHER_MASTER))
{
if(!GetIsEnemy(oDamager) && !GetFactionEqual(oDamager))
{
AdjustReputation(oDamager, OBJECT_SELF, -100);
}
}
// Turn of hiding, a timer to activate Hiding in the main file. This is
// done in each of the events, with the opposition checking seen/heard.
TurnOffHiding(oDamager);
// Did they do damage to use? (IE: No DR) Some things are inapproprate
// to check if no damage was actually done.
if(nDamage > 0)
{
// Speak the damaged string, if applicable.
// * Don't speak when dead. 1.4 change (an obvious one to make)
if(CanSpeak())
{
SpeakArrayString(AI_TALK_ON_DAMAGED);
}
// 1.4 note: These two variables are currently *unused* apart from
// healing. When healing a being (even another NPC) they are checked
// for massive damage. Can not bother to set the highest damager for now.
// NEW:
int nHighestDamage = GetAIInteger(AI_HIGHEST_DAMAGE_AMOUNT);
if(nDamage >= nHighestDamage)
{
SetAIInteger(AI_HIGHEST_DAMAGE_AMOUNT, nDamage);
}
/* OLD:
// Get the previous highest damager, and highest damage amount
object oHighestDamager = GetAIObject(AI_HIGHEST_DAMAGER);
int nHighestDamage = GetAIInteger(AI_HIGHEST_DAMAGE_AMOUNT);
// Set the highest damager, if they are seen or heard, and have done loads.
if((GetObjectSeen(oDamager) || GetObjectHeard(oDamager)) &&
nDamage >= nHighestDamage || !GetIsObjectValid(oHighestDamager))
{
SetAIObject(AI_HIGHEST_DAMAGER, oDamager);
SetAIInteger(AI_HIGHEST_DAMAGE_AMOUNT, nDamage);
}
// Else, if the original was not valid...or not seen/heard, we
// delete it so we don't bother to use it later.
else if(!GetIsObjectValid(oHighestDamager) ||
(!GetObjectSeen(oHighestDamager) && !GetObjectHeard(oHighestDamager)))
{
DeleteAIObject(AI_HIGHEST_DAMAGER);
DeleteAIInteger(AI_HIGHEST_DAMAGE_AMOUNT);
}
*/
// Get all the physical damage. Elemental damage is then nDamage minus
// the physical damage.
int nPhysical = GetDamageDealtByType(DAMAGE_TYPE_BASE_WEAPON |
DAMAGE_TYPE_BLUDGEONING |
DAMAGE_TYPE_PIERCING |
DAMAGE_TYPE_SLASHING);
// If they are all -1, then we make nPhysical 0.
if(nPhysical <= -1) nPhysical = 0;
// Physical damage - only sets if the last damager is the last attacker.
if(GetAIObject(AI_STORED_LAST_ATTACKER) == oDamager)
{
// Get the previous highest damage and test it
if(nPhysical > GetAIInteger(AI_HIGHEST_PHISICAL_DAMAGE_AMOUNT))
{
// If higher, and was a melee/ranged attacker, set it.
// This does include other additional physical damage - EG:
// weapon property: Bonus Damage.
SetAIInteger(AI_HIGHEST_PHISICAL_DAMAGE_AMOUNT, nPhysical);
}
}
// Set the max elemental damage done, for better use of elemental
// protections. This is set for the most damage...so it could be
// 1 (for a +1 fire weapon, any number of hits) or over 50 (good
// fireball/flame storm etc.)
int nElemental = nDamage - nPhysical;
if(nElemental > GetAIInteger(MAX_ELEMENTAL_DAMAGE))
{
SetAIInteger(MAX_ELEMENTAL_DAMAGE, nElemental);
}
// Set the last damage done, may set to 0 of course :-P
// * This is only set if they did damage us at all, however.
SetAIInteger(LAST_ELEMENTAL_DAMAGE, nElemental);
// Morale: We may get a penalty if it does more than a cirtain amount of HP damage.
// Other: We set highest damager and amount.
if(!GetSpawnInCondition(AI_FLAG_FLEEING_FEARLESS, AI_TARGETING_FLEE_MASTER))
{
// Get penalty and how much damage at once needs to be done
int nPenalty = GetBoundriedAIInteger(AI_DAMAGE_AT_ONCE_PENALTY, 6, 50, 1);
int nToDamage = GetBoundriedAIInteger(AI_DAMAGE_AT_ONCE_FOR_MORALE_PENALTY, GetMaxHitPoints()/6, GetMaxHitPoints(), 1);
if(nDamage > nToDamage)
{
// 61: "[Damaged] Morale Penalty for 600 seconds [Penalty]" + IntToString(iPenalty)
DebugActionSpeakByInt(61, OBJECT_INVALID, nPenalty);
// Apply penalty
SetMoralePenalty(nPenalty, 300.0);
}
}
}
// If we are not attacking anything, and not in combat, react!
if(!CannotPerformCombatRound())
{
// 62: "[Damaged] Not in combat: DCR [Damager]" + GetName(oDamager)
DebugActionSpeakByInt(62, oDamager);
// Check if they are in the same area. Can be a left AOE spell.
// Don't attack purposly across area's.
if(GetArea(oDamager) == GetArea(OBJECT_SELF))
{
// Shout to allies to attack the enemy who attacked me
AISpeakString(AI_SHOUT_I_WAS_ATTACKED);
DetermineCombatRound(oDamager);
}
else
{
// Shout to allies to attack, or be prepared.
AISpeakString(AI_SHOUT_CALL_TO_ARMS);
DetermineCombatRound();
}
}
else
{
// Shout to allies to attack, or be prepared.
AISpeakString(AI_SHOUT_CALL_TO_ARMS);
}
}
// Else it is friendly, or invalid damager
else
{
// Still will react - eg: A left AOE spell (which might mean a battle
// just happened)
if(!CannotPerformCombatRound())
{
// Shout to allies to attack generally. No target to specifically attack,
// as it is an ally.
AISpeakString(AI_SHOUT_CALL_TO_ARMS);
// 63: [Damaged] Not in combat: DCR. Ally hit us. [Damager(Ally?)]" + GetName(oDamager)
DebugActionSpeakByInt(63, oDamager);
DetermineCombatRound();
}
else
{
// Shout to allies to attack, or be prepared.
AISpeakString(AI_SHOUT_CALL_TO_ARMS);
}
}
// User defined event - for normally immoral creatures.
if(GetCurrentHitPoints() == 1)
{
// Fire the immortal damaged at 1 HP event.
FireUserEvent(AI_FLAG_UDE_DAMAGED_AT_1_HP, EVENT_DAMAGED_AT_1_HP);
}
// Fire End of Damaged event
FireUserEvent(AI_FLAG_UDE_DAMAGED_EVENT, EVENT_DAMAGED_EVENT);
}

View File

@@ -1,164 +0,0 @@
/*/////////////////////// [On Death] ///////////////////////////////////////////
Filename: J_AI_OnDeath or nw_c2_default7
///////////////////////// [On Death] ///////////////////////////////////////////
Speeded up no end, when compiling, with seperate Include.
Cleans up all un-droppable items, all ints and all local things when destroyed.
Check down near the bottom for a good place to add XP or corpse lines ;-)
///////////////////////// [History] ////////////////////////////////////////////
1.3 - Added in Turn of corpses toggle
- Added in appropriate space for XP awards, marked with ideas (effect death)
1.4 - Removed the redudnant notes on the "You have gained 0 experience" message
///////////////////////// [Workings] ///////////////////////////////////////////
You can edit this for experience, there is a seperate section for it.
It will use DeathCheck to execute a cleanup-and-destroy script, that removes
any coprse, named "j_ai_destroyself".
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: GetLastKiller.
///////////////////////// [On Death] /////////////////////////////////////////*/
// We only require the constants/debug file. We have 1 function, not worth another include.
#include "J_INC_CONSTANTS"
// We need a wrapper. If the amount of deaths, got in this, is not equal to iDeaths,
// we don't execute the script, else we do. :-P
void DeathCheck(int nDeaths);
void main()
{
// If we are set to, don't fire this script at all
if(GetAIInteger(I_AM_TOTALLY_DEAD)) return;
// Pre-death-event. Returns TRUE if we interrupt this script call.
if(FirePreUserEvent(AI_FLAG_UDE_DEATH_PRE_EVENT, EVENT_DEATH_PRE_EVENT)) return;
// Note: No AI on/off check here.
// Who killed us? (alignment changing, debug, XP).
object oKiller = GetLastKiller();
// Stops if we just applied EffectDeath to ourselves.
if(GetLocalTimer(AI_TIMER_DEATH_EFFECT_DEATH)) return;
// Special: To stop giving out multiple amounts of XP, we use EffectDeath
// to change the killer, so the XP systems will NOT award MORE XP.
// - Even the default one suffers from this!
if(GetAIInteger(WE_HAVE_DIED_ONCE))
{
if(!GetLocalTimer(AI_TIMER_DEATH_EFFECT_DEATH))
{
// Don't apply effect death to self more then once per 2 seconds.
SetLocalTimer(AI_TIMER_DEATH_EFFECT_DEATH, 2.0);
// This should make the last killer us.
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectResurrection(), OBJECT_SELF);
ApplyEffectToObject(DURATION_TYPE_INSTANT, EffectDamage(GetMaxHitPoints()), OBJECT_SELF);
}
}
else if(oKiller != OBJECT_SELF)
{
// Set have died once, stops giving out mulitple amounts of XP.
SetAIInteger(WE_HAVE_DIED_ONCE, TRUE);
/*/////////////////////// [Experience] /////////////////////////////////////////
THIS is the place for it, below this comment.
It is useful to use GetFirstFactionMember (and Next), GiveXPToCreature,
GetXP, SetXP, GetChallengeRating (of self) all are really useful.
Bug note: GetFirstFactionMember/Next with the PC parameter means either ONLY PC,
and so NPC henchmen, unless FALSE is used, will not be even recognised.
///////////////////////// [Experience] ///////////////////////////////////////*/
// Do XP things (Use object "oKiller" for who killed us).
/*/////////////////////// [Experience] ///////////////////////////////////////*/
}
// Note: Here we do a simple way of checking how many times we have died.
// Nothing special. Debugging most useful aspect.
int nDeathCounterNew = GetAIInteger(AMOUNT_OF_DEATHS);
nDeathCounterNew++;
SetAIInteger(AMOUNT_OF_DEATHS, nDeathCounterNew);
// Here is the last time (in game seconds) we died. It is used in the executed script
// to make sure we don't prematurly remove areselves.
// We may want some sort of visual effect - like implosion or something, to fire.
int nDeathEffect = GetAIConstant(AI_DEATH_VISUAL_EFFECT);
// Valid constants from 0 and up. Apply to our location (not to us, who will go!)
if(nDeathEffect >= 0)
{
ApplyEffectAtLocation(DURATION_TYPE_INSTANT, EffectVisualEffect(nDeathEffect), GetLocation(OBJECT_SELF));
}
// Default Commoner alignment changing. (If the commoner is not evil!)
if(GetLevelByClass(CLASS_TYPE_COMMONER) > 0 &&
GetAlignmentGoodEvil(OBJECT_SELF) != ALIGNMENT_EVIL &&
!GetSpawnInCondition(AI_FLAG_OTHER_NO_COMMONER_ALIGNMENT_CHANGE, AI_OTHER_MASTER))
{
if(GetIsPC(oKiller))
{
AdjustAlignment(oKiller, ALIGNMENT_EVIL, 5);
}
else
{
// If it is a summon, henchmen or familar of a PC, we adust the PC itself
// Clever, eh?
object oMaster = GetMaster(oKiller);
if(GetIsObjectValid(oMaster) && GetIsPC(oMaster))
{
AdjustAlignment(oMaster, ALIGNMENT_EVIL, 5);
}
}
}
// Always shout when we are killed. Reactions - Morale penalty, and
// attack the killer.
AISpeakString(AI_SHOUT_I_WAS_KILLED);
// Speaks the set death speak, like "AGGGGGGGGGGGGGGGGGGG!! NOOOO!" for instance :-)
// Note for 1.4: No need for "CanSpeak()" for this, of course.
SpeakArrayString(AI_TALK_ON_DEATH);
// First check - do we use "destroyable corpses" or not? (default, yes)
if(!GetSpawnInCondition(AI_FLAG_OTHER_TURN_OFF_CORPSES, AI_OTHER_MASTER))
{
// We will actually dissapear after 30.0 seconds if not raised.
int nTime = GetAIInteger(AI_CORPSE_DESTROY_TIME);
if(nTime == 0) // Error checking
{
nTime = 30;
}
// 64: "[Death] Checking corpse status in " + IntToString(nTime) + " [Killer] " + GetName(oKiller) + " [Times Died Now] " + IntToString(nDeathCounterNew)
DebugActionSpeakByInt(64, oKiller, nTime, IntToString(nDeathCounterNew));
// Delay check
DelayCommand(IntToFloat(nTime), DeathCheck(nDeathCounterNew));
}
else
{
/************************ [Alternative Corpses] ********************************
This is where you can add some alternative corpse code - EG looting
and so on, without disrupting the rest of the AI (as the corpses
are turned off).
************************* [Alternative Corpses] *******************************/
// Add alternative corpse code here
/************************ [Alternative Corpses] *******************************/
}
// Signal the death event.
FireUserEvent(AI_FLAG_UDE_DEATH_EVENT, EVENT_DEATH_EVENT);
}
// We need a wrapper. If the amount of deaths, got in this, is not equal to iDeaths,
// we don't execute the script, else we do. :-P
void DeathCheck(int nDeaths)
{
// Do the deaths imputted equal the amount we have suffered?
if(GetAIInteger(AMOUNT_OF_DEATHS) == nDeaths)
{
// - This now includes a check for Bioware's lootable functions and using them.
ExecuteScript(FILE_DEATH_CLEANUP, OBJECT_SELF);
}
}

View File

@@ -1,85 +0,0 @@
/*/////////////////////// [On Disturbed] ///////////////////////////////////////
Filename: J_AI_OnDisturbed or nw_c2_default8
///////////////////////// [On Disturbed] ///////////////////////////////////////
This will attack pickpockets, and inventory disturbers. Note: Stupidly, Bioware
made this only affect the creature by stealing. Still, oh well :-(
This means that the only event which fires it is pickpocketing.
///////////////////////// [History] ////////////////////////////////////////////
1.3 - Changed why we determine combat round
- Any change in inventory will trigger appropriate SetWeapons again.
- Added turn of hide things.
1.4 - Cleaned up a bit. Removed unused declared variable.
///////////////////////// [Workings] ///////////////////////////////////////////
Only fired by stealing, great. Oh well, it will attack any disturber anyway.
It *might* not be fired if the natural spot check to notice a theft doesn't
work. No idea personally.
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: GetInventoryDisturbItem, GetLastDisturbed,
GetInventoryDisturbType (I think it is always be stolen :-( ).
///////////////////////// [On Disturbed] /////////////////////////////////////*/
#include "J_INC_OTHER_AI"
void main()
{
// Pre-disturbed-event. Returns TRUE if we interrupt this script call.
if(FirePreUserEvent(AI_FLAG_UDE_DISTURBED_PRE_EVENT, EVENT_DISTURBED_PRE_EVENT)) return;
// AI status check. Is the AI on?
if(GetAIOff()) return;
// Declare major variables
object oDisturber = GetLastDisturbed();
object oItem = GetInventoryDisturbItem();
int nType = GetInventoryDisturbType();
int nBase = GetBaseItemType(oItem);
// We will reset weapons if it is a weapon.
// Reset weapons, or specifically healers kits.
if(GetIsObjectValid(oItem))
{
// Kits
if(nBase == BASE_ITEM_HEALERSKIT)
{
SetLocalInt(OBJECT_SELF, AI_WEAPONSETTING_SETWEAPONS, 2);
ExecuteScript(FILE_RE_SET_WEAPONS, OBJECT_SELF);
}
else // Think it is a weapon. Saves time :-)
{
SetLocalInt(OBJECT_SELF, AI_WEAPONSETTING_SETWEAPONS, 1);
ExecuteScript(FILE_RE_SET_WEAPONS, OBJECT_SELF);
}
}
// Fight! Or search!
if(!GetIgnoreNoFriend(oDisturber) &&
(nType == INVENTORY_DISTURB_TYPE_STOLEN || GetIsEnemy(oDisturber)))
{
// Turn of hiding, a timer to activate Hiding in the main file. This is
// done in each of the events, with the opposition checking seen/heard.
TurnOffHiding(oDisturber);
// Can we attack?
if(!CannotPerformCombatRound())
{
// Someone specific to attack
AISpeakString(AI_SHOUT_I_WAS_ATTACKED);
// One debug speak. We always do one.
// 65: "[Disturbed] (pickpocket) Attacking Enemy Distrube [Disturber] " + GetName(oTarget) + " [Type] " + IntToString(iType)
DebugActionSpeakByInt(65, oDisturber, nType);
// Attack the disturber
DetermineCombatRound(oDisturber);
}
else
{
// Get allies interested.
AISpeakString(AI_SHOUT_CALL_TO_ARMS);
}
}
// Fire End-heartbeat-UDE
FireUserEvent(AI_FLAG_UDE_DISTURBED_EVENT, EVENT_DISTURBED_EVENT);
}

View File

@@ -1,644 +0,0 @@
/*/////////////////////// [On Spawn] ///////////////////////////////////////////
Filename: J_AI_OnSpawn or nw_c2_default9
///////////////////////// [On Spawn] ///////////////////////////////////////////
This file contains options that will determine some AI behaviour, and a lot
of toggles for turning things on/off. A big read, but might be worthwhile.
The documentation is actually fully in the readme files, under the name
"On Spawn.html", under "AI File Explanations".
The order of the options:
- Important Spawn Settings N/A
- Targeting & Fleeing (AI_TARGETING_FLEE_MASTER)
- Fighting & Spells (AI_COMBAT_MASTER)
- Other Combat - Healing, Skills & Bosses (AI_OTHER_COMBAT_MASTER)
- Other - Death corpses, minor things (AI_OTHER_MASTER)
- User Defined (AI_UDE_MASTER)
- Shouts N/A
- Default Bioware settings (WP's, Anims) (NW_GENERIC_MASTER)
The OnSpawn file is a settings file. These things are set onto a creature, to
define cirtain actions. If more than one creature has this script, they all
use the settings, unless If/Else statements are used somehow. There is also
the process of setting any spells/feats availible, and hiding and walk waypoints
are started.
Other stuff:
- Targeting is imporant :-D
- If you delete this script, there is a template for the On Spawn file
in the zip it came in, for use in the "scripttemplate" directory.
///////////////////////// [History] ////////////////////////////////////////////
Note: I have removed:
- Default "Teleporting" and exit/return (this seemed bugged anyway, or useless)
- Spawn in animation. This can be, of course, re-added.
- Day/night posting. This is uneeded, with a changed walk waypoints that does it automatically.
1.0-1.2 - Used short amount of spawn options.
1.3 - All constants names are changed, I am afraid.
- Added Set/Delete/GetAIInteger/Constant/Object. This makes sure that the AI
doesn't ever interfere with other things - it pre-fixes all stored things
with AI_INTEGER_ (and so on)
1.4 - TO DO: Clear up some old non-working ones
- Added in User Defined part of the script, an auto-turn-off-spells for
Ranger and Paladin classes. Need to test - perhaps 1.64 fixed it?
Spawn options changed:
- Removed AI level settings (can still be done manually)
- Added optional (and off by default) fear-visual for fleeing
///////////////////////// [Workings] ///////////////////////////////////////////
Note: You can do without all the comments (it may be that you don't want
the extra KB it adds or something, although it does not at all slow down a module)
so as long as you have these at the end:
AI_SetUpEndOfSpawn();
DelayCommand(2.0, SpawnWalkWayPoints());
Oh, and the include file (Below, "j_inc_spawnin") must be at the top like
here. Also recommended is the AI_INTELLIGENCE and AI_MORALE being set (if
not using custom AI).
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: GetIsEncounterCreature
///////////////////////// [On Spawn] /////////////////////////////////////////*/
// Treasure Includes - See end of spawn for uncomment options.
//#include "nw_o2_coninclude"
// Uncomment this if you want default NwN Treasure - Uses line "GenerateNPCTreasure()" at the end of spawn.
// - This generates random things from the default pallet based on the creatures level + race
//#include "x0_i0_treasure"
// Uncomment this if you want the SoU Treasure - Uses line "CTG_GenerateNPCTreasure()" at the end of spawn.
// - This will spawn treasure based on chests placed in the module. See "x0_i0_treasure" for more information.
// This is required for all spawn in options!
#include "J_INC_SPAWNIN"
void main()
{
/************************ [Important Spawn Settings] **************************/
SetAIInteger(AI_INTELLIGENCE, 10);
// Intelligence value of the creauture. Can be 1-10, read readme's for help.
SetAIInteger(AI_MORALE, 10);
// Will save (See readme). Remember: -1 or below means they always flee.
//SetCustomAIFileName("CUSTOM_AI_FILE");
// Sets our custom AI file. Really, only animation settings will apply when this is set.
// - Can sort actions against a imputted target (EG: On Percieved enemy) by
// "GetLocalObject(OBJECT_SELF, "AI_TEMP_SET_TARGET");"
/************************ [Important Spawn Settings] **************************/
/************************ [Targeting] ******************************************
All targeting settings.
************************* [Targeting] *****************************************/
//SetSpawnInCondition(AI_FLAG_TARGETING_LIKE_LOWER_HP, AI_TARGETING_FLEE_MASTER);
// We only attack the lowest current HP.
//SetSpawnInCondition(AI_FLAG_TARGETING_LIKE_LOWER_AC, AI_TARGETING_FLEE_MASTER);
// We only attack the lowest AC (as in 1.2).
//SetSpawnInCondition(AI_FLAG_TARGETING_LIKE_LOWER_HD, AI_TARGETING_FLEE_MASTER);
// Target the lowest hit dice
//SetSpawnInCondition(AI_FLAG_TARGETING_LIKE_MAGE_CLASSES, AI_TARGETING_FLEE_MASTER);
// We go straight for mages/sorcerors. Nearest one.
//SetSpawnInCondition(AI_FLAG_TARGETING_LIKE_ARCHERS, AI_TARGETING_FLEE_MASTER);
// We go for the nearest enemy with a ranged weapon equipped.
//SetSpawnInCondition(AI_FLAG_TARGETING_LIKE_PCS, AI_TARGETING_FLEE_MASTER);
// We go for the nearest seen PC enemy.
//SetAIConstant(AI_FAVOURED_ENEMY_RACE, RACIAL_TYPE_HUMAN);
// The AI attacks the nearest enemy, seen, of this race. Use the RACIAL_* constants.
//SetAIConstant(AI_FAVOURED_ENEMY_CLASS, CLASS_TYPE_BARD);
// The AI attacks the nearest enemy, seen, of this class. Use the CLASS_* constants.
// Target changing - see readme for info.
//SetAIInteger(AI_MAX_TURNS_TO_ATTACK_ONE_TARGET, 6);
// Maximum rounds to attack the current target, before re-checking.
// % Chance to re-set each target type each round (Could result in current target still)
//SetAIInteger(AI_MELEE_LAST_TO_NEW_TARGET_CHANCE, 20);
//SetAIInteger(AI_RANGED_LAST_TO_NEW_TARGET_CHANCE, 20);
//SetAIInteger(AI_SPELL_LAST_TO_NEW_TARGET_CHANCE, 20);
// We only target PC's if there are any in range if this is set
//SetSpawnInCondition(AI_FLAG_TARGETING_FILTER_FOR_PC_TARGETS, AI_TARGETING_FLEE_MASTER);
// Main explanation of AI_SetAITargetingValues, see the AI readme (spawn file)
// - Remember, uncommenting one will just ignore it (so will never check target's
// AC without TARGETING_AC on)
AI_SetAITargetingValues(TARGETING_MANTALS, TARGET_LOWER, 1, 12);
// Spell mantals are checked only for the spell target. Either Absense of or got any.
AI_SetAITargetingValues(TARGETING_RANGE, TARGET_HIGHER, 2, 9);
// Range - very imporant! Basis for all ranged/spell attacks.
AI_SetAITargetingValues(TARGETING_AC, TARGET_LOWER, 2, 6);
// AC is used for all phisical attacks. Lower targets lower (By default).
AI_SetAITargetingValues(TARGETING_SAVES, TARGET_LOWER, 2, 4);
// Used for spell attacks. Saves are sorta a AC versus spells.
// Phisical protections. Used by spells, ranged and melee.
// Jasperre - simple check if we are a fighter (hit lower phisicals) or a
// mage (attack higher!)
if(GetBaseAttackBonus(OBJECT_SELF) > ((GetHitDice(OBJECT_SELF)/2) + 1))
{
// Fighter/Clerics (It is over a mages BAB + 1 (IE 0.5 BAB/Level) target lower
AI_SetAITargetingValues(TARGETING_PHISICALS, TARGET_LOWER, 2, 6);
}
else
{
// Mages target higher (so dispel/elemental attack those who fighters
// cannot hit as much). (the lowest BAB, under half our hit dice in BAB)
AI_SetAITargetingValues(TARGETING_PHISICALS, TARGET_HIGHER, 1, 5);
}
// Base attack bonus. Used for spells and phisical attacks. Checked with GetBaseAttackBonus.
AI_SetAITargetingValues(TARGETING_BAB, TARGET_LOWER, 1, 4);
// Hit dice - how powerful in levels the enemy is. Used for all checks.
AI_SetAITargetingValues(TARGETING_HITDICE, TARGET_LOWER, 1, 3);
//AI_SetAITargetingValues(TARGETING_HP_PERCENT, TARGET_LOWER, 1, 3);
//AI_SetAITargetingValues(TARGETING_HP_CURRENT, TARGET_LOWER, 1, 3);
//AI_SetAITargetingValues(TARGETING_HP_MAXIMUM, TARGET_LOWER, 1, 3);
// The HP's are the last thing to choose a target with.
/************************ [Targeting] *****************************************/
/************************ [Fleeing] ********************************************
Fleeing - these are toggled on/off by FEARLESS flag.
3 or under intelligence will just run away. 4 or more will know where allies
are, and if there are none, will not run.
************************* [Fleeing] *******************************************/
SetSpawnInCondition(AI_FLAG_FLEEING_FEARLESS, AI_TARGETING_FLEE_MASTER);
// Forces them to not flee. This may be set with AI_SetMaybeFearless at the end.
//SetSpawnInCondition(AI_FLAG_FLEEING_NEVER_FIGHT_IMPOSSIBLE_ODDS, AI_TARGETING_FLEE_MASTER);
// This will make the creature never fight against impossible odds (8HD+ different)
//SetSpawnInCondition(AI_FLAG_FLEEING_TURN_OFF_GROUP_MORALE, AI_TARGETING_FLEE_MASTER);
// This turns OFF any sort of group morale bonuses.
//SetAIInteger(AMOUNT_OF_HD_DIFFERENCE_TO_CHECK, -2);
// If enemy is within this amount of HD, we do not check morale.
SetAIInteger(BASE_MORALE_SAVE, 5);
// Base DC of the will save. It is set to 20 + HD difference - Morale - Group morale mod.
//SetAIInteger(HP_PERCENT_TO_CHECK_AT, 80);
// %HP needed to be at to check morale. This doesn't affect "Never fight impossible odds"
//SetSpawnInCondition(AI_FLAG_FLEEING_NO_OVERRIDING_HP_AMOUNT, AI_TARGETING_FLEE_MASTER);
// This will turn off overriding HP checks. AI may decide to run even
// not at the %HP above, this turns the checks off.
//SetAIInteger(AI_DAMAGE_AT_ONCE_FOR_MORALE_PENALTY, GetMaxHitPoints()/6);
// Damage needed to be done at once to get a massive morale penalty (Below)
//SetAIInteger(AI_DAMAGE_AT_ONCE_PENALTY, 6);
// Penalty for the above, set for some time to negativly affect morale. Added to save DC for fleeing.
//SetSpawnInCondition(AI_FLAG_FLEEING_FLEE_TO_NEAREST_NONE_SEEN, AI_TARGETING_FLEE_MASTER);
// If set, just runs to nearest non-seen ally, and removes the loop for a good group of allies to run to.
//SetSpawnInCondition(AI_FLAG_FLEEING_FLEE_TO_OBJECT, AI_TARGETING_FLEE_MASTER);
// They will flee to the nearest object of the tag below, if set.
//SetLocalString(OBJECT_SELF, AI_FLEE_OBJECT, "BOSS_TAG_OR_WHATEVER");
// This needs setting if the above is to work.
//SetSpawnInCondition(AI_FLAG_FLEEING_USE_VISUAL_EFFECT, AI_TARGETING_FLEE_MASTER);
// If this is on, we play a visual effect while we flee.
/************************ [Fleeing] *******************************************/
/************************ [Combat - Fighters] **********************************
Fighter (Phiscal attacks, really) specific stuff - disarmed weapons, better
at hand to hand, and archer behaviour.
************************* [Combat - Fighters] *********************************/
SetSpawnInCondition(AI_FLAG_COMBAT_PICK_UP_DISARMED_WEAPONS, AI_COMBAT_MASTER);
// This sets to pick up weapons which are disarmed.
//SetAIInteger(AI_RANGED_WEAPON_RANGE, 3);
// This is the range at which they go into melee (from using a ranged weapon). Default is 3 or 5.
//SetSpawnInCondition(AI_FLAG_COMBAT_BETTER_AT_HAND_TO_HAND, AI_COMBAT_MASTER);
// Set if you want them to move forwards into HTH sooner. Will always
// if the enemy is a mage/archer, else % based on range.
//SetSpawnInCondition(AI_FLAG_COMBAT_ARCHER_ATTACKING, AI_COMBAT_MASTER);
// For archers. If they have ally support, they'd rather move back & shoot then go into HTH.
//SetSpawnInCondition(AI_FLAG_COMBAT_ARCHER_ALWAYS_MOVE_BACK, AI_COMBAT_MASTER);
// This forces the move back from attackers, and shoot bows. Very small chance to go melee.
//SetSpawnInCondition(AI_FLAG_COMBAT_ARCHER_ALWAYS_USE_BOW, AI_COMBAT_MASTER);
// This will make the creature ALWAYs use any bows it has. ALWAYS.
//SetSpawnInCondition(AI_FLAG_COMBAT_NO_GO_FOR_THE_KILL, AI_COMBAT_MASTER);
// Turns off any attempts to kill dying PCs, or attack low hit point people.
// This is only ever attempted at 9 or 10 intelligence anyway.
/************************ [Combat - Fighters] *********************************/
/************************ [Combat - Spell Casters] *****************************
Spellcaster AI has been improved significantly. As well as adding all new spells,
now spellcasters more randomly choose spells from the same level (EG: they
may choose not to cast magic missile, and cast negative energy ray instead).
There are also options here for counterspelling, fast buffing, Cheat cast spells,
dispelling, spell triggers, long ranged spells first, immunity toggles, and AOE settings.
************************* [Combat - Spell Casters] ****************************/
//SetSpawnInCondition(AI_FLAG_COMBAT_LONGER_RANGED_SPELLS_FIRST, AI_COMBAT_MASTER);
// Casts spells only if the caster would not move into range to cast them.
// IE long range spells, then medium, then short (unless the enemy comes to us!)
//SetSpawnInCondition(AI_FLAG_COMBAT_FLAG_FAST_BUFF_ENEMY, AI_COMBAT_MASTER);
// When an enemy comes in 40M, we fast-cast many defensive spells, as if prepared.
//SetSpawnInCondition(AI_FLAG_COMBAT_SUMMON_FAMILIAR, AI_COMBAT_MASTER);
// The caster summons thier familiar/animal companion. Either a nameless Bat or Badger respectivly.
// Counterspelling/Dispelling...
// It checks for these classes within the 20M counterspell range.
//SetSpawnInCondition(AI_FLAG_COMBAT_COUNTER_SPELL_ARCANE, AI_COMBAT_MASTER);
// If got dispels, it counterspells Arcane (Mage/Sorceror) spellcasters.
//SetSpawnInCondition(AI_FLAG_COMBAT_COUNTER_SPELL_DIVINE, AI_COMBAT_MASTER);
// If got dispels, it counterspells Divine (Cleric/Druid) spellcasters.
//SetSpawnInCondition(AI_FLAG_COMBAT_COUNTER_SPELL_ONLY_IN_GROUP, AI_COMBAT_MASTER);
// Recommended. Only counterspells with 5+ allies in group.
//SetSpawnInCondition(AI_FLAG_COMBAT_DISPEL_MAGES_MORE, AI_COMBAT_MASTER);
// Targets seen mages to dispel, else uses normal spell target.
SetSpawnInCondition(AI_FLAG_COMBAT_DISPEL_IN_ORDER, AI_COMBAT_MASTER);
// This will make the mage not dispel just anything all the time, but important (spell-stopping)
// things first, others later, after some spells. If off, anything is dispelled.
// AOE's
//SetSpawnInCondition(AI_FLAG_COMBAT_NEVER_HIT_ALLIES, AI_COMBAT_MASTER);
// Override toggle. Forces to never cast AOE's if it will hit an ally + harm them.
//SetSpawnInCondition(AI_FLAG_COMBAT_AOE_DONT_MIND_IF_THEY_SURVIVE, AI_COMBAT_MASTER);
// Allies who will survive the blast are ignored for calculating best target.
//SetAIInteger(AI_AOE_ALLIES_LOWEST_IN_AOE, 3);
// Defualt: 3. If amount of allies in blast radius are equal or more then
// this, then that location is ignored.
//SetAIInteger(AI_AOE_HD_DIFFERENCE, -8);
// Very weak allies (who are not comparable to us) are ignored if we would hit them.
// For these 2, if neither are set, the AI will choose AOE more if there are
// lots of enemies, or singles if there are not many.
//SetSpawnInCondition(AI_FLAG_COMBAT_SINGLE_TARGETING, AI_COMBAT_MASTER);
// For Same-level spells, single target spells are used first.
//SetSpawnInCondition(AI_FLAG_COMBAT_MANY_TARGETING, AI_COMBAT_MASTER);
// For Same-level spells, AOE spells are used first.
SetSpawnInCondition(AI_FLAG_COMBAT_IMPROVED_INSTANT_DEATH_SPELLS, AI_COMBAT_MASTER);
// A few Death spells may be cast top-prioritory if the enemy will always fail saves.
SetSpawnInCondition(AI_FLAG_COMBAT_IMPROVED_SUMMON_TARGETING, AI_COMBAT_MASTER);
// Will use a better target to summon a creature at (EG: Ranged attacker)
SetSpawnInCondition(AI_FLAG_COMBAT_IMPROVED_IMMUNITY_CHECKING, AI_COMBAT_MASTER);
// Turns On "GetIsImmune" checks. Auto on for 7+ Intel.
SetSpawnInCondition(AI_FLAG_COMBAT_IMPROVED_SPECIFIC_SPELL_IMMUNITY, AI_COMBAT_MASTER);
// Turns On checks for Globes & levels of spells. Auto on for 9+ Intel.
//SetSpawnInCondition(AI_FLAG_COMBAT_MORE_ALLY_BUFFING_SPELLS, AI_COMBAT_MASTER);
// This will make the caster buff more allies - or, in fact, use spells
// to buff allies which they might have not used before.
//SetSpawnInCondition(AI_FLAG_COMBAT_USE_ALL_POTIONS, AI_COMBAT_MASTER);
// Uses all buffing spells before melee.
//SetAICheatCastSpells(SPELL_MAGIC_MISSILE, SPELL_ICE_DAGGER, SPELL_HORIZIKAULS_BOOM, SPELL_MELFS_ACID_ARROW, SPELL_NEGATIVE_ENERGY_RAY, SPELL_FLAME_ARROW);
// Special: Mages cast for ever with this set.
// Spell triggers
//SetSpellTrigger(SPELLTRIGGER_NOT_GOT_FIRST_SPELL, FALSE, 1, SPELL_PREMONITION);
// This is just an example. See readme for more info.
/************************ [Combat - Spell Casters] ****************************/
/************************ [Combat - Dragons] ***********************************
I have a fondness for dragons - in NWN they are deprived of many abilities. Here
are some new ones for your enjoyment! Switches and flying for ANYTHING! :-)
************************* [Combat - Dragons] **********************************/
//SetSpawnInCondition(AI_FLAG_COMBAT_NO_WING_BUFFET, AI_COMBAT_MASTER);
//This sets so there is no Dragon wing buffet. Readme has details of it.
//SetAIInteger(AI_DRAGON_FREQUENCY_OF_BUFFET, 3);
// Min. Amount of Rounds between each buffet. See readme for counter defaults. Def: 3
//SetAIInteger(AI_DRAGON_FREQUENCY_OF_BREATH, 3);
// Min. Amount of Rounds between each breath use. See readme for counter defaults. Def: 3
// Default checks for dragon flying automatic turning on of flying.
if(GetLevelByClass(CLASS_TYPE_DRAGON) || MyPRCGetRacialType(OBJECT_SELF) == RACIAL_TYPE_DRAGON)
{
SetSpawnInCondition(AI_FLAG_COMBAT_FLYING, AI_COMBAT_MASTER);
// This turns ON combat flying. I think anything winged looks A-OK. See readme for info.
}
/************************ [Combat - Dragons] **********************************/
/************************ [Combat Other - Healers/Healing] *********************
Healing behaviour - not specifically clerics. See readme.
************************* [Combat Other - Healers/Healing] ********************/
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_HEAL_AT_PERCENT_NOT_AMOUNT, AI_OTHER_COMBAT_MASTER);
// if this is set, we ignore the amount we need to be damaged, as long
// as we are under AI_HEALING_US_PERCENT.
//SetAIInteger(AI_HEALING_US_PERCENT, 50);
// % of HP we need to be at until we heal us at all. Default: 50
//SetAIInteger(AI_HEALING_ALLIES_PERCENT, 60);
// % of HP allies would need to be at to heal them Readme = info. Default: 60
SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_WILL_RAISE_ALLIES_IN_BATTLE, AI_OTHER_COMBAT_MASTER);
// Turns on rasing dead with Resurrection/Raise dead.
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_CURING, AI_OTHER_COMBAT_MASTER);
// This turns off all healing.
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_ONLY_CURE_SELF, AI_OTHER_COMBAT_MASTER);
// This turns off ally healing.
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_ONLY_RESTORE_SELF, AI_OTHER_COMBAT_MASTER);
// This turns off ally restoring (Remove/Restoration).
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_USE_BAD_HEALING_SPELLS, AI_OTHER_COMBAT_MASTER);
// This forces all cure spells to be used, check readme.
//SetAIInteger(SECONDS_BETWEEN_STATUS_CHECKS, 30);
// Seconds between when we loop everyone for bad effects like Fear/stun ETC. If not set, done each round.
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_GIVE_POTIONS_TO_HELP, AI_OTHER_COMBAT_MASTER);
// ActionGiveItem standard healing potion's to allies who need them, if they possess them.
/************************ [Combat Other - Healers/Healing] ********************/
/************************ [Combat Other - Skills] ******************************
Skills are a part of fighting - EG Taunt. These are mainly on/off switches.
A creature will *may* use it if they are not set to "NO_" for the skill.
************************* [Combat Other - Skills] *****************************/
// "NO" - This is for forcing the skill NEVER to be used by the combat AI.
// "FORCE" - This forces it on (and to be used), except if they have no got the skill.
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_PICKPOCKETING, AI_OTHER_COMBAT_MASTER);
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_FORCE_PICKPOCKETING, AI_OTHER_COMBAT_MASTER);
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_TAUNTING, AI_OTHER_COMBAT_MASTER);
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_FORCE_TAUNTING, AI_OTHER_COMBAT_MASTER);
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_EMPATHY, AI_OTHER_COMBAT_MASTER);
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_FORCE_EMPATHY, AI_OTHER_COMBAT_MASTER);
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_HIDING, AI_OTHER_COMBAT_MASTER);
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_FORCE_HIDING, AI_OTHER_COMBAT_MASTER);
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_OPENING_LOCKED_DOORS, AI_OTHER_COMBAT_MASTER);
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_FORCE_OPENING_LOCKED_DOORS, AI_OTHER_COMBAT_MASTER);
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_USING_HEALING_KITS, AI_OTHER_COMBAT_MASTER);
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_PARRYING, AI_OTHER_COMBAT_MASTER);
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_FORCE_PARRYING, AI_OTHER_COMBAT_MASTER);
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_SEARCH, AI_OTHER_COMBAT_MASTER);
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_FORCE_SEARCH, AI_OTHER_COMBAT_MASTER);
// - Concentration - special notes in the readme
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_CONCENTRATION, AI_OTHER_COMBAT_MASTER);
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_FORCE_CONCENTRATION, AI_OTHER_COMBAT_MASTER);
/************************ [Combat Other - Skills] *****************************/
/************************ [Combat Other - Leaders] *****************************
Leaders/Bosses can be set to issue some orders and inspire more morale - and bring
a lot of allies to a battle at once!
************************* [Combat Other - Leaders] ****************************/
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_GROUP_LEADER, AI_OTHER_COMBAT_MASTER);
// Special leader. Can issuse some orders. See readme for details.
//SetSpawnInCondition(AI_FLAG_OTHER_COMBAT_BOSS_MONSTER_SHOUT, AI_OTHER_COMBAT_MASTER);
// Boss shout. 1 time use - calls all creatures in X meters (below) for battle!
//SetAIInteger(AI_BOSS_MONSTER_SHOUT_RANGE, 60);
// Defaults to a 60 M range. This can change it. Note: 1 toolset square = 10M.
/************************ [Combat Other - Leaders] ****************************/
/************************ [Other - Behaviour/Generic] **************************
This is generic behaviours - alright, really it is all things that cannot
really be categorised.
************************* [Other - Behaviour/Generic] *************************/
//SetSpawnInCondition(AI_FLAG_OTHER_NO_CLEAR_ACTIONS_BEFORE_CONVERSATION, AI_OTHER_MASTER);
// No ClearAllActions() before BeginConversation. May keep a creature sitting.
//SetSpawnInCondition(AI_FLAG_OTHER_NO_POLYMORPHING, AI_OTHER_MASTER);
// This will stop all polymorphing spells feats from being used.
//SetSpawnInCondition(AI_FLAG_OTHER_CHEAT_MORE_POTIONS, AI_OTHER_MASTER);
// If at low HP, and no potion, create one and use it.
//SetAIConstant(AI_POLYMORPH_INTO, POLYMORPH_TYPE_WEREWOLF);
// Polymorph to this creature when damaged (once, natural effect).
//AI_CreateRandomStats(-3, 3, 6);
// Create (Effect-applied) random statistics.
//AI_CreateRandomOther(-2, 2, -2, 2, -2, 2, -2, 2);
// Create (Effect-applied) random HP, saves, AC.
//SetSpawnInCondition(AI_FLAG_OTHER_RETURN_TO_SPAWN_LOCATION, AI_OTHER_MASTER);
// This will store our spawn location, and then move back there after combat.
SetSpawnInCondition(AI_FLAG_OTHER_DONT_RESPOND_TO_EMOTES, AI_OTHER_MASTER);
// This will ignore ALL chat by PC's (Enemies) who speak actions in Stars - *Bow*
//SetSpawnInCondition(AI_FLAG_OTHER_DONT_SHOUT, AI_OTHER_MASTER);
// Turns off all silent talking NPC's do to other NPC's.
//SetSpawnInCondition(AI_FLAG_OTHER_SEARCH_IF_ENEMIES_NEAR, AI_OTHER_MASTER);
// Move randomly closer to enemies in range set below.
//SetAIInteger(AI_SEARCH_IF_ENEMIES_NEAR_RANGE, 25);
// This is the range creatures use, in metres.
//SetSpawnInCondition(AI_FLAG_OTHER_ONLY_ATTACK_IF_ATTACKED, AI_OTHER_MASTER);
// One shot. We won't instantly attack a creature we see. See readme.
//SetAIInteger(AI_DOOR_INTELLIGENCE, 1);
// 3 Special "What to do with Doors" settings. See readme. Good for animals.
//SetSpawnInCondition(AI_FLAG_OTHER_REST_AFTER_COMBAT, AI_OTHER_MASTER);
// When combat is over, creature rests. Useful for replenising health.
//SetSpawnInCondition(AI_FLAG_OTHER_NO_PLAYING_VOICE_CHAT, AI_OTHER_MASTER);
// Stops any use of "PlayVoiceChat". Use with Custom speakstrings.
/*** Death settings - still under AI_OTHER_MASTER ***/
//AI_SetDeathResRef("Resref Here");
// Creates a creature from the string set. Instantly destroys this creatures body on death.
//SetAIConstant(AI_DEATH_VISUAL_EFFECT, VFX_FNF_IMPLOSION);
// Fires this visual effect number instantly on death. Use FNF and IMP ones.
//SetAIInteger(AI_CORPSE_DESTROY_TIME, 30);
// Seconds before body finally gets destroyed. Used for Clerical Raise Dead on NPC's.
//SetSpawnInCondition(AI_FLAG_OTHER_TURN_OFF_CORPSES, AI_OTHER_MASTER);
// This turns off the SetDestroyable() usually performed, and the above timer.
//SetSpawnInCondition(AI_FLAG_OTHER_USE_BIOWARE_LOOTING, AI_OTHER_MASTER);
// Makes the death file use Bioware's cool SetLootable() feature when corpses would disappear.
/*** Lag and a few performance settings - still under AI_OTHER_MASTER ***/
//SetSpawnInCondition(AI_FLAG_OTHER_LAG_NO_ITEMS, AI_OTHER_MASTER);
// The creature doesn't check for, or use any items that cast spells.
//SetSpawnInCondition(AI_FLAG_OTHER_LAG_NO_SPELLS, AI_OTHER_MASTER);
//The creature doesn't ever cast spells (and never checks them)
//SetSpawnInCondition(AI_FLAG_OTHER_LAG_NO_LISTENING, AI_OTHER_MASTER);
// The creature doesn't have SetListening() set. Turns of the basic listening for shouts.
//SetSpawnInCondition(AI_FLAG_OTHER_LAG_EQUIP_MOST_DAMAGING, AI_OTHER_MASTER);
// Uses EquipMostDamaging(), like Bioware code. No shield/second weapon equipped.
//SetSpawnInCondition(AI_FLAG_OTHER_LAG_NO_CURING_ALLIES, AI_OTHER_MASTER);
// This will stop checks for and curing of allies ailments.
//SetSpawnInCondition(AI_FLAG_OTHER_LAG_IGNORE_HEARTBEAT, AI_OTHER_MASTER);
// Stops the heartbeat running (Except Pre-Heartbeat-event).
//SetSpawnInCondition(AI_FLAG_OTHER_LAG_TARGET_NEAREST_ENEMY, AI_OTHER_MASTER);
// Ignores targeting settings. VERY good for lag/bad AI. Attacks nearest seen enemy.
/************************ [Other - Behaviour/Generic] *************************/
/************************ [User Defined and Shouts] ****************************
The user defined events, set up to fire here.
- New "Start combat attack" and "End Combat Attack" events
- New "Pre" events. Use these to optionally stop a script from firing
under cirtain circumstances as well! (Read nw_c2_defaultd or j_ai_onuserdef)
(User Defined Event = UDE)
************************* [User Defined and Shouts] ***************************/
// This is REQUIRED if we use any Pre-events. If not there, it will default
// to the default User Defined Event script for the default AI.
SetCustomUDEFileName("k_ai_onuserdef");
//SetSpawnInCondition(AI_FLAG_UDE_HEARTBEAT_EVENT, AI_UDE_MASTER); // UDE 1001
//SetSpawnInCondition(AI_FLAG_UDE_HEARTBEAT_PRE_EVENT, AI_UDE_MASTER); // UDE 1021
//SetSpawnInCondition(AI_FLAG_UDE_PERCIEVE_EVENT, AI_UDE_MASTER); // UDE 1002
//SetSpawnInCondition(AI_FLAG_UDE_PERCIEVE_PRE_EVENT, AI_UDE_MASTER); // UDE 1022
//SetSpawnInCondition(AI_FLAG_UDE_END_COMBAT_ROUND_EVENT, AI_UDE_MASTER); // UDE 1003
//SetSpawnInCondition(AI_FLAG_UDE_END_COMBAT_ROUND_PRE_EVENT, AI_UDE_MASTER); // UDE 1023
//SetSpawnInCondition(AI_FLAG_UDE_ON_DIALOGUE_EVENT, AI_UDE_MASTER); // UDE 1004
//SetSpawnInCondition(AI_FLAG_UDE_ON_DIALOGUE_PRE_EVENT, AI_UDE_MASTER); // UDE 1024
//SetSpawnInCondition(AI_FLAG_UDE_ATTACK_EVENT, AI_UDE_MASTER); // UDE 1005
//SetSpawnInCondition(AI_FLAG_UDE_ATTACK_PRE_EVENT, AI_UDE_MASTER); // UDE 1025
//SetSpawnInCondition(AI_FLAG_UDE_DAMAGED_EVENT, AI_UDE_MASTER); // UDE 1006
//SetSpawnInCondition(AI_FLAG_UDE_DAMAGED_PRE_EVENT, AI_UDE_MASTER); // UDE 1026
//SetSpawnInCondition(AI_FLAG_UDE_DEATH_EVENT, AI_UDE_MASTER); // UDE 1007
//SetSpawnInCondition(AI_FLAG_UDE_DEATH_PRE_EVENT, AI_UDE_MASTER); // UDE 1027
//SetSpawnInCondition(AI_FLAG_UDE_DISTURBED_EVENT, AI_UDE_MASTER); // UDE 1008
//SetSpawnInCondition(AI_FLAG_UDE_DISTURBED_PRE_EVENT, AI_UDE_MASTER); // UDE 1028
//SetSpawnInCondition(AI_FLAG_UDE_RESTED_EVENT, AI_UDE_MASTER); // UDE 1009
//SetSpawnInCondition(AI_FLAG_UDE_RESTED_PRE_EVENT, AI_UDE_MASTER); // UDE 1029
//SetSpawnInCondition(AI_FLAG_UDE_SPELL_CAST_AT_EVENT, AI_UDE_MASTER); // UDE 1011
//SetSpawnInCondition(AI_FLAG_UDE_SPELL_CAST_AT_PRE_EVENT, AI_UDE_MASTER); // UDE 1031
//SetSpawnInCondition(AI_FLAG_UDE_ON_BLOCKED_EVENT, AI_UDE_MASTER); // UDE 1015
//SetSpawnInCondition(AI_FLAG_UDE_ON_BLOCKED_PRE_EVENT, AI_UDE_MASTER); // UDE 1035
//SetSpawnInCondition(AI_FLAG_UDE_COMBAT_ACTION_EVENT, AI_UDE_MASTER); // UDE 1012
// Fires when we have finnished all combat actions.
//SetSpawnInCondition(AI_FLAG_UDE_COMBAT_ACTION_PRE_EVENT, AI_UDE_MASTER); // UDE 1032
// This fires at the start of DetermineCombatRound() *IF they can do an action*.
//SetSpawnInCondition(AI_FLAG_UDE_DAMAGED_AT_1_HP, AI_UDE_MASTER); // UDE 1014
// Fires when we are damaged, and are at 1 HP. Use for immortal-flagged creatures.
/*** Speakstrings - as it were, said under cirtain conditions % chance each time ***/
//AI_SetSpawnInSpeakArray(AI_TALK_ON_CONVERSATION, 100, 4, "Hello there", "I hope you enjoy your stay", "Do you work here too?", "*Hic*");
// On Conversation - see readme. Replaces BeginConversation().
// Morale
//AI_SetSpawnInSpeakArray(AI_TALK_ON_MORALE_BREAK, 100, 3, "No more!", "I'm outta here!", "Catch me if you can!");
// Spoken at running point, if they run to a group of allies.
//AI_SetSpawnInSpeakArray(AI_TALK_ON_CANNOT_RUN, 100, 3, "Never give up! Never surrender!", "I've no where to run, so make my day!", "RRRAAAAA!!!");
// Spoken at running point, if they can find no ally to run to, and 4+ Intelligence. See readme
//AI_SetSpawnInSpeakValue(AI_TALK_ON_STUPID_RUN, "Ahhhhgggg! NO MORE! Run!!");
// As above, when morale breaks + no ally, but they panic and run from enemy at 3 or less intelligence.
// Combat
//AI_SetSpawnInSpeakArray(AI_TALK_ON_COMBAT_ROUND_EQUAL, 5, 4, "Come on!", "You won't win!", "We are not equals! I am better!", "Nothing will stop me!");
//AI_SetSpawnInSpeakArray(AI_TALK_ON_COMBAT_ROUND_THEM_OVER_US, 5, 4, "I'll try! try! and try again!", "Tough man, are we?", "Trying out your 'skills'? Pathetic excuse!", "Nothing good will come from killing me!");
//AI_SetSpawnInSpeakArray(AI_TALK_ON_COMBAT_ROUND_US_OVER_THEM, 5, 4, "My strength is mighty then yours!", "You will definatly die!", "NO chance for you!", "No mercy! Not for YOU!");
// Spoken each DetermineCombatRound. % is /1000. See readme for Equal/Over/Under values.
//AI_SetSpawnInSpeakArray(AI_TALK_ON_TAUNT, 100, 3, "You're going down!", "No need to think, let my blade do it for you!", "Time to meet your death!");
// If the creature uses thier skill, taunt, on an enemy this will be said.
// Event-driven.
//AI_SetSpawnInSpeakArray(AI_TALK_ON_PERCIEVE_ENEMY, 70, 6, "Stand and fight, lawbreaker!", "Don't run from the law!", "I have my orders!", "I am ready for violence!", "CHARGE!", "Time you died!");
// This is said when they see/hear a new enemy, and start attacking them.
//AI_SetSpawnInSpeakArray(AI_TALK_ON_DAMAGED, 20, 2, "Ouch, damn you!", "Haha! Nothing will stop me!");
// A random value is set to speak when damaged, and may fire same time as below ones.
//AI_SetSpawnInSpeakArray(AI_TALK_ON_PHISICALLY_ATTACKED, 20, 2, "Hah! Mear weapons won't defeat me!", "Pah! You cannot defeat me with such rubbish!");
// This is said when an enemy attacks the creature with a melee/ranged weapon.
//AI_SetSpawnInSpeakArray(AI_TALK_ON_HOSTILE_SPELL_CAST_AT, 20, 2, "No one spell will stop me!", "Is that all you have!?!");
// This is said when an enemy attacks the creature with a hostile spell.
//AI_SetSpawnInSpeakValue(AI_TALK_ON_DEATH, "Agggggg!");
// This will ALWAYS be said, whenever the creature dies.
// Specific potion ones.
//AI_SetSpawnInSpeakValue(AI_TALK_WE_PASS_POTION, "Here! Catch!");
// This will be spoken when the creature passes a potion to an ally. See readme.
//AI_SetSpawnInSpeakValue(AI_TALK_WE_GOT_POTION, "Got it!");
// This will be spoken by the creature we pass the potion too, using AssignCommand().
// Leader ones
//AI_SetSpawnInSpeakValue(AI_TALK_ON_LEADER_SEND_RUNNER, "Quickly! We need help!");
// This will be said when the leader, if this creature, sends a runner.
//AI_SetSpawnInSpeakValue(AI_TALK_ON_LEADER_ATTACK_TARGET, "Help attack this target!");
// When the leader thinks target X should be attacked, it will say this.
//AI_SetSpawnInSpeakValue(AI_TALK_ON_LEADER_BOSS_SHOUT, "Come my minions! To battle!");
// This will be said when the leader, if this creature, sees an enemy and uses his "Boss Monster Shout", if turned on.
/************************ [User Defined and Shouts] ***************************/
/************************ [Bioware: Animations/Waypoints/Treasure] *************
All Bioware Stuff. I'd check out "x0_c2_spwn_def" for the SoU/Hordes revisions.
************************* [Bioware: Animations/Waypoints/Treasure] ************/
// SetSpawnInCondition(NW_FLAG_STEALTH, NW_GENERIC_MASTER);
// SetSpawnInCondition(NW_FLAG_SEARCH, NW_GENERIC_MASTER);
// Uses said skill while WalkWaypoints()
// SetSpawnInCondition(NW_FLAG_DAY_NIGHT_POSTING, NW_GENERIC_MASTER);
// Separate the NPC's waypoints into day & night. See comment in "nw_i0_generic" for use.
// SetSpawnInCondition(NW_FLAG_IMMOBILE_AMBIENT_ANIMATIONS, NW_GENERIC_MASTER);
// This will cause an NPC to use common animations it possesses,
// and use social ones to any other nearby friendly NPCs.
// SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS, NW_GENERIC_MASTER);
// Same as above, except NPC will wander randomly around the area.
// SetAnimationCondition(NW_ANIM_FLAG_IS_CIVILIZED);
// Interacts with placeables + More civilized actions. See Readme.
// SetAnimationCondition(NW_ANIM_FLAG_CHATTER);
// Will use random voicechats during animations, if Civilized
// SetAnimationCondition(NW_ANIM_FLAG_IS_MOBILE_CLOSE_RANGE);
// Will move around the area a bit more, if using Immobile Animations. See readme.
// Treasure generating.
//CTG_GenerateNPCTreasure();
// SoU. Requires "x0_i0_treasure" to be uncommented. See readme.
//GenerateNPCTreasure();
// Default NwN. Requires "nw_o2_coninclude" to be uncommented. See readme.
/************************ [Bioware: Animations/Waypoints/Treasure] ************/
// AI Behaviour. DO NOT CHANGE! DO NOT CHANGE!!!
AI_SetUpEndOfSpawn();
// This MUST be called. It fires these events:
// SetUpSpells, SetUpSkillToUse, SetListeningPatterns, SetWeapons, AdvancedAuras.
// These MUST be called! the AI might fail to work correctly if they don't fire!
/************************ [User] ***********************************************
This is the ONLY place you should add user things, on spawn, such as
visual effects or anything, as it is after SetUpEndOfSpawn. By default, this
does have encounter animations on. This is here, so is easily changed :-D
Be careful otherwise.
Notes:
- SetListening is already set to TRUE, unless AI_FLAG_OTHER_LAG_NO_LISTENING is on.
- SetListenPattern's are set from 0 to 7.
- You can use the wrappers AI_SpawnInInstantVisual and AI_SpawnInPermamentVisual
for visual effects (Instant/Permament as appropriate).
************************* [User] **********************************************/
// Example (and default) of user addition:
// - If we are from an encounter, set mobile (move around) animations.
if(GetIsEncounterCreature())
{
SetSpawnInCondition(NW_FLAG_AMBIENT_ANIMATIONS, NW_GENERIC_MASTER);
}
// Leave this in if you use the variable for creature attacks, as for golems. Bioware's code.
int nNumber = GetLocalInt(OBJECT_SELF, "CREATURE_VAR_NUMBER_OF_ATTACKS");
if(nNumber > 0)
{
SetBaseAttackBonus(nNumber);
}
// If we are a ranger or paladin class, do not cast spells. This can be
// manually removed if wished. To get the spells they have working correctly,
// remove this, and use Monster Abilties instead of thier normal class spells.
// if(GetLevelByClass(CLASS_TYPE_RANGER) >= 1 || GetLevelByClass(CLASS_TYPE_PALADIN) >= 1)
// {
// SetSpawnInCondition(AI_FLAG_OTHER_LAG_NO_SPELLS, AI_OTHER_MASTER);
// }
/************************ [User] **********************************************/
// Note: You shouldn't really remove this, even if they have no waypoints.
DelayCommand(2.0, SpawnWalkWayPoints());
// Delayed walk waypoints, as to not upset instant combat spawning.
// This will also check if to change to day/night posts during the walking, no heartbeats.
}

View File

@@ -1,84 +0,0 @@
/*/////////////////////// [On Rested] //////////////////////////////////////////
Filename: J_AI_OnRest or nw_c2_defaulta
///////////////////////// [On Rested] //////////////////////////////////////////
This will play the sitting animation for 6 seconds, just something for resting.
Also, walks waypoints (as resting would stop this) :-) and signals event (if so be)
Feel free to edit.
It does have the spell trigger information resetting, however. This can
only be removed if they have no spell triggers, although it is hardly worth it.
///////////////////////// [History] ////////////////////////////////////////////
1.3 - Added sitting.
1.4 - Will be editing this down. No need to reset anything on rest, for a
better working AI.
IDEA: Change so that we will work through all spells/feats in order.
If, at cirtain levels, we do not have any spells to cast from that
level (set in a global stored integer in the general AI) we ignore all
spells in that level. Same for each talent category (no need to use
talents for them in the spawn script).
If not in combat (EG: In heartbeat) we reset the integers saying "don't
bother checking those spells" to false.
///////////////////////// [Workings] ///////////////////////////////////////////
This fires once, at the END of resting.
If ClearAllActions is added, the resting is actually stopped, or so it seems.
It doesn't fire more then once.
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: None, it seems.
///////////////////////// [On Rested] ////////////////////////////////////////*/
#include "J_INC_CONSTANTS"
// Resets all spell triggers used for sString
void LoopResetTriggers(string sString, object oTrigger);
void main()
{
// Pre-rest-event. Returns TRUE if we interrupt this script call.
if(FirePreUserEvent(AI_FLAG_UDE_RESTED_PRE_EVENT, EVENT_RESTED_PRE_EVENT)) return;
// AI status check. Is the AI on?
if(GetAIOff()) return;
// Simple debug.
// 66: "[Rested] Resting. Type: " + IntToString(GetLastRestEventType())
DebugActionSpeakByInt(66, OBJECT_INVALID, GetLastRestEventType());
// Reset all spell triggers.
// Set all triggers
object oTrigger = GetAIObject(AI_SPELL_TRIGGER_CREATURE);
if(GetIsObjectValid(oTrigger))
{
LoopResetTriggers(SPELLTRIGGER_NOT_GOT_FIRST_SPELL, oTrigger);
LoopResetTriggers(SPELLTRIGGER_DAMAGED_AT_PERCENT, oTrigger);
LoopResetTriggers(SPELLTRIGGER_IMMOBILE, oTrigger);
LoopResetTriggers(SPELLTRIGGER_START_OF_COMBAT, oTrigger);
}
// Some sitting for a few seconds.
ActionPlayAnimation(ANIMATION_LOOPING_SIT_CROSS, 1.0, 6.0);
DelayCommand(9.0, ExecuteScript(FILE_WALK_WAYPOINTS, OBJECT_SELF));
// Fire End-heartbeat-UDE
FireUserEvent(AI_FLAG_UDE_RESTED_EVENT, EVENT_RESTED_EVENT);
}
// Resets all spell triggers used for sString
void LoopResetTriggers(string sString, object oTrigger)
{
int nCnt, bBreak, bUsed;
for(nCnt = 1; bBreak != TRUE; nCnt++)
{
// Check max for this setting
bUsed = GetLocalInt(oTrigger, sString + USED);
if(bUsed)
{
DeleteLocalInt(oTrigger, sString + USED);
}
else
{
bBreak = TRUE;
}
}
}

View File

@@ -1,493 +0,0 @@
/*/////////////////////// [On Spell Cast At] ///////////////////////////////////
Filename: j_ai_onspellcast or nw_c2_defaultb
///////////////////////// [On Spell Cast At] ///////////////////////////////////
What does this do? Well...
- Any AOE spell effects are set in a timer, so we can react to them right
- Reacts to hostile casters, or allies in combat
And the normal attack :-)
///////////////////////// [History] ////////////////////////////////////////////
1.3 - Added special AOE checks.
- Hide checks.
1.4 - Added more silent shouts. Edited the formatting. Moved a few things around.
///////////////////////// [Workings] ///////////////////////////////////////////
This is fired when EventSpellCastAt(object oCaster, int nSpell, int bHarmful=TRUE)
is signaled on the creature.
GetLastSpellCaster() = oCaster (Door, Placeable, Creature who cast it)
GetLastSpell() = nSpell (The spell cast at us)
GetLastSpellHarmful()= bHarmful (If it is harmful!)
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: GetLastSpellCaster, GetLastSpellHarmful GetLastSpell()
///////////////////////// [On Spell Cast At] /////////////////////////////////*/
#include "J_INC_OTHER_AI"
// Sets a local timer if the spell is an AOE one
void SetAOESpell(int nSpellCast, object oCaster);
// Gets the nearest AOE cast by oCaster, of sTag.
object GetNearestAOECastBy(string sTag, object oCaster);
// Gets the amount of protections we have - IE globes
int GetOurSpellLevelImmunity();
void main()
{
// Pre-spell cast at-event. Returns TRUE if we interrupt this script call.
if(FirePreUserEvent(AI_FLAG_UDE_SPELL_CAST_AT_PRE_EVENT, EVENT_SPELL_CAST_AT_PRE_EVENT)) return;
// AI status check. Is the AI on?
if(GetAIOff()) return;
object oCaster = GetLastSpellCaster();
int bHarmful = GetLastSpellHarmful();
int nSpellCast = GetLastSpell();
object oAttackerOfCaster;
// If harmful, we set the spell to a timer, if an AOE one.
if(bHarmful && GetIsObjectValid(oCaster))
{
// Might set AOE spell to cast.
SetAOESpell(nSpellCast, oCaster);
}
// If not a creature, probably an AOE or trap.
if(GetObjectType(oCaster) != OBJECT_TYPE_CREATURE)
{
// 67: "[Spell] Caster isn't a creature! May look for target [Caster] " + GetName(oCaster)
DebugActionSpeakByInt(67, oCaster);
// Shout to allies to attack, or be prepared.
AISpeakString(AI_SHOUT_CALL_TO_ARMS);
// Attack anyone else around
if(!CannotPerformCombatRound())
{
// Determine Combat Round
DetermineCombatRound();
}
}
// If a friend, or dead, or a DM, or invalid, or self, we ignore them.
else if(!GetIgnoreNoFriend(oCaster) && oCaster != OBJECT_SELF)
{
// 1.3 changes here:
// - We do NOT need to know if it is hostile or not, except if it is hostile
// and they are not our faction! We do, however, use bHarmful for speakstrings.
// If harmful, we attack anyone! (and if is enemy)
// 1.4: Faction equal check in GetIgnoreNoFriend()
if(bHarmful || GetIsEnemy(oCaster))
{
// Spawn in condition hostile thingy
if(GetSpawnInCondition(AI_FLAG_OTHER_CHANGE_FACTIONS_TO_HOSTILE_ON_ATTACK, AI_OTHER_MASTER))
{
if(!GetIsEnemy(oCaster))
{
AdjustReputation(oCaster, OBJECT_SELF, -100);
}
}
if(bHarmful)
{
// * Don't speak when dead. 1.4 change (an obvious one to make)
if(CanSpeak())
{
// Hostile spell speaksting, if set.
SpeakArrayString(AI_TALK_ON_HOSTILE_SPELL_CAST_AT);
}
}
// Turn of hiding check
TurnOffHiding(oCaster);
// We attack
if(!CannotPerformCombatRound())
{
// 68: "[Spell:Enemy/Hostile] Not in combat. Attacking: [Caster] " + GetName(oCaster)
DebugActionSpeakByInt(68, oCaster);
DetermineCombatRound(oCaster);
}
// Shout to allies to attack the enemy who attacked me, got via. Last Hostile Actor.
AISpeakString(AI_SHOUT_I_WAS_ATTACKED);
}
// Else, was neutral perhaps. Don't attack them anyway.
else
{
// 69: "[Spell] (ally). Not in combat. May Attack/Move [Caster] " + GetName(oCaster)
DebugActionSpeakByInt(69, oCaster);
// Set special action to investigate - as if this event was triggered
// by I_WAS_ATTACKED.
// If we are already attacking, we do not move
if(CannotPerformCombatRound())
{
// Shout to allies to attack, or be prepared.
AISpeakString(AI_SHOUT_CALL_TO_ARMS);
}
else
{
// We react as if the caster, a neutral, called for help ala
// I_WAS_ATTACKED (they might not have, might just be
// preperation for something), but normally, this is a neutral
// casting a spell. Do not respond to PC's.
if(!GetIsPC(oCaster))
{
IWasAttackedResponse(oCaster);
}
}
}
}
// If they are not a faction equal, and valid, we help them.
else if(GetIsObjectValid(oCaster) && GetFactionEqual(oCaster))
{
IWasAttackedResponse(oCaster);
}
// Fire End-spell cast at-UDE
FireUserEvent(AI_FLAG_UDE_SPELL_CAST_AT_EVENT, EVENT_SPELL_CAST_AT_EVENT);
}
// Sets a local timer if the spell is an AOE one
void SetAOESpell(int nSpellCast, object oCaster)
{
// Check it is one we can check
int bStop = TRUE;
switch(nSpellCast)
{
case SPELL_ACID_FOG:
case SPELL_MIND_FOG:
case SPELL_STORM_OF_VENGEANCE:
case SPELL_GREASE:
case SPELL_CREEPING_DOOM:
case SPELL_SILENCE:
case SPELL_BLADE_BARRIER:
case SPELL_CLOUDKILL:
case SPELL_STINKING_CLOUD:
case SPELL_WALL_OF_FIRE:
case SPELL_INCENDIARY_CLOUD:
case SPELL_ENTANGLE:
case SPELL_EVARDS_BLACK_TENTACLES:
case SPELL_CLOUD_OF_BEWILDERMENT:
case SPELL_STONEHOLD:
case SPELL_VINE_MINE:
case SPELL_SPIKE_GROWTH:
case SPELL_VINE_MINE_HAMPER_MOVEMENT:
case SPELL_VINE_MINE_ENTANGLE:
{
bStop = FALSE;
}
break;
}
// Check immune level
int nImmuneLevel = GetOurSpellLevelImmunity();
if(nImmuneLevel >= 9)
{
bStop = TRUE;
}
// Check
if(bStop == TRUE)
{
return;
}
// We do use intelligence here...
int nAIInt = GetBoundriedAIInteger(AI_INTELLIGENCE);
int bIgnoreSaves;
int bIgnoreImmunities;
object oAOE;
// If it is low, we ignore all things that we could ignore with it...
if(nAIInt <= 3)
{
bIgnoreSaves = TRUE;
bIgnoreImmunities = TRUE;
}
// Average ignores saves
else if(nAIInt <= 7)
{
bIgnoreSaves = TRUE;
bIgnoreImmunities = FALSE;
}
// Else, we do both.
else
{
bIgnoreSaves = FALSE;
bIgnoreImmunities = FALSE;
}
int bSetAOE = FALSE;// TRUE means set to timer
int nSaveDC = 11;
// Get the caster DC, the most out of WIS, INT or CHA...
int nInt = GetAbilityModifier(ABILITY_INTELLIGENCE, oCaster);
int nWis = GetAbilityModifier(ABILITY_WISDOM, oCaster);
int nCha = GetAbilityModifier(ABILITY_CHARISMA, oCaster);
if(nInt > nWis && nInt > nCha)
{
nSaveDC += nInt;
}
else if(nWis > nCha)
{
nSaveDC += nWis;
}
else
{
nSaveDC += nCha;
}
// Note:
// - No reaction type/friendly checks. Signal Event is only fired if the
// spell WILL pierce any PvP/Friendly/Area settings
// We check immunities here, please note...
switch(nSpellCast)
{
// First: IS GetIsReactionTypeHostile ones.
case SPELL_EVARDS_BLACK_TENTACLES:
// Fortitude save, but if we are immune to the hits, its impossible to hurt us
{
// If save immune OR AC immune, we ignore this.
if(25 >= GetAC(OBJECT_SELF) && nImmuneLevel < 4 &&
((GetFortitudeSavingThrow(OBJECT_SELF) < nSaveDC + 2) || bIgnoreSaves))
{
bSetAOE = TRUE;
// Nearest string of tag
oAOE = GetNearestAOECastBy(AI_AOE_PER_EVARDS_BLACK_TENTACLES, oCaster);
}
}
case SPELL_SPIKE_GROWTH:
case SPELL_VINE_MINE_HAMPER_MOVEMENT:
// d4 damage. LOTS of speed loss.
// Reflex save, or immunity, would stop the speed
{
if(nImmuneLevel < 3 &&
(!GetIsImmune(OBJECT_SELF, IMMUNITY_TYPE_MOVEMENT_SPEED_DECREASE) || bIgnoreImmunities) &&
((GetReflexSavingThrow(OBJECT_SELF) < nSaveDC + 5) || bIgnoreSaves))
{
bSetAOE = TRUE;
// Both use ENTANGLE AOE's
oAOE = GetNearestAOECastBy(AI_AOE_PER_ENTANGLE, oCaster);
}
}
break;
case SPELL_ENTANGLE:
case SPELL_VINE_MINE_ENTANGLE:
{
if(nImmuneLevel < 1 &&
(!GetHasFeat(FEAT_WOODLAND_STRIDE) || bIgnoreImmunities) &&
(!GetIsImmune(OBJECT_SELF, IMMUNITY_TYPE_ENTANGLE) || bIgnoreImmunities) &&
((GetReflexSavingThrow(OBJECT_SELF) < nSaveDC + 4) || bIgnoreSaves))
{
bSetAOE = TRUE;
// Both use ENTANGLE AOE's
oAOE = GetNearestAOECastBy(AI_AOE_PER_ENTANGLE, oCaster);
}
}
break;
case SPELL_WEB:
{
if(nImmuneLevel < 1 &&
(!GetHasFeat(FEAT_WOODLAND_STRIDE) || bIgnoreImmunities) &&
(!GetIsImmune(OBJECT_SELF, IMMUNITY_TYPE_ENTANGLE) || bIgnoreImmunities) &&
((GetReflexSavingThrow(OBJECT_SELF) < nSaveDC + 4) || bIgnoreSaves))
{
bSetAOE = TRUE;
// Web AOE
oAOE = GetNearestAOECastBy(AI_AOE_PER_WEB, oCaster);
}
}
break;
// Fort save
case SPELL_STINKING_CLOUD:
{
if(nImmuneLevel < 3 &&
(!GetIsImmune(OBJECT_SELF, IMMUNITY_TYPE_POISON) || bIgnoreImmunities) &&
(!GetIsImmune(OBJECT_SELF, IMMUNITY_TYPE_DAZED) || bIgnoreImmunities) &&
((GetFortitudeSavingThrow(OBJECT_SELF) < nSaveDC + 6) || bIgnoreSaves))
{
bSetAOE = TRUE;
// Stinking cloud persistant AOE.
oAOE = GetNearestAOECastBy(AI_AOE_PER_FOGSTINK, oCaster);
}
}
break;
// Fort save
case SPELL_CLOUD_OF_BEWILDERMENT:
{
if(nImmuneLevel < 2 &&
((GetFortitudeSavingThrow(OBJECT_SELF) < nSaveDC + 7) || bIgnoreSaves))
{
bSetAOE = TRUE;
// Bewilderment cloud persistant AOE.
oAOE = GetNearestAOECastBy(AI_AOE_PER_FOGBEWILDERMENT, oCaster);
}
}
break;
// Special: Mind save is the effect.
case SPELL_STONEHOLD:
{
if(nImmuneLevel < 6 &&
(!GetIsImmune(OBJECT_SELF, IMMUNITY_TYPE_MIND_SPELLS) || bIgnoreImmunities) &&
((GetWillSavingThrow(OBJECT_SELF) < nSaveDC + 7) || bIgnoreSaves))
{
bSetAOE = TRUE;
// Stonehold persistant AOE.
oAOE = GetNearestAOECastBy(AI_AOE_PER_STONEHOLD, oCaster);
}
}
break;
// Special: EFFECT_TYPE_SAVING_THROW_DECREASE is the effect.
case SPELL_MIND_FOG:
{
if(nImmuneLevel < 5 &&
(!GetIsImmune(OBJECT_SELF, IMMUNITY_TYPE_SAVING_THROW_DECREASE) || bIgnoreImmunities) &&
((GetWillSavingThrow(OBJECT_SELF) < nSaveDC + 6) || bIgnoreSaves))
{
bSetAOE = TRUE;
// Mind fog
oAOE = GetNearestAOECastBy(AI_AOE_PER_FOGMIND, oCaster);
}
}
break;
// Special: Feats, knockdown
case SPELL_GREASE:
{
if(nImmuneLevel < 1 &&
(!GetIsImmune(OBJECT_SELF, IMMUNITY_TYPE_KNOCKDOWN) || bIgnoreImmunities) &&
(!GetHasFeat(FEAT_WOODLAND_STRIDE, OBJECT_SELF) || bIgnoreImmunities) &&
((GetReflexSavingThrow(OBJECT_SELF) < nSaveDC + 2) || bIgnoreSaves))
{
bSetAOE = TRUE;
// Grease
oAOE = GetNearestAOECastBy(AI_AOE_PER_GREASE, oCaster);
}
}
break;
// All other ReactionType ones. Some have different saves though!
case SPELL_BLADE_BARRIER: // Reflex
case SPELL_INCENDIARY_CLOUD:// reflex
case SPELL_WALL_OF_FIRE:// Reflex
{
if(nImmuneLevel < 6 &&
(((GetReflexSavingThrow(OBJECT_SELF) < nSaveDC + 6) &&
!GetHasFeat(FEAT_IMPROVED_EVASION) &&
!GetHasFeat(FEAT_EVASION)) || bIgnoreSaves))
{
bSetAOE = TRUE;
if(nSpellCast == SPELL_BLADE_BARRIER)
{
// BB
oAOE = GetNearestAOECastBy(AI_AOE_PER_WALLBLADE, oCaster);
}
else if(nSpellCast == SPELL_INCENDIARY_CLOUD)
{
// Fog of fire
oAOE = GetNearestAOECastBy(AI_AOE_PER_FOGFIRE, oCaster);
}
else if(nSpellCast == SPELL_WALL_OF_FIRE)
{
// Wall of fire
oAOE = GetNearestAOECastBy(AI_AOE_PER_WALLFIRE, oCaster);
}
}
}
break;
case SPELL_ACID_FOG: // Fort: Half. No check, always damages.
case SPELL_CLOUDKILL:// No save!
case SPELL_CREEPING_DOOM: // No save!
{
if(nImmuneLevel < 6)
{
bSetAOE = TRUE;
if(nSpellCast == SPELL_ACID_FOG)
{
// Acid fog
oAOE = GetNearestAOECastBy(AI_AOE_PER_FOGACID, oCaster);
}
else if(nSpellCast == SPELL_CLOUDKILL)
{
// Cloud Kill
oAOE = GetNearestAOECastBy(AI_AOE_PER_FOGKILL, oCaster);
}
else if(nSpellCast == SPELL_CREEPING_DOOM)
{
// Creeping doom
oAOE = GetNearestAOECastBy(AI_AOE_PER_CREEPING_DOOM, oCaster);
}
}
}
// Storm - because the AI likes it, we stay in it if it is ours :-)
case SPELL_STORM_OF_VENGEANCE: // Reflex partial. No check, always damages.
{
if(oCaster != OBJECT_SELF && nImmuneLevel < 9)
{
bSetAOE = TRUE;
// Storm of vengance
oAOE = GetNearestAOECastBy(AI_AOE_PER_STORM, oCaster);
}
}
}
if(bSetAOE)
{
if(!GetLocalTimer(AI_TIMER_AOE_SPELL_EVENT + IntToString(nSpellCast)))
{
SetLocalTimer(AI_TIMER_AOE_SPELL_EVENT + IntToString(nSpellCast), 18.0);
// Set nearest AOE
if(GetIsObjectValid(oAOE))
{
// Set nearest AOE of this spell to the local
object oNearest = GetAIObject(AI_TIMER_AOE_SPELL_EVENT + IntToString(nSpellCast));
if(GetDistanceToObject(oAOE) < GetDistanceToObject(oNearest) ||
!GetIsObjectValid(oNearest))
{
SetAIObject(AI_TIMER_AOE_SPELL_EVENT + IntToString(nSpellCast), oAOE);
}
}
}
}
}
// Gets the nearest AOE cast by oCaster, of sTag.
object GetNearestAOECastBy(string sTag, object oCaster)
{
int nCnt = 1;
object oAOE = GetNearestObjectByTag(sTag, OBJECT_SELF, nCnt);
object oReturn = OBJECT_INVALID;
// Loop
while(GetIsObjectValid(oAOE) && !GetIsObjectValid(oReturn))
{
// Check creator
if(GetAreaOfEffectCreator(oAOE) == oCaster)
{
oReturn = oAOE;
}
nCnt++;
oAOE = GetNearestObjectByTag(sTag, OBJECT_SELF, nCnt);
}
return oReturn;
}
// Gets the amount of protections we have - IE globes
int GetOurSpellLevelImmunity()
{
int nNatural = GetLocalInt(OBJECT_SELF, AI_SPELL_IMMUNE_LEVEL);
// Stop here, if natural is over 4
if(nNatural > 4) return nNatural;
// Big globe affects 4 or lower spells
if(GetHasSpellEffect(SPELL_GLOBE_OF_INVULNERABILITY, OBJECT_SELF) || nNatural >= 4)
return 4;
// Minor globe is 3 or under
if(GetHasSpellEffect(SPELL_MINOR_GLOBE_OF_INVULNERABILITY, OBJECT_SELF) ||
// Shadow con version
GetHasSpellEffect(SPELL_GREATER_SHADOW_CONJURATION_MINOR_GLOBE, OBJECT_SELF) ||
nNatural >= 3)
return 3;
// 2 and under is ethereal visage.
if(GetHasSpellEffect(SPELL_ETHEREAL_VISAGE, OBJECT_SELF) || nNatural >= 2)
return 2;
// Ghostly Visarge affects 1 or 0 level spells, and any spell immunity.
if(GetHasSpellEffect(SPELL_GHOSTLY_VISAGE, OBJECT_SELF) || nNatural >= 1 ||
// Or shadow con version.
GetHasSpellEffect(SPELL_GREATER_SHADOW_CONJURATION_MIRROR_IMAGE, OBJECT_SELF))
return 1;
// Return nNatural, which is 0-9
return FALSE;
}

View File

@@ -1,326 +0,0 @@
/*/////////////////////// [On User Defined] ////////////////////////////////////
Filename: J_AI_OnUserDef or nw_c2_defaultd
///////////////////////// [Workings] ///////////////////////////////////////////
1.4 Adds proper Pre-event functionality. Use this to make sure you keep the
AI working, but making small additions using this event.
Can be deleted to save space if you want :-)
How to use user defined events (brief):
There are a set of optional Spawn In values you can set within the spawn file.
If you set one of the Events to fire, it will activate this script. Then,
under the correct choice (EG I choose the Pre-Heartbeat event, then I
uncomment the line "SetSpawnInCondition(AI_FLAG_UDE_HEARTBEAT_PRE_EVENT, AI_UDE_MASTER);"
and find, in this file, the section with EVENT_HEARTBEAT_PRE_EVENT above it).
add in whatever to do.
With my Pre-heartbeat example, if I wanted it to check for a PC, then
check for a combat dummy, and attack it, I'd add this between the brackets:
// Code:
// Not in combat, of course!
if(!GetIsInCombat())
{
// Function in j_inc_npc_attack to get nearest PC
object oPC = GetNearestPCCreature();
// Why check for a PC? Well, it saves memory
if(GetIsObjectValid(oPC) && GetDistanceToObject(oPC) <= 40.0)
{
object oDummy = GetNearestObjectByTag("DUMMY");
if(GetIsObjectValid(oDummy))
{
ClearAllActions();
ActionAttack(oDummy);
// Exit (Stop the rest of the script)
SetToExitFromUDE(EVENT_HEARTBEAT_PRE_EVENT);
// Stop rest of script
return;
}
}
}
// End code
Simple, no?
You can delete sections you don't need, and is recommended as long as you know
how to use User Defined events.
///////////////////////// [History] ////////////////////////////////////////////
1.3 - Added in with some documentation
1.4 - Changed Pre-events. Now, it uses Execute Script. Will need to set
a special string on the creature to now what script to fire.
- It means they work correctly, however!
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: Dependant on event. See seperate event scripts.
///////////////////////// [On User Defined] //////////////////////////////////*/
// This contains a lot of useful things.
// - Combat starting
// - Constant values
// - Get/Set spawn in values.
#include "J_INC_OTHER_AI"
// This contains some useful things to get NPC's to attack and so on.
#include "J_INC_NPC_ATTACK"
/************************ [UDE Values] *****************************************
These are uneeded, but here for reference. Use the constants in the file
"j_inc_constants" like "EVENT_HEARTBEAT_PRE_EVENT" which is classed as 1021.
* The normal death event might not fire before the creature has vanished.
Use the Pre-event (but with no stopping the death event) if you want a special
death event to happen.
Name Normal-End event - Pre-Event
Heartbeat Event 1001 1021
Percieve Event 1002 1022
Combat Round Event 1003 1023
Dialog Event 1004 1024
Attack Event 1005 1025
Damaged Event 1006 1026
Death Event 1007 1027
Disturbed Event 1008 1028
Rested Event 1009 1029
Spell Cast At Event 1011 1031
Combat Action Event 1012 1032
Damaged 1HP Event 1014 -
Blocked Event 1015 1035
************************* [UDE Values] ****************************************/
void main()
{
// Get the user defined number.
// * NOTE: YOU MUST USE AI_GetUDENumber(), not GetUserDefinedEventNumber()!
int nEvent = AI_GetUDENumber();
// Events.
switch(nEvent)
{
// Event Heartbeat
// Arguments: Basically, none. Nothing activates this script. Fires every 6 seconds.
case EVENT_HEARTBEAT_PRE_EVENT:
{
// This fires before the rest of the On Heartbeat file does
// Exit (Stop the rest of the script)
SetToExitFromUDE(EVENT_HEARTBEAT_PRE_EVENT);
}
break;
case EVENT_HEARTBEAT_EVENT:
{
// This fires after the rest of the On Heartbeat file does
}
break;
// Event Percieve
// Arguments: GetLastPerceived, GetLastPerceptionSeen, GetLastPerceptionHeard,
// GetLastPerceptionVanished, GetLastPerceptionInaudible.
case EVENT_PERCIEVE_PRE_EVENT:
{
// This fires before the rest of the On Percieve file does
// Exit (Stop the rest of the script)
SetToExitFromUDE(EVENT_PERCIEVE_PRE_EVENT);
}
break;
case EVENT_PERCIEVE_EVENT:
{
// This fires after the rest of the On Percieve file does
}
break;
// Event Combat Round End
// Arguments: GetAttackTarget, GetLastHostileActor, GetAttemptedAttackTarget,
// GetAttemptedSpellTarget (Or these are useful at least!)
case EVENT_END_COMBAT_ROUND_PRE_EVENT:
{
// This fires before the rest of the On Combat Round End file does
// Exit (Stop the rest of the script)
SetToExitFromUDE(EVENT_END_COMBAT_ROUND_PRE_EVENT);
}
break;
case EVENT_END_COMBAT_ROUND_EVENT:
{
// This fires after the rest of the On Combat Round End file does
}
break;
// Event Dialogue
// Arguments: GetListenPatternNumber, GetLastSpeaker, TestStringAgainstPattern,
// GetMatchedSubstring (I think),
case EVENT_ON_DIALOGUE_PRE_EVENT:
{
// This fires before the rest of the dialog file does
// Exit (Stop the rest of the script)
SetToExitFromUDE(EVENT_ON_DIALOGUE_PRE_EVENT);
}
break;
case EVENT_ON_DIALOGUE_EVENT:
{
// This fires after the rest of the dialog file does
}
break;
// Event Attacked
// Arguments: GetLastAttacker, GetLastWeaponUsed, GetLastAttackMode,
// GetLastAttackType
case EVENT_ATTACK_PRE_EVENT:
{
// This fires before the rest of the Attacked file does
// Exit (Stop the rest of the script)
SetToExitFromUDE(EVENT_ATTACK_PRE_EVENT);
}
break;
case EVENT_ATTACK_EVENT:
{
// This fires after the rest of the Attacked file does
}
break;
// Event Damaged
// Arguments: GetTotalDamageDealt, GetLastDamager, GetCurrentHitPoints
// (and max), GetDamageDealtByType
case EVENT_DAMAGED_PRE_EVENT:
{
// This fires before the rest of the damaged file does
// Exit (Stop the rest of the script)
SetToExitFromUDE(EVENT_DAMAGED_PRE_EVENT);
}
break;
case EVENT_DAMAGED_EVENT:
{
// This fires after the rest of the damaged file does
}
break;
// Event Death
// Arguments: GetLastKiller
case EVENT_DEATH_PRE_EVENT:
{
// This fires before the rest of the death file does
// Exit (Stop the rest of the script)
SetToExitFromUDE(EVENT_DEATH_PRE_EVENT);
}
break;
case EVENT_DEATH_EVENT:
{
// This fires after the rest of the death file does
}
break;
// Event Distrubed
// Arguments: GetInventoryDisturbItem, GetLastDisturbed,
// GetInventoryDisturbType (should always be stolen :-( ).
case EVENT_DISTURBED_PRE_EVENT:
{
// This fires before the rest of the disturbed file does
// Exit (Stop the rest of the script)
SetToExitFromUDE(EVENT_DISTURBED_PRE_EVENT);
}
break;
case EVENT_DISTURBED_EVENT:
{
// This fires after the rest of the disturbed file does
}
break;
// Event Rested
// Arguments: None
// Note: Not sure if this fires at the end of rest event, but the actual
// duration of the rest is 0, so you never "see" it.
case EVENT_RESTED_PRE_EVENT:
{
// This fires before the rest of the rested file does
// Exit (Stop the rest of the script)
SetToExitFromUDE(EVENT_RESTED_PRE_EVENT);
}
break;
case EVENT_RESTED_EVENT:
{
// This fires after the rest of the rested file does
}
break;
// Event Spell cast at
// Arguments: GetLastSpellCaster, GetLastSpellHarmful GetLastSpell()
case EVENT_SPELL_CAST_AT_PRE_EVENT:
{
// This fires before the rest of the Spell Cast At file does
// Exit (Stop the rest of the script)
SetToExitFromUDE(EVENT_SPELL_CAST_AT_PRE_EVENT);
}
break;
case EVENT_SPELL_CAST_AT_EVENT:
{
// This fires after the rest of the Spell Cast At End file does
}
break;
// Event Blocked
// Arguements: GetBlockingDoor, GetIsDoorActionPossible, GetLocked,
// GetLockKeyRequired, GetLockKeyTag, GetLockUnlockDC, GetPlotFlag.
case EVENT_ON_BLOCKED_PRE_EVENT:
{
// This fires before the rest of the on blocked file does
// Exit (Stop the rest of the script)
SetToExitFromUDE(EVENT_ON_BLOCKED_PRE_EVENT);
}
break;
case EVENT_ON_BLOCKED_EVENT:
{
// This fires after the rest of the on blocked file does
}
break;
// Event Combat Action
// Arguments: GetAttackTarget(), and lots of others.
// Note: Fires when DetermineCombatRound runs to perform an action.
case EVENT_COMBAT_ACTION_PRE_EVENT:
{
// This fires before the rest of the Determine Combat Round call does
// Exit (Stop the rest of the script)
SetToExitFromUDE(EVENT_COMBAT_ACTION_PRE_EVENT);
}
break;
case EVENT_COMBAT_ACTION_EVENT:
{
// This fires after the rest of the Determine Combat Round call does
// Calling ClearAllActions should stop any actions added in the call.
}
break;
// Event Damaged at 1 HP.
// Arguments: None really.
// Note: Fires OnDamaged, when we have exactly 1HP. Use for Immortal Creatures.
case EVENT_DAMAGED_AT_1_HP:
{
// This fires after the rest of the On Combat Round End file does
}
break;
// End all in-built events. Add more in here, if you wish.
}
}

View File

@@ -1,332 +0,0 @@
/*/////////////////////// [On Blocked] /////////////////////////////////////////
Filename: J_AI_OnBlocked or nw_c2_defaulte
///////////////////////// [On Blocked] /////////////////////////////////////////
Added in user defined constant - won't open any doors.
0 = Default (even if not set) opens as appropriate
1 = Always bashes the door.
2 = Never open any doors
3 = Never opens plot doors
They will: (int is intellgience needed)
1. Open if not trapped (7 int)
2. Unlock if possible, and rank is high enough, and it needs no key and is not trapped (7 int)
3. Untrap the door, if possible, if trapped (7 int)
4. Else, if has high enough stats, try Knock. (10 int)
6. Else Equip appropriate weapons and bash (5 int)
Note: This also fires for blocking via. creatures. It is optimised, and
works by re-targeting and doing a few small things to do with blocking.
///////////////////////// [History] ////////////////////////////////////////////
1.0 - Opens with Knock. Unlocks door. Ignores trapped doors.
1.3 - Debug messages.
- New events, even if the change of using them is small!
- No ClearAllactions so any previous movings will carry on once the door is gone.
- Removed debug messages
- Added Creature reaction code
1.4 - Need to add a "hands" check (done on spawn, to set a setting to not
open doors at all, IE: We do NOT have hands, do not open doors), so
its a little more realistic "out of the box"
- Fixed an instance of GetObjectSeen being repeated.
- Fixed the variable AI_DOOR_INTELLIGENCE not being got via GetAIInteger().
- Removed unneeded else statement.
///////////////////////// [Workings] ///////////////////////////////////////////
Uses simple code to deal with a door in the best way possible.
Uses DoDoorAction, which is added to the top of an action queue and doesn't,
therefore, delete any ActionAttack's and so on below it. (Or I hope it
is like this)
Creatures are reacted by with ClearAllActions usually.
///////////////////////// [Arguments] //////////////////////////////////////////
Arguments: GetBlockingDoor, GetIsDoorActionPossible, GetLocked, GetLockKeyRequired
GetLockKeyTag, GetLockUnlockDC, GetPlotFlag, DoDoorAction
///////////////////////// [On Blocked] ///////////////////////////////////////*/
#include "J_INC_OTHER_AI"
// Fires the end-blocked event.
void FireBlockedEvent();
// Range attack oTarget.
int RangedAttack(object oTarget = OBJECT_INVALID);
void main()
{
// Pre-on blocked-event. Returns TRUE if we interrupt this script call.
if(FirePreUserEvent(AI_FLAG_UDE_ON_BLOCKED_PRE_EVENT, EVENT_ON_BLOCKED_PRE_EVENT)) return;
// AI status check. Is the AI on?
if(GetAIOff()) return;
// This CAN return a blocking creature.
object oBlocker = GetBlockingDoor();
int nBlockerType = GetObjectType(oBlocker);
if(!GetIsObjectValid(oBlocker)) return;
// Anyone blocked by an enemy will re-target them (and attack them), blocked
// by someone they cannot get they will cast seeing spells and react, and if
// blocked by a friend, they may run back and use a ranged weapon if they
// have one.
if(nBlockerType == OBJECT_TYPE_CREATURE)
{
// Are we doing something that should not be overriden? (even fleeing,
// if stuck, we can't do anything else then move again on heartbeat!)
if(GetIsPerformingSpecialAction()) return;
// Blocked timer, we normally do an action. A small timer stops a lot
// of lag.
if(GetLocalTimer(AI_TIMER_BLOCKED)) return;
// Set the timer for 1 second
SetLocalTimer(AI_TIMER_BLOCKED, 1.0);
// Is it an enemy?
if(GetIsEnemy(oBlocker))
{
// Check if seen or heard
if(GetObjectSeen(oBlocker) || GetObjectHeard(oBlocker))
{
// Enemy :-) We can re-target (as know of thier presence), using
// them as a target.
// - This overrides even casting a spell - basically, as we should
// be moving, this will re-cast it at someone or something in range
SetAIObject(AI_ATTACK_SPECIFIC_OBJECT, oBlocker);
// Check if we can do combat - if we cannot, we can re-do combat
// next time
if(!GetIsBusyWithAction())
{
// Attacks if we are not attacking
ClearAllActions();
DetermineCombatRound(oBlocker);
return;
}
}
else
{
// Invisible? Not there? Some odd error? We set that we know of
// someone invisible, and will attack if not in combat.
if(GetHasEffect(EFFECT_TYPE_INVISIBILITY, oBlocker) ||
GetStealthMode(oBlocker) == STEALTH_MODE_ACTIVATED)
{
SetAIObject(AI_LAST_TO_GO_INVISIBLE, oBlocker);
}
// Shout to allies
AISpeakString(AI_SHOUT_CALL_TO_ARMS);
// Check if we can do combat
if(!GetIsBusyWithAction())
{
// Attacks if we are not attacking
ClearAllActions();
DetermineCombatRound();
return;
}
}
}
// Else is non-enemy, a friend or neutral
else
{
// As we are blocked by them, we re-do combat - we have a choice of
// either using a Bow to attack our target (if that was what
// we were doing) and move back a little, or re-initiate combat
// Were we attacking in combat?
object oPrevious = GetAttackTarget();
// Check action
if(GetCurrentAction() == ACTION_ATTACKOBJECT)
{
// This gets set to FALSE if we can cutthrough attack,
// or whatever.
int bPreviousAttackFailed = FALSE;
// Check if we can see our previous target
if(GetObjectSeen(oPrevious) ||
(GetObjectHeard(oPrevious) && LineOfSightObject(OBJECT_SELF, oPrevious)))
{
// We can! see if we can re-attack with ranged weapon, else
// doesn't matter we can see them
bPreviousAttackFailed = RangedAttack(oPrevious);
}
// If we havn't added an action yet...
if(bPreviousAttackFailed == FALSE)
{
// We have not stopped the script - so determine combat
// round against nearest seen or heard enemy!
if(!RangedAttack())
{
// Else normal round to try and get a new target
ClearAllActions();
DetermineCombatRound();
}
}
// Action attack, normally means melee attack. If we can, we
// attack our previous target if seen, ELSE we will re-initate
// combat.
AISpeakString(AI_SHOUT_I_WAS_ATTACKED);
// Fire the On blocked event as normal
FireBlockedEvent();
return;
}
else // if(nAction == ACTION_CASTSPELL and others)
{
// Reinitate combat, but don't attack oPrevious
ClearAllActions();
DetermineCombatRound();
// Action attack, normally means melee attack. If we can, we
// attack our previous target if seen, ELSE we will re-initate
// combat.
AISpeakString(AI_SHOUT_I_WAS_ATTACKED);
// Fire the On blocked event as normal
FireBlockedEvent();
return;
}
}
}
// Placeable - Currently not returned, however, added just in case!
else if(nBlockerType == OBJECT_TYPE_PLACEABLE)
{
// Check for plot, and therefore attack it to bring it down.
// - Remember, ActionAttack will re-initiate when combat round fires
// again in 3 or 6 seconds (or less, if we just were moving)
if(!GetPlotFlag(oBlocker) &&
GetIsPlaceableObjectActionPossible(oBlocker, PLACEABLE_ACTION_BASH))
{
// Do placeable action
DoPlaceableObjectAction(oBlocker, PLACEABLE_ACTION_BASH);
FireBlockedEvent();
return;
}
return;
}
// Door behaviour
else if(nBlockerType == OBJECT_TYPE_DOOR)
{
int nDoorIntelligence = GetAIInteger(AI_DOOR_INTELLIGENCE);
int nInt = GetAbilityScore(OBJECT_SELF, ABILITY_INTELLIGENCE);
if(nDoorIntelligence == 1)// 1 = Always bashes the doors, plot, locked or anything.
{
DoDoorAction(oBlocker, DOOR_ACTION_BASH);
// We re-initiate combat.
FireBlockedEvent();
return;
}
else if(nDoorIntelligence == 2)// 2 = Never open anything, bashing or not.
{
FireBlockedEvent();
return;
}
else if(nDoorIntelligence == 3)// 3 = Never tries anything against plot doors.
{
if(GetPlotFlag(oBlocker))
{
FireBlockedEvent();
return;
}
}
if(nInt >= 5)
{
// Need some intelligence :-)
if(nInt >= 7)
{
// Right, first, we may...shock...open it!!!
// Checks Key, lock, trap and if the action is possible.
if(GetIsDoorActionPossible(oBlocker, DOOR_ACTION_OPEN) &&
!GetLocked(oBlocker) &&
!GetIsTrapped(oBlocker) &&
(!GetLockKeyRequired(oBlocker) ||
(GetLockKeyRequired(oBlocker) && GetItemPossessor(GetObjectByTag(GetLockKeyTag(oBlocker))) == OBJECT_SELF)))
{
DoDoorAction(oBlocker, DOOR_ACTION_OPEN);
FireBlockedEvent();
return;
}
// Unlock it with the skill, if it is not trapped and we can :-P
// We take 20 off the door DC, thats our minimum roll, after all.
if(GetLocked(oBlocker) &&
!GetSpawnInCondition(AI_FLAG_OTHER_COMBAT_NO_OPENING_LOCKED_DOORS, AI_OTHER_COMBAT_MASTER) &&
!GetLockKeyRequired(oBlocker) && GetHasSkill(SKILL_OPEN_LOCK) &&
GetIsDoorActionPossible(oBlocker, DOOR_ACTION_UNLOCK) && !GetIsTrapped(oBlocker) &&
(GetSkillRank(SKILL_OPEN_LOCK) >= (GetLockLockDC(oBlocker) - 20)))
{
DoDoorAction(oBlocker, DOOR_ACTION_UNLOCK);
FireBlockedEvent();
return;
}
// Specilist thing - knock
if(nInt >= 10)
{
if((GetIsDoorActionPossible(oBlocker, DOOR_ACTION_KNOCK)) &&
GetLockUnlockDC(oBlocker) <= 25 &&
!GetLockKeyRequired(oBlocker) && GetHasSpell(SPELL_KNOCK))
{
DoDoorAction(oBlocker, DOOR_ACTION_KNOCK);
FireBlockedEvent();
return;
}
}
}
// If Our Int is over 5, we will bash after everything else.
if(GetIsDoorActionPossible(oBlocker, DOOR_ACTION_BASH) && !GetPlotFlag(oBlocker))
{
if(GetAttackTarget() != oBlocker)
{
DoDoorAction(oBlocker, DOOR_ACTION_BASH);
}
FireBlockedEvent();
return;
}
}
}
// Fire Blocked event
FireBlockedEvent();
}
// Fires the end-blocked event.
void FireBlockedEvent()
{
// Fire End-blocked-UDE
FireUserEvent(AI_FLAG_UDE_ON_BLOCKED_EVENT, EVENT_ON_BLOCKED_EVENT);
}
// Range attack oTarget.
int RangedAttack(object oTarget)
{
// If we are primarily melee, don't use this
if(!GetSpawnInCondition(AI_FLAG_COMBAT_BETTER_AT_HAND_TO_HAND, AI_COMBAT_MASTER)) return FALSE;
object oRangedTarget = oTarget;
if(!GetIsObjectValid(oRangedTarget))
{
oRangedTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_SEEN, CREATURE_TYPE_IS_ALIVE, TRUE);
if(!GetIsObjectValid(oTarget))
{
oTarget = GetNearestCreature(CREATURE_TYPE_REPUTATION, REPUTATION_TYPE_ENEMY, OBJECT_SELF, 1, CREATURE_TYPE_PERCEPTION, PERCEPTION_HEARD, CREATURE_TYPE_IS_ALIVE, TRUE);
// heard must be in LOS to attack, as we are probably stuck
if(!GetIsObjectValid(oTarget) && LineOfSightObject(OBJECT_SELF, oRangedTarget))
{
return FALSE;
}
}
}
// Ranged weapon attack against oTarget
// doesn't matter we can see them
object oRanged = GetAIObject(AI_WEAPON_RANGED);
int nAmmo = GetAIInteger(AI_WEAPON_RANGED_AMMOSLOT);
// Check ammo and validness
if(GetIsObjectValid(oRanged) && (nAmmo == INVENTORY_SLOT_RIGHTHAND ||
GetIsObjectValid(GetItemInSlot(nAmmo))))
{
// Attack with it
ClearAllActions();
ActionEquipItem(oRanged, INVENTORY_SLOT_RIGHTHAND);
ActionAttack(oRangedTarget);
// Stop
return TRUE;
}
return FALSE;
}

View File

@@ -1,15 +0,0 @@
// Dimension Doors spawn in
// This is the DimDoors varient. It requires "nw_c2_dimdoor" in the UDE
// Flags combat round event, and then fires the default spawn in script.
#include "J_INC_CONSTANTS"
void main()
{
// Spawn in condition
SetSpawnInCondition(AI_FLAG_UDE_END_COMBAT_ROUND_EVENT, AI_UDE_MASTER);
// Execute the default On Spawn file.
ExecuteScript("nw_c2_default9", OBJECT_SELF);
}

Some files were not shown because too many files have changed in this diff Show More