PDA

View Full Version : [wip] NPC spellcasting


zeiksz2
01-19-2008, 02:43 AM
having human warrior as first char from 1999 made me dislike to fight NPCs that can cast spells.. heals.. blinds.. slows.. so the cleric / shaman mobs. sure you can shield bash, if you do not miss, if you manage to bash them actually with stunning effect.
after stopping to play the "blind fool" i started elf cleric to see the other sight of this.. well.. i was interrupted by each and every hit of my enemies.. hard to regain concentration and such, but no warhamer was good enough to interrupt an enemy casting but the high mana cost stun spells (etc).

nahh well.. after "ballancing" the NPC melee for my own "fair-play"-taste i thought i take my revenge on those duhhh casters. so first thing i thought why not make them be so less good caster and have same chance on losing concentration

instead of having bad dreams of old-time-rememberings of some sabbertooth soothslayer lets modify the spells.cpp a bit



//if(IsClient())
//{
// // max 93% chance at 252 skill

//we give same chances to PC and NPC
//first we get base amount after channeling skill
if (IsClient())
{
channelchance = 30 + GetSkill(CHANNELING) / 400.0f * 100;
}
else
{
channelchance = 30 + (GetLevel() * 5) / 400.0f * 100;
}
//then we take some chance for each (max 15) slaps taken
channelchance -= attacked_count * 2;
//then we give some chance after AA skill
float mult;
if (IsClient())
{
mult = (GetAA(aaChanellingFocus)*5) / 100;
}
else
{
//NPC has no AA, so we "make" it after level to have almost the same chances
int szimulaa = 0;
if (GetLevel() > 59) { szimulaa++; }
if (GetLevel() > 55) { szimulaa++; }
if (GetLevel() > 51) { szimulaa++; }
}
channelchance += channelchance * mult;
//would be good to know what level attackers are, so we could make sure that lesser
//levels interrupt us with less chances, but this is alright so far

//} else {
// // NPCs are just hard to interrupt, otherwise they get pwned
// channelchance = 85;
// channelchance -= attacked_count;
//}



check the commented out source (should be commented out) in mob::casterspellfinished(...

the code is not pretty at all, but wanted to rip it this apart so the comments are ok and good looking.

next thing for me is to go for mobs' fizzling (all i got so far is a fizzle and they never ever casted spells, so i guess there is more in it.. some timer or such - no idea yet.. any suggestions please?)

zeiksz2
01-19-2008, 11:48 AM
well to make mobs fizzle you are to insert some code - since there is no way a mob to fizzle normally there is nothing in yet

into mob::CheckFizzle


//after player code we should have always 5% to fizzle
//rest is kinda unimportant here, since mobs have always max skill points
if (MakeRandomInt(1,100) <= 5) return false;
return true;



you can play with lowering the success rate by checking the spell level too (saying that you fizzle more on lower levels).

this is not enough you are to insert a line too into mob::CastSpell


// check for fizzle
// note that CheckFizzle itself doesn't let NPCs fizzle,
// but this code allows for it.
if(slot < MAX_PP_MEMSPELL && !CheckFizzle(spell_id))
{
int fizzle_msg = IsBardSong(spell_id) ? MISS_NOTE : SPELL_FIZZLE;
InterruptSpell(fizzle_msg, 0x121, spell_id);

uint32 use_mana = mana_cost / 4;
mlog(SPELLS__CASTING_ERR, "Spell casting canceled: fizzled. %d mana has been consumed", use_mana);

// fizzle 1/4 the mana away
SetMana(GetMana() - use_mana);

******** extra start

//if NPC fizzles...
if (IsNPC()) CastToNPC()->AI_Event_SpellCastFinished(false, slot);

******** extra end

return(false);
}



inserted all of that block here so you can find it easier

zeiksz2
01-19-2008, 12:06 PM
quickfix for post #1

instead of "float mult;" write "float mult = 0;"