diff --git a/src/game/SpellEffects.cpp b/src/game/SpellEffects.cpp index 317f44ffc..de8a899d3 100644 --- a/src/game/SpellEffects.cpp +++ b/src/game/SpellEffects.cpp @@ -147,9 +147,9 @@ pEffect SpellEffects[TOTAL_SPELL_EFFECTS] = &Spell::EffectStuck, // 84 SPELL_EFFECT_STUCK &Spell::EffectSummonPlayer, // 85 SPELL_EFFECT_SUMMON_PLAYER &Spell::EffectActivateObject, // 86 SPELL_EFFECT_ACTIVATE_OBJECT - &Spell::EffectNULL, // 87 SPELL_EFFECT_WMO_DAMAGE (57 spells in 3.3.2) - &Spell::EffectNULL, // 88 SPELL_EFFECT_WMO_REPAIR (2 spells in 3.3.2) - &Spell::EffectNULL, // 89 SPELL_EFFECT_WMO_CHANGE (7 spells in 3.3.2) + &Spell::EffectWMODamage, // 87 SPELL_EFFECT_WMO_DAMAGE (57 spells in 3.3.2) + &Spell::EffectWMORepair, // 88 SPELL_EFFECT_WMO_REPAIR (2 spells in 3.3.2) + &Spell::EffectWMOChange, // 89 SPELL_EFFECT_WMO_CHANGE (7 spells in 3.3.2) &Spell::EffectKillCreditPersonal, // 90 SPELL_EFFECT_KILL_CREDIT_PERSONAL Kill credit but only for single person &Spell::EffectUnused, // 91 SPELL_EFFECT_THREAT_ALL one spell: zzOLDBrainwash &Spell::EffectEnchantHeldItem, // 92 SPELL_EFFECT_ENCHANT_HELD_ITEM @@ -1194,22 +1194,22 @@ void Spell::EffectDummy(SpellEffectEntry const* effect) m_caster->RemoveSpellsCausingAura(SPELL_AURA_MOUNTED); - //5 different spells used depending on mounted speed and if mount can fly or not + // 5 different spells used depending on mounted speed and if mount can fly or not if (flyspeed >= 4.1f) // Flying Reindeer - m_caster->CastSpell(m_caster, 44827, true); //310% flying Reindeer + m_caster->CastSpell(m_caster, 44827, true); // 310% flying Reindeer else if (flyspeed >= 3.8f) // Flying Reindeer - m_caster->CastSpell(m_caster, 44825, true); //280% flying Reindeer + m_caster->CastSpell(m_caster, 44825, true); // 280% flying Reindeer else if (flyspeed >= 1.6f) // Flying Reindeer - m_caster->CastSpell(m_caster, 44824, true); //60% flying Reindeer + m_caster->CastSpell(m_caster, 44824, true); // 60% flying Reindeer else if (speed >= 2.0f) // Reindeer - m_caster->CastSpell(m_caster, 25859, true); //100% ground Reindeer + m_caster->CastSpell(m_caster, 25859, true); // 100% ground Reindeer else // Reindeer - m_caster->CastSpell(m_caster, 25858, true); //60% ground Reindeer + m_caster->CastSpell(m_caster, 25858, true); // 60% ground Reindeer return; } @@ -1415,6 +1415,15 @@ void Spell::EffectDummy(SpellEffectEntry const* effect) ((Creature*)unitTarget)->ForcedDespawn(10000); return; } + case 39635: // Throw Glaive (first) + case 39849: // Throw Glaive (second) + { + if (!unitTarget) + return; + + unitTarget->CastSpell(unitTarget, 41466, true, NULL, NULL, m_caster->GetObjectGuid()); + return; + } case 40802: // Mingo's Fortune Generator (Mingo's Fortune Giblets) { // selecting one from Bloodstained Fortune item @@ -1448,6 +1457,14 @@ void Spell::EffectDummy(SpellEffectEntry const* effect) DoCreateItem(effect, newitemid); return; } + case 40834: // Agonizing Flames + { + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + + m_caster->CastSpell(unitTarget, 40932, true); + return; + } case 40962: // Blade's Edge Terrace Demon Boss Summon Branch { if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) @@ -1671,6 +1688,13 @@ void Spell::EffectDummy(SpellEffectEntry const* effect) } case 44997: // Converting Sentry { + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_UNIT) + return; + + Creature* creatureTarget = (Creature*)unitTarget; + + creatureTarget->ForcedDespawn(); + // Converted Sentry Credit m_caster->CastSpell(m_caster, 45009, true); return; @@ -2623,6 +2647,23 @@ void Spell::EffectDummy(SpellEffectEntry const* effect) unitTarget->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_OOC_NOT_ATTACKABLE); return; } + case 63820: // Summon Scrap Bot Trigger (Ulduar - Mimiron) for Scrap Bots + case 64425: // Summon Scrap Bot Trigger (Ulduar - Mimiron) for Assault Bots + case 64620: // Summon Fire Bot Trigger (Ulduar - Mimiron) for Fire Bots + { + if (!unitTarget) + return; + + uint32 triggerSpell = 0; + switch (m_spellInfo->Id) + { + case 63820: triggerSpell = 64398; break; + case 64425: triggerSpell = 64426; break; + case 64620: triggerSpell = 64621; break; + } + unitTarget->CastSpell(unitTarget, triggerSpell, false); + return; + } case 64385: // Spinning (from Unusual Compass) { m_caster->SetFacingTo(frand(0, M_PI_F * 2)); @@ -2748,6 +2789,15 @@ void Spell::EffectDummy(SpellEffectEntry const* effect) m_caster->CastSpell(unitTarget, m_caster->CanReachWithMeleeAttack(unitTarget) ? 71623 : 72264, true); return; } + case 74452: // Conflagration + { + if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) + return; + + m_caster->CastSpell(unitTarget, 74453, true); + m_caster->CastSpell(unitTarget, 74454, true, NULL, NULL, m_caster->GetObjectGuid(), m_spellInfo); + return; + } } break; } @@ -3578,7 +3628,7 @@ void Spell::EffectTriggerSpellWithValue(SpellEffectEntry const* effect) } int32 bp = damage; - m_caster->CastCustomSpell(unitTarget, triggered_spell_id, &bp, &bp, &bp, true, NULL, NULL, m_originalCasterGUID); + m_caster->CastCustomSpell(unitTarget, triggered_spell_id, &bp, &bp, &bp, true, m_CastItem , NULL, m_originalCasterGUID, m_spellInfo); } void Spell::EffectTriggerRitualOfSummoning(SpellEffectEntry const* effect) @@ -3798,7 +3848,7 @@ void Spell::EffectTriggerSpell(SpellEffectEntry const* effect) caster = IsSpellWithCasterSourceTargetsOnly(spellInfo) ? unitTarget : m_caster; } - caster->CastSpell(unitTarget, spellInfo, true, NULL, NULL, m_originalCasterGUID); + caster->CastSpell(unitTarget, spellInfo, true, m_CastItem, NULL, m_originalCasterGUID, m_spellInfo); } void Spell::EffectTriggerMissileSpell(SpellEffectEntry const* effect) @@ -3818,7 +3868,7 @@ void Spell::EffectTriggerMissileSpell(SpellEffectEntry const* effect) if (m_CastItem) DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "WORLD: cast Item spellId - %i", spellInfo->Id); - m_caster->CastSpell(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, spellInfo, true, m_CastItem, 0, m_originalCasterGUID); + m_caster->CastSpell(m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, spellInfo, true, m_CastItem, NULL, m_originalCasterGUID, m_spellInfo); } void Spell::EffectJump(SpellEffectEntry const* effect) @@ -4149,11 +4199,10 @@ void Spell::EffectSendEvent(SpellEffectEntry const* effect) { /* we do not handle a flag dropping or clicking on flag in battleground by sendevent system + TODO: Actually, why not... */ DEBUG_FILTER_LOG(LOG_FILTER_SPELL_CAST, "Spell ScriptStart %u for spellid %u in EffectSendEvent ", effect->EffectMiscValue, m_spellInfo->Id); - - if (!sScriptMgr.OnProcessEvent(effect->EffectMiscValue, m_caster, focusObject, true)) - m_caster->GetMap()->ScriptsStart(sEventScripts, effect->EffectMiscValue, m_caster, focusObject); + StartEvents_Event(m_caster->GetMap(), effect->EffectMiscValue, m_caster, focusObject, true, m_caster); } void Spell::EffectPowerBurn(SpellEffectEntry const* effect) @@ -4514,7 +4563,7 @@ void Spell::EffectCreateItem2(SpellEffectEntry const* effect) } // create some random items - player->AutoStoreLoot(m_spellInfo->Id, LootTemplates_Spell); + player->AutoStoreLoot(NULL, m_spellInfo->Id, LootTemplates_Spell); } } @@ -4525,7 +4574,7 @@ void Spell::EffectCreateRandomItem(SpellEffectEntry const* /*effect*/) Player* player = (Player*)m_caster; // create some random items - player->AutoStoreLoot(m_spellInfo->Id, LootTemplates_Spell); + player->AutoStoreLoot(NULL, m_spellInfo->Id, LootTemplates_Spell); } void Spell::EffectPersistentAA(SpellEffectEntry const* effect) @@ -4535,7 +4584,7 @@ void Spell::EffectPersistentAA(SpellEffectEntry const* effect) if (!pCaster) pCaster = m_caster; - float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(effect->EffectRadiusIndex)); + float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(effect->GetRadiusIndex())); if (Player* modOwner = pCaster->GetSpellModOwner()) modOwner->ApplySpellMod(m_spellInfo->Id, SPELLMOD_RADIUS, radius); @@ -4888,6 +4937,10 @@ void Spell::EffectSummonType(SpellEffectEntry const* effect) // Expected Amount: TODO - there are quite some exceptions (like totems, engineering dragonlings..) uint32 amount = damage > 0 ? damage : 1; + // basepoints of SUMMON_PROP_GROUP_VEHICLE is often a spellId, set amount to 1 + if (summon_prop->Group == SUMMON_PROP_GROUP_VEHICLE) + amount = 1; + // Expected Level (Totem, Pet and Critter may not use this) uint32 level = m_caster->getLevel(); // level of creature summoned using engineering item based at engineering skill level @@ -4917,20 +4970,20 @@ void Spell::EffectSummonType(SpellEffectEntry const* effect) } // Set summon positions - float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(effect->EffectRadiusIndex)); + float radius = GetSpellRadius(sSpellRadiusStore.LookupEntry(effect->GetRadiusIndex())); CreatureSummonPositions::iterator itr = summonPositions.begin(); for (++itr; itr != summonPositions.end(); ++itr) // In case of multiple summons around position for not-fist positions { if (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION || radius > 1.0f) { m_caster->GetRandomPoint(summonPositions[0].x, summonPositions[0].y, summonPositions[0].z, radius, itr->x, itr->y, itr->z); - if (m_caster->GetMap()->GetObjectHitPos(summonPositions[0].x, summonPositions[0].y, summonPositions[0].z, itr->x, itr->y, itr->z, itr->x, itr->y, itr->z, 0.5f)) + if (m_caster->GetMap()->GetHitPosition(summonPositions[0].x, summonPositions[0].y, summonPositions[0].z, itr->x, itr->y, itr->z, m_caster->GetPhaseMask(), -0.5f)) m_caster->UpdateAllowedPositionZ(itr->x, itr->y, itr->z); } else // Get a point near the caster { m_caster->GetClosePoint(itr->x, itr->y, itr->z, 0.0f, radius, frand(0.0f, 2 * M_PI_F)); - if (m_caster->GetMap()->GetObjectHitPos(summonPositions[0].x, summonPositions[0].y, summonPositions[0].z, itr->x, itr->y, itr->z, itr->x, itr->y, itr->z, 0.5f)) + if (m_caster->GetMap()->GetHitPosition(summonPositions[0].x, summonPositions[0].y, summonPositions[0].z, itr->x, itr->y, itr->z, m_caster->GetPhaseMask(), -0.5f)) m_caster->UpdateAllowedPositionZ(itr->x, itr->y, itr->z); } } @@ -4947,8 +5000,8 @@ void Spell::EffectSummonType(SpellEffectEntry const* effect) case UNITNAME_SUMMON_TITLE_NONE: { // those are classical totems - effectbasepoints is their hp and not summon ammount! - //121: 23035, battlestands - //647: 52893, Anti-Magic Zone (npc used) + // 121: 23035, battlestands + // 647: 52893, Anti-Magic Zone (npc used) if (prop_id == 121 || prop_id == 647) summonResult = DoSummonTotem(effect); else @@ -5005,15 +5058,12 @@ void Spell::EffectSummonType(SpellEffectEntry const* effect) summonResult = DoSummonCritter(summonPositions, summon_prop, effect, level); break; case UNITNAME_SUMMON_TITLE_OPPONENT: + case UNITNAME_SUMMON_TITLE_VEHICLE: + case UNITNAME_SUMMON_TITLE_MOUNT: case UNITNAME_SUMMON_TITLE_LIGHTWELL: case UNITNAME_SUMMON_TITLE_BUTLER: summonResult = DoSummonWild(summonPositions, summon_prop, effect, level); break; - case UNITNAME_SUMMON_TITLE_VEHICLE: - case UNITNAME_SUMMON_TITLE_MOUNT: - // TODO - // EffectSummonVehicle(i); - break; default: sLog.outError("EffectSummonType: Unhandled summon title %u", summon_prop->Title); break; @@ -5038,9 +5088,7 @@ void Spell::EffectSummonType(SpellEffectEntry const* effect) } case SUMMON_PROP_GROUP_VEHICLE: { - // TODO - // EffectSummonVehicle(i); - sLog.outDebug("EffectSummonType: Unhandled summon group type SUMMON_PROP_GROUP_VEHICLE(%u)", summon_prop->Group); + summonResult = DoSummonVehicle(summonPositions, summon_prop, effect, level); break; } default: @@ -5090,7 +5138,7 @@ bool Spell::DoSummonWild(CreatureSummonPositions& list, SummonPropertiesEntry co return false; } - TempSummonType summonType = (m_duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_OR_DEAD_DESPAWN; + TempSummonType summonType = (m_duration == 0) ? TEMPSUMMON_DEAD_DESPAWN : TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN; for (CreatureSummonPositions::iterator itr = list.begin(); itr != list.end(); ++itr) if (Creature* summon = m_caster->SummonCreature(creature_entry, itr->x, itr->y, itr->z, m_caster->GetOrientation(), summonType, m_duration)) @@ -5156,7 +5204,7 @@ bool Spell::DoSummonCritter(CreatureSummonPositions& list, SummonPropertiesEntry // itr! list[0].creature = critter; - critter->SetSummonPoint(pos); + critter->SetRespawnCoord(pos); // critter->SetName(""); // generated by client critter->SetOwnerGuid(m_caster->GetObjectGuid()); @@ -5164,7 +5212,6 @@ bool Spell::DoSummonCritter(CreatureSummonPositions& list, SummonPropertiesEntry critter->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); - critter->InitPetCreateSpells(); // e.g. disgusting oozeling has a create spell as critter... // critter->InitLevelupSpellsForLevel(); // none? critter->SelectLevel(critter->GetCreatureInfo()); // some summoned creaters have different from 1 DB data for level/hp @@ -5230,7 +5277,7 @@ bool Spell::DoSummonGuardian(CreatureSummonPositions& list, SummonPropertiesEntr itr->creature = spawnCreature; - spawnCreature->SetSummonPoint(pos); + spawnCreature->SetRespawnCoord(pos); if (m_duration > 0) spawnCreature->SetDuration(m_duration); @@ -5284,7 +5331,7 @@ bool Spell::DoSummonTotem(SpellEffectEntry const* effect, uint8 slot_dbc) return false; } - pTotem->SetSummonPoint(pos); + pTotem->SetRespawnCoord(pos); if (slot < MAX_TOTEM_SLOT) m_caster->_AddTotem(TotemSlot(slot), pTotem); @@ -5357,7 +5404,7 @@ bool Spell::DoSummonPossessed(CreatureSummonPositions& list, SummonPropertiesEnt spawnCreature->SetLevel(level); - spawnCreature->SetWalk(m_caster->IsWalking()); + spawnCreature->SetWalk(m_caster->IsWalking(), true); // TODO: Set Fly (ie glyph dependend) // Internal changes @@ -5433,7 +5480,7 @@ bool Spell::DoSummonPet(SpellEffectEntry const* effect) return false; } - spawnCreature->SetSummonPoint(pos); + spawnCreature->SetRespawnCoord(pos); // set timer for unsummon if (m_duration > 0) @@ -5480,6 +5527,55 @@ bool Spell::DoSummonPet(SpellEffectEntry const* effect) return false; } +bool Spell::DoSummonVehicle(CreatureSummonPositions& list, SummonPropertiesEntry const* prop, SpellEffectEntry const * effect, uint32 /*level*/) +{ + MANGOS_ASSERT(!list.empty() && prop); + + uint32 creatureEntry = effect->EffectMiscValue; + CreatureInfo const* cInfo = ObjectMgr::GetCreatureTemplate(creatureEntry); + if (!cInfo) + { + sLog.outErrorDb("Spell::DoSummonVehicle: creature entry %u not found for spell %u.", creatureEntry, m_spellInfo->Id); + return false; + } + + Creature* spawnCreature = m_caster->SummonCreature(creatureEntry, list[0].x, list[0].y, list[0].z, m_caster->GetOrientation(), + (m_duration == 0) ? TEMPSUMMON_CORPSE_DESPAWN : TEMPSUMMON_TIMED_OOC_OR_CORPSE_DESPAWN, m_duration); + + if (!spawnCreature) + { + sLog.outError("Spell::DoSummonVehicle: creature entry %u for spell %u could not be summoned.", creatureEntry, m_spellInfo->Id); + return false; + } + + list[0].creature = spawnCreature; + + // Changes to be sent + spawnCreature->SetCreatorGuid(m_caster->GetObjectGuid()); + spawnCreature->SetUInt32Value(UNIT_CREATED_BY_SPELL, m_spellInfo->Id); + //spawnCreature->SetLevel(level); // Do we need to set level for vehicles? + + // Board the caster right after summoning + SpellEntry const* controlSpellEntry = sSpellStore.LookupEntry(effect->CalculateSimpleValue()); + if (controlSpellEntry && IsSpellHaveAura(controlSpellEntry, SPELL_AURA_CONTROL_VEHICLE)) + m_caster->CastSpell(spawnCreature, controlSpellEntry, true); + else + m_caster->CastSpell(spawnCreature, SPELL_RIDE_VEHICLE_HARDCODED, true); + + // If the boarding failed... + if (!spawnCreature->HasAuraType(SPELL_AURA_CONTROL_VEHICLE)) + { + spawnCreature->ForcedDespawn(); + return false; + } + + // Notify Summoner + if (m_originalCaster && m_originalCaster != m_caster && m_originalCaster->GetTypeId() == TYPEID_UNIT && ((Creature*)m_originalCaster)->AI()) + ((Creature*)m_originalCaster)->AI()->JustSummoned(spawnCreature); + + return true; +} + void Spell::EffectLearnSpell(SpellEffectEntry const* effect) { if (!unitTarget) @@ -5727,7 +5823,7 @@ void Spell::EffectTeleUnitsFaceCaster(SpellEffectEntry const* effect) m_targets.getDestination(fx, fy, fz); else { - float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(effect->EffectRadiusIndex)); + float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(effect->GetRadiusIndex())); m_caster->GetClosePoint(fx, fy, fz, unitTarget->GetObjectBoundingRadius(), dis); } @@ -6152,7 +6248,7 @@ void Spell::EffectSummonPet(SpellEffectEntry const* effect) return; } - NewSummon->SetSummonPoint(pos); + NewSummon->SetRespawnCoord(pos); uint32 petlevel = m_caster->getLevel(); NewSummon->setPetType(SUMMON_PET); @@ -7016,7 +7112,7 @@ void Spell::EffectScriptEffect(SpellEffectEntry const* effect) for (uint8 i = 0; i < 4; ++i) { unitTarget->GetNearPoint(unitTarget, x, y, z, unitTarget->GetObjectBoundingRadius(), 5.0f, angle + i * M_PI_F / 2); - unitTarget->SummonCreature(16119, x, y, z, angle, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 10 * MINUTE * IN_MILLISECONDS); + unitTarget->SummonCreature(16119, x, y, z, angle, TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN, 10 * MINUTE * IN_MILLISECONDS); } return; } @@ -7087,7 +7183,7 @@ void Spell::EffectScriptEffect(SpellEffectEntry const* effect) creature_id = 17039; if (WorldObject* pSource = GetAffectiveCasterObject()) - pSource->SummonCreature(creature_id, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 120 * IN_MILLISECONDS); + pSource->SummonCreature(creature_id, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN, 120 * IN_MILLISECONDS); return; } case 29830: // Mirren's Drinking Hat @@ -7111,6 +7207,14 @@ void Spell::EffectScriptEffect(SpellEffectEntry const* effect) break; } + case 30541: // Blaze + { + if (!unitTarget) + return; + + unitTarget->CastSpell(unitTarget, 30542, true); + break; + } case 30769: // Pick Red Riding Hood { if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) @@ -7155,10 +7259,18 @@ void Spell::EffectScriptEffect(SpellEffectEntry const* effect) for (uint8 i = 0; i < 4; ++i) { m_caster->GetNearPoint(m_caster, x, y, z, 0, 5.0f, M_PI_F * .5f * i + M_PI_F * .25f); - m_caster->SummonCreature(21002, x, y, z, 0, TEMPSUMMON_TIMED_OR_DEAD_DESPAWN, 30000); + m_caster->SummonCreature(21002, x, y, z, 0, TEMPSUMMON_TIMED_OOC_OR_DEAD_DESPAWN, 30000); } return; } + case 37431: // Spout + { + if (!unitTarget) + return; + + unitTarget->CastSpell(unitTarget, urand(0, 1) ? 37429 : 37430, true); + return; + } case 38358: // Tidal Surge { if (!unitTarget) @@ -7475,7 +7587,7 @@ void Spell::EffectScriptEffect(SpellEffectEntry const* effect) // "escort" aura not present, so let nothing happen if (!m_caster->HasAura(effect->CalculateSimpleValue())) return; - // "escort" aura is present so break; and let DB table spell_scripts be used and process further. + // "escort" aura is present so break; and let DB table dbscripts_on_spell be used and process further. else break; } @@ -7495,12 +7607,12 @@ void Spell::EffectScriptEffect(SpellEffectEntry const* effect) unitTarget->CastSpell(unitTarget, spellId, true); break; } - case 46642: //5,000 Gold + case 46642: // 5,000 Gold { if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) return; - ((Player*)unitTarget)->ModifyMoney(50000000); + ((Player*)unitTarget)->ModifyMoney(5000 * GOLD); break; } case 47097: // Surge Needle Teleporter @@ -7862,6 +7974,17 @@ void Spell::EffectScriptEffect(SpellEffectEntry const* effect) m_caster->CastSpell(m_caster, 51864, true); return; } + case 51904: // Summon Ghouls On Scarlet Crusade + { + if (!unitTarget) + return; + + // cast Summon Ghouls On Scarlet Crusade + float x, y, z; + m_targets.getDestination(x, y, z); + unitTarget->CastSpell(x, y, z, 54522, true, NULL, NULL, m_originalCasterGUID); + return; + } case 51910: // Kickin' Nass: Quest Completion { if (m_caster->GetTypeId() != TYPEID_PLAYER) @@ -7875,6 +7998,58 @@ void Spell::EffectScriptEffect(SpellEffectEntry const* effect) } return; } + case 52479: // Gift of the Harvester + { + if (m_caster->GetTypeId() != TYPEID_PLAYER || !unitTarget) + return; + + // Each ghoul casts 52500 onto player, so use number of auras as check + Unit::SpellAuraHolderConstBounds bounds = m_caster->GetSpellAuraHolderBounds(52500); + uint32 summonedGhouls = std::distance(bounds.first, bounds.second); + + m_caster->CastSpell(unitTarget->GetPositionX(), unitTarget->GetPositionY(), unitTarget->GetPositionZ(), urand(0, 2) || summonedGhouls >= 5 ? 52505 : 52490, true); + return; + } + case 52555: // Dispel Scarlet Ghoul Credit Counter + { + if (!unitTarget) + return; + + unitTarget->RemoveAurasByCasterSpell(effect->CalculateSimpleValue(), m_caster->GetObjectGuid()); + return; + } + case 52694: // Recall Eye of Acherus + { + if (!m_caster || m_caster->GetTypeId() != TYPEID_UNIT) + return; + + Unit* charmer = m_caster->GetCharmer(); + if (!charmer || charmer->GetTypeId() != TYPEID_PLAYER) + return; + + charmer->RemoveAurasDueToSpell(51923); + + // HACK ALERT + // Replace with Spell Interrupting, when casting spells properly is possible in mangos + //charmer->InterruptNonMeleeSpells(true); + + Player* player = (Player*)charmer; + Creature* possessed = (Creature*)m_caster; + player->RemoveAurasDueToSpell(51852); + + player->SetCharm(NULL); + player->SetClientControl(possessed, 0); + player->SetMover(NULL); + player->GetCamera().ResetView(); + player->RemovePetActionBar(); + + possessed->clearUnitState(UNIT_STAT_CONTROLLED); + possessed->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PLAYER_CONTROLLED); + possessed->SetCharmerGuid(ObjectGuid()); + possessed->ForcedDespawn(); + + return; + } case 52751: // Death Gate { if (!unitTarget || unitTarget->getClass() != CLASS_DEATH_KNIGHT) @@ -8258,6 +8433,14 @@ void Spell::EffectScriptEffect(SpellEffectEntry const* effect) return; } + case 74455: // Conflagration + { + if (!unitTarget) + return; + + unitTarget->CastSpell(m_caster, effect->CalculateSimpleValue(), true); + return; + } } break; } @@ -8857,7 +9040,7 @@ void Spell::EffectApplyGlyph(SpellEffectEntry const* effect) Player* player = (Player*)m_caster; - // glyph sockets level requirement + // glyph sockets level requirement uint8 minLevel = 0; switch (m_glyphIndex) { @@ -9150,7 +9333,7 @@ void Spell::EffectLeapForward(SpellEffectEntry const* effect) if (m_spellInfo->rangeIndex == 1) // self range { - float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(effect->EffectRadiusIndex)); + float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(effect->GetRadiusIndex())); // before caster float fx, fy, fz; @@ -9158,7 +9341,7 @@ void Spell::EffectLeapForward(SpellEffectEntry const* effect) float ox, oy, oz; unitTarget->GetPosition(ox, oy, oz); - if (unitTarget->GetMap()->GetObjectHitPos(ox, oy, oz + 0.5f, fx, fy, oz + 0.5f, fx, fy, fz, -0.5f)) + if (unitTarget->GetMap()->GetHitPosition(ox, oy, oz + 0.5f, fx, fy, fz, unitTarget->GetPhaseMask(), -0.5f)) unitTarget->UpdateAllowedPositionZ(fx, fy, fz); unitTarget->NearTeleportTo(fx, fy, fz, unitTarget->GetOrientation(), unitTarget == m_caster); @@ -9287,7 +9470,7 @@ void Spell::EffectCharge(SpellEffectEntry const* /*effect*/) return; // TODO: research more ContactPoint/attack distance. - //3.666666 instead of ATTACK_DISTANCE(5.0f) in below seem to give more accurate result. + // 3.666666 instead of ATTACK_DISTANCE(5.0f) in below seem to give more accurate result. float x, y, z; unitTarget->GetContactPoint(m_caster, x, y, z, 3.666666f); @@ -9525,9 +9708,9 @@ void Spell::EffectTransmitted(SpellEffectEntry const* effect) if (m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION) m_targets.getDestination(fx, fy, fz); // FIXME: this can be better check for most objects but still hack - else if (effect->EffectRadiusIndex && m_spellInfo->speed == 0) + else if (effect->GetRadiusIndex() && m_spellInfo->speed == 0) { - float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(effect->EffectRadiusIndex)); + float dis = GetSpellRadius(sSpellRadiusStore.LookupEntry(effect->GetRadiusIndex())); m_caster->GetClosePoint(fx, fy, fz, DEFAULT_WORLD_OBJECT_SIZE, dis); } else @@ -9568,7 +9751,6 @@ void Spell::EffectTransmitted(SpellEffectEntry const* effect) Map* cMap = m_caster->GetMap(); - // if gameobject is summoning object, it should be spawned right on caster's position if (goinfo->type == GAMEOBJECT_TYPE_SUMMONING_RITUAL) { @@ -9780,6 +9962,81 @@ void Spell::EffectStealBeneficialBuff(SpellEffectEntry const* effect) } } +void Spell::EffectWMODamage(SpellEffectEntry const* effect) +{ + DEBUG_LOG("Effect: WMODamage"); + + if (!gameObjTarget || gameObjTarget->GetGoType() != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING) + { + sLog.outError("Spell::EffectWMODamage called without valid targets. Spell Id %u", m_spellInfo->Id); + return; + } + + if (!gameObjTarget->GetHealth()) + return; + + Unit* caster = GetAffectiveCaster(); + if (!caster) + return; + + DEBUG_LOG("Spell::EffectWMODamage, spell Id %u, go entry %u, damage %u", m_spellInfo->Id, gameObjTarget->GetEntry(), uint32(damage)); + gameObjTarget->DealGameObjectDamage(uint32(damage), m_spellInfo->Id, caster); +} + +void Spell::EffectWMORepair(SpellEffectEntry const* effect) +{ + DEBUG_LOG("Effect: WMORepair"); + + if (!gameObjTarget || gameObjTarget->GetGoType() != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING) + { + sLog.outError("Spell::EffectWMORepair called without valid targets. Spell Id %u", m_spellInfo->Id); + return; + } + + Unit* caster = GetAffectiveCaster(); + if (!caster) + return; + + DEBUG_LOG("Spell::EffectWMORepair, spell Id %u, go entry %u", m_spellInfo->Id, gameObjTarget->GetEntry()); + gameObjTarget->RebuildGameObject(m_spellInfo->Id, caster); +} + +void Spell::EffectWMOChange(SpellEffectEntry const* effect) +{ + DEBUG_LOG("Effect: WMOChange"); + + if (!gameObjTarget || gameObjTarget->GetGoType() != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING) + { + sLog.outError("Spell::EffectWMOChange called without valid targets. Spell Id %u", m_spellInfo->Id); + return; + } + + DEBUG_LOG("Spell::EffectWMOChange, spell Id %u, object %u, misc-value %u", m_spellInfo->Id,gameObjTarget->GetEntry(), effect->EffectMiscValue); + + Unit* caster = GetAffectiveCaster(); + if (!caster) + return; + + switch (effect->EffectMiscValue) + { + case 0: // Set to full health + gameObjTarget->ForceGameObjectHealth(gameObjTarget->GetMaxHealth(), caster); + break; + case 1: // Set to damaged + gameObjTarget->ForceGameObjectHealth(gameObjTarget->GetGOInfo()->destructibleBuilding.damagedNumHits, caster); + break; + case 2: // Set to destroyed + gameObjTarget->ForceGameObjectHealth(-int32(gameObjTarget->GetHealth()), caster); + break; + case 3: // Set to rebuilding + gameObjTarget->ForceGameObjectHealth(0, caster); + break; + default: + sLog.outError("Spell::EffectWMOChange, spell Id %u with undefined change value %u", m_spellInfo->Id,effect->EffectMiscValue); + break; + } +} + void Spell::EffectKillCreditPersonal(SpellEffectEntry const* effect) { if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER) @@ -9871,6 +10128,7 @@ void Spell::EffectPlayMusic(SpellEffectEntry const* effect) WorldPacket data(SMSG_PLAY_MUSIC, 4); data << uint32(soundId); + data << ObjectGuid(); ((Player*)unitTarget)->GetSession()->SendPacket(&data); } @@ -10048,7 +10306,7 @@ void Spell::EffectKnockBackFromPosition(SpellEffectEntry const* effect) else m_caster->GetPosition(x, y, z); - float angle = unitTarget->GetAngle(x,y) + M_PI_F; + float angle = unitTarget->GetAngle(x, y) + M_PI_F; float horizontalSpeed = effect->EffectMiscValue * 0.1f; float verticalSpeed = damage * 0.1f; unitTarget->KnockBackWithAngle(angle, horizontalSpeed, verticalSpeed); diff --git a/src/shared/revision_nr.h b/src/shared/revision_nr.h index 7b4c04b7f..450cb11be 100644 --- a/src/shared/revision_nr.h +++ b/src/shared/revision_nr.h @@ -1,4 +1,4 @@ #ifndef __REVISION_NR_H__ #define __REVISION_NR_H__ - #define REVISION_NR "12222" + #define REVISION_NR "12527" #endif // __REVISION_NR_H__