LMAO! SWEET! You keep saving me from work and trying to learn to program by examples from the source (which is no easy task).
So far, this is what I came up with, but it is missing the most important part (Changes are in
RED):
MobAI.cpp
Code:
const int MobAISpellRange=100; // max range of buffs
const int SpellType_Nuke=1;
const int SpellType_Heal=2;
const int SpellType_Root=4;
const int SpellType_Buff=8;
const int SpellType_Escape=16;
const int SpellType_Pet=32;
const int SpellType_Lifetap=64;
const int SpellType_Snare=128;
const int SpellType_DOT=256;
const int SpellType_Dispel=512;
const int SpellType_Disc=1024;
const int SpellType_ComBuff=2048;
const int SpellTypes_Detrimental = SpellType_Nuke|SpellType_Root|SpellType_Lifetap|SpellType_Snare|SpellType_DOT|SpellType_Dispel|SpellType_Disc|SpellType_ComBuff;
const int SpellTypes_Beneficial = SpellType_Heal|SpellType_Buff|SpellType_Escape|SpellType_Pet;
This part is the main section and this is where the actual adjustments need to be made to tell the spells when to be used. This is not complete code in this section:
Code:
case SpellType_Disc: {
if (
(spells[AIspells[i].spellid].targettype == ST_Target || tar == this)
&& tar->DontBuffMeBefore() < Timer::GetCurrentTime()
&& !tar->IsImmuneToSpell(AIspells[i].spellid, this)
&& tar->CanBuffStack(AIspells[i].spellid, GetLevel(), true) >= 0
&& !(tar->IsPet() && tar->GetOwner()->IsClient() && this != tar) //no buffing PC's pets, but they can buff themself
) {
AIDoSpellCast(i, tar, mana_cost, &tar->pDontBuffMeBefore);
return true;
}
break;
}
case SpellType_ComBuff: {
if (
(spells[AIspells[i].spellid].targettype == ST_Target || tar == this)
&& tar->DontBuffMeBefore() < Timer::GetCurrentTime()
&& !tar->IsImmuneToSpell(AIspells[i].spellid, this)
&& tar->CanBuffStack(AIspells[i].spellid, GetLevel(), true) >= 0
&& !(tar->IsPet() && tar->GetOwner()->IsClient() && this != tar) //no buffing PC's pets, but they can buff themself
) {
AIDoSpellCast(i, tar, mana_cost, &tar->pDontBuffMeBefore);
return true;
}
break;
}
Code:
if( AIspells[i].type == SpellType_Nuke
|| AIspells[i].type == SpellType_Root
|| AIspells[i].type == SpellType_Lifetap
|| AIspells[i].type == SpellType_Snare
|| AIspells[i].type == SpellType_DOT
|| AIspells[i].type == SpellType_Dispel
|| AIspells[i].type == SpellType_Disc
|| AIspells[i].type == SpellType_ComBuff
Code:
bool NPC::AI_EngagedCastCheck() {
if (AIautocastspell_timer->Check(false)) {
_ZP(Mob_AI_Process_engaged_cast);
AIautocastspell_timer->Disable(); //prevent the timer from going off AGAIN while we are casting.
mlog(AI__SPELLS, "Engaged autocast check triggered. Trying to cast healing spells then maybe offensive spells.");
// try casting a heal or gate
if (!AICastSpell(this, 100, SpellType_Heal | SpellType_Escape)) {
// try casting a heal on nearby
if (!entity_list.AICheckCloseBeneficialSpells(this, 25, MobAISpellRange, SpellType_Heal)) {
//nobody to heal, try some detrimental spells.
if(!AICastSpell(target, 20, SpellType_Nuke | SpellType_Lifetap | SpellType_DOT | SpellType_Dispel | SpellType_Disc | SpellType_ComBuff)) {
//no spell to cast, try again soon.
AIautocastspell_timer->Start(RandomTimer(500, 1000), false);
}
} //else, spell casting finishing will reset the timer.
}
return(true);
}
return(false);
}
bool NPC::AI_PursueCastCheck() {
if (AIautocastspell_timer->Check(false)) {
_ZP(Mob_AI_Process_pursue_cast);
AIautocastspell_timer->Disable(); //prevent the timer from going off AGAIN while we are casting.
mlog(AI__SPELLS, "Engaged (pursuing) autocast check triggered. Trying to cast offensive spells.");
if(!AICastSpell(target, 90, SpellType_Root | SpellType_Nuke | SpellType_Lifetap | SpellType_Snare | SpellType_DOT | SpellType_Dispel | SpellType_Disc | SpellType_ComBuff)) {
//no spell cast, try again soon.
AIautocastspell_timer->Start(RandomTimer(500, 2000), false);
} //else, spell casting finishing will reset the timer.
return(true);
}
return(false);
}
I imagine that combat buffs wouldn't be very hard to add. They would work like normal buffs, but only be cast during combat (mostly for Yaulp-Like spells with short duration and maybe some damage shields). The trickier one might be Disciplines, but I doubt it would be hard for KLS to do. Basically, Disciplines would need to cast the first disc and then not cast the second one until the buff duration was finished on the previous one. Or, they could all be treated like the same buff so that it won't cast another (cause it thinks of it as the same spell) until the buff timer fades. The only requirement for disciplines is that only one can be up at a time.
LOL, I am still laughing at KLS! I am just so glad to hear that I don't have to figure this out myself lol. Not that it would be a ton of work to do, cause I imagine it could be done pretty quick for someone with programming skill. But, mostly cause I am working on a new zone that will be more dynamic than any I have done so far and having more options for spells lists (especially disciplines) will really add a cool dynamic to the zone. My spell lists are done, but with them stacking discs, it makes them impossible to tune the encounters.