Skip to content

Commit

Permalink
Server-side "prohibit spell school" implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
Olion17 authored and billy1arm committed Aug 21, 2017
1 parent b233e4d commit 37ae1f2
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 1 deletion.
4 changes: 4 additions & 0 deletions src/game/Object/CreatureAI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ CanCastResult CreatureAI::CanCastSpell(Unit* pTarget, const SpellEntry* pSpell,
// Check for power (also done by Spell::CheckCast())
if (m_creature->GetPower((Powers)pSpell->powerType) < Spell::CalculatePowerCost(pSpell, m_creature))
{ return CAST_FAIL_POWER; }

// Spell school check; for the mobs, only non-triggered spells are affected
if (pSpell->SchoolMask && !m_creature->IsSchoolAllowed(SpellSchoolMask(pSpell->SchoolMask)))
return CAST_FAIL_STATE;
}

if (!m_creature->IsWithinLOSInMap(pTarget))
Expand Down
1 change: 1 addition & 0 deletions src/game/Object/Player.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17954,6 +17954,7 @@ void Player::ContinueTaxiFlight()

void Player::ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs)
{
Unit::ProhibitSpellSchool(idSchoolMask, unTimeMs);
// last check 2.0.10
WorldPacket data(SMSG_SPELL_COOLDOWN, 8 + 1 + m_spells.size() * 8);
data << GetObjectGuid();
Expand Down
29 changes: 29 additions & 0 deletions src/game/Object/Unit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -275,6 +275,11 @@ Unit::Unit() :

m_isCreatureLinkingTrigger = false;
m_isSpawningLinked = false;

// disabled spell school
uint32 rightnow = WorldTimer::getMSTime() - 1;
for (int i = 0; i < MAX_SPELL_SCHOOL; ++i)
m_schoolAllowedSince[i] = rightnow;
}

Unit::~Unit()
Expand Down Expand Up @@ -9960,3 +9965,27 @@ void Unit::DisableSpline()
m_movementInfo.RemoveMovementFlag(MovementFlags(MOVEFLAG_SPLINE_ENABLED | MOVEFLAG_FORWARD));
movespline->_Interrupt();
}

bool Unit::IsSchoolAllowed(SpellSchoolMask mask) const
{
uint32 now = WorldTimer::getMSTime();
uint32 imask = mask;
while (int i = ffs(imask))
{
if (m_schoolAllowedSince[i - 1] > now)
return false;
imask &= ~(1 << (i - 1));
}
return true;
}

void Unit::ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs)
{
uint32 when = WorldTimer::getMSTime() + unTimeMs;
uint32 imask = idSchoolMask;
while (int i = ffs(imask))
{
m_schoolAllowedSince[i - 1] = when;
imask &= ~(1 << (i - 1));
}
}
4 changes: 3 additions & 1 deletion src/game/Object/Unit.h
Original file line number Diff line number Diff line change
Expand Up @@ -3462,7 +3462,8 @@ class Unit : public WorldObject
float GetCreateStat(Stats stat) const { return m_createStats[stat]; }

void SetCurrentCastedSpell(Spell* pSpell);
virtual void ProhibitSpellSchool(SpellSchoolMask /*idSchoolMask*/, uint32 /*unTimeMs*/) { }
bool IsSchoolAllowed(SpellSchoolMask mask) const;
virtual void ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs);
void InterruptSpell(CurrentSpellTypes spellType, bool withDelayed = true);
void FinishSpell(CurrentSpellTypes spellType, bool ok = true);

Expand Down Expand Up @@ -3820,6 +3821,7 @@ class Unit : public WorldObject

MotionMaster i_motionMaster;

uint32 m_schoolAllowedSince[MAX_SPELL_SCHOOL];
uint32 m_reactiveTimer[MAX_REACTIVE];
uint32 m_regenTimer;
uint32 m_lastManaUseTimer;
Expand Down
3 changes: 3 additions & 0 deletions src/game/WorldHandlers/Spell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4201,6 +4201,9 @@ SpellCastResult Spell::CheckCast(bool strict)
// check global cooldown
if (strict && !m_IsTriggeredSpell && HasGlobalCooldown())
{ return SPELL_FAILED_NOT_READY; }
// check disabled spell school; TODO how to handle triggered spells?
if (strict && GetSpellSchoolMask(m_spellInfo) && !m_caster->IsSchoolAllowed(GetSpellSchoolMask(m_spellInfo)))
return SPELL_FAILED_SILENCED;

// only allow triggered spells if at an ended battleground
if (!m_IsTriggeredSpell && m_caster->GetTypeId() == TYPEID_PLAYER)
Expand Down

0 comments on commit 37ae1f2

Please sign in to comment.