aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/world/2012_09_07_00_world_spell_bonus_data.sql4
-rwxr-xr-xsrc/server/game/AI/CoreAI/CombatAI.cpp5
-rwxr-xr-xsrc/server/game/AI/CoreAI/CombatAI.h1
-rwxr-xr-xsrc/server/game/AI/CoreAI/UnitAI.h4
-rwxr-xr-xsrc/server/game/AI/EventAI/CreatureEventAI.cpp4
-rw-r--r--src/server/game/AI/SmartScripts/SmartAI.cpp2
-rwxr-xr-xsrc/server/game/Entities/Creature/Creature.cpp32
-rwxr-xr-xsrc/server/game/Entities/Creature/Creature.h7
-rwxr-xr-xsrc/server/game/Entities/Pet/Pet.cpp37
-rwxr-xr-xsrc/server/game/Entities/Pet/Pet.h1
-rwxr-xr-xsrc/server/game/Entities/Player/Player.cpp6
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.cpp53
-rwxr-xr-xsrc/server/game/Entities/Unit/Unit.h11
-rw-r--r--src/server/game/Movement/Spline/MoveSplineInit.cpp4
-rwxr-xr-xsrc/server/game/Spells/Spell.cpp4
-rwxr-xr-xsrc/server/game/Spells/SpellEffects.cpp16
-rw-r--r--src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp6
-rw-r--r--src/server/scripts/Spells/spell_generic.cpp13
-rw-r--r--src/server/scripts/Spells/spell_item.cpp11
19 files changed, 175 insertions, 46 deletions
diff --git a/sql/updates/world/2012_09_07_00_world_spell_bonus_data.sql b/sql/updates/world/2012_09_07_00_world_spell_bonus_data.sql
new file mode 100644
index 00000000000..3d39c06051a
--- /dev/null
+++ b/sql/updates/world/2012_09_07_00_world_spell_bonus_data.sql
@@ -0,0 +1,4 @@
+SET @Spell := 28715; -- Flamecap Fire
+DELETE FROM `spell_bonus_data` WHERE `entry`=@Spell;
+INSERT INTO `spell_bonus_data` (`entry`,`direct_bonus`,`dot_bonus`,`ap_bonus`,`ap_dot_bonus`,`comments`) VALUES
+(@Spell,0,0,0,0, 'Flamecap Fire');
diff --git a/src/server/game/AI/CoreAI/CombatAI.cpp b/src/server/game/AI/CoreAI/CombatAI.cpp
index 7d7a27fce13..946fe664798 100755
--- a/src/server/game/AI/CoreAI/CombatAI.cpp
+++ b/src/server/game/AI/CoreAI/CombatAI.cpp
@@ -111,6 +111,11 @@ void CombatAI::UpdateAI(const uint32 diff)
DoMeleeAttackIfReady();
}
+void CombatAI::SpellInterrupted(uint32 spellId, uint32 unTimeMs)
+{
+ events.RescheduleEvent(spellId, unTimeMs);
+}
+
/////////////////
//CasterAI
/////////////////
diff --git a/src/server/game/AI/CoreAI/CombatAI.h b/src/server/game/AI/CoreAI/CombatAI.h
index ad98cec0779..fa31e57d780 100755
--- a/src/server/game/AI/CoreAI/CombatAI.h
+++ b/src/server/game/AI/CoreAI/CombatAI.h
@@ -46,6 +46,7 @@ class CombatAI : public CreatureAI
void EnterCombat(Unit* who);
void JustDied(Unit* killer);
void UpdateAI(const uint32 diff);
+ void SpellInterrupted(uint32 spellId, uint32 unTimeMs);
static int Permissible(const Creature*);
protected:
EventMap events;
diff --git a/src/server/game/AI/CoreAI/UnitAI.h b/src/server/game/AI/CoreAI/UnitAI.h
index 593f0d15e18..e824ac0e76b 100755
--- a/src/server/game/AI/CoreAI/UnitAI.h
+++ b/src/server/game/AI/CoreAI/UnitAI.h
@@ -242,6 +242,10 @@ class UnitAI
// Called when the unit heals
virtual void HealDone(Unit* /*done_to*/, uint32& /*addhealth*/) {}
+ /// Called when a spell is interrupted by Spell::EffectInterruptCast
+ /// Use to reschedule next planned cast of spell.
+ virtual void SpellInterrupted(uint32 /*spellId*/, uint32 /*unTimeMs*/) {}
+
void AttackStartCaster(Unit* victim, float dist);
void DoAddAuraToAllHostilePlayers(uint32 spellid);
diff --git a/src/server/game/AI/EventAI/CreatureEventAI.cpp b/src/server/game/AI/EventAI/CreatureEventAI.cpp
index aa14bc1b56e..951a035628a 100755
--- a/src/server/game/AI/EventAI/CreatureEventAI.cpp
+++ b/src/server/game/AI/EventAI/CreatureEventAI.cpp
@@ -1317,6 +1317,10 @@ bool CreatureEventAI::CanCast(Unit* target, SpellInfo const* spell, bool trigger
if (!me->IsInRange(target, spell->GetMinRange(false), spell->GetMaxRange(false)))
return false;
+ //Spell is on cooldown
+ if (me->HasSpellCooldown(spell->Id))
+ return false;
+
return true;
}
diff --git a/src/server/game/AI/SmartScripts/SmartAI.cpp b/src/server/game/AI/SmartScripts/SmartAI.cpp
index a7660a0a44b..7dd4053b82f 100644
--- a/src/server/game/AI/SmartScripts/SmartAI.cpp
+++ b/src/server/game/AI/SmartScripts/SmartAI.cpp
@@ -634,7 +634,7 @@ void SmartAI::SpellHitTarget(Unit* target, const SpellInfo* spellInfo)
void SmartAI::DamageTaken(Unit* doneBy, uint32& damage)
{
GetScript()->ProcessEventsFor(SMART_EVENT_DAMAGED, doneBy, damage);
- if ((damage >= me->GetHealth() - mInvincibilityHpLevel) && (mInvincibilityHpLevel > 0))
+ if (mInvincibilityHpLevel && (damage >= me->GetHealth() - mInvincibilityHpLevel))
{
damage = 0;
me->SetHealth(mInvincibilityHpLevel);
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index afa4b62d8b0..0b9d0b40b4a 100755
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -2231,6 +2231,38 @@ bool Creature::HasSpellCooldown(uint32 spell_id) const
return (itr != m_CreatureSpellCooldowns.end() && itr->second > time(NULL)) || HasCategoryCooldown(spell_id);
}
+void Creature::ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs)
+{
+ time_t curTime = time(NULL);
+ for (uint8 i = 0; i < CREATURE_MAX_SPELLS; ++i)
+ {
+ if (m_spells[i] == 0)
+ continue;
+
+ uint32 unSpellId = m_spells[i];
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(unSpellId);
+ if (!spellInfo)
+ {
+ ASSERT(spellInfo);
+ continue;
+ }
+
+ // Not send cooldown for this spells
+ if (spellInfo->Attributes & SPELL_ATTR0_DISABLED_WHILE_ACTIVE)
+ continue;
+
+ if (spellInfo->PreventionType != SPELL_PREVENTION_TYPE_SILENCE)
+ continue;
+
+ if ((idSchoolMask & spellInfo->GetSchoolMask()) && GetCreatureSpellCooldownDelay(unSpellId) < unTimeMs)
+ {
+ _AddCreatureSpellCooldown(unSpellId, curTime + unTimeMs/IN_MILLISECONDS);
+ if (UnitAI* ai = GetAI())
+ ai->SpellInterrupted(unSpellId, unTimeMs);
+ }
+ }
+}
+
bool Creature::HasSpell(uint32 spellID) const
{
uint8 i;
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index 4dd080f8b15..7359385cd0a 100755
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -540,6 +540,13 @@ class Creature : public Unit, public GridObject<Creature>, public MapCreature
void AddCreatureSpellCooldown(uint32 spellid);
bool HasSpellCooldown(uint32 spell_id) const;
bool HasCategoryCooldown(uint32 spell_id) const;
+ uint32 GetCreatureSpellCooldownDelay(uint32 spellId) const
+ {
+ CreatureSpellCooldowns::const_iterator itr = m_CreatureSpellCooldowns.find(spellId);
+ time_t t = time(NULL);
+ return uint32(itr != m_CreatureSpellCooldowns.end() && itr->second > t ? itr->second - t : 0);
+ }
+ virtual void ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs);
bool HasSpell(uint32 spellID) const;
diff --git a/src/server/game/Entities/Pet/Pet.cpp b/src/server/game/Entities/Pet/Pet.cpp
index 17b214857db..b2cdb56a33e 100755
--- a/src/server/game/Entities/Pet/Pet.cpp
+++ b/src/server/game/Entities/Pet/Pet.cpp
@@ -2033,3 +2033,40 @@ void Pet::SynchronizeLevelWithOwner()
break;
}
}
+
+void Pet::ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs)
+{
+ WorldPacket data(SMSG_SPELL_COOLDOWN, 8+1+m_spells.size()*8);
+ data << uint64(GetGUID());
+ data << uint8(0x0); // flags (0x1, 0x2)
+ time_t curTime = time(NULL);
+ for (PetSpellMap::const_iterator itr = m_spells.begin(); itr != m_spells.end(); ++itr)
+ {
+ if (itr->second.state == PETSPELL_REMOVED)
+ continue;
+ uint32 unSpellId = itr->first;
+ SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(unSpellId);
+ if (!spellInfo)
+ {
+ ASSERT(spellInfo);
+ continue;
+ }
+
+ // Not send cooldown for this spells
+ if (spellInfo->Attributes & SPELL_ATTR0_DISABLED_WHILE_ACTIVE)
+ continue;
+
+ if (spellInfo->PreventionType != SPELL_PREVENTION_TYPE_SILENCE)
+ continue;
+
+ if ((idSchoolMask & spellInfo->GetSchoolMask()) && GetCreatureSpellCooldownDelay(unSpellId) < unTimeMs)
+ {
+ data << uint32(unSpellId);
+ data << uint32(unTimeMs); // in m.secs
+ _AddCreatureSpellCooldown(unSpellId, curTime + unTimeMs/IN_MILLISECONDS);
+ }
+ }
+
+ if (Player* owner = GetOwner())
+ owner->GetSession()->SendPacket(&data);
+} \ No newline at end of file
diff --git a/src/server/game/Entities/Pet/Pet.h b/src/server/game/Entities/Pet/Pet.h
index 3475817816d..c0c47367240 100755
--- a/src/server/game/Entities/Pet/Pet.h
+++ b/src/server/game/Entities/Pet/Pet.h
@@ -200,6 +200,7 @@ class Pet : public Guardian
bool unlearnSpell(uint32 spell_id, bool learn_prev, bool clear_ab = true);
bool removeSpell(uint32 spell_id, bool learn_prev, bool clear_ab = true);
void CleanupActionBar();
+ virtual void ProhibitSpellSchool(SpellSchoolMask idSchoolMask, uint32 unTimeMs);
PetSpellMap m_spells;
AutoSpellList m_autospells;
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 65f6588f80e..142b5939d9b 100755
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -24502,11 +24502,11 @@ bool Player::canSeeSpellClickOn(Creature const* c) const
ConditionList conds = sConditionMgr->GetConditionsForSpellClickEvent(c->GetEntry(), itr->second.spellId);
ConditionSourceInfo info = ConditionSourceInfo(const_cast<Player*>(this), const_cast<Creature*>(c));
- if (!sConditionMgr->IsObjectMeetToConditions(info, conds))
- return false;
+ if (sConditionMgr->IsObjectMeetToConditions(info, conds))
+ return true;
}
- return true;
+ return false;
}
void Player::BuildPlayerTalentsInfoData(WorldPacket* data)
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index 27e2cbf358b..5d248b0ae87 100755
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -405,6 +405,7 @@ void Unit::UpdateSplineMovement(uint32 t_diff)
pos.m_positionY = loc.y;
pos.m_positionZ = loc.z;
pos.m_orientation = loc.orientation;
+
if (Unit* vehicle = GetVehicleBase())
{
loc.x += vehicle->GetPositionX();
@@ -861,17 +862,24 @@ void Unit::CastCustomSpell(Unit* target, uint32 spellId, int32 const* bp0, int32
values.AddSpellMod(SPELLVALUE_BASE_POINT1, *bp1);
if (bp2)
values.AddSpellMod(SPELLVALUE_BASE_POINT2, *bp2);
- CastCustomSpell(spellId, values, target, triggered, castItem, triggeredByAura, originalCaster);
+ CastCustomSpell(spellId, values, target, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, castItem, triggeredByAura, originalCaster);
}
void Unit::CastCustomSpell(uint32 spellId, SpellValueMod mod, int32 value, Unit* target, bool triggered, Item* castItem, AuraEffect const* triggeredByAura, uint64 originalCaster)
{
CustomSpellValues values;
values.AddSpellMod(mod, value);
- CastCustomSpell(spellId, values, target, triggered, castItem, triggeredByAura, originalCaster);
+ CastCustomSpell(spellId, values, target, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, castItem, triggeredByAura, originalCaster);
+}
+
+void Unit::CastCustomSpell(uint32 spellId, SpellValueMod mod, int32 value, Unit* target, TriggerCastFlags triggerFlags, Item* castItem, AuraEffect const* triggeredByAura, uint64 originalCaster)
+{
+ CustomSpellValues values;
+ values.AddSpellMod(mod, value);
+ CastCustomSpell(spellId, values, target, triggerFlags, castItem, triggeredByAura, originalCaster);
}
-void Unit::CastCustomSpell(uint32 spellId, CustomSpellValues const& value, Unit* victim, bool triggered, Item* castItem, AuraEffect const* triggeredByAura, uint64 originalCaster)
+void Unit::CastCustomSpell(uint32 spellId, CustomSpellValues const& value, Unit* victim, TriggerCastFlags triggerFlags, Item* castItem, AuraEffect const* triggeredByAura, uint64 originalCaster)
{
SpellInfo const* spellInfo = sSpellMgr->GetSpellInfo(spellId);
if (!spellInfo)
@@ -882,7 +890,7 @@ void Unit::CastCustomSpell(uint32 spellId, CustomSpellValues const& value, Unit*
SpellCastTargets targets;
targets.SetUnitTarget(victim);
- CastSpell(targets, spellInfo, &value, triggered ? TRIGGERED_FULL_MASK : TRIGGERED_NONE, castItem, triggeredByAura, originalCaster);
+ CastSpell(targets, spellInfo, &value, triggerFlags, castItem, triggeredByAura, originalCaster);
}
void Unit::CastSpell(float x, float y, float z, uint32 spellId, bool triggered, Item* castItem, AuraEffect const* triggeredByAura, uint64 originalCaster)
@@ -6728,7 +6736,7 @@ bool Unit::HandleDummyAuraProc(Unit* victim, uint32 damage, AuraEffect* triggere
if (!victim)
return false;
- // 2% of base mana
+ // 2% of maximum health
basepoints0 = int32(victim->CountPctFromMaxHealth(2));
victim->CastCustomSpell(victim, 20267, &basepoints0, 0, 0, true, 0, triggeredByAura);
return true;
@@ -11086,9 +11094,12 @@ uint32 Unit::SpellCriticalDamageBonus(SpellInfo const* spellProto, uint32 damage
crit_bonus -= damage;
- // adds additional damage to crit_bonus (from talents)
- if (Player* modOwner = GetSpellModOwner())
- modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_CRIT_DAMAGE_BONUS, crit_bonus);
+ if (damage > uint32(crit_bonus))
+ {
+ // adds additional damage to critBonus (from talents)
+ if (Player* modOwner = GetSpellModOwner())
+ modOwner->ApplySpellMod(spellProto->Id, SPELLMOD_CRIT_DAMAGE_BONUS, crit_bonus);
+ }
crit_bonus += damage;
@@ -16965,19 +16976,20 @@ void Unit::JumpTo(WorldObject* obj, float speedZ)
bool Unit::HandleSpellClick(Unit* clicker, int8 seatId)
{
+ bool result = false;
uint32 spellClickEntry = GetVehicleKit() ? GetVehicleKit()->GetCreatureEntry() : GetEntry();
SpellClickInfoMapBounds clickPair = sObjectMgr->GetSpellClickInfoMapBounds(spellClickEntry);
for (SpellClickInfoContainer::const_iterator itr = clickPair.first; itr != clickPair.second; ++itr)
{
//! First check simple relations from clicker to clickee
if (!itr->second.IsFitToRequirements(clicker, this))
- return false;
+ continue;
//! Check database conditions
ConditionList conds = sConditionMgr->GetConditionsForSpellClickEvent(spellClickEntry, itr->second.spellId);
ConditionSourceInfo info = ConditionSourceInfo(clicker, this);
if (!sConditionMgr->IsObjectMeetToConditions(info, conds))
- return false;
+ continue;
Unit* caster = (itr->second.castFlags & NPC_CLICK_CAST_CASTER_CLICKER) ? clicker : this;
Unit* target = (itr->second.castFlags & NPC_CLICK_CAST_TARGET_CLICKER) ? clicker : this;
@@ -17003,11 +17015,11 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId)
if (!valid)
{
sLog->outError(LOG_FILTER_SQL, "Spell %u specified in npc_spellclick_spells is not a valid vehicle enter aura!", itr->second.spellId);
- return false;
+ continue;
}
if (IsInMap(caster))
- caster->CastCustomSpell(itr->second.spellId, SpellValueMod(SPELLVALUE_BASE_POINT0+i), seatId+1, target, false, NULL, NULL, origCasterGUID);
+ caster->CastCustomSpell(itr->second.spellId, SpellValueMod(SPELLVALUE_BASE_POINT0+i), seatId+1, target, GetVehicleKit() ? TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE : TRIGGERED_NONE, NULL, NULL, origCasterGUID);
else // This can happen during Player::_LoadAuras
{
int32 bp0 = seatId;
@@ -17017,22 +17029,27 @@ bool Unit::HandleSpellClick(Unit* clicker, int8 seatId)
else
{
if (IsInMap(caster))
- caster->CastSpell(target, spellEntry, false, NULL, NULL, origCasterGUID);
+ caster->CastSpell(target, spellEntry, GetVehicleKit() ? TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE : TRIGGERED_NONE, NULL, NULL, origCasterGUID);
else
Aura::TryRefreshStackOrCreate(spellEntry, MAX_EFFECT_MASK, this, clicker, NULL, NULL, origCasterGUID);
}
+
+ result = true;
}
- Creature* creature = ToCreature();
- if (creature && creature->IsAIEnabled)
- creature->AI()->OnSpellClick(clicker);
+ if (result)
+ {
+ Creature* creature = ToCreature();
+ if (creature && creature->IsAIEnabled)
+ creature->AI()->OnSpellClick(clicker);
+ }
- return true;
+ return result;
}
void Unit::EnterVehicle(Unit* base, int8 seatId)
{
- CastCustomSpell(VEHICLE_SPELL_RIDE_HARDCODED, SPELLVALUE_BASE_POINT0, seatId+1, base, false);
+ CastCustomSpell(VEHICLE_SPELL_RIDE_HARDCODED, SPELLVALUE_BASE_POINT0, seatId+1, base, TRIGGERED_IGNORE_CASTER_MOUNTED_OR_ON_VEHICLE);
}
void Unit::_EnterVehicle(Vehicle* vehicle, int8 seatId, AuraApplication const* aurApp)
diff --git a/src/server/game/Entities/Unit/Unit.h b/src/server/game/Entities/Unit/Unit.h
index 98d7bbcdcde..415d63a0c84 100755
--- a/src/server/game/Entities/Unit/Unit.h
+++ b/src/server/game/Entities/Unit/Unit.h
@@ -1568,13 +1568,14 @@ class Unit : public WorldObject
void CastSpell(SpellCastTargets const& targets, SpellInfo const* spellInfo, CustomSpellValues const* value, TriggerCastFlags triggerFlags = TRIGGERED_NONE, Item* castItem = NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0);
void CastSpell(Unit* victim, uint32 spellId, bool triggered, Item* castItem = NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0);
void CastSpell(Unit* victim, uint32 spellId, TriggerCastFlags triggerFlags = TRIGGERED_NONE, Item* castItem = NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0);
- void CastSpell(Unit* victim, SpellInfo const* spellInfo, bool triggered, Item* castItem= NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0);
- void CastSpell(Unit* victim, SpellInfo const* spellInfo, TriggerCastFlags triggerFlags = TRIGGERED_NONE, Item* castItem= NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0);
+ void CastSpell(Unit* victim, SpellInfo const* spellInfo, bool triggered, Item* castItem = NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0);
+ void CastSpell(Unit* victim, SpellInfo const* spellInfo, TriggerCastFlags triggerFlags = TRIGGERED_NONE, Item* castItem = NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0);
void CastSpell(float x, float y, float z, uint32 spellId, bool triggered, Item* castItem = NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0);
- void CastCustomSpell(Unit* Victim, uint32 spellId, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item* castItem= NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0);
- void CastCustomSpell(uint32 spellId, SpellValueMod mod, int32 value, Unit* Victim = NULL, bool triggered = true, Item* castItem = NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0);
- void CastCustomSpell(uint32 spellId, CustomSpellValues const &value, Unit* Victim = NULL, bool triggered = true, Item* castItem = NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0);
void CastSpell(GameObject* go, uint32 spellId, bool triggered, Item* castItem = NULL, AuraEffect* triggeredByAura = NULL, uint64 originalCaster = 0);
+ void CastCustomSpell(Unit* victim, uint32 spellId, int32 const* bp0, int32 const* bp1, int32 const* bp2, bool triggered, Item* castItem = NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0);
+ void CastCustomSpell(uint32 spellId, SpellValueMod mod, int32 value, Unit* victim, bool triggered, Item* castItem = NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0);
+ void CastCustomSpell(uint32 spellId, SpellValueMod mod, int32 value, Unit* victim = NULL, TriggerCastFlags triggerFlags = TRIGGERED_NONE, Item* castItem = NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0);
+ void CastCustomSpell(uint32 spellId, CustomSpellValues const &value, Unit* victim = NULL, TriggerCastFlags triggerFlags = TRIGGERED_NONE, Item* castItem = NULL, AuraEffect const* triggeredByAura = NULL, uint64 originalCaster = 0);
Aura* AddAura(uint32 spellId, Unit* target);
Aura* AddAura(SpellInfo const* spellInfo, uint8 effMask, Unit* target);
void SetAuraStack(uint32 spellId, Unit* target, uint32 stack);
diff --git a/src/server/game/Movement/Spline/MoveSplineInit.cpp b/src/server/game/Movement/Spline/MoveSplineInit.cpp
index c539dd3cc39..a47c25610b0 100644
--- a/src/server/game/Movement/Spline/MoveSplineInit.cpp
+++ b/src/server/game/Movement/Spline/MoveSplineInit.cpp
@@ -71,10 +71,10 @@ namespace Movement
real_position.z = unit.GetTransOffsetZ();
real_position.orientation = unit.GetTransOffsetO();
}
-
// there is a big chance that current position is unknown if current state is not finalized, need compute it
// this also allows calculate spline position and update map position in much greater intervals
- if (!move_spline.Finalized())
+ // Don't compute for transport movement. The unit could be in a motion between two transports, thus having transport moveflag but is resulting in regular positions
+ else if (!move_spline.Finalized())
real_position = move_spline.ComputePosition();
// should i do the things that user should do? - no.
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 1dcee6dbac7..eee6a1f02d4 100755
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -5145,6 +5145,10 @@ SpellCastResult Spell::CheckCast(bool strict)
}
if (m_caster->HasUnitState(UNIT_STATE_ROOT))
return SPELL_FAILED_ROOTED;
+ if (m_caster->GetTypeId() == TYPEID_PLAYER)
+ if (Unit* target = m_targets.GetUnitTarget())
+ if (!target->isAlive())
+ return SPELL_FAILED_BAD_TARGETS;
break;
}
case SPELL_EFFECT_SKINNING:
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index ad9298f0144..75cf7e82b25 100755
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -4141,6 +4141,8 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
return;
}
case 59317: // Teleporting
+ {
+
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
@@ -4152,20 +4154,6 @@ void Spell::EffectScriptEffect(SpellEffIndex effIndex)
unitTarget->CastSpell(unitTarget, 59314, true);
return;
- // random spell learn instead placeholder
- case 60893: // Northrend Alchemy Research
- case 61177: // Northrend Inscription Research
- case 61288: // Minor Inscription Research
- case 61756: // Northrend Inscription Research (FAST QA VERSION)
- case 64323: // Book of Glyph Mastery
- {
- if (m_caster->GetTypeId() != TYPEID_PLAYER)
- return;
-
- // learn random explicit discovery recipe (if any)
- if (uint32 discoveredSpell = GetExplicitDiscoverySpell(m_spellInfo->Id, m_caster->ToPlayer()))
- m_caster->ToPlayer()->learnSpell(discoveredSpell, false);
- return;
}
case 62482: // Grab Crate
{
diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
index a8657925131..ba1a0614cdf 100644
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_the_lich_king.cpp
@@ -2112,7 +2112,7 @@ class spell_the_lich_king_necrotic_plague : public SpellScriptLoader
CustomSpellValues values;
//values.AddSpellMod(SPELLVALUE_AURA_STACK, 2);
values.AddSpellMod(SPELLVALUE_MAX_TARGETS, 1);
- GetTarget()->CastCustomSpell(SPELL_NECROTIC_PLAGUE_JUMP, values, NULL, true, NULL, NULL, GetCasterGUID());
+ GetTarget()->CastCustomSpell(SPELL_NECROTIC_PLAGUE_JUMP, values, NULL, TRIGGERED_FULL_MASK, NULL, NULL, GetCasterGUID());
if (Unit* caster = GetCaster())
caster->CastSpell(caster, SPELL_PLAGUE_SIPHON, true);
}
@@ -2204,7 +2204,7 @@ class spell_the_lich_king_necrotic_plague_jump : public SpellScriptLoader
CustomSpellValues values;
values.AddSpellMod(SPELLVALUE_AURA_STACK, GetStackAmount());
- GetTarget()->CastCustomSpell(SPELL_NECROTIC_PLAGUE_JUMP, values, NULL, true, NULL, NULL, GetCasterGUID());
+ GetTarget()->CastCustomSpell(SPELL_NECROTIC_PLAGUE_JUMP, values, NULL, TRIGGERED_FULL_MASK, NULL, NULL, GetCasterGUID());
if (Unit* caster = GetCaster())
caster->CastSpell(caster, SPELL_PLAGUE_SIPHON, true);
}
@@ -2223,7 +2223,7 @@ class spell_the_lich_king_necrotic_plague_jump : public SpellScriptLoader
CustomSpellValues values;
values.AddSpellMod(SPELLVALUE_AURA_STACK, GetStackAmount());
values.AddSpellMod(SPELLVALUE_BASE_POINT1, AURA_REMOVE_BY_ENEMY_SPELL); // add as marker (spell has no effect 1)
- GetTarget()->CastCustomSpell(SPELL_NECROTIC_PLAGUE_JUMP, values, NULL, true, NULL, NULL, GetCasterGUID());
+ GetTarget()->CastCustomSpell(SPELL_NECROTIC_PLAGUE_JUMP, values, NULL, TRIGGERED_FULL_MASK, NULL, NULL, GetCasterGUID());
if (Unit* caster = GetCaster())
caster->CastSpell(caster, SPELL_PLAGUE_SIPHON, true);
diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp
index 5153010c0cc..ed4148cd033 100644
--- a/src/server/scripts/Spells/spell_generic.cpp
+++ b/src/server/scripts/Spells/spell_generic.cpp
@@ -907,9 +907,22 @@ class spell_gen_profession_research : public SpellScriptLoader
return SPELL_CAST_OK;
}
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ Player* caster = GetCaster()->ToPlayer();
+ uint32 spellId = GetSpellInfo()->Id;
+
+ // learn random explicit discovery recipe (if any)
+ if (uint32 discoveredSpellId = GetExplicitDiscoverySpell(spellId, caster))
+ caster->learnSpell(discoveredSpellId, false);
+
+ caster->UpdateCraftSkill(spellId);
+ }
+
void Register()
{
OnCheckCast += SpellCheckCastFn(spell_gen_profession_research_SpellScript::CheckRequirement);
+ OnEffectHitTarget += SpellEffectFn(spell_gen_profession_research_SpellScript::HandleScript, EFFECT_1, SPELL_EFFECT_SCRIPT_EFFECT);
}
};
diff --git a/src/server/scripts/Spells/spell_item.cpp b/src/server/scripts/Spells/spell_item.cpp
index 3c89cb7005a..0508d95a60b 100644
--- a/src/server/scripts/Spells/spell_item.cpp
+++ b/src/server/scripts/Spells/spell_item.cpp
@@ -836,9 +836,20 @@ class spell_item_book_of_glyph_mastery : public SpellScriptLoader
return SPELL_CAST_OK;
}
+ void HandleScript(SpellEffIndex /*effIndex*/)
+ {
+ Player* caster = GetCaster()->ToPlayer();
+ uint32 spellId = GetSpellInfo()->Id;
+
+ // learn random explicit discovery recipe (if any)
+ if (uint32 discoveredSpellId = GetExplicitDiscoverySpell(spellId, caster))
+ caster->learnSpell(discoveredSpellId, false);
+ }
+
void Register()
{
OnCheckCast += SpellCheckCastFn(spell_item_book_of_glyph_mastery_SpellScript::CheckRequirement);
+ OnEffectHitTarget += SpellEffectFn(spell_item_book_of_glyph_mastery_SpellScript::HandleScript, EFFECT_0, SPELL_EFFECT_SCRIPT_EFFECT);
}
};