aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/game/Pet.cpp17
-rw-r--r--src/game/Spell.cpp39
-rw-r--r--src/game/SpellAuras.cpp3
-rw-r--r--src/game/SpellEffects.cpp51
-rw-r--r--src/game/StatSystem.cpp18
-rw-r--r--src/game/TemporarySummon.h1
-rw-r--r--src/game/Unit.cpp28
7 files changed, 134 insertions, 23 deletions
diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp
index e27981922b6..1332a444438 100644
--- a/src/game/Pet.cpp
+++ b/src/game/Pet.cpp
@@ -259,6 +259,21 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
CharacterDatabase.CommitTransaction();
}
+ // Send fake summon spell cast - this is needed for correct cooldown application for spells
+ // Example: 46584 - without this cooldown (which should be set always when pet is loaded) isn't set clientside
+ // TODO: pets should be summoned from real cast instead of just faking it?
+ if (GetUInt32Value(UNIT_CREATED_BY_SPELL))
+ {
+ WorldPacket data(SMSG_SPELL_GO, (8+8+4+4+2));
+ data.append(owner->GetPackGUID());
+ data.append(owner->GetPackGUID());
+ data << uint8(0);
+ data << uint32(GetUInt32Value(UNIT_CREATED_BY_SPELL));
+ data << uint32(256); // CAST_FLAG_UNKNOWN3
+ data << uint32(0);
+ SendMessageToSet(&data, true);
+ }
+
owner->SetMinion(this, true);
map->Add((Creature*)this);
@@ -766,6 +781,7 @@ bool Pet::CreateBaseAtCreature(Creature* creature)
return true;
}
+// TODO: Move stat mods code to pet passive auras
bool Guardian::InitStatsForLevel(uint32 petlevel)
{
CreatureInfo const *cinfo = GetCreatureInfo();
@@ -949,7 +965,6 @@ bool Guardian::InitStatsForLevel(uint32 petlevel)
SetHealth(GetMaxHealth());
SetPower(POWER_MANA, GetMaxPower(POWER_MANA));
-
return true;
}
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index adcffee15b7..fe42dec9a4f 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -2152,8 +2152,8 @@ void Spell::SetTargetMap(uint32 i, uint32 cur)
radius = GetSpellRadius(m_spellInfo, i, true);
targetType = SPELL_TARGETS_ALLY;
break;
- case TARGET_UNIT_AREA_ENTRY_SRC:
case TARGET_UNIT_AREA_ENTRY_DST:
+ case TARGET_UNIT_AREA_ENTRY_SRC:
case TARGET_UNIT_CONE_ENTRY: // fix me
radius = GetSpellRadius(m_spellInfo, i, IsPositiveSpell(m_spellInfo->Id));
targetType = SPELL_TARGETS_ENTRY;
@@ -2175,14 +2175,36 @@ void Spell::SetTargetMap(uint32 i, uint32 cur)
SpellScriptTarget::const_iterator upper = spellmgr.GetEndSpellScriptTarget(m_spellInfo->Id);
if(lower == upper)
{
- sLog.outDebug("Spell (ID: %u) (caster Entry: %u) does not have record in `spell_script_target`", m_spellInfo->Id, m_caster->GetEntry());
+ // Custom entries
+ // TODO: move these to sql
+ switch (m_spellInfo->Id)
+ {
+ case 46584: // Raise Dead
+ {
+ // TODO: change visual of corpses which gave ghoul?
+ // Allow corpses to be ghouled only once?
+ m_targets.m_targetMask &= ~TARGET_FLAG_DEST_LOCATION;
+ WorldObject* result = FindCorpseUsing<MaNGOS::RaiseDeadObjectCheck> ();
+ if(result)
+ {
+ switch(result->GetTypeId())
+ {
+ case TYPEID_UNIT:
+ m_targets.setDestination(result);
+ }
+ }
+ break;
+ }
+ default:
+ sLog.outDebug("Spell (ID: %u) (caster Entry: %u) does not have record in `spell_script_target`", m_spellInfo->Id, m_caster->GetEntry());
- if(m_spellInfo->Effect[i] == SPELL_EFFECT_TELEPORT_UNITS)
- SearchAreaTarget(unitList, radius, pushType, SPELL_TARGETS_ENTRY, 0);
- else if(IsPositiveEffect(m_spellInfo->Id, i))
- SearchAreaTarget(unitList, radius, pushType, SPELL_TARGETS_ALLY);
- else
- SearchAreaTarget(unitList, radius, pushType, SPELL_TARGETS_ENEMY);
+ if(m_spellInfo->Effect[i] == SPELL_EFFECT_TELEPORT_UNITS)
+ SearchAreaTarget(unitList, radius, pushType, SPELL_TARGETS_ENTRY, 0);
+ else if(IsPositiveEffect(m_spellInfo->Id, i))
+ SearchAreaTarget(unitList, radius, pushType, SPELL_TARGETS_ALLY);
+ else
+ SearchAreaTarget(unitList, radius, pushType, SPELL_TARGETS_ENEMY);
+ }
}
// let it be done in one check?
else
@@ -2448,6 +2470,7 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect* triggeredByAura
triggeredByAura->GetParentAura()->SetAuraDuration(0);
}
SendCastResult(result);
+
finish(false);
return;
}
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index e33fa8a5b9d..abc0e97206a 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -6924,9 +6924,6 @@ void AuraEffect::PeriodicDummyTick()
caster->CastCustomSpell(m_target, 52212, &m_amount, NULL, NULL, true, 0, this);
return;
}
- // Raise Dead
-// if (spell->SpellFamilyFlags & 0x0000000000001000LL)
-// return;
// Chains of Ice
if (spell->SpellFamilyFlags[1] & 0x00004000)
{
diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp
index 3efd29c6e69..edc17b35b19 100644
--- a/src/game/SpellEffects.cpp
+++ b/src/game/SpellEffects.cpp
@@ -703,6 +703,8 @@ void Spell::EffectDummy(uint32 i)
uint32 spell_id = 0;
int32 bp = 0;
+ bool triggered = true;
+ SpellCastTargets targets;
// selection by spell family
switch(m_spellInfo->SpellFamilyName)
@@ -1908,17 +1910,52 @@ void Spell::EffectDummy(uint32 i)
}
return;
}
+ // Hungering Cold
+ if (m_spellInfo->SpellFamilyFlags[1] & 0x1000)
+ {
+ unitTarget->CastSpell(m_caster, 51209, true);
+ return;
+ }
// Death Grip
if(m_spellInfo->Id == 49560)
{
unitTarget->CastSpell(m_caster, damage, true);
return;
}
- // Hungering Cold
- if (m_spellInfo->SpellFamilyFlags[1] & 0x1000)
+ else if(m_spellInfo->Id == 46584) // Raise dead
{
- unitTarget->CastSpell(m_caster, 51209, true);
- return;
+ if ( m_caster->GetTypeId() != TYPEID_PLAYER)
+ return;
+
+ // Do we have talent Master of Ghouls?
+ if(m_caster->HasAura(52143))
+ // summon as pet
+ bp = 52150;
+ else
+ // or guardian
+ bp = 46585;
+
+ if (m_targets.HasDst())
+ {
+ targets.setDestination(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ);
+ }
+ else
+ {
+ targets.setDestination(m_caster);
+ // Corpse not found - take reagents ( only not triggered cast can take them)
+ triggered = false;
+ }
+ // Remove cooldown - summon spellls have category
+ ((Player*)m_caster)->RemoveSpellCooldown(m_spellInfo->Id,true);
+ spell_id=48289;
+ }
+ // Raise dead - take reagents and trigger summon spells
+ else if (m_spellInfo->Id ==48289)
+ {
+ if (m_targets.HasDst())
+ targets.setDestination(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ);
+
+ spell_id = m_currentBasePoints[0];
}
break;
}
@@ -1934,10 +1971,9 @@ void Spell::EffectDummy(uint32 i)
return;
}
- Spell* spell = new Spell(m_caster, spellInfo, true, m_originalCasterGUID, NULL, true);
- if(bp) spell->m_currentBasePoints[0] = bp;
- SpellCastTargets targets;
targets.setUnitTarget(unitTarget);
+ Spell* spell = new Spell(m_caster, spellInfo, triggered, m_originalCasterGUID, NULL, true);
+ if(bp) spell->m_currentBasePoints[0] = bp;
spell->prepare(&targets);
}
@@ -5379,6 +5415,7 @@ void Spell::EffectScriptEffect(uint32 effIndex)
m_caster->CastSpell(unitTarget, 55095, true);
}
}
+ break;
}
}
diff --git a/src/game/StatSystem.cpp b/src/game/StatSystem.cpp
index 2049964c779..1d6ad79fda8 100644
--- a/src/game/StatSystem.cpp
+++ b/src/game/StatSystem.cpp
@@ -387,13 +387,12 @@ void Player::UpdateAttackPowerAndDamage(bool ranged )
SetInt32Value(index_mod, (uint32)attPowerMod); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MODS field
SetFloatValue(index_mult, attPowerMultiplier); //UNIT_FIELD_(RANGED)_ATTACK_POWER_MULTIPLIER field
+ Pet *pet = GetPet(); //update pet's AP
//automatically update weapon damage after attack power modification
if(ranged)
{
UpdateDamagePhysical(RANGED_ATTACK);
-
- Pet *pet = GetPet(); //update pet's AP
- if(pet)
+ if(pet && pet->isHunterPet()) // At ranged attack change for hunter pet
pet->UpdateAttackPowerAndDamage();
}
else
@@ -403,6 +402,9 @@ void Player::UpdateAttackPowerAndDamage(bool ranged )
UpdateDamagePhysical(OFF_ATTACK);
if(getClass() == CLASS_SHAMAN) // mental quickness
UpdateSpellDamageAndHealingBonus();
+
+ if(pet && pet->IsPetGhoul()) // At ranged attack change for hunter pet
+ pet->UpdateAttackPowerAndDamage();
}
}
@@ -952,6 +954,11 @@ bool Guardian::UpdateStats(Stats stat)
if(owner->getClass() == CLASS_WARLOCK || owner->getClass() == CLASS_MAGE)
value += float(owner->GetStat(stat)) * 0.3f;
}
+ else if ( stat == STAT_STRENGTH )
+ {
+ if (IsPetGhoul())
+ value += float(owner->GetStat(stat)) * 0.3f;
+ }
SetStat(stat, int32(value));
@@ -1089,6 +1096,11 @@ void Guardian::UpdateAttackPowerAndDamage(bool ranged)
bonusAP = owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.22f;
SetBonusDamage( int32(owner->GetTotalAttackPowerValue(RANGED_ATTACK) * 0.1287f));
}
+ else if (IsPetGhoul()) //ghouls benefit from deathknight's attack power (may be summon pet or not)
+ {
+ bonusAP = owner->GetTotalAttackPowerValue(BASE_ATTACK) * 0.22f;
+ SetBonusDamage( int32(owner->GetTotalAttackPowerValue(BASE_ATTACK) * 0.1287f));
+ }
//demons benefit from warlocks shadow or fire damage
else if(isPet())
{
diff --git a/src/game/TemporarySummon.h b/src/game/TemporarySummon.h
index d6e532626ce..47961d714ec 100644
--- a/src/game/TemporarySummon.h
+++ b/src/game/TemporarySummon.h
@@ -54,6 +54,7 @@ class Minion : public TempSummon
void InitSummon();
void RemoveFromWorld();
Unit *GetOwner() { return m_owner; }
+ bool IsPetGhoul() const {return GetEntry() == 26125;} // Ghoul may be guardian or pet
protected:
Unit * const m_owner;
};
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 037c00fcff2..b3e113ff6fb 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -1821,7 +1821,7 @@ uint32 Unit::CalcArmorReducedDamage(Unit* pVictim, const uint32 damage, SpellEnt
// Apply Player CR_ARMOR_PENETRATION rating
if (GetTypeId()==TYPEID_PLAYER)
- armor *= 1.0f - ((Player*)this)->GetRatingBonusValue(CR_ARMOR_PENETRATION) / 100.0f;
+ armor *= 1.0f - (((Player*)this)->GetRatingBonusValue(CR_ARMOR_PENETRATION) / 100.0f);
if (armor < 0.0f) armor=0.0f;
@@ -8685,6 +8685,22 @@ void Unit::SetMinion(Minion *minion, bool apply)
if(GetTypeId() == TYPEID_PLAYER && minion->HasSummonMask(SUMMON_MASK_PET))
for(int i = 0; i < MAX_MOVE_TYPE; ++i)
minion->SetSpeed(UnitMoveType(i), m_speed_rate[i], true);
+
+ // Ghoul pets have energy instead of mana (is anywhere better place for this code?)
+ if (minion->IsPetGhoul())
+ {
+ minion->setPowerType(POWER_ENERGY);
+ }
+
+ if (GetTypeId() == TYPEID_PLAYER)
+ {
+ // Send infinity cooldown - client does that automatically but after relog cooldown needs to be set again
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(minion->GetUInt32Value(UNIT_CREATED_BY_SPELL));
+ if (spellInfo && (spellInfo->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE))
+ {
+ ((Player*)this)->AddSpellAndCategoryCooldowns(spellInfo, 0, NULL ,true);
+ }
+ }
}
else
{
@@ -8702,6 +8718,16 @@ void Unit::SetMinion(Minion *minion, bool apply)
SetPetGUID(0);
}
+ if (GetTypeId() == TYPEID_PLAYER)
+ {
+ SpellEntry const *spellInfo = sSpellStore.LookupEntry(minion->GetUInt32Value(UNIT_CREATED_BY_SPELL));
+ // Remove infinity cooldown
+ if (spellInfo && (spellInfo->Attributes & SPELL_ATTR_DISABLED_WHILE_ACTIVE))
+ {
+ ((Player*)this)->SendCooldownEvent(spellInfo);
+ }
+ }
+
//if(minion->HasSummonMask(SUMMON_MASK_GUARDIAN))
{
if(RemoveUInt64Value(UNIT_FIELD_SUMMON, minion->GetGUID()))