Well, I am still trying to figure out why this is happening on my server. I was looking at my variables table and I have a setting for "ailevel", and it is set to 6 (which is how it came from the PEQ db), but I don't really know what that does. So far, it is the only thing I can think of that might be causing this issue. I am running the latest version of the emu (111

with some modified code additions, but nothing that I think would relate to this issue at all.
I was looking at the source and in npc.h, I see a public section that mentions ailevel, and has some recast delay info in there. So, I am wondering if maybe my ailevel is set wrong, and maybe setting it to 6 isn't enough for it to use recast delays...
Here is the code from the public section of npc.h that I am referring to (I highlighted a few things in
RED cause I think they are involved in making the decision for recast delay settings):
Code:
class NPC : public Mob
{
public:
static NPC* SpawnNPC(const char* spawncommand, float in_x, float in_y, float in_z, float in_heading = 0, Client* client = 0);
static sint8 GetAILevel(bool iForceReRead = false);
NPC(const NPCType* data, Spawn2* respawn, float x, float y, float z, float heading, bool IsCorpse = false);
virtual ~NPC();
virtual bool IsNPC() const { return true; }
virtual bool Process();
virtual void AI_Init();
virtual void AI_Start(int32 iMoveDelay = 0);
virtual void AI_Stop();
void AI_DoMovement();
bool AI_AddNPCSpells(int32 iDBSpellsID);
virtual bool AI_EngagedCastCheck();
virtual bool AI_PursueCastCheck();
virtual bool AI_IdleCastCheck();
virtual void AI_Event_SpellCastFinished(bool iCastSucceeded, int8 slot);
virtual void SetTarget(Mob* mob);
virtual uint16 GetSkill(SkillType skill_num) const { if (skill_num <= HIGHEST_SKILL) { return skills[skill_num]; } return 0; }
/* virtual void SetSkill(int in_skill_num, int8 in_skill_value) { // socket 12-29-01
if (in_skill_num <= HIGHEST_SKILL) { skills[in_skill_num + 1] = in_skill_value; } }*/
void CalcItemBonuses(StatBonuses *newbon);
virtual void CalcBonuses();
#ifdef GUILDWARS
int32 GetGuildLocationID() { return guildlocationid; }
#endif
// neotokyo: added frenzy
bool Attack(Mob* other, int Hand = 13, bool = false);
void Damage(Mob* other, sint32 damage, int16 spell_id, SkillType attack_skill, bool avoidable = true, sint8 buffslot = -1, bool iBuffTic = false);
void Death(Mob* other, sint32 damage, int16 spell_id, SkillType attack_skill);
bool DatabaseCastAccepted(int spell_id);
bool IsFactionListAlly(uint32 other_faction);
FACTION_VALUE CheckNPCFactionAlly(sint32 other_faction);
FACTION_VALUE GetReverseFactionCon(Mob* iOther);
void GoToBind() { GMMove(org_x, org_y, org_z, org_heading); }
void Gate();
void GetPetState(SpellBuff_Struct *buffs, int32 *items, char *name);
void SetPetState(SpellBuff_Struct *buffs, int32 *items);
void InteractiveChat(int8 chan_num, int8 language, const char * message, const char* targetname,Mob* sender);
void TakenAction(int8 action,Mob* actiontaker);
virtual void SpellProcess();
virtual void FillSpawnStruct(NewSpawn_Struct* ns, Mob* ForWho);
void AddItem(const Item_Struct* item, int8 charges, int8 slot = 0);
void AddItem(int32 itemid, int8 charges, int8 slot = 0);
void AddLootTable();
/*
void NPCSpecialAttacks(const char* parse, int permtag);
void NPCDatabaseSpells(const char* parse);
void NPCUnharmSpell(int spell_id);
void CheckFriendlySpellStatus();
void CheckEnemySpellStatus();
void NPCHarmSpell(int target,int type);
void HateSummon();
*/
void DescribeAggro(Client *towho, Mob *mob, bool verbose);
void RemoveItem(uint16 item_id, int16 quantity = 0, int16 slot = 0);
// bool AddNPCSpells(int32 iDBSpellsID, AISpells_Struct* AIspells);
// void RemoveItem(uint16 item_id);
void ClearItemList();
ServerLootItem_Struct* GetItem(int slot_id);
void AddCash(int16 in_copper, int16 in_silver, int16 in_gold, int16 in_platinum);
void AddCash();
void RemoveCash();
void QueryLoot(Client* to);
int32 CountLoot();
void DumpLoot(int32 npcdump_index, ZSDump_NPC_Loot* npclootdump, int32* NPCLootindex);
inline int32 GetLoottableID() const { return loottable_id; }
// void SetPetType(int16 in_type) { typeofpet = in_type; } // put this here because only NPCs can be anything but charmed pets
inline uint32 GetCopper() const { return copper; }
inline uint32 GetSilver() const { return silver; }
inline uint32 GetGold() const { return gold; }
inline uint32 GetPlatinum() const { return platinum; }
inline void SetCopper(uint32 amt) { copper = amt; }
inline void SetSilver(uint32 amt) { silver = amt; }
inline void SetGold(uint32 amt) { gold = amt; }
inline void SetPlatinum(uint32 amt) { platinum = amt; }
void SetGrid(int32 grid_){ grid=grid_; }
void SetSp2(int32 sg2){ spawn_group=sg2; }
void SetWaypointMax(int16 wp_){ wp_m=wp_; }
int16 GetWaypointMax() const { return wp_m; }
int32 GetGrid() const { return grid; }
int32 GetSp2() const { return spawn_group; }
uint32 MerchantType;
void Depop(bool StartSpawnTimer = true);
void Stun(int duration);
void UnStun();
inline void SignalNPC(int _signal_id) { signaled = true; signal_id = _signal_id; }
inline sint32 GetNPCFactionID() const { return npc_faction_id; }
inline sint32 GetPrimaryFaction() const { return primary_faction; }
sint32 GetNPCHate(Mob* in_ent) {return hate_list.GetEntHate(in_ent);}
bool IsOnHatelist(Mob*p) { return hate_list.IsOnHateList(p);}
void SetNPCFactionID(sint32 in) { npc_faction_id = in; database.GetFactionIdsForNPC(npc_faction_id, &faction_list, &primary_faction); }
float org_x, org_y, org_z, org_heading;
int16 GetMaxDMG() const {return max_dmg;}
bool IsAnimal() const { return(bodytype == BT_Animal); }
int16 GetPetSpellID() const {return pet_spell_id;}
void SetPetSpellID(int16 amt) {pet_spell_id = amt;}
int32 GetMaxDamage(int8 tlevel);
void SetTaunting(bool tog) {taunting = tog;}
void PickPocket(Client* thief);
void StartSwarmTimer(int32 duration) { swarm_timer.Start(duration); }
void AddLootDrop(const Item_Struct*dbitem, ItemList* itemlistconst, sint8 charges, bool equipit, bool wearchange = false);
void DoClassAttacks(Mob *target);
void CheckSignal();
//waypoint crap
int GetMaxWp() const { return max_wp; }
void DisplayWaypointInfo(Client *to);
void CalculateNewWaypoint();
// int8 CalculateHeadingToNextWaypoint();
// float CalculateDistanceToNextWaypoint();
void AssignWaypoints(int32 grid);
void SetWaypointPause();
void UpdateWaypoint(int wp_index);
// quest wandering commands
void StopWandering();
void ResumeWandering();
void PauseWandering(int pausetime);
void MoveTo(float mtx, float mty, float mtz);
int32 GetEquipment(int8 material_slot) const; // returns item id
sint32 GetEquipmentMaterial(int8 material_slot) const;
void NextGuardPosition();
void SaveGuardSpot(bool iClearGuardSpot = false);
inline bool IsGuarding() const { return(guard_heading != 0); }
/* void SaveSpawnSpot();
inline const float GetSpawnX() const { return spawn_x; }
inline const float GetSpawnY() const { return spawn_y; }
inline const float GetSpawnZ() const { return spawn_z; }
inline const float GetSpawnHeading() const { return spawn_heading; }
*/
void AI_SetRoambox(float iDist, float iRoamDist, int32 iDelay = 2500);
void AI_SetRoambox(float iDist, float iMaxX, float iMinX, float iMaxY, float iMinY, int32 iDelay = 2500);
inline bool WillAggroNPCs() const { return(npc_aggro); }
inline void GiveNPCTypeData(NPCType *ours) { NPCTypedata_ours = ours; }
inline const int32 GetNPCSpellsID() const { return npc_spells_id; }
ItemList itemlist; //kathgar - why is this public? Doing other things or I would check the code
NPCProximity* proximity;
Spawn2* respawn2;
AA_SwarmPetInfo *GetSwarmInfo() { return (swarmInfoPtr); }
void SetSwarmInfo(AA_SwarmPetInfo *mSwarmInfo) { swarmInfoPtr = mSwarmInfo; }
sint32 GetAccuracyRating() { return (accuracy_rating); }
void SetAccuracyRating(sint32 d) { accuracy_rating = d;}
protected:
const NPCType* NPCTypedata;
NPCType* NPCTypedata_ours; //special case for npcs with uniquely created data.
friend class EntityList;
list<struct NPCFaction*> faction_list;
uint32 copper;
uint32 silver;
uint32 gold;
uint32 platinum;
int32 grid;
int32 spawn_group;
int16 wp_m;
sint32 npc_faction_id;
sint32 primary_faction;
Timer attacked_timer; //running while we are being attacked (damaged)
Timer combat_event_timer; //running while we are engaged in offensive or defensive combat activities
Timer swarm_timer;
Timer classattack_timer;
Timer knightattack_timer;
Timer assist_timer; //ask for help from nearby mobs
Timer global_position_update_timer;
bool attack_event; //true if we have fired an EVENT_ATTACK and our attacked timer has not gone off
bool combat_event; //true if we have fired an EVENT_COMBAT and our combat activity timer has not gone off
// int8 position; // 0 - Standing, 1 - Sitting, 2 - Crouching, 4 - Looting
Timer sendhpupdate_timer;
Timer enraged_timer;
int32 npc_spells_id;
struct AISpells_Struct {
int16 type; // 0 = never, must be one (and only one) of the defined values
uint16 spellid; // <= 0 = no spell
sint16 manacost; // -1 = use spdat, -2 = no cast time
int32 time_cancast; // when we can cast this spell next
sint32 recast_delay;
sint16 priority;
};
int8 casting_spell_AIindex;
Timer* AIautocastspell_timer;
int32* pDontCastBefore_casting_spell;
AISpells_Struct AIspells[MAX_AISPELLS]; // expected to be pre-sorted, best at low index
void AddSpellToNPCList(AISpells_Struct* AIspells, sint16 iPriority, sint16 iSpellID, uint16 iType, sint16 iManaCost, sint32 iRecastDelay);
bool AICastSpell(Mob* tar, int8 iChance, int16 iSpellTypes);
void AIDoSpellCast(int8 i, Mob* tar, sint32 mana_cost, int32* oDontDoAgainBefore = 0);
int16 max_dmg;
int16 min_dmg;
sint32 accuracy_rating;
//pet crap:
int16 pet_spell_id;
bool taunting;
Timer taunt_timer; //for pet taunting
bool npc_aggro;
int signal_id;
bool signaled; // used by quest signal() command
//waypoint crap:
//MyList <wplist> Waypoints;
vector<wplist> Waypoints;
void _ClearWaypints();
int max_wp;
int save_wp;
float guard_x, guard_y, guard_z, guard_heading;
// float spawn_x, spawn_y, spawn_z, spawn_heading;
float roambox_max_x;
float roambox_max_y;
float roambox_min_x;
float roambox_min_y;
float roambox_distance;
float roambox_movingto_x;
float roambox_movingto_y;
int32 roambox_delay;
int16 skills[HIGHEST_SKILL+1];
int32 equipment[MAX_MATERIALS]; //this is an array of item IDs
int16 d_meele_texture1; //this is an item Material value
int16 d_meele_texture2; //this is an item Material value (offhand)
AA_SwarmPetInfo *swarmInfoPtr;
This issue is hanging me up from adding disciplines to NPCs to make some interesting encounters. I know I could probably do most of it via quests if I wanted, but these are mainly for my trash mobs. I am trying to make trash mob fights a little more dynamic.