Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Scripts/Icecrown Citadel: Fixed Ice Bomb visual synchronization

Closes #5179
  • Loading branch information...
commit 33d5e7c753f484c33f7bbc017bbfc52549a12e30 1 parent 478427e
@Shauren Shauren authored
View
5 src/server/game/Spells/SpellMgr.cpp
@@ -3410,10 +3410,7 @@ void SpellMgr::LoadDbcDataCorrections()
spellInfo->EffectImplicitTargetA[0] = TARGET_DEST_CASTER;
break;
case 69846: // Frost Bomb
- spellInfo->speed = 10;
- spellInfo->EffectImplicitTargetA[0] = TARGET_DEST_TARGET_ANY;
- spellInfo->EffectImplicitTargetB[0] = TARGET_UNIT_TARGET_ANY;
- spellInfo->Effect[1] = 0;
+ spellInfo->speed = 0.0f; // This spell's summon happens instantly
break;
case 71614: // Ice Lock
spellInfo->Mechanic = MECHANIC_STUN;
View
59 src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
@@ -61,6 +61,7 @@ enum Spells
SPELL_ASPHYXIATION = 71665,
SPELL_FROST_BOMB_TRIGGER = 69846,
SPELL_FROST_BOMB_VISUAL = 70022,
+ SPELL_BIRTH_NO_VISUAL = 40031,
SPELL_FROST_BOMB = 69845,
SPELL_MYSTIC_BUFFET = 70128,
@@ -169,6 +170,23 @@ class FrostwyrmLandEvent : public BasicEvent
Position const& _dest;
};
+class FrostBombExplosion : public BasicEvent
+{
+ public:
+ FrostBombExplosion(Creature* owner, uint64 sindragosaGUID) : _owner(owner), _sindragosaGUID(sindragosaGUID) { }
+
+ bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/)
+ {
+ _owner->CastSpell((Unit*)NULL, SPELL_FROST_BOMB, true, NULL, NULL, _sindragosaGUID);
+ _owner->RemoveAurasDueToSpell(SPELL_FROST_BOMB_VISUAL);
+ return true;
+ }
+
+ private:
+ Creature* _owner;
+ uint64 _sindragosaGUID;
+};
+
class boss_sindragosa : public CreatureScript
{
public:
@@ -325,6 +343,12 @@ class boss_sindragosa : public CreatureScript
void JustSummoned(Creature* summon)
{
summons.Summon(summon);
+ if (summon->GetEntry() == NPC_FROST_BOMB)
+ {
+ summon->CastSpell(summon, SPELL_FROST_BOMB_VISUAL, true);
+ summon->CastSpell(summon, SPELL_BIRTH_NO_VISUAL, true);
+ summon->m_Events.AddEvent(new FrostBombExplosion(summon, me->GetGUID()), summon->m_Events.CalculateTime(5500));
+ }
}
void SummonedCreatureDespawn(Creature* summon)
@@ -337,18 +361,25 @@ class boss_sindragosa : public CreatureScript
void SpellHitTarget(Unit* target, SpellInfo const* spell)
{
if (uint32 spellId = sSpellMgr->GetSpellIdForDifficulty(70127, me))
+ {
if (spellId == spell->Id)
+ {
if (Aura const* mysticBuffet = target->GetAura(spell->Id))
_mysticBuffetStack = std::max<uint8>(_mysticBuffetStack, mysticBuffet->GetStackAmount());
+ return;
+ }
+ }
+
// Frost Infusion
if (Player* player = target->ToPlayer())
{
if (uint32 spellId = sSpellMgr->GetSpellIdForDifficulty(_isThirdPhase ? SPELL_FROST_BREATH_P2 : SPELL_FROST_BREATH_P1, me))
{
- if (player->GetQuestStatus(QUEST_FROST_INFUSION) == QUEST_STATUS_INCOMPLETE && spellId == spell->Id)
+ if (spellId == spell->Id)
{
- if (Item* shadowsEdge = player->GetWeaponForAttack(BASE_ATTACK, true))
+ Item* shadowsEdge = player->GetWeaponForAttack(BASE_ATTACK, true);
+ if (player->GetQuestStatus(QUEST_FROST_INFUSION) == QUEST_STATUS_INCOMPLETE && shadowsEdge)
{
if (!player->HasAura(SPELL_FROST_IMBUED_BLADE) && shadowsEdge->GetEntry() == ITEM_SHADOW_S_EDGE)
{
@@ -366,15 +397,11 @@ class boss_sindragosa : public CreatureScript
player->CastSpell(player, SPELL_FROST_INFUSION, true);
}
}
+
+ return;
}
}
}
-
- if (spell->Id == SPELL_FROST_BOMB_TRIGGER)
- {
- target->CastSpell(target, SPELL_FROST_BOMB, true);
- target->RemoveAurasDueToSpell(SPELL_FROST_BOMB_VISUAL);
- }
}
void UpdateAI(uint32 const diff)
@@ -458,21 +485,11 @@ class boss_sindragosa : public CreatureScript
case EVENT_FROST_BOMB:
{
float destX, destY, destZ;
- destX = float(rand_norm()) * 117.25f + 4339.25f;
- if (destX > 4371.5f && destX < 4432.0f)
- destY = float(rand_norm()) * 111.0f + 2429.0f;
- else
- destY = float(rand_norm()) * 31.23f + 2454.64f;
+ destX = float(rand_norm()) * 75.0f + 4350.0f;
+ destY = float(rand_norm()) * 75.0f + 2450.0f;
destZ = 205.0f; // random number close to ground, get exact in next call
me->UpdateGroundPositionZ(destX, destY, destZ);
- Position pos;
- pos.Relocate(destX, destY, destZ, 0.0f);
- if (TempSummon* summ = me->SummonCreature(NPC_FROST_BOMB, pos, TEMPSUMMON_TIMED_DESPAWN, 40000))
- {
- summ->CastSpell(summ, SPELL_FROST_BOMB_VISUAL, true);
- DoCast(summ, SPELL_FROST_BOMB_TRIGGER);
- //me->CastSpell(destX, destY, destZ, SPELL_FROST_BOMB_TRIGGER, false);
- }
+ me->CastSpell(destX, destY, destZ, SPELL_FROST_BOMB_TRIGGER, false);
events.ScheduleEvent(EVENT_FROST_BOMB, urand(5000, 10000));
break;
}

10 comments on commit 33d5e7c

@ille

Does this mean tc devs do not work on a general solution to use scriptdata from spellmissilemotion.dbc?

@Warpten
Collaborator

That requires an LUA engine to make it easily, but i've been trying to implement it before my hard drive died, using database data.

@Shauren: looks like using 6000 ms instead of 5500 causes less desync, except if the old spellInfo->Speed (10f) has an effect on that timer. i've been using it but left the old spellInfo dbc corrections.

@NorthStrider

why 6000ms ? ive tested the airphase 2 times A 5 bombs so 10 bombings and every bomb exploded perfectly timed

@Warpten
Collaborator

l2r.

@Warpten
Collaborator

To be more precise is used this:

diff --git a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
index d16666b..8a24553 100755
--- a/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
+++ b/src/server/scripts/Northrend/IcecrownCitadel/boss_sindragosa.cpp
@@ -169,6 +169,22 @@ class FrostwyrmLandEvent : public BasicEvent
         Position const& _dest;
 };

+class FrostBombTriggerEvent : public BasicEvent
+{
+    public:
+        FrostBombTriggerEvent(Creature& target) : _target(target) { }
+
+        bool Execute(uint64 /*eventTime*/, uint32 /*updateTime*/)
+        {
+            _target.CastSpell(&_target, SPELL_FROST_BOMB, true);
+            _target.RemoveAurasDueToSpell(SPELL_FROST_BOMB_VISUAL);
+            return true;
+        }
+
+    private:
+        Creature& _target;
+};
+
 class boss_sindragosa : public CreatureScript
 {
     public:
@@ -364,12 +380,6 @@ class boss_sindragosa : public CreatureScript
                         }
                     }
                 }
-
-                if (spell->Id == SPELL_FROST_BOMB_TRIGGER)
-                {
-                    target->CastSpell(target, SPELL_FROST_BOMB, true);
-                    target->RemoveAurasDueToSpell(SPELL_FROST_BOMB_VISUAL);
-                }
             }

             void UpdateAI(uint32 const diff)
@@ -467,6 +477,7 @@ class boss_sindragosa : public CreatureScript
                                 DoCast(summ, SPELL_FROST_BOMB_TRIGGER);
                                 //me->CastSpell(destX, destY, destZ, SPELL_FROST_BOMB_TRIGGER, false);
                             }
+
                             events.ScheduleEvent(EVENT_FROST_BOMB, urand(5000, 10000));
                             break;
                         }
@@ -586,6 +597,32 @@ class npc_ice_tomb : public CreatureScript
         }
 };

+class npc_frost_bomb : public CreatureScript
+{
+    public:
+        npc_frost_bomb() : CreatureScript("npc_frost_bomb") { }
+
+        struct npc_frost_bombAI : public ScriptedAI
+        {
+            npc_frost_bombAI(Creature* creature) : ScriptedAI(creature) { }
+
+            void SpellHit(Unit* target, const SpellInfo* spellInfo)
+            {
+                if (spellInfo->Id != SPELL_FROST_BOMB_VISUAL)
+                    return;
+
+                //! Client data suggests time should be 5.5 seconds,
+                //! But it seems like it's turned into 6 when used.
+                me->m_Events.AddEvent(new FrostBombTriggerEvent(*me), me->m_Events.CalculateTime(6000));
+            }
+        };
+
+        CreatureAI* GetAI(Creature* creature) const
+        {
+            return GetIcecrownCitadelAI<npc_frost_bombAI>(creature);
+        }
+};
+
 class npc_spinestalker : public CreatureScript
 {
     public:
@@ -1448,6 +1485,7 @@ void AddSC_boss_sindragosa()
 {
     new boss_sindragosa();
     new npc_ice_tomb();
+    new npc_frost_bomb();
     new npc_spinestalker();
     new npc_rimefang();
     new npc_sindragosa_trash();

but shauren's way works (and is prolly moar sniffwise), no doubt about it.

@Shauren
Owner

@Warpten: I replaced speed 10 with 0 because as seen on sniffs, the dummy summon happens instantly, then explodes 5.5 seconds later

@Warpten
Collaborator

kay. Sniff power > all. Waiting for the laptop ... :<

@ille

from spellmissilemotion: speedAbs = totalDistance/5.5
You think this speed is used only in client for visualization, or could it be that summoneffect is instant, the dummy effect takes speed from dbc ?

@Warpten
Collaborator

no its used on both sides. i had to use 6000 because i left the spellInfo->Speed attribute to 10 instead of turning it to 0, that caused some more delay on my side (and thats why i didnt pr my crap)

spellmissilemotion is used clientside for visual computations (pitch, etc), serverside for hit time (i guess). we at tc compute WHEN a missile hit WHEN ITS LAUNCHED, on retail they do it the other way (see the source of tc for more details)

@ille

@ warpten
looks like you triggered the event wit the spell, so it was distance dependent when the spell arrives, and so your eventtimer must increase/decrease with distance, only dont see why it goes over 5500
but that was not my question

How speed is computed in tc is clear, the blizzard way is the interesting way.
wanted to know tc devs thougts about how the data must be handle, shauren stated summoneffect is instant, that is obviously, but how the dummyeffect is handled? creating a event with timer is just a workaround

Please sign in to comment.
Something went wrong with that request. Please try again.