aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bindings/scripts/scripts/npc/npcs_special.cpp40
-rw-r--r--src/game/AggressorAI.h2
-rw-r--r--src/game/Pet.cpp10
-rw-r--r--src/game/Spell.cpp2
-rw-r--r--src/game/SpellAuras.cpp65
-rw-r--r--src/game/Unit.cpp7
-rw-r--r--src/game/Unit.h2
7 files changed, 104 insertions, 24 deletions
diff --git a/src/bindings/scripts/scripts/npc/npcs_special.cpp b/src/bindings/scripts/scripts/npc/npcs_special.cpp
index 9bf3113a9c6..655ab7b4ffd 100644
--- a/src/bindings/scripts/scripts/npc/npcs_special.cpp
+++ b/src/bindings/scripts/scripts/npc/npcs_special.cpp
@@ -1636,7 +1636,7 @@ CreatureAI* GetAI_mob_mojo(Creature *_Creature)
return new mob_mojoAI (_Creature);
}
-struct TRINITY_DLL_DECL npc_mirror_image : public SpellAI
+struct TRINITY_DLL_DECL npc_mirror_image : SpellAI
{
npc_mirror_image(Creature *c) : SpellAI(c) {}
@@ -1647,7 +1647,6 @@ struct TRINITY_DLL_DECL npc_mirror_image : public SpellAI
owner = ((TempSummon*)me)->GetOwner();
if (!owner)
return;
- me->SetDisplayId(owner->GetDisplayId());
owner->SetLevel(owner->getLevel());
// Inherit Master's Threat List (not yet implemented)
owner->CastSpell((Unit*)NULL, 58838, true);
@@ -1656,6 +1655,43 @@ struct TRINITY_DLL_DECL npc_mirror_image : public SpellAI
// Clone Me!
owner->CastSpell(me, 45204, false);
}
+
+ void EnterCombat(Unit *who)
+ {
+ if (spells.empty())
+ return;
+
+ uint32 spell = rand() % spells.size();
+ uint32 count = 0;
+ for(SpellVct::iterator itr = spells.begin(); itr != spells.end(); ++itr, ++count)
+ {
+ uint32 cooldown = GetAISpellInfo(*itr)->cooldown;
+ if (count == spell)
+ {
+ DoCast(spells[spell]);
+ cooldown += me->GetCurrentSpellCastTime(*itr);
+ }
+ events.ScheduleEvent(*itr, cooldown);
+ }
+ }
+
+ void UpdateAI(const uint32 diff)
+ {
+ if(!UpdateVictim())
+ return;
+
+ events.Update(diff);
+
+ if(me->hasUnitState(UNIT_STAT_CASTING))
+ return;
+
+ if(uint32 spellId = events.ExecuteEvent())
+ {
+ DoCast(spellId);
+ uint32 casttime = me->GetCurrentSpellCastTime(spellId);
+ events.ScheduleEvent(spellId, casttime ? casttime : 500 + GetAISpellInfo(spellId)->cooldown);
+ }
+ }
};
CreatureAI* GetAI_npc_mirror_image(Creature *_Creature)
diff --git a/src/game/AggressorAI.h b/src/game/AggressorAI.h
index 2c43ccf82b7..1b0f36da62e 100644
--- a/src/game/AggressorAI.h
+++ b/src/game/AggressorAI.h
@@ -48,7 +48,7 @@ class TRINITY_DLL_SPEC SpellAI : public CreatureAI
void JustDied(Unit *killer);
void UpdateAI(const uint32 diff);
static int Permissible(const Creature *);
- private:
+ protected:
EventMap events;
SpellVct spells;
};
diff --git a/src/game/Pet.cpp b/src/game/Pet.cpp
index 96e365c2251..704e0981413 100644
--- a/src/game/Pet.cpp
+++ b/src/game/Pet.cpp
@@ -928,6 +928,16 @@ bool Guardian::InitStatsForLevel(uint32 petlevel)
SetBaseWeaponDamage(BASE_ATTACK, MAXDAMAGE, float(petlevel * 4 + petlevel));
break;
}
+ case 31216: // Mirror Image
+ {
+ SetBonusDamage( int32(m_owner->SpellBaseDamageBonus(SPELL_SCHOOL_MASK_FROST) * 0.33f));
+ if(!pInfo)
+ {
+ SetCreateMana(28 + 30*petlevel);
+ SetCreateHealth(28 + 10*petlevel);
+ }
+ break;
+ }
default:
{
if(!pInfo)
diff --git a/src/game/Spell.cpp b/src/game/Spell.cpp
index e6af34e9429..f4e992b6a7b 100644
--- a/src/game/Spell.cpp
+++ b/src/game/Spell.cpp
@@ -1296,7 +1296,7 @@ SpellMissInfo Spell::DoSpellHitOnUnit(Unit *unit, const uint32 effectMask, bool
}
if( unit->isInCombat() && !(m_spellInfo->AttributesEx3 & SPELL_ATTR_EX3_NO_INITIAL_AGGRO) )
{
- m_caster->SetInCombatState(unit->GetCombatTimer() > 0);
+ m_caster->SetInCombatState(unit->GetCombatTimer() > 0, unit);
unit->getHostilRefManager().threatAssist(m_caster, 0.0f);
}
}
diff --git a/src/game/SpellAuras.cpp b/src/game/SpellAuras.cpp
index 7515126b6cd..a94b681ab0b 100644
--- a/src/game/SpellAuras.cpp
+++ b/src/game/SpellAuras.cpp
@@ -7514,38 +7514,63 @@ void AuraEffect::HandleReflectSpells( bool Apply, bool Real , bool /*changeAmoun
}
void AuraEffect::HandleAuraInitializeImages( bool Apply, bool Real , bool /*changeAmount*/)
{
- if (!Real || !Apply)
- return;
- Unit * caster = GetCaster();
- if (!caster)
+ if (!Real)
return;
- // Set item visual
- if (caster->GetTypeId()== TYPEID_PLAYER)
+ if (Apply)
{
- if (Item const * item = ((Player *)caster)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND))
- m_target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, item->GetProto()->ItemId);
- if (Item const * item = ((Player *)caster)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND))
- m_target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, item->GetProto()->ItemId);
+ Unit * caster = GetCaster();
+ if (!caster)
+ return;
+ // Set item visual
+ if (caster->GetTypeId()== TYPEID_PLAYER)
+ {
+ if (Item const * item = ((Player *)caster)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_MAINHAND))
+ m_target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, item->GetProto()->ItemId);
+ if (Item const * item = ((Player *)caster)->GetItemByPos(INVENTORY_SLOT_BAG_0, EQUIPMENT_SLOT_OFFHAND))
+ m_target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, item->GetProto()->ItemId);
+ }
+ else // TYPEID_UNIT
+ {
+ m_target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, caster->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID));
+ m_target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, caster->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1));
+ m_target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2, caster->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2));
+ }
}
else
{
- m_target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID, caster->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID));
- m_target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1, caster->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 1));
- m_target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2, caster->GetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + 2));
+ // Remove equipment visual
+ if (m_target->GetTypeId() == TYPEID_PLAYER)
+ {
+ for (uint8 i = 0; i < 3; ++i)
+ m_target->SetUInt32Value(UNIT_VIRTUAL_ITEM_SLOT_ID + i, 0);
+ }
+ else // TYPEID_UNIT
+ {
+ ((Creature*)m_target)->LoadEquipment(((Creature*)m_target)->GetEquipmentId());
+ }
}
}
void AuraEffect::HandleAuraCloneCaster( bool Apply, bool Real , bool /*changeAmount*/)
{
- if (!Real || !Apply)
- return;
- Unit * caster = GetCaster();
- if (!caster)
+ if (!Real)
return;
- // Set item visual
- m_target->SetDisplayId(caster->GetDisplayId());
- m_target->SetUInt32Value(UNIT_FIELD_FLAGS_2, 2064);
+ if (Apply)
+ {
+ Unit * caster = GetCaster();
+ if (!caster)
+ return;
+ // Set display id (probably for portrait?)
+ m_target->SetDisplayId(caster->GetDisplayId());
+ m_target->SetFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_MIRROR_IMAGE);
+ }
+ else
+ {
+ m_target->SetDisplayId(m_target->GetNativeDisplayId());
+ m_target->RemoveFlag(UNIT_FIELD_FLAGS_2, UNIT_FLAG2_MIRROR_IMAGE);
+ }
}
+
int32 AuraEffect::CalculateCrowdControlAuraAmount(Unit * caster)
{
// Damage cap for CC effects
diff --git a/src/game/Unit.cpp b/src/game/Unit.cpp
index 0990a7c3965..b10bc30edf2 100644
--- a/src/game/Unit.cpp
+++ b/src/game/Unit.cpp
@@ -3521,6 +3521,13 @@ Spell* Unit::FindCurrentSpellBySpellId(uint32 spell_id) const
return NULL;
}
+int32 Unit::GetCurrentSpellCastTime(uint32 spell_id) const
+{
+ if (Spell const * spell = FindCurrentSpellBySpellId(spell_id))
+ return spell->GetCastTime();
+ return 0;
+}
+
bool Unit::isInFrontInMap(Unit const* target, float distance, float arc) const
{
return IsWithinDistInMap(target, distance) && HasInArc( arc, target );
diff --git a/src/game/Unit.h b/src/game/Unit.h
index cad248c7489..3488c9b8f14 100644
--- a/src/game/Unit.h
+++ b/src/game/Unit.h
@@ -583,6 +583,7 @@ enum UnitFlags2
UNIT_FLAG2_FEIGN_DEATH = 0x00000001,
UNIT_FLAG2_UNK1 = 0x00000002, // Hide unit model (show only player equip)
UNIT_FLAG2_COMPREHEND_LANG = 0x00000008,
+ UNIT_FLAG2_MIRROR_IMAGE = 0x00000010,
UNIT_FLAG2_FORCE_MOVE = 0x00000040,
UNIT_FLAG2_DISARM_OFFHAND = 0x00000080,
UNIT_FLAG2_DISARM_RANGED = 0x00000400, //this does not disable ranged weapon display (maybe additional flag needed?)
@@ -1497,6 +1498,7 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void InterruptNonMeleeSpells(bool withDelayed, uint32 spellid = 0, bool withInstant = true);
Spell* FindCurrentSpellBySpellId(uint32 spell_id) const;
+ int32 GetCurrentSpellCastTime(uint32 spell_id) const;
Spell* m_currentSpells[CURRENT_MAX_SPELL];