Added Mob::DoCastingChecks() which checks for various casting fail conditions while casting

This commit is contained in:
Michael Cook 2013-11-17 00:31:17 -05:00
parent 3c2ae8250f
commit 3d5b3d1e8c
3 changed files with 62 additions and 1 deletions

View File

@ -2,6 +2,7 @@ EQEMu Changelog (Started on Sept 24, 2003 15:50)
-------------------------------------------------------
== 11/16/2013 ==
Leere: Fixed the drinking message for auto-consume, it will again correctly show up for forced consumption instead.
demonstar55: Added Mob::DoCastingChecks() which will check for various fail conditions while the casting bar is up. This is called after Mob::DoCastSpell() starts the casting and before it returns.
== 11/15/2013 ==
demonstar55: Fixed Mob::CalcFocusEffect()'s SE_LimitEffect

View File

@ -198,6 +198,7 @@ public:
void InterruptSpell(uint16, uint16, uint16 spellid = SPELL_UNKNOWN);
inline bool IsCasting() const { return((casting_spell_id != 0)); }
uint16 CastingSpellID() const { return casting_spell_id; }
bool DoCastingChecks();
//Buff
void BuffProcess();
@ -998,6 +999,7 @@ protected:
uint32 casting_spell_timer_duration;
uint32 casting_spell_type;
int16 casting_spell_resist_adjust;
bool casting_spell_checks;
uint16 bardsong;
uint8 bardsong_slot;
uint32 bardsong_target_id;

View File

@ -115,7 +115,7 @@ void Mob::SpellProcess()
}
// a timed spell is finished casting
if (casting_spell_id != 0 && spellend_timer.Check())
if (casting_spell_id != 0 && casting_spell_checks && spellend_timer.Check())
{
spellend_timer.Disable();
delaytimer = false;
@ -474,9 +474,66 @@ bool Mob::DoCastSpell(uint16 spell_id, uint16 target_id, uint16 slot,
entity_list.QueueCloseClients(this, outapp, false, 200, 0, true); //IsClient() ? FILTER_PCSPELLS : FILTER_NPCSPELLS);
safe_delete(outapp);
outapp = nullptr;
if (!DoCastingChecks()) {
InterruptSpell();
return false;
}
return(true);
}
/*
* Some failures should be caught before the spell finishes casting
* This is especially helpful to clients when they cast really long things
* If this passes it sets casting_spell_checks to true which is checked in
* SpellProcess(), if a situation ever arises where a spell is delayed by these
* it's probably doing something wrong.
*/
bool Mob::DoCastingChecks()
{
if (!IsClient() || (IsClient() && CastToClient()->GetGM())) {
casting_spell_checks = true;
return true;
}
uint16 spell_id = casting_spell_id;
Mob *spell_target = entity_list.GetMob(casting_spell_targetid);
if (RuleB(Spells, BuffLevelRestrictions) &&
!spell_target->CheckSpellLevelRestriction(spell_id)) {
mlog(SPELLS__BUFFS, "Spell %d failed: recipient did not meet the level restrictions", spell_id);
if (!IsBardSong(spell_id))
Message_StringID(MT_SpellFailure, SPELL_TOO_POWERFUL);
return false;
}
if (spells[spell_id].zonetype == 1 && !zone->CanCastOutdoor()) {
Message_StringID(13, CAST_OUTDOORS);
return false;
}
if (IsEffectInSpell(spell_id, SE_Levitate) && !zone->CanLevitate()) {
Message(13, "You can't levitate in this zone.");
return false;
}
if (zone->IsSpellBlocked(spell_id, GetX(), GetY(), GetZ())) {
const char *msg = zone->GetSpellBlockedMessage(spell_id, GetX(), GetY(), GetZ());
if (msg) {
Message(13, msg);
return false;
} else {
Message(13, "You can't cast this spell here.");
return false;
}
}
casting_spell_checks = true;
return true;
}
uint16 Mob::GetSpecializeSkillValue(uint16 spell_id) const {
switch(spells[spell_id].skill) {
case SkillAbjuration:
@ -687,6 +744,7 @@ void Mob::ZeroCastingVars()
casting_spell_timer_duration = 0;
casting_spell_type = 0;
casting_spell_resist_adjust = 0;
casting_spell_checks = false;
delaytimer = false;
}