diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/game/Pet.cpp | 17 | ||||
-rw-r--r-- | src/game/Spell.cpp | 39 | ||||
-rw-r--r-- | src/game/SpellAuras.cpp | 3 | ||||
-rw-r--r-- | src/game/SpellEffects.cpp | 51 | ||||
-rw-r--r-- | src/game/StatSystem.cpp | 18 | ||||
-rw-r--r-- | src/game/TemporarySummon.h | 1 | ||||
-rw-r--r-- | src/game/Unit.cpp | 28 |
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())) |