Skip to content

Commit

Permalink
Scripts/Icecrown Citadel:
Browse files Browse the repository at this point in the history
* Fixed Coldflame dealing double damage
* Targets hit by Bone Slice will now be immune to Bone Spike Graveyard
* Fixed healing players on Bone Spike

Closes #1091
Closes #4473
Closes #5854
Closes #7060
  • Loading branch information
Shauren committed Feb 1, 2013
1 parent 957375c commit 817f5b3
Show file tree
Hide file tree
Showing 4 changed files with 182 additions and 50 deletions.
4 changes: 4 additions & 0 deletions sql/updates/world/2013_02_01_02_world_spell_script_names.sql
Original file line number Original file line Diff line number Diff line change
@@ -0,0 +1,4 @@
DELETE FROM `spell_script_names` WHERE `ScriptName`='spell_marrowgar_bone_slice';
INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES
(69055,'spell_marrowgar_bone_slice'),
(70814,'spell_marrowgar_bone_slice');
18 changes: 0 additions & 18 deletions src/server/game/Spells/SpellEffects.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -3212,24 +3212,6 @@ void Spell::EffectWeaponDmg(SpellEffIndex effIndex)


switch (m_spellInfo->SpellFamilyName) switch (m_spellInfo->SpellFamilyName)
{ {
case SPELLFAMILY_GENERIC:
{
switch (m_spellInfo->Id)
{
case 69055: // Saber Lash
case 70814: // Saber Lash
{
uint32 count = 0;
for (std::list<TargetInfo>::iterator ihit = m_UniqueTargetInfo.begin(); ihit != m_UniqueTargetInfo.end(); ++ihit)
if (ihit->effectMask & (1 << effIndex))
++count;

totalDamagePercentMod /= count;
break;
}
}
break;
}
case SPELLFAMILY_WARRIOR: case SPELLFAMILY_WARRIOR:
{ {
// Devastate (player ones) // Devastate (player ones)
Expand Down
6 changes: 3 additions & 3 deletions src/server/game/Spells/SpellMgr.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -3397,9 +3397,9 @@ void SpellMgr::LoadDbcDataCorrections()
case 70861: // Sindragosa's Lair Teleport case 70861: // Sindragosa's Lair Teleport
spellInfo->EffectImplicitTargetA[0] = TARGET_DEST_DB; spellInfo->EffectImplicitTargetA[0] = TARGET_DEST_DB;
break; break;
case 69055: // Saber Lash (Lord Marrowgar) case 69055: // Bone Slice (Lord Marrowgar)
case 70814: // Saber Lash (Lord Marrowgar) case 70814: // Bone Slice (Lord Marrowgar)
spellInfo->EffectRadiusIndex[0] = EFFECT_RADIUS_5_YARDS; // 5yd spellInfo->EffectRadiusIndex[0] = EFFECT_RADIUS_8_YARDS; // 5yd

This comment has been minimized.

Copy link
@HolyRoses

HolyRoses Feb 1, 2013

shouldn't that be // 8yd ?

break; break;
case 69075: // Bone Storm (Lord Marrowgar) case 69075: // Bone Storm (Lord Marrowgar)
case 70834: // Bone Storm (Lord Marrowgar) case 70834: // Bone Storm (Lord Marrowgar)
Expand Down
204 changes: 175 additions & 29 deletions src/server/scripts/Northrend/IcecrownCitadel/boss_lord_marrowgar.cpp
Original file line number Original file line Diff line number Diff line change
Expand Up @@ -20,8 +20,9 @@
#include "ScriptedCreature.h" #include "ScriptedCreature.h"
#include "SpellAuras.h" #include "SpellAuras.h"
#include "MapManager.h" #include "MapManager.h"
#include "icecrown_citadel.h" #include "MoveSplineInit.h"
#include "Player.h" #include "Player.h"
#include "icecrown_citadel.h"


enum ScriptTexts enum ScriptTexts
{ {
Expand Down Expand Up @@ -78,7 +79,46 @@ enum MovementPoints
POINT_TARGET_COLDFLAME = 36672631, POINT_TARGET_COLDFLAME = 36672631,
}; };


#define DATA_COLDFLAME_GUID 0 enum MiscInfo
{
DATA_COLDFLAME_GUID = 0,

// Manual marking for targets hit by Bone Slice as no aura exists for this purpose
// These units are the tanks in this encounter
// and should be immune to Bone Spike Graveyard
DATA_SPIKE_IMMUNE = 1,
//DATA_SPIKE_IMMUNE_1, = 2, // Reserved & used
//DATA_SPIKE_IMMUNE_2, = 3, // Reserved & used

ACTION_CLEAR_SPIKE_IMMUNITIES = 1,

MAX_BONE_SPIKE_IMMUNE = 3,
};

class BoneSpikeTargetSelector : public std::unary_function<Unit*, bool>
{
public:
BoneSpikeTargetSelector(UnitAI* ai) : _ai(ai) { }

bool operator()(Unit* unit) const
{
if (unit->GetTypeId() != TYPEID_PLAYER)
return false;

if (unit->HasAura(SPELL_IMPALED))
return false;

// Check if it is one of the tanks soaking Bone Slice
for (uint32 i = 0; i < MAX_BONE_SPIKE_IMMUNE; ++i)
if (unit->GetGUID() == _ai->GetGUID(DATA_SPIKE_IMMUNE + i))
return false;

return true;
}

private:
UnitAI* _ai;
};


class boss_lord_marrowgar : public CreatureScript class boss_lord_marrowgar : public CreatureScript
{ {
Expand Down Expand Up @@ -108,6 +148,7 @@ class boss_lord_marrowgar : public CreatureScript
events.ScheduleEvent(EVENT_WARN_BONE_STORM, urand(45000, 50000)); events.ScheduleEvent(EVENT_WARN_BONE_STORM, urand(45000, 50000));
events.ScheduleEvent(EVENT_ENRAGE, 600000); events.ScheduleEvent(EVENT_ENRAGE, 600000);
_boneSlice = false; _boneSlice = false;
_boneSpikeImmune.clear();
} }


void EnterCombat(Unit* /*who*/) void EnterCombat(Unit* /*who*/)
Expand Down Expand Up @@ -205,7 +246,7 @@ class boss_lord_marrowgar : public CreatureScript
case EVENT_BONE_STORM_END: case EVENT_BONE_STORM_END:
if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE) if (me->GetMotionMaster()->GetCurrentMovementGeneratorType() == POINT_MOTION_TYPE)
me->GetMotionMaster()->MovementExpired(); me->GetMotionMaster()->MovementExpired();
DoStartMovement(me->getVictim()); me->GetMotionMaster()->MoveChase(me->getVictim());
me->SetSpeed(MOVE_RUN, _baseSpeed, true); me->SetSpeed(MOVE_RUN, _baseSpeed, true);
events.CancelEvent(EVENT_BONE_STORM_MOVE); events.CancelEvent(EVENT_BONE_STORM_MOVE);
events.ScheduleEvent(EVENT_ENABLE_BONE_SLICE, 10000); events.ScheduleEvent(EVENT_ENABLE_BONE_SLICE, 10000);
Expand Down Expand Up @@ -239,31 +280,59 @@ class boss_lord_marrowgar : public CreatureScript
return; return;


// lock movement // lock movement
DoStartNoMovement(me->getVictim()); me->GetMotionMaster()->MoveIdle();
} }


Position const* GetLastColdflamePosition() const Position const* GetLastColdflamePosition() const
{ {
return &_coldflameLastPos; return &_coldflameLastPos;
} }


uint64 GetGUID(int32 type/* = 0 */) const uint64 GetGUID(int32 type /*= 0 */) const
{ {
if (type == DATA_COLDFLAME_GUID) switch (type)
return _coldflameTarget; {
case DATA_COLDFLAME_GUID:
return _coldflameTarget;
case DATA_SPIKE_IMMUNE + 0:
case DATA_SPIKE_IMMUNE + 1:
case DATA_SPIKE_IMMUNE + 2:
{
int32 index = type - DATA_SPIKE_IMMUNE;
if (index < _boneSpikeImmune.size())
return _boneSpikeImmune[index];

break;
}
}

return 0LL; return 0LL;
} }


void SetGUID(uint64 guid, int32 type/* = 0 */) void SetGUID(uint64 guid, int32 type /*= 0 */)
{
switch (type)
{
case DATA_COLDFLAME_GUID:
_coldflameTarget = guid;
break;
case DATA_SPIKE_IMMUNE:
_boneSpikeImmune.push_back(guid);
break;
}
}

void DoAction(int32 const action)
{ {
if (type != DATA_COLDFLAME_GUID) if (action != ACTION_CLEAR_SPIKE_IMMUNITIES)
return; return;


_coldflameTarget = guid; _boneSpikeImmune.clear();
} }


private: private:
Position _coldflameLastPos; Position _coldflameLastPos;
std::vector<uint64> _boneSpikeImmune;
uint64 _coldflameTarget; uint64 _coldflameTarget;
uint32 _boneStormDuration; uint32 _boneStormDuration;
float _baseSpeed; float _baseSpeed;
Expand Down Expand Up @@ -323,7 +392,7 @@ class npc_coldflame : public CreatureScript
} }


me->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), me->GetPositionZ(), me->GetOrientation()); me->NearTeleportTo(pos.GetPositionX(), pos.GetPositionY(), me->GetPositionZ(), me->GetOrientation());
_events.ScheduleEvent(EVENT_COLDFLAME_TRIGGER, 450); _events.ScheduleEvent(EVENT_COLDFLAME_TRIGGER, 500);
} }


void UpdateAI(uint32 const diff) void UpdateAI(uint32 const diff)
Expand All @@ -333,10 +402,10 @@ class npc_coldflame : public CreatureScript
if (_events.ExecuteEvent() == EVENT_COLDFLAME_TRIGGER) if (_events.ExecuteEvent() == EVENT_COLDFLAME_TRIGGER)
{ {
Position newPos; Position newPos;
me->GetNearPosition(newPos, 5.5f, 0.0f); me->GetNearPosition(newPos, 5.0f, 0.0f);
me->NearTeleportTo(newPos.GetPositionX(), newPos.GetPositionY(), me->GetPositionZ(), me->GetOrientation()); me->NearTeleportTo(newPos.GetPositionX(), newPos.GetPositionY(), me->GetPositionZ(), me->GetOrientation());
DoCast(SPELL_COLDFLAME_SUMMON); DoCast(SPELL_COLDFLAME_SUMMON);
_events.ScheduleEvent(EVENT_COLDFLAME_TRIGGER, 450); _events.ScheduleEvent(EVENT_COLDFLAME_TRIGGER, 500);
} }
} }


Expand Down Expand Up @@ -385,6 +454,24 @@ class npc_bone_spike : public CreatureScript
_hasTrappedUnit = true; _hasTrappedUnit = true;
} }


void PassengerBoarded(Unit* passenger, int8 /*seat*/, bool apply)
{
if (!apply)
return;

/// @HACK - Change passenger offset to the one taken directly from sniffs
/// Remove this when proper calculations are implemented.
/// This fixes healing spiked people
Movement::MoveSplineInit init(passenger);
init.DisableTransportPathTransformations();
init.MoveTo(-0.02206125f, -0.02132235f, 5.514783f, false);
init.Launch();

/// @WORKAROUND - Clear ON VEHICLE state to allow healing (Invalid target errors)
/// Current rule for applying this state is questionable (seatFlags & VEHICLE_SEAT_FLAG_ALLOW_TURNING ???)
passenger->ClearUnitState(UNIT_STATE_ONVEHICLE);
}

void UpdateAI(uint32 const diff) void UpdateAI(uint32 const diff)
{ {
if (!_hasTrappedUnit) if (!_hasTrappedUnit)
Expand Down Expand Up @@ -487,16 +574,24 @@ class spell_marrowgar_coldflame_damage : public SpellScriptLoader
{ {
PrepareAuraScript(spell_marrowgar_coldflame_damage_AuraScript); PrepareAuraScript(spell_marrowgar_coldflame_damage_AuraScript);


void OnPeriodic(AuraEffect const* /*aurEff*/) bool CanBeAppliedOn(Unit* target)
{ {
if (DynamicObject* owner = GetDynobjOwner()) if (target->HasAura(SPELL_IMPALED))
if (GetTarget()->GetExactDist2d(owner) >= owner->GetRadius() || GetTarget()->HasAura(SPELL_IMPALED)) return false;
PreventDefaultAction();
if (target->GetExactDist2d(GetOwner()) > GetSpellInfo()->Effects[EFFECT_0].CalcRadius())
return false;

if (Aura* aur = target->GetAura(GetId()))
if (aur->GetOwner() != GetOwner())
return false;

return true;
} }


void Register() void Register()
{ {
OnEffectPeriodic += AuraEffectPeriodicFn(spell_marrowgar_coldflame_damage_AuraScript::OnPeriodic, EFFECT_0, SPELL_AURA_PERIODIC_DAMAGE); DoCheckAreaTarget += AuraCheckAreaTargetFn(spell_marrowgar_coldflame_damage_AuraScript::CanBeAppliedOn);
} }
}; };


Expand Down Expand Up @@ -531,30 +626,30 @@ class spell_marrowgar_bone_spike_graveyard : public SpellScriptLoader


SpellCastResult CheckCast() SpellCastResult CheckCast()
{ {
return GetCaster()->GetAI()->SelectTarget(SELECT_TARGET_TOPAGGRO, 1, 0.0f, true, -SPELL_IMPALED) ? SPELL_CAST_OK : SPELL_FAILED_NO_VALID_TARGETS; return GetCaster()->GetAI()->SelectTarget(SELECT_TARGET_RANDOM, 0, BoneSpikeTargetSelector(GetCaster()->GetAI())) ? SPELL_CAST_OK : SPELL_FAILED_NO_VALID_TARGETS;
} }


void HandleSpikes(SpellEffIndex effIndex) void HandleSpikes(SpellEffIndex effIndex)
{ {
PreventHitDefaultEffect(effIndex); PreventHitDefaultEffect(effIndex);
if (Creature* marrowgar = GetCaster()->ToCreature()) if (Creature* marrowgar = GetCaster()->ToCreature())
{ {
bool didHit = false;
CreatureAI* marrowgarAI = marrowgar->AI(); CreatureAI* marrowgarAI = marrowgar->AI();
uint8 boneSpikeCount = uint8(GetCaster()->GetMap()->GetSpawnMode() & 1 ? 3 : 1); uint8 boneSpikeCount = uint8(GetCaster()->GetMap()->GetSpawnMode() & 1 ? 3 : 1);
for (uint8 i = 0; i < boneSpikeCount; ++i)
{
// select any unit but not the tank
Unit* target = marrowgarAI->SelectTarget(SELECT_TARGET_RANDOM, 1, 150.0f, true, -SPELL_IMPALED);
if (!target)
break;


didHit = true; std::list<Unit*> targets;
marrowgarAI->SelectTargetList(targets, BoneSpikeTargetSelector(marrowgarAI), boneSpikeCount, SELECT_TARGET_RANDOM);
if (targets.empty())
return;

uint32 i = 0;
for (std::list<Unit*>::const_iterator itr = targets.begin(); itr != targets.end(); ++itr, ++i)
{
Unit* target = *itr;
target->CastCustomSpell(BoneSpikeSummonId[i], SPELLVALUE_BASE_POINT0, 0, target, true); target->CastCustomSpell(BoneSpikeSummonId[i], SPELLVALUE_BASE_POINT0, 0, target, true);
} }


if (didHit) marrowgarAI->Talk(SAY_BONESPIKE);
marrowgarAI->Talk(SAY_BONESPIKE);
} }
} }


Expand Down Expand Up @@ -597,6 +692,56 @@ class spell_marrowgar_bone_storm : public SpellScriptLoader
} }
}; };


class spell_marrowgar_bone_slice : public SpellScriptLoader
{
public:
spell_marrowgar_bone_slice() : SpellScriptLoader("spell_marrowgar_bone_slice") { }

class spell_marrowgar_bone_slice_SpellScript : public SpellScript
{
PrepareSpellScript(spell_marrowgar_bone_slice_SpellScript);

bool Load()
{
_targetCount = 0;
return true;
}

void ClearSpikeImmunities()
{
GetCaster()->GetAI()->DoAction(ACTION_CLEAR_SPIKE_IMMUNITIES);
}

void CountTarget(SpellEffIndex /*effIndex*/)
{
++_targetCount;
GetCaster()->GetAI()->SetGUID(GetHitUnit()->GetGUID(), DATA_SPIKE_IMMUNE);
}

void SplitDamage()
{
if (!_targetCount)
return; // why would there be an unit not hit by effect hook and hit by this?

This comment has been minimized.

Copy link
@Pesthuf

Pesthuf Feb 2, 2013

Contributor

why not place an assertion here then?


SetHitDamage(GetHitDamage() / _targetCount);
}

void Register()
{
BeforeCast += SpellCastFn(spell_marrowgar_bone_slice_SpellScript::ClearSpikeImmunities);
OnEffectLaunchTarget += SpellEffectFn(spell_marrowgar_bone_slice_SpellScript::CountTarget, EFFECT_0, SPELL_EFFECT_WEAPON_PERCENT_DAMAGE);
OnHit += SpellHitFn(spell_marrowgar_bone_slice_SpellScript::SplitDamage);
}

uint32 _targetCount;
};

SpellScript* GetSpellScript() const
{
return new spell_marrowgar_bone_slice_SpellScript();
}
};

void AddSC_boss_lord_marrowgar() void AddSC_boss_lord_marrowgar()
{ {
new boss_lord_marrowgar(); new boss_lord_marrowgar();
Expand All @@ -607,4 +752,5 @@ void AddSC_boss_lord_marrowgar()
new spell_marrowgar_coldflame_damage(); new spell_marrowgar_coldflame_damage();
new spell_marrowgar_bone_spike_graveyard(); new spell_marrowgar_bone_spike_graveyard();
new spell_marrowgar_bone_storm(); new spell_marrowgar_bone_storm();
new spell_marrowgar_bone_slice();
} }

6 comments on commit 817f5b3

@soulfrost
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good job man

@Metal69
Copy link

@Metal69 Metal69 commented on 817f5b3 Feb 1, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

good work!! thanks

@Lat89
Copy link

@Lat89 Lat89 commented on 817f5b3 Feb 1, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

awesome, tnx a lot

@2010phenix
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 thx

@Betaman2k
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi
nobody confirmed ?

@Betaman2k
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi
ok i confirmed now
core: 2976f94
WDB: Latest TDB
Patches: No

Validating spell scripts...
Spell 69146 of script spell_marrowgar_coldflame_damage does not have area aura effect - handler bound to hook DoCheckAreaTarget of AuraScript won't be executed
Spell 70823 of script spell_marrowgar_coldflame_damage does not have area aura effect - handler bound to hook DoCheckAreaTarget of AuraScript won't be executed
Spell 70824 of script spell_marrowgar_coldflame_damage does not have area aura effect - handler bound to hook DoCheckAreaTarget of AuraScript won't be executed
Spell 70825 of script spell_marrowgar_coldflame_damage does not have area aura effect - handler bound to hook DoCheckAreaTarget of AuraScript won't be executed

Validated 1332 scripts in 9 ms

i hope u can fixed

Please sign in to comment.