diff options
32 files changed, 918 insertions, 771 deletions
diff --git a/sql/updates/world/2011_09_21_00_world_misc.sql b/sql/updates/world/2011_09_21_00_world_misc.sql new file mode 100644 index 00000000000..730e27fb2b2 --- /dev/null +++ b/sql/updates/world/2011_09_21_00_world_misc.sql @@ -0,0 +1,6 @@ +UPDATE `creature_template` SET `scriptname`='mob_bullet_controller' WHERE `entry` = 34743; + +DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId` = 13 AND `ConditionTypeOrReference` = 18 AND `SourceEntry` IN (66152,66153); +INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES +(13, 0, 66152, 0, 18, 1, 34720, 1, 0, '', 'Light Bullets Stalker - Light Orb Spawn'), +(13, 0, 66153, 0, 18, 1, 34704, 1, 0, '', 'Dark Bullets Stalker - Dark Orb Spawn'); diff --git a/sql/updates/world/2011_09_21_01_world_spell_script_names.sql b/sql/updates/world/2011_09_21_01_world_spell_script_names.sql new file mode 100644 index 00000000000..d3c16bec947 --- /dev/null +++ b/sql/updates/world/2011_09_21_01_world_spell_script_names.sql @@ -0,0 +1,5 @@ +DELETE FROM `spell_script_names` WHERE `spell_id` IN (53475,53487,54015); +INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES +(53475, 'spell_gen_oracle_wolvar_reputation'), -- Set Oracle Faction Friendly +(53487, 'spell_gen_oracle_wolvar_reputation'), -- Set Wolvar Faction Honored +(54015, 'spell_gen_oracle_wolvar_reputation'); -- Set Oracle Faction Honored
\ No newline at end of file diff --git a/sql/updates/world/2011_09_21_02_world_command.sql b/sql/updates/world/2011_09_21_02_world_command.sql new file mode 100644 index 00000000000..629f0c9ab32 --- /dev/null +++ b/sql/updates/world/2011_09_21_02_world_command.sql @@ -0,0 +1,3 @@ +DELETE FROM command WHERE name = 'dev';
+INSERT INTO command VALUES
+('dev', 3, 'Syntax: .dev [on/off]\r\n\r\nEnable or Disable in game Dev tag or show current state if on/off not provided.');
diff --git a/sql/updates/world/2011_09_21_02_world_trinity_string.sql b/sql/updates/world/2011_09_21_02_world_trinity_string.sql new file mode 100644 index 00000000000..954c4a7eded --- /dev/null +++ b/sql/updates/world/2011_09_21_02_world_trinity_string.sql @@ -0,0 +1,4 @@ +DELETE FROM trinity_string WHERE entry IN (1137, 1138);
+INSERT INTO trinity_string (`entry`,`content_default`) VALUES
+(1137, 'Dev mode is ON'),
+(1138, 'Dev mode is OFF');
diff --git a/sql/updates/world/2011_09_22_00_world_spell_script_names.sql b/sql/updates/world/2011_09_22_00_world_spell_script_names.sql new file mode 100644 index 00000000000..af75822087e --- /dev/null +++ b/sql/updates/world/2011_09_22_00_world_spell_script_names.sql @@ -0,0 +1,3 @@ +DELETE FROM `spell_script_names` WHERE `spell_id`=63342; +INSERT INTO `spell_script_names` (`spell_id`,`ScriptName`) VALUES +(63342,'spell_kologarn_summon_focused_eyebeam'); diff --git a/src/server/game/Combat/ThreatManager.cpp b/src/server/game/Combat/ThreatManager.cpp index 58d46dda62f..e5a2460b1a6 100755 --- a/src/server/game/Combat/ThreatManager.cpp +++ b/src/server/game/Combat/ThreatManager.cpp @@ -74,6 +74,10 @@ bool ThreatCalcHelper::isValidProcess(Unit* hatedUnit, Unit* hatingUnit, SpellIn if (!hatedUnit->isAlive() || !hatingUnit->isAlive()) return false; + // not in same map or phase + if (!hatedUnit->IsInMap(hatingUnit)) + return false; + // spell not causing threat if (threatSpell && threatSpell->AttributesEx & SPELL_ATTR1_NO_THREAT) return false; @@ -174,11 +178,13 @@ void HostileReference::updateOnlineStatus() // ref is valid // target is no player or not gamemaster // target is not in flight - if (isValid() && - ((getTarget()->GetTypeId() != TYPEID_PLAYER || !getTarget()->ToPlayer()->isGameMaster()) || - !getTarget()->HasUnitState(UNIT_STAT_IN_FLIGHT))) + if (isValid() + && (getTarget()->GetTypeId() != TYPEID_PLAYER || !getTarget()->ToPlayer()->isGameMaster()) + && !getTarget()->HasUnitState(UNIT_STAT_IN_FLIGHT) + && getTarget()->IsInMap(getSourceUnit()) + ) { - Creature* creature = getSourceUnit()->ToCreature(); + Creature* creature = getSourceUnit()->ToCreature(); online = getTarget()->isInAccessiblePlaceFor(creature); if (!online) { diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp index cbcf95cd5b0..8e75ca40f73 100755 --- a/src/server/game/Entities/Player/Player.cpp +++ b/src/server/game/Entities/Player/Player.cpp @@ -2329,6 +2329,7 @@ bool Player::TeleportToBGEntryPoint() ScheduleDelayedOperation(DELAYED_BG_MOUNT_RESTORE); ScheduleDelayedOperation(DELAYED_BG_TAXI_RESTORE); + ScheduleDelayedOperation(DELAYED_BG_GROUP_RESTORE); return TeleportTo(m_bgData.joinPos); } @@ -2383,7 +2384,13 @@ void Player::ProcessDelayedOperations() ContinueTaxiFlight(); } } - + + if (m_DelayedOperations & DELAYED_BG_GROUP_RESTORE) + { + if (Group *g = GetGroup()) + g->SendUpdateToPlayer(GetGUID()); + } + //we have executed ALL delayed ops, so clear the flag m_DelayedOperations = 0; } diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h index e7493f57791..65746043894 100755 --- a/src/server/game/Entities/Player/Player.h +++ b/src/server/game/Entities/Player/Player.h @@ -820,6 +820,7 @@ enum PlayerDelayedOperations DELAYED_SPELL_CAST_DESERTER = 0x04, DELAYED_BG_MOUNT_RESTORE = 0x08, ///< Flag to restore mount state after teleport from BG DELAYED_BG_TAXI_RESTORE = 0x10, ///< Flag to restore taxi state after teleport from BG + DELAYED_BG_GROUP_RESTORE = 0x20, ///< Flag to restore group state after teleport from BG DELAYED_END }; diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp index 077bde85162..d6199cbd910 100755 --- a/src/server/game/Entities/Unit/Unit.cpp +++ b/src/server/game/Entities/Unit/Unit.cpp @@ -1584,7 +1584,7 @@ uint32 Unit::CalcArmorReducedDamage(Unit* victim, const uint32 damage, SpellInfo // Figure out how much armor do we ignore float armorPen = CalculatePctF(maxArmorPen, ToPlayer()->GetRatingBonusValue(CR_ARMOR_PENETRATION)); // Got the value, apply it - armor -= armorPen; + armor -= std::min(armorPen, maxArmorPen); } if (armor < 0.0f) diff --git a/src/server/game/Entities/Vehicle/Vehicle.h b/src/server/game/Entities/Vehicle/Vehicle.h index aca6a5c6444..51ad500572b 100755 --- a/src/server/game/Entities/Vehicle/Vehicle.h +++ b/src/server/game/Entities/Vehicle/Vehicle.h @@ -36,6 +36,7 @@ class Vehicle void Reset(bool evading = false); void InstallAllAccessories(bool evading); void ApplyAllImmunities(); + void InstallAccessory(uint32 entry, int8 seatId, bool minion, uint8 type, uint32 summonTime); //! May be called from scripts Unit* GetBase() const { return _me; } VehicleEntry const* GetVehicleInfo() const { return _vehicleInfo; } @@ -61,7 +62,6 @@ class Vehicle private: SeatMap::iterator GetSeatIteratorForPassenger(Unit* passenger); void InitMovementInfoForBase(); - void InstallAccessory(uint32 entry, int8 seatId, bool minion, uint8 type, uint32 summonTime); Unit* _me; VehicleEntry const* _vehicleInfo; diff --git a/src/server/game/Groups/Group.cpp b/src/server/game/Groups/Group.cpp index 039a2c8e517..df9ed7a4145 100755 --- a/src/server/game/Groups/Group.cpp +++ b/src/server/game/Groups/Group.cpp @@ -1184,59 +1184,75 @@ void Group::SendTargetIconList(WorldSession* session) void Group::SendUpdate() { - Player* player; - for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) + for (member_witerator witr = m_memberSlots.begin(); witr != m_memberSlots.end(); ++witr) { - player = ObjectAccessor::FindPlayer(citr->guid); - if (!player || !player->GetSession() || player->GetGroup() != this) - continue; + SendUpdateToPlayer(witr->guid, &(*witr)); + } +} - WorldPacket data(SMSG_GROUP_LIST, (1+1+1+1+1+4+8+4+4+(GetMembersCount()-1)*(13+8+1+1+1+1)+8+1+8+1+1+1+1)); - data << uint8(m_groupType); // group type (flags in 3.3) - data << uint8(citr->group); - data << uint8(citr->flags); - data << uint8(citr->roles); - if (isLFGGroup()) - { - data << uint8(sLFGMgr->GetState(m_guid) == LFG_STATE_FINISHED_DUNGEON ? 2 : 0); // FIXME - Dungeon save status? 2 = done - data << uint32(sLFGMgr->GetDungeon(m_guid)); - } +void Group::SendUpdateToPlayer(uint64 playerGUID, MemberSlot* slot) +{ + Player* player = ObjectAccessor::FindPlayer(playerGUID); - data << uint64(m_guid); - data << uint32(m_counter++); // 3.3, value increases every time this packet gets sent - data << uint32(GetMembersCount()-1); - for (member_citerator citr2 = m_memberSlots.begin(); citr2 != m_memberSlots.end(); ++citr2) - { - if (citr->guid == citr2->guid) - continue; + if (!player || !player->GetSession() || player->GetGroup() != this) + return; - Player* member = ObjectAccessor::FindPlayer(citr2->guid); + // if MemberSlot wasn't provided + if (!slot) + { + member_witerator witr = _getMemberWSlot(playerGUID); - uint8 onlineState = (member) ? MEMBER_STATUS_ONLINE : MEMBER_STATUS_OFFLINE; - onlineState = onlineState | ((isBGGroup()) ? MEMBER_STATUS_PVP : 0); + if (witr == m_memberSlots.end()) // if there is no MemberSlot for such a player + return; - data << citr2->name; - data << uint64(citr2->guid); // guid - data << uint8(onlineState); // online-state - data << uint8(citr2->group); // groupid - data << uint8(citr2->flags); // See enum GroupMemberFlags - data << uint8(citr2->roles); // Lfg Roles - } + slot = &(*witr); + } + + WorldPacket data(SMSG_GROUP_LIST, (1+1+1+1+1+4+8+4+4+(GetMembersCount()-1)*(13+8+1+1+1+1)+8+1+8+1+1+1+1)); + data << uint8(m_groupType); // group type (flags in 3.3) + data << uint8(slot->group); + data << uint8(slot->flags); + data << uint8(slot->roles); + if (isLFGGroup()) + { + data << uint8(sLFGMgr->GetState(m_guid) == LFG_STATE_FINISHED_DUNGEON ? 2 : 0); // FIXME - Dungeon save status? 2 = done + data << uint32(sLFGMgr->GetDungeon(m_guid)); + } - data << uint64(m_leaderGuid); // leader guid + data << uint64(m_guid); + data << uint32(m_counter++); // 3.3, value increases every time this packet gets sent + data << uint32(GetMembersCount()-1); + for (member_citerator citr = m_memberSlots.begin(); citr != m_memberSlots.end(); ++citr) + { + if (slot->guid == citr->guid) + continue; - if (GetMembersCount() - 1) - { - data << uint8(m_lootMethod); // loot method - data << uint64(m_looterGuid); // looter guid - data << uint8(m_lootThreshold); // loot threshold - data << uint8(m_dungeonDifficulty); // Dungeon Difficulty - data << uint8(m_raidDifficulty); // Raid Difficulty - data << uint8(0); // 3.3 - } + Player* member = ObjectAccessor::FindPlayer(citr->guid); + + uint8 onlineState = (member) ? MEMBER_STATUS_ONLINE : MEMBER_STATUS_OFFLINE; + onlineState = onlineState | ((isBGGroup()) ? MEMBER_STATUS_PVP : 0); - player->GetSession()->SendPacket(&data); + data << citr->name; + data << uint64(citr->guid); // guid + data << uint8(onlineState); // online-state + data << uint8(citr->group); // groupid + data << uint8(citr->flags); // See enum GroupMemberFlags + data << uint8(citr->roles); // Lfg Roles } + + data << uint64(m_leaderGuid); // leader guid + + if (GetMembersCount() - 1) + { + data << uint8(m_lootMethod); // loot method + data << uint64(m_looterGuid); // looter guid + data << uint8(m_lootThreshold); // loot threshold + data << uint8(m_dungeonDifficulty); // Dungeon Difficulty + data << uint8(m_raidDifficulty); // Raid Difficulty + data << uint8(0); // 3.3 + } + + player->GetSession()->SendPacket(&data); } void Group::UpdatePlayerOutOfRange(Player* pPlayer) diff --git a/src/server/game/Groups/Group.h b/src/server/game/Groups/Group.h index 78f7a24a505..9fcc5f66f58 100755 --- a/src/server/game/Groups/Group.h +++ b/src/server/game/Groups/Group.h @@ -260,6 +260,7 @@ class Group //void SendInit(WorldSession* session); void SendTargetIconList(WorldSession* session); void SendUpdate(); + void SendUpdateToPlayer(uint64 playerGUID, MemberSlot* slot = NULL); void UpdatePlayerOutOfRange(Player* pPlayer); // ignore: GUID of player that will be ignored void BroadcastPacket(WorldPacket* packet, bool ignorePlayersInBGRaid, int group=-1, uint64 ignore=0); diff --git a/src/server/game/Miscellaneous/Language.h b/src/server/game/Miscellaneous/Language.h index 9e8a4b17f84..ce6d66c4026 100755 --- a/src/server/game/Miscellaneous/Language.h +++ b/src/server/game/Miscellaneous/Language.h @@ -805,7 +805,9 @@ enum TrinityStrings LANG_ALLOW_TICKETS = 1134, LANG_DISALLOW_TICKETS = 1135, LANG_CHAR_NOT_BANNED = 1136, - // Room for more level 3 1137-1199 not used + LANG_DEV_ON = 1137, + LANG_DEV_OFF = 1138, + // Room for more level 3 1139-1199 not used // Debug commands LANG_CINEMATIC_NOT_EXIST = 1200, diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp index 5149308f481..64c92470fd7 100755 --- a/src/server/game/Scripting/ScriptLoader.cpp +++ b/src/server/game/Scripting/ScriptLoader.cpp @@ -52,6 +52,7 @@ void AddSC_go_commandscript(); void AddSC_gobject_commandscript(); void AddSC_honor_commandscript(); void AddSC_learn_commandscript(); +void AddSC_misc_commandscript(); void AddSC_modify_commandscript(); void AddSC_npc_commandscript(); void AddSC_quest_commandscript(); @@ -652,6 +653,7 @@ void AddCommandScripts() AddSC_gobject_commandscript(); AddSC_honor_commandscript(); AddSC_learn_commandscript(); + AddSC_misc_commandscript(); AddSC_modify_commandscript(); AddSC_npc_commandscript(); AddSC_quest_commandscript(); diff --git a/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp b/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp index f8752d9b167..125fba6db91 100755 --- a/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp +++ b/src/server/game/Server/Protocol/Handlers/MiscHandler.cpp @@ -339,6 +339,12 @@ void WorldSession::HandleWhoOpcode(WorldPacket & recv_data) if ((matchcount++) >= sWorld->getIntConfig(CONFIG_MAX_WHO)) continue; + if (itr->second->isGameMaster()) + { + pname = "<GM>"; + pname.append(itr->second->GetName()); + } + data << pname; // player name data << gname; // guild name data << uint32(lvl); // player level diff --git a/src/server/game/Spells/Auras/SpellAuraEffects.cpp b/src/server/game/Spells/Auras/SpellAuraEffects.cpp index b34d4f73461..e8de9c4c773 100755 --- a/src/server/game/Spells/Auras/SpellAuraEffects.cpp +++ b/src/server/game/Spells/Auras/SpellAuraEffects.cpp @@ -5623,6 +5623,13 @@ void AuraEffect::HandlePeriodicDummyAuraTick(Unit* target, Unit* caster) const case SPELLFAMILY_GENERIC: switch (GetId()) { + case 66149: // Bullet Controller Periodic - 10 Man + case 68396: // Bullet Controller Periodic - 25 Man + { + caster->CastCustomSpell(66152, SPELLVALUE_MAX_TARGETS, urand(1,6), target, true); + caster->CastCustomSpell(66153, SPELLVALUE_MAX_TARGETS, urand(1,6), target, true); + break; + } case 54798: // FLAMING Arrow Triggered Effect { if (!caster || !target || !target->ToCreature() || !caster->GetVehicle() || target->HasAura(54683)) diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp index c5392a0e55b..68dde527ab7 100755 --- a/src/server/game/Spells/Spell.cpp +++ b/src/server/game/Spells/Spell.cpp @@ -656,7 +656,7 @@ void Spell::InitExplicitTargets(SpellCastTargets const& targets) else if ((m_caster->GetTypeId() == TYPEID_UNIT) && neededTargets & (TARGET_FLAG_UNIT_ENEMY | TARGET_FLAG_UNIT)) target = m_caster->getVictim(); // didn't find anything - let's use self as target - if (!target && neededTargets & (TARGET_FLAG_UNIT_RAID | TARGET_FLAG_UNIT_PARTY | TARGET_FLAG_UNIT_ALLY | TARGET_FLAG_UNIT)) + if (!target && neededTargets & (TARGET_FLAG_UNIT_RAID | TARGET_FLAG_UNIT_PARTY | TARGET_FLAG_UNIT_ALLY)) target = m_caster; m_targets.SetUnitTarget(target); @@ -709,121 +709,21 @@ void Spell::SelectSpellTargets() if (implicitTargetMask & (TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_GAMEOBJECT_ITEM)) m_targets.SetTargetFlag(TARGET_FLAG_GAMEOBJECT); - uint32 effectTargetType = m_spellInfo->Effects[i].GetRequiredTargetType(); - - // is it possible that areaaura is not applied to caster? - if (effectTargetType == SPELL_REQUIRE_NONE) - continue; - uint32 targetA = m_spellInfo->Effects[i].TargetA.GetTarget(); uint32 targetB = m_spellInfo->Effects[i].TargetB.GetTarget(); if (targetA) processedTargets |= SelectEffectTargets(i, m_spellInfo->Effects[i].TargetA); - if (targetB) // In very rare case !A && B + if (targetB) processedTargets |= SelectEffectTargets(i, m_spellInfo->Effects[i].TargetB); - if (effectTargetType != SPELL_REQUIRE_UNIT) - { - if (effectTargetType == SPELL_REQUIRE_CASTER) - AddUnitTarget(m_caster, 1 << i, false); - else if (effectTargetType == SPELL_REQUIRE_ITEM) - if (m_targets.GetItemTarget()) - AddItemTarget(m_targets.GetItemTarget(), 1 << i); - continue; - } - - if (!targetA && !targetB) - { - if (!m_spellInfo->GetMaxRange(true)) - { - AddUnitTarget(m_caster, 1 << i, false); - continue; - } + // Select targets of effect based on effect type + // those are used when no valid target could be added for spell effect based on spell target type + // some spell effects use explicit target as a default target added to target map (like SPELL_EFFECT_LEARN_SPELL) + // some spell effects add target to target map only when target type specified (like SPELL_EFFECT_WEAPON) + // some spell effects don't add anything to target map (confirmed with sniffs) (like SPELL_EFFECT_DESTROY_ALL_TOTEMS) + SelectEffectTypeImplicitTargets(i); - // add here custom effects that need default target. - // FOR EVERY TARGET TYPE THERE IS A DIFFERENT FILL!! - switch (m_spellInfo->Effects[i].Effect) - { - case SPELL_EFFECT_DUMMY: - { - if (m_targets.GetUnitTarget()) - AddUnitTarget(m_targets.GetUnitTarget(), 1 << i, false); - else - AddUnitTarget(m_caster, 1 << i, false); - break; - } - case SPELL_EFFECT_BIND: - case SPELL_EFFECT_RESURRECT: - case SPELL_EFFECT_CREATE_ITEM: - case SPELL_EFFECT_TRIGGER_SPELL: - case SPELL_EFFECT_SKILL_STEP: - case SPELL_EFFECT_PROFICIENCY: - case SPELL_EFFECT_SUMMON_OBJECT_WILD: - case SPELL_EFFECT_SELF_RESURRECT: - case SPELL_EFFECT_REPUTATION: - case SPELL_EFFECT_LEARN_SPELL: - case SPELL_EFFECT_SEND_TAXI: - if (m_targets.GetUnitTarget()) - AddUnitTarget(m_targets.GetUnitTarget(), 1 << i, false); - // Triggered spells have additional spell targets - cast them even if no explicit unit target is given (required for spell 50516 for example) - else if (m_spellInfo->Effects[i].Effect == SPELL_EFFECT_TRIGGER_SPELL) - AddUnitTarget(m_caster, 1 << i, false); - break; - case SPELL_EFFECT_SUMMON_RAF_FRIEND: - case SPELL_EFFECT_SUMMON_PLAYER: - if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->ToPlayer()->GetSelection()) - { - Player* target = ObjectAccessor::FindPlayer(m_caster->ToPlayer()->GetSelection()); - if (target) - AddUnitTarget(target, 1 << i, false); - } - break; - case SPELL_EFFECT_SKIN_PLAYER_CORPSE: - case SPELL_EFFECT_RESURRECT_NEW: - if (WorldObject* target = m_targets.GetObjectTarget()) - { - if (Unit* unitTarget = target->ToUnit()) - AddUnitTarget(unitTarget, 1 << i, false); - else if (Corpse* corpseTarget = target->ToCorpse()) - { - Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID()); - if (owner) - AddUnitTarget(owner, 1 << i, false); - } - } - break; - case SPELL_EFFECT_SUMMON_CHANGE_ITEM: - case SPELL_EFFECT_ADD_FARSIGHT: - case SPELL_EFFECT_APPLY_GLYPH: - case SPELL_EFFECT_STUCK: - case SPELL_EFFECT_FEED_PET: - case SPELL_EFFECT_DESTROY_ALL_TOTEMS: - case SPELL_EFFECT_KILL_CREDIT2: // only one spell: 42793 - AddUnitTarget(m_caster, 1 << i, false); - break; - case SPELL_EFFECT_LEARN_PET_SPELL: - if (Guardian* pet = m_caster->GetGuardianPet()) - AddUnitTarget(pet, 1 << i); - break; - case SPELL_EFFECT_APPLY_AURA: - switch (m_spellInfo->Effects[i].ApplyAuraName) - { - case SPELL_AURA_ADD_FLAT_MODIFIER: // some spell mods auras have 0 target modes instead expected TARGET_UNIT_CASTER(1) (and present for other ranks for same spell for example) - case SPELL_AURA_ADD_PCT_MODIFIER: - AddUnitTarget(m_caster, 1 << i, false); - break; - default: // apply to target in other case - if (m_targets.GetUnitTarget()) - AddUnitTarget(m_targets.GetUnitTarget(), 1 << i, false); - break; - } - break; - default: - AddUnitTarget(m_caster, 1 << i, false); - break; - } - } if (m_spellInfo->IsChanneled()) { uint8 mask = (1 << i); @@ -877,6 +777,82 @@ void Spell::SelectSpellTargets() } } +void Spell::SelectEffectTypeImplicitTargets(uint8 effIndex) +{ + // special case for SPELL_EFFECT_SUMMON_RAF_FRIEND and SPELL_EFFECT_SUMMON_PLAYER + // TODO: this is a workaround - target shouldn't be stored in target map for those spells + switch (m_spellInfo->Effects[effIndex].Effect) + { + case SPELL_EFFECT_SUMMON_RAF_FRIEND: + case SPELL_EFFECT_SUMMON_PLAYER: + if (m_caster->GetTypeId() == TYPEID_PLAYER && m_caster->ToPlayer()->GetSelection()) + { + Player* target = ObjectAccessor::FindPlayer(m_caster->ToPlayer()->GetSelection()); + if (target) + AddUnitTarget(target, 1 << effIndex, false); + } + return; + default: + break; + } + + // select spell implicit targets based on effect type + if (!m_spellInfo->Effects[effIndex].GetImplicitTargetType()) + return; + + uint32 targetMask = m_spellInfo->Effects[effIndex].GetMissingTargetMask(); + + if (!targetMask) + return; + + switch (m_spellInfo->Effects[effIndex].GetImplicitTargetType()) + { + // add explicit object target or self to the target map + case EFFECT_IMPLICIT_TARGET_EXPLICIT: + // player which not released his spirit is Unit, but target flag for it is TARGET_FLAG_CORPSE_MASK + if (targetMask & (TARGET_FLAG_UNIT_MASK | TARGET_FLAG_CORPSE_MASK)) + { + if (Unit* unitTarget = m_targets.GetUnitTarget()) + AddUnitTarget(unitTarget, 1 << effIndex, false); + else if (targetMask & TARGET_FLAG_CORPSE_MASK) + { + if (Corpse* corpseTarget = m_targets.GetCorpseTarget()) + { + // TODO: this is a workaround - corpses should be added to spell target map too, but we can't do that so we add owner instead + if (Player* owner = ObjectAccessor::FindPlayer(corpseTarget->GetOwnerGUID())) + AddUnitTarget(owner, 1 << effIndex, false); + } + } + else //if (targetMask & TARGET_FLAG_UNIT_MASK) + { + AddUnitTarget(m_caster, 1 << effIndex, false); + } + } + if (targetMask & TARGET_FLAG_ITEM_MASK) + { + if (Item* itemTarget = m_targets.GetItemTarget()) + AddItemTarget(itemTarget, 1 << effIndex); + } + if (targetMask & TARGET_FLAG_GAMEOBJECT_MASK) + { + if (GameObject* gObjTarget = m_targets.GetGOTarget()) + AddGOTarget(gObjTarget, 1 << effIndex); + } + break; + // add self to the target map + case EFFECT_IMPLICIT_TARGET_CASTER: + if (targetMask & TARGET_FLAG_UNIT_MASK) + AddUnitTarget(m_caster, 1 << effIndex, false); + break; + // for EFFECT_LEARN_PET_SPELL - maybe should add unitTarget's pet instead of caster's? + case EFFECT_IMPLICIT_TARGET_PET: + if (targetMask & TARGET_FLAG_UNIT_MASK) + if (Guardian* pet = m_caster->GetGuardianPet()) + AddUnitTarget(pet, 1 << effIndex, false); + break; + } +} + void Spell::prepareDataForTriggerSystem(AuraEffect const* /*triggeredByAura*/) { //========================================================================================== @@ -2505,10 +2481,6 @@ uint32 Spell::SelectEffectTargets(uint32 i, SpellImplicitTargetInfo const& cur) } else if (pushType) { - // Dummy, just for client - if (m_spellInfo->Effects[i].GetRequiredTargetType() != SPELL_REQUIRE_UNIT) - return 0; - float radius; SpellTargets targetType; switch (cur.GetTarget()) @@ -3015,7 +2987,7 @@ void Spell::prepare(SpellCastTargets const* targets, AuraEffect const* triggered { m_caster->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_CAST); for (uint32 i = 0; i < MAX_SPELL_EFFECTS; ++i) - if (m_spellInfo->Effects[i].GetRequiredTargetType() == SPELL_REQUIRE_UNIT) + if (m_spellInfo->Effects[i].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_UNIT) { m_caster->RemoveAurasWithInterruptFlags(AURA_INTERRUPT_FLAG_SPELL_ATTACK); break; @@ -3438,17 +3410,17 @@ void Spell::_handle_immediate_phase() // process ground for (uint32 j = 0; j < MAX_SPELL_EFFECTS; ++j) { - if (m_spellInfo->Effects[j].Effect == 0) + if (!m_spellInfo->Effects[j].IsEffect()) continue; - if (m_spellInfo->Effects[j].GetRequiredTargetType() == SPELL_REQUIRE_DEST) + if (m_spellInfo->Effects[j].GetUsedTargetObjectType() == TARGET_OBJECT_TYPE_DEST) { if (!m_targets.HasDst()) // FIXME: this will ignore dest set in effect m_targets.SetDst(*m_caster); HandleEffects(m_originalCaster, NULL, NULL, j); m_effectMask |= (1<<j); } - else if (m_spellInfo->Effects[j].GetRequiredTargetType() == SPELL_REQUIRE_NONE) + else if (m_spellInfo->Effects[j].GetUsedTargetObjectType() && !m_spellInfo->Effects[j].GetImplicitTargetType()) { HandleEffects(m_originalCaster, NULL, NULL, j); m_effectMask |= (1<<j); @@ -5703,16 +5675,7 @@ SpellCastResult Spell::CheckRange(bool strict) if (!strict && m_casttime == 0) return SPELL_CAST_OK; - uint32 range_type = 0; - - if (m_spellInfo->RangeEntry) - { - // self cast doesn't need range checking -- also for Starshards fix - if (m_spellInfo->RangeEntry->ID == 1) - return SPELL_CAST_OK; - - range_type = m_spellInfo->RangeEntry->type; - } + uint32 range_type = m_spellInfo->RangeEntry ? m_spellInfo->RangeEntry->type : 0; Unit* target = m_targets.GetUnitTarget(); float max_range = m_caster->GetSpellMaxRangeForTarget(target, m_spellInfo); diff --git a/src/server/game/Spells/Spell.h b/src/server/game/Spells/Spell.h index be6e16b30d2..c0a752ce704 100755 --- a/src/server/game/Spells/Spell.h +++ b/src/server/game/Spells/Spell.h @@ -202,6 +202,14 @@ enum SpellState SPELL_STATE_DELAYED = 5 }; +enum SpellEffectHandleMode +{ + SPELL_EFFECT_HANDLE_LAUNCH, + SPELL_EFFECT_HANDLE_LAUNCH_TARGET, + SPELL_EFFECT_HANDLE_HIT, + SPELL_EFFECT_HANDLE_HIT_TARGET, +}; + enum SpellTargets { SPELL_TARGETS_NONE = 0, @@ -400,6 +408,7 @@ class Spell void InitExplicitTargets(SpellCastTargets const& targets); void SelectSpellTargets(); + void SelectEffectTypeImplicitTargets(uint8 effIndex); uint32 SelectEffectTargets(uint32 i, SpellImplicitTargetInfo const& cur); void SelectTrajTargets(); diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp index 8f7bdc1ba25..f0e63398b8f 100755 --- a/src/server/game/Spells/SpellEffects.cpp +++ b/src/server/game/Spells/SpellEffects.cpp @@ -422,6 +422,7 @@ void Spell::SpellDamageSchoolDmg(SpellEffIndex effIndex) case 20625: // Ritual of Doom Sacrifice case 29142: // Eyesore Blaster case 35139: // Throw Boom's Doom + case 42393: // Brewfest - Attack Keg case 55269: // Deathly Stare case 56578: // Rapid-Fire Harpoon case 62775: // Tympanic Tantrum diff --git a/src/server/game/Spells/SpellInfo.cpp b/src/server/game/Spells/SpellInfo.cpp index d880b9524b2..1e4aa4f00f5 100644 --- a/src/server/game/Spells/SpellInfo.cpp +++ b/src/server/game/Spells/SpellInfo.cpp @@ -29,7 +29,12 @@ uint32 GetTargetFlagMask(SpellTargetObjectTypes objType) return TARGET_FLAG_DEST_LOCATION; case TARGET_OBJECT_TYPE_UNIT_AND_DEST: return TARGET_FLAG_DEST_LOCATION | TARGET_FLAG_UNIT; + case TARGET_OBJECT_TYPE_CORPSE_ALLY: + return TARGET_FLAG_CORPSE_ALLY; + case TARGET_OBJECT_TYPE_CORPSE_ENEMY: + return TARGET_FLAG_CORPSE_ENEMY; case TARGET_OBJECT_TYPE_CORPSE: + return TARGET_FLAG_CORPSE_ALLY | TARGET_FLAG_CORPSE_ENEMY; case TARGET_OBJECT_TYPE_UNIT: return TARGET_FLAG_UNIT; case TARGET_OBJECT_TYPE_GOBJ: @@ -531,7 +536,11 @@ bool SpellEffectInfo::IsAreaAuraEffect() const bool SpellEffectInfo::IsFarUnitTargetEffect() const { - return Effect == SPELL_EFFECT_SUMMON_PLAYER; + return (Effect == SPELL_EFFECT_SUMMON_PLAYER) + || (Effect == SPELL_EFFECT_SUMMON_RAF_FRIEND) + || (Effect == SPELL_EFFECT_RESURRECT) + || (Effect == SPELL_EFFECT_RESURRECT_NEW) + || (Effect == SPELL_EFFECT_SKIN_PLAYER_CORPSE); } bool SpellEffectInfo::IsFarDestTargetEffect() const @@ -647,265 +656,208 @@ float SpellEffectInfo::CalcRadius(Unit* caster, Spell* spell) const return radius; } -SpellEffectTargetTypes SpellEffectInfo::GetRequiredTargetType() const +uint32 SpellEffectInfo::GetMissingTargetMask(bool srcSet /*= false*/, bool dstSet /*= false*/, uint32 mask /*=0*/) const { - return RequiredTargetType[Effect]; -} + uint32 effImplicitTargetMask = GetTargetFlagMask(GetUsedTargetObjectType()); + uint32 providedTargetMask = GetTargetFlagMask(TargetA.GetObjectType()) | GetTargetFlagMask(TargetB.GetObjectType()) | mask; -SpellTargetObjectTypes SpellEffectInfo::GetImplicitTargetObjectType() const -{ - return _data[Effect].ImplicitObjectType; -} + // remove all flags covered by effect target mask + if (providedTargetMask & TARGET_FLAG_UNIT_MASK) + effImplicitTargetMask &= ~(TARGET_FLAG_UNIT_MASK); + if (providedTargetMask & TARGET_FLAG_CORPSE_MASK) + effImplicitTargetMask &= ~(TARGET_FLAG_UNIT_MASK | TARGET_FLAG_CORPSE_MASK); + if (providedTargetMask & TARGET_FLAG_GAMEOBJECT_ITEM) + effImplicitTargetMask &= ~(TARGET_FLAG_GAMEOBJECT_ITEM | TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_ITEM); + if (providedTargetMask & TARGET_FLAG_GAMEOBJECT) + effImplicitTargetMask &= ~(TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_GAMEOBJECT_ITEM); + if (providedTargetMask & TARGET_FLAG_ITEM) + effImplicitTargetMask &= ~(TARGET_FLAG_ITEM | TARGET_FLAG_GAMEOBJECT_ITEM); + if (dstSet || providedTargetMask & TARGET_FLAG_DEST_LOCATION) + effImplicitTargetMask &= ~(TARGET_FLAG_DEST_LOCATION); + if (srcSet || providedTargetMask & TARGET_FLAG_SOURCE_LOCATION) + effImplicitTargetMask &= ~(TARGET_FLAG_SOURCE_LOCATION); -SpellTargetObjectTypes SpellEffectInfo::GetRequiredTargetObjectType() const -{ - return _data[Effect].RequiredObjectType; + return effImplicitTargetMask; } -bool SpellEffectInfo::InitStaticData() +SpellEffectImplicitTargetTypes SpellEffectInfo::GetImplicitTargetType() const { - InitRequiredTargetTypeData(); - return true; + return _data[Effect].ImplicitTargetType; } -void SpellEffectInfo::InitRequiredTargetTypeData() +SpellTargetObjectTypes SpellEffectInfo::GetUsedTargetObjectType() const { - for (uint8 i = 0; i < TOTAL_SPELL_EFFECTS; ++i) - { - switch (i) - { - case SPELL_EFFECT_PERSISTENT_AREA_AURA: //27 - case SPELL_EFFECT_SUMMON: //28 - case SPELL_EFFECT_TRIGGER_MISSILE: //32 - case SPELL_EFFECT_TRANS_DOOR: //50 summon object - case SPELL_EFFECT_SUMMON_PET: //56 - case SPELL_EFFECT_ADD_FARSIGHT: //72 - case SPELL_EFFECT_SUMMON_OBJECT_WILD: //76 - //case SPELL_EFFECT_SUMMON_CRITTER: //97 not 303 - case SPELL_EFFECT_SUMMON_OBJECT_SLOT1: //104 - case SPELL_EFFECT_SUMMON_OBJECT_SLOT2: //105 - case SPELL_EFFECT_SUMMON_OBJECT_SLOT3: //106 - case SPELL_EFFECT_SUMMON_OBJECT_SLOT4: //107 - case SPELL_EFFECT_SUMMON_DEAD_PET: //109 - case SPELL_EFFECT_TRIGGER_SPELL_2: //151 ritual of summon - RequiredTargetType[i] = SPELL_REQUIRE_DEST; - break; - case SPELL_EFFECT_PARRY: // 0 - case SPELL_EFFECT_BLOCK: // 0 - case SPELL_EFFECT_SKILL: // always with dummy 3 as A - //case SPELL_EFFECT_LEARN_SPELL: // 0 may be 5 pet - case SPELL_EFFECT_TRADE_SKILL: // 0 or 1 - case SPELL_EFFECT_PROFICIENCY: // 0 - RequiredTargetType[i] = SPELL_REQUIRE_NONE; - break; - case SPELL_EFFECT_ENCHANT_ITEM: - case SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY: - case SPELL_EFFECT_DISENCHANT: - //in 243 this is 0, in 309 it is 1 - //so both item target and unit target is pushed, and cause crash - //case SPELL_EFFECT_FEED_PET: - case SPELL_EFFECT_PROSPECTING: - case SPELL_EFFECT_MILLING: - case SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC: - RequiredTargetType[i] = SPELL_REQUIRE_ITEM; - break; - //caster must be pushed otherwise no sound - case SPELL_EFFECT_APPLY_AREA_AURA_PARTY: - case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND: - case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY: - case SPELL_EFFECT_APPLY_AREA_AURA_PET: - case SPELL_EFFECT_APPLY_AREA_AURA_OWNER: - case SPELL_EFFECT_APPLY_AREA_AURA_RAID: - case SPELL_EFFECT_CHARGE: - case SPELL_EFFECT_CHARGE_DEST: - case SPELL_EFFECT_JUMP: - case SPELL_EFFECT_JUMP_DEST: - case SPELL_EFFECT_LEAP_BACK: - RequiredTargetType[i] = SPELL_REQUIRE_CASTER; - break; - //case SPELL_EFFECT_WMO_DAMAGE: - //case SPELL_EFFECT_WMO_REPAIR: - //case SPELL_EFFECT_WMO_CHANGE: - // RequiredTargetType[i] = SPELL_REQUIRE_GOBJECT; - // break; - default: - RequiredTargetType[i] = SPELL_REQUIRE_UNIT; - break; - } - } + return _data[Effect].UsedTargetObjectType; } -bool SpellEffectInfo::Init = SpellEffectInfo::InitStaticData(); -SpellEffectTargetTypes SpellEffectInfo::RequiredTargetType[TOTAL_SPELL_EFFECTS]; - SpellEffectInfo::StaticData SpellEffectInfo::_data[TOTAL_SPELL_EFFECTS] = { - // implicit target required target - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_NONE}, // 0 - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 1 SPELL_EFFECT_INSTAKILL - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 2 SPELL_EFFECT_SCHOOL_DAMAGE - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_NONE}, // 3 SPELL_EFFECT_DUMMY - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_NONE}, // 4 SPELL_EFFECT_PORTAL_TELEPORT - {TARGET_OBJECT_TYPE_UNIT_AND_DEST,TARGET_OBJECT_TYPE_UNIT_AND_DEST},// 5 SPELL_EFFECT_TELEPORT_UNITS - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 6 SPELL_EFFECT_APPLY_AURA - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 7 SPELL_EFFECT_ENVIRONMENTAL_DAMAGE - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 8 SPELL_EFFECT_POWER_DRAIN - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 9 SPELL_EFFECT_HEALTH_LEECH - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 10 SPELL_EFFECT_HEAL - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 11 SPELL_EFFECT_BIND - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_NONE}, // 12 SPELL_EFFECT_PORTAL - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_NONE}, // 13 SPELL_EFFECT_RITUAL_BASE - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_NONE}, // 14 SPELL_EFFECT_RITUAL_SPECIALIZE - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_NONE}, // 15 SPELL_EFFECT_RITUAL_ACTIVATE_PORTAL - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 16 SPELL_EFFECT_QUEST_COMPLETE - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 17 SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL - {TARGET_OBJECT_TYPE_CORPSE, TARGET_OBJECT_TYPE_CORPSE}, // 18 SPELL_EFFECT_RESURRECT - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 19 SPELL_EFFECT_ADD_EXTRA_ATTACKS - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 20 SPELL_EFFECT_DODGE - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 21 SPELL_EFFECT_EVADE - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 22 SPELL_EFFECT_PARRY - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 23 SPELL_EFFECT_BLOCK - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 24 SPELL_EFFECT_CREATE_ITEM - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 25 SPELL_EFFECT_WEAPON - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 26 SPELL_EFFECT_DEFENSE - {TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_DEST}, // 27 SPELL_EFFECT_PERSISTENT_AREA_AURA - {TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_DEST}, // 28 SPELL_EFFECT_SUMMON - {TARGET_OBJECT_TYPE_UNIT_AND_DEST, TARGET_OBJECT_TYPE_UNIT_AND_DEST},// 29 SPELL_EFFECT_LEAP - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 30 SPELL_EFFECT_ENERGIZE - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 31 SPELL_EFFECT_WEAPON_PERCENT_DAMAGE - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_NONE}, // 32 SPELL_EFFECT_TRIGGER_MISSILE - {TARGET_OBJECT_TYPE_GOBJ_ITEM, TARGET_OBJECT_TYPE_GOBJ_ITEM}, // 33 SPELL_EFFECT_OPEN_LOCK - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 34 SPELL_EFFECT_SUMMON_CHANGE_ITEM - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 35 SPELL_EFFECT_APPLY_AREA_AURA_PARTY - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 36 SPELL_EFFECT_LEARN_SPELL - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 37 SPELL_EFFECT_SPELL_DEFENSE - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 38 SPELL_EFFECT_DISPEL - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 39 SPELL_EFFECT_LANGUAGE - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 40 SPELL_EFFECT_DUAL_WIELD - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 41 SPELL_EFFECT_JUMP - {TARGET_OBJECT_TYPE_UNIT_AND_DEST,TARGET_OBJECT_TYPE_UNIT_AND_DEST},// 42 SPELL_EFFECT_JUMP_DEST - {TARGET_OBJECT_TYPE_UNIT_AND_DEST,TARGET_OBJECT_TYPE_UNIT_AND_DEST},// 43 SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 44 SPELL_EFFECT_SKILL_STEP - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 45 SPELL_EFFECT_ADD_HONOR - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 46 SPELL_EFFECT_SPAWN - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 47 SPELL_EFFECT_TRADE_SKILL - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 48 SPELL_EFFECT_STEALTH - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 49 SPELL_EFFECT_DETECT - {TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_DEST}, // 50 SPELL_EFFECT_TRANS_DOOR - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 51 SPELL_EFFECT_FORCE_CRITICAL_HIT - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 52 SPELL_EFFECT_GUARANTEE_HIT - {TARGET_OBJECT_TYPE_ITEM, TARGET_OBJECT_TYPE_ITEM}, // 53 SPELL_EFFECT_ENCHANT_ITEM - {TARGET_OBJECT_TYPE_ITEM, TARGET_OBJECT_TYPE_ITEM}, // 54 SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 55 SPELL_EFFECT_TAMECREATURE - {TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_DEST}, // 56 SPELL_EFFECT_SUMMON_PET - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 57 SPELL_EFFECT_LEARN_PET_SPELL - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 58 SPELL_EFFECT_WEAPON_DAMAGE - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 59 SPELL_EFFECT_CREATE_RANDOM_ITEM - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 60 SPELL_EFFECT_PROFICIENCY - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_NONE}, // 61 SPELL_EFFECT_SEND_EVENT - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 62 SPELL_EFFECT_POWER_BURN - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 63 SPELL_EFFECT_THREAT - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_NONE}, // 64 SPELL_EFFECT_TRIGGER_SPELL - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 65 SPELL_EFFECT_APPLY_AREA_AURA_RAID - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 66 SPELL_EFFECT_CREATE_MANA_GEM - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 67 SPELL_EFFECT_HEAL_MAX_HEALTH - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 68 SPELL_EFFECT_INTERRUPT_CAST - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 69 SPELL_EFFECT_DISTRACT - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 70 SPELL_EFFECT_PULL - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 71 SPELL_EFFECT_PICKPOCKET - {TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_DEST}, // 72 SPELL_EFFECT_ADD_FARSIGHT - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 73 SPELL_EFFECT_UNTRAIN_TALENTS - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 74 SPELL_EFFECT_APPLY_GLYPH - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 75 SPELL_EFFECT_HEAL_MECHANICAL - {TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_DEST}, // 76 SPELL_EFFECT_SUMMON_OBJECT_WILD - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_NONE}, // 77 SPELL_EFFECT_SCRIPT_EFFECT - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 78 SPELL_EFFECT_ATTACK - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 79 SPELL_EFFECT_SANCTUARY - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 80 SPELL_EFFECT_ADD_COMBO_POINTS - {TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_DEST}, // 81 SPELL_EFFECT_CREATE_HOUSE - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 82 SPELL_EFFECT_BIND_SIGHT - {TARGET_OBJECT_TYPE_UNIT_AND_DEST,TARGET_OBJECT_TYPE_UNIT_AND_DEST},// 83 SPELL_EFFECT_DUEL - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 84 SPELL_EFFECT_STUCK - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_NONE}, // 85 SPELL_EFFECT_SUMMON_PLAYER - {TARGET_OBJECT_TYPE_GOBJ, TARGET_OBJECT_TYPE_GOBJ}, // 86 SPELL_EFFECT_ACTIVATE_OBJECT - {TARGET_OBJECT_TYPE_GOBJ, TARGET_OBJECT_TYPE_GOBJ}, // 87 SPELL_EFFECT_GAMEOBJECT_DAMAGE - {TARGET_OBJECT_TYPE_GOBJ, TARGET_OBJECT_TYPE_GOBJ}, // 88 SPELL_EFFECT_GAMEOBJECT_REPAIR - {TARGET_OBJECT_TYPE_GOBJ, TARGET_OBJECT_TYPE_GOBJ}, // 89 SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 90 SPELL_EFFECT_KILL_CREDIT - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 91 SPELL_EFFECT_THREAT_ALL - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 92 SPELL_EFFECT_ENCHANT_HELD_ITEM - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 93 SPELL_EFFECT_FORCE_DESELECT - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 94 SPELL_EFFECT_SELF_RESURRECT - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 95 SPELL_EFFECT_SKINNING - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 96 SPELL_EFFECT_CHARGE - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 97 SPELL_EFFECT_CAST_BUTTON - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 98 SPELL_EFFECT_KNOCK_BACK - {TARGET_OBJECT_TYPE_ITEM, TARGET_OBJECT_TYPE_ITEM}, // 99 SPELL_EFFECT_DISENCHANT - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 100 SPELL_EFFECT_INEBRIATE - {TARGET_OBJECT_TYPE_ITEM, TARGET_OBJECT_TYPE_ITEM}, // 101 SPELL_EFFECT_FEED_PET - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 102 SPELL_EFFECT_DISMISS_PET - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 103 SPELL_EFFECT_REPUTATION - {TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_DEST}, // 104 SPELL_EFFECT_SUMMON_OBJECT_SLOT1 - {TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_DEST}, // 105 SPELL_EFFECT_SUMMON_OBJECT_SLOT2 - {TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_DEST}, // 106 SPELL_EFFECT_SUMMON_OBJECT_SLOT3 - {TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_DEST}, // 107 SPELL_EFFECT_SUMMON_OBJECT_SLOT4 - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 108 SPELL_EFFECT_DISPEL_MECHANIC - {TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_DEST}, // 109 SPELL_EFFECT_SUMMON_DEAD_PET - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 110 SPELL_EFFECT_DESTROY_ALL_TOTEMS - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 111 SPELL_EFFECT_DURABILITY_DAMAGE - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 112 SPELL_EFFECT_112 - {TARGET_OBJECT_TYPE_CORPSE, TARGET_OBJECT_TYPE_CORPSE}, // 113 SPELL_EFFECT_RESURRECT_NEW - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 114 SPELL_EFFECT_ATTACK_ME - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 115 SPELL_EFFECT_DURABILITY_DAMAGE_PCT - {TARGET_OBJECT_TYPE_CORPSE, TARGET_OBJECT_TYPE_CORPSE}, // 116 SPELL_EFFECT_SKIN_PLAYER_CORPSE - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 117 SPELL_EFFECT_SPIRIT_HEAL - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 118 SPELL_EFFECT_SKILL - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 119 SPELL_EFFECT_APPLY_AREA_AURA_PET - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 120 SPELL_EFFECT_TELEPORT_GRAVEYARD - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 121 SPELL_EFFECT_NORMALIZED_WEAPON_DMG - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_NONE}, // 122 SPELL_EFFECT_122 - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 123 SPELL_EFFECT_SEND_TAXI - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 124 SPELL_EFFECT_PULL_TOWARDS - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 125 SPELL_EFFECT_MODIFY_THREAT_PERCENT - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 126 SPELL_EFFECT_STEAL_BENEFICIAL_BUFF - {TARGET_OBJECT_TYPE_ITEM, TARGET_OBJECT_TYPE_ITEM}, // 127 SPELL_EFFECT_PROSPECTING - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 128 SPELL_EFFECT_APPLY_AREA_AURA_FRIEND - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 129 SPELL_EFFECT_APPLY_AREA_AURA_ENEMY - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 130 SPELL_EFFECT_REDIRECT_THREAT - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 131 SPELL_EFFECT_131 - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 132 SPELL_EFFECT_PLAY_MUSIC - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 133 SPELL_EFFECT_UNLEARN_SPECIALIZATION - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 134 SPELL_EFFECT_KILL_CREDIT2 - {TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_DEST}, // 135 SPELL_EFFECT_CALL_PET - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 136 SPELL_EFFECT_HEAL_PCT - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 137 SPELL_EFFECT_ENERGIZE_PCT - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 138 SPELL_EFFECT_LEAP_BACK - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 139 SPELL_EFFECT_CLEAR_QUEST - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 140 SPELL_EFFECT_FORCE_CAST - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 141 SPELL_EFFECT_FORCE_CAST_WITH_VALUE - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 142 SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 143 SPELL_EFFECT_APPLY_AREA_AURA_OWNER - {TARGET_OBJECT_TYPE_UNIT_AND_DEST,TARGET_OBJECT_TYPE_UNIT_AND_DEST},// 144 SPELL_EFFECT_KNOCK_BACK_DEST - {TARGET_OBJECT_TYPE_UNIT_AND_DEST,TARGET_OBJECT_TYPE_UNIT_AND_DEST},// 145 SPELL_EFFECT_PULL_TOWARDS_DEST - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 146 SPELL_EFFECT_ACTIVATE_RUNE - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 147 SPELL_EFFECT_QUEST_FAIL - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_NONE}, // 148 SPELL_EFFECT_148 - {TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_DEST}, // 149 SPELL_EFFECT_CHARGE_DEST - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 150 SPELL_EFFECT_QUEST_START - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_NONE}, // 151 SPELL_EFFECT_TRIGGER_SPELL_2 - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_NONE}, // 152 SPELL_EFFECT_SUMMON_RAF_FRIEND - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 153 SPELL_EFFECT_CREATE_TAMED_PET - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 154 SPELL_EFFECT_DISCOVER_TAXI - {TARGET_OBJECT_TYPE_NONE, TARGET_OBJECT_TYPE_UNIT}, // 155 SPELL_EFFECT_TITAN_GRIP - {TARGET_OBJECT_TYPE_ITEM, TARGET_OBJECT_TYPE_ITEM}, // 156 SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 157 SPELL_EFFECT_CREATE_ITEM_2 - {TARGET_OBJECT_TYPE_ITEM, TARGET_OBJECT_TYPE_ITEM}, // 158 SPELL_EFFECT_MILLING - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 159 SPELL_EFFECT_ALLOW_RENAME_PET - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 160 SPELL_EFFECT_160 - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 161 SPELL_EFFECT_TALENT_SPEC_COUNT - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 162 SPELL_EFFECT_TALENT_SPEC_SELECT - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 163 SPELL_EFFECT_163 - {TARGET_OBJECT_TYPE_UNIT, TARGET_OBJECT_TYPE_UNIT}, // 164 SPELL_EFFECT_REMOVE_AURA + // implicit target type used target object type + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 0 + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 1 SPELL_EFFECT_INSTAKILL + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 2 SPELL_EFFECT_SCHOOL_DAMAGE + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 3 SPELL_EFFECT_DUMMY + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 4 SPELL_EFFECT_PORTAL_TELEPORT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST},// 5 SPELL_EFFECT_TELEPORT_UNITS + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 6 SPELL_EFFECT_APPLY_AURA + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 7 SPELL_EFFECT_ENVIRONMENTAL_DAMAGE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 8 SPELL_EFFECT_POWER_DRAIN + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 9 SPELL_EFFECT_HEALTH_LEECH + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 10 SPELL_EFFECT_HEAL + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 11 SPELL_EFFECT_BIND + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 12 SPELL_EFFECT_PORTAL + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 13 SPELL_EFFECT_RITUAL_BASE + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 14 SPELL_EFFECT_RITUAL_SPECIALIZE + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 15 SPELL_EFFECT_RITUAL_ACTIVATE_PORTAL + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 16 SPELL_EFFECT_QUEST_COMPLETE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 17 SPELL_EFFECT_WEAPON_DAMAGE_NOSCHOOL + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_CORPSE_ALLY}, // 18 SPELL_EFFECT_RESURRECT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 19 SPELL_EFFECT_ADD_EXTRA_ATTACKS + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 20 SPELL_EFFECT_DODGE + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 21 SPELL_EFFECT_EVADE + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 22 SPELL_EFFECT_PARRY + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 23 SPELL_EFFECT_BLOCK + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 24 SPELL_EFFECT_CREATE_ITEM + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 25 SPELL_EFFECT_WEAPON + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 26 SPELL_EFFECT_DEFENSE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 27 SPELL_EFFECT_PERSISTENT_AREA_AURA + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 28 SPELL_EFFECT_SUMMON + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST},// 29 SPELL_EFFECT_LEAP + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 30 SPELL_EFFECT_ENERGIZE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 31 SPELL_EFFECT_WEAPON_PERCENT_DAMAGE + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 32 SPELL_EFFECT_TRIGGER_MISSILE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_GOBJ_ITEM}, // 33 SPELL_EFFECT_OPEN_LOCK + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 34 SPELL_EFFECT_SUMMON_CHANGE_ITEM + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 35 SPELL_EFFECT_APPLY_AREA_AURA_PARTY + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 36 SPELL_EFFECT_LEARN_SPELL + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 37 SPELL_EFFECT_SPELL_DEFENSE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 38 SPELL_EFFECT_DISPEL + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 39 SPELL_EFFECT_LANGUAGE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 40 SPELL_EFFECT_DUAL_WIELD + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 41 SPELL_EFFECT_JUMP + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST},// 42 SPELL_EFFECT_JUMP_DEST + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST},// 43 SPELL_EFFECT_TELEPORT_UNITS_FACE_CASTER + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 44 SPELL_EFFECT_SKILL_STEP + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 45 SPELL_EFFECT_ADD_HONOR + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 46 SPELL_EFFECT_SPAWN + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 47 SPELL_EFFECT_TRADE_SKILL + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 48 SPELL_EFFECT_STEALTH + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 49 SPELL_EFFECT_DETECT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 50 SPELL_EFFECT_TRANS_DOOR + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 51 SPELL_EFFECT_FORCE_CRITICAL_HIT + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 52 SPELL_EFFECT_GUARANTEE_HIT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 53 SPELL_EFFECT_ENCHANT_ITEM + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 54 SPELL_EFFECT_ENCHANT_ITEM_TEMPORARY + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 55 SPELL_EFFECT_TAMECREATURE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 56 SPELL_EFFECT_SUMMON_PET + {EFFECT_IMPLICIT_TARGET_PET, TARGET_OBJECT_TYPE_UNIT}, // 57 SPELL_EFFECT_LEARN_PET_SPELL + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 58 SPELL_EFFECT_WEAPON_DAMAGE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 59 SPELL_EFFECT_CREATE_RANDOM_ITEM + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 60 SPELL_EFFECT_PROFICIENCY + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 61 SPELL_EFFECT_SEND_EVENT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 62 SPELL_EFFECT_POWER_BURN + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 63 SPELL_EFFECT_THREAT + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 64 SPELL_EFFECT_TRIGGER_SPELL + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 65 SPELL_EFFECT_APPLY_AREA_AURA_RAID + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 66 SPELL_EFFECT_CREATE_MANA_GEM + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 67 SPELL_EFFECT_HEAL_MAX_HEALTH + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 68 SPELL_EFFECT_INTERRUPT_CAST + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 69 SPELL_EFFECT_DISTRACT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 70 SPELL_EFFECT_PULL + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 71 SPELL_EFFECT_PICKPOCKET + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 72 SPELL_EFFECT_ADD_FARSIGHT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 73 SPELL_EFFECT_UNTRAIN_TALENTS + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 74 SPELL_EFFECT_APPLY_GLYPH + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 75 SPELL_EFFECT_HEAL_MECHANICAL + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 76 SPELL_EFFECT_SUMMON_OBJECT_WILD + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 77 SPELL_EFFECT_SCRIPT_EFFECT + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 78 SPELL_EFFECT_ATTACK + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 79 SPELL_EFFECT_SANCTUARY + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 80 SPELL_EFFECT_ADD_COMBO_POINTS + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 81 SPELL_EFFECT_CREATE_HOUSE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 82 SPELL_EFFECT_BIND_SIGHT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST},// 83 SPELL_EFFECT_DUEL + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 84 SPELL_EFFECT_STUCK + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 85 SPELL_EFFECT_SUMMON_PLAYER + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_GOBJ}, // 86 SPELL_EFFECT_ACTIVATE_OBJECT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_GOBJ}, // 87 SPELL_EFFECT_GAMEOBJECT_DAMAGE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_GOBJ}, // 88 SPELL_EFFECT_GAMEOBJECT_REPAIR + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_GOBJ}, // 89 SPELL_EFFECT_GAMEOBJECT_SET_DESTRUCTION_STATE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 90 SPELL_EFFECT_KILL_CREDIT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 91 SPELL_EFFECT_THREAT_ALL + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 92 SPELL_EFFECT_ENCHANT_HELD_ITEM + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 93 SPELL_EFFECT_FORCE_DESELECT + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 94 SPELL_EFFECT_SELF_RESURRECT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 95 SPELL_EFFECT_SKINNING + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 96 SPELL_EFFECT_CHARGE + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 97 SPELL_EFFECT_CAST_BUTTON + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 98 SPELL_EFFECT_KNOCK_BACK + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 99 SPELL_EFFECT_DISENCHANT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 100 SPELL_EFFECT_INEBRIATE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 101 SPELL_EFFECT_FEED_PET + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 102 SPELL_EFFECT_DISMISS_PET + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 103 SPELL_EFFECT_REPUTATION + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 104 SPELL_EFFECT_SUMMON_OBJECT_SLOT1 + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 105 SPELL_EFFECT_SUMMON_OBJECT_SLOT2 + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 106 SPELL_EFFECT_SUMMON_OBJECT_SLOT3 + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 107 SPELL_EFFECT_SUMMON_OBJECT_SLOT4 + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 108 SPELL_EFFECT_DISPEL_MECHANIC + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 109 SPELL_EFFECT_SUMMON_DEAD_PET + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 110 SPELL_EFFECT_DESTROY_ALL_TOTEMS + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 111 SPELL_EFFECT_DURABILITY_DAMAGE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 112 SPELL_EFFECT_112 + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_CORPSE_ALLY}, // 113 SPELL_EFFECT_RESURRECT_NEW + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 114 SPELL_EFFECT_ATTACK_ME + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 115 SPELL_EFFECT_DURABILITY_DAMAGE_PCT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_CORPSE_ENEMY}, // 116 SPELL_EFFECT_SKIN_PLAYER_CORPSE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 117 SPELL_EFFECT_SPIRIT_HEAL + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 118 SPELL_EFFECT_SKILL + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 119 SPELL_EFFECT_APPLY_AREA_AURA_PET + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 120 SPELL_EFFECT_TELEPORT_GRAVEYARD + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 121 SPELL_EFFECT_NORMALIZED_WEAPON_DMG + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 122 SPELL_EFFECT_122 + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 123 SPELL_EFFECT_SEND_TAXI + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 124 SPELL_EFFECT_PULL_TOWARDS + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 125 SPELL_EFFECT_MODIFY_THREAT_PERCENT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 126 SPELL_EFFECT_STEAL_BENEFICIAL_BUFF + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 127 SPELL_EFFECT_PROSPECTING + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 128 SPELL_EFFECT_APPLY_AREA_AURA_FRIEND + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 129 SPELL_EFFECT_APPLY_AREA_AURA_ENEMY + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 130 SPELL_EFFECT_REDIRECT_THREAT + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 131 SPELL_EFFECT_131 + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 132 SPELL_EFFECT_PLAY_MUSIC + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 133 SPELL_EFFECT_UNLEARN_SPECIALIZATION + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 134 SPELL_EFFECT_KILL_CREDIT2 + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 135 SPELL_EFFECT_CALL_PET + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 136 SPELL_EFFECT_HEAL_PCT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 137 SPELL_EFFECT_ENERGIZE_PCT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 138 SPELL_EFFECT_LEAP_BACK + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 139 SPELL_EFFECT_CLEAR_QUEST + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 140 SPELL_EFFECT_FORCE_CAST + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 141 SPELL_EFFECT_FORCE_CAST_WITH_VALUE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 142 SPELL_EFFECT_TRIGGER_SPELL_WITH_VALUE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 143 SPELL_EFFECT_APPLY_AREA_AURA_OWNER + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST},// 144 SPELL_EFFECT_KNOCK_BACK_DEST + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT_AND_DEST},// 145 SPELL_EFFECT_PULL_TOWARDS_DEST + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 146 SPELL_EFFECT_ACTIVATE_RUNE + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 147 SPELL_EFFECT_QUEST_FAIL + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 148 SPELL_EFFECT_148 + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_DEST}, // 149 SPELL_EFFECT_CHARGE_DEST + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 150 SPELL_EFFECT_QUEST_START + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_DEST}, // 151 SPELL_EFFECT_TRIGGER_SPELL_2 + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_NONE}, // 152 SPELL_EFFECT_SUMMON_RAF_FRIEND + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 153 SPELL_EFFECT_CREATE_TAMED_PET + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 154 SPELL_EFFECT_DISCOVER_TAXI + {EFFECT_IMPLICIT_TARGET_NONE, TARGET_OBJECT_TYPE_UNIT}, // 155 SPELL_EFFECT_TITAN_GRIP + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 156 SPELL_EFFECT_ENCHANT_ITEM_PRISMATIC + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 157 SPELL_EFFECT_CREATE_ITEM_2 + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_ITEM}, // 158 SPELL_EFFECT_MILLING + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 159 SPELL_EFFECT_ALLOW_RENAME_PET + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 160 SPELL_EFFECT_160 + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 161 SPELL_EFFECT_TALENT_SPEC_COUNT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 162 SPELL_EFFECT_TALENT_SPEC_SELECT + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 163 SPELL_EFFECT_163 + {EFFECT_IMPLICIT_TARGET_EXPLICIT, TARGET_OBJECT_TYPE_UNIT}, // 164 SPELL_EFFECT_REMOVE_AURA }; SpellInfo::SpellInfo(SpellEntry const* spellEntry) @@ -2277,65 +2229,13 @@ uint32 SpellInfo::_GetExplicitTargetMask() const continue; targetMask |= Effects[i].TargetA.GetExplicitTargetMask(srcSet, dstSet); targetMask |= Effects[i].TargetB.GetExplicitTargetMask(srcSet, dstSet); - } - // spells with range may need explicit targets, even if target entries not set - // for example many SPELL_EFFECT_LEARN_SPELL spells need to have unit target - if (GetMaxRange(true) > 0.0f || GetMaxRange(false) > 0.0f) - { - for (uint8 i = 0; i < MAX_SPELL_EFFECTS; ++i) - { - if (!Effects[i].IsEffect()) - continue; - uint32 effImplicitTargetMask = GetTargetFlagMask(Effects[i].GetImplicitTargetObjectType()); - uint32 providedTargetMask = GetTargetFlagMask(Effects[i].TargetA.GetObjectType()) | GetTargetFlagMask(Effects[i].TargetB.GetObjectType()) | targetMask; - - // check if valid targets already present, prevent adding redundant flags - switch (Effects[i].GetImplicitTargetObjectType()) - { - case TARGET_OBJECT_TYPE_UNIT_AND_DEST: - if (providedTargetMask & TARGET_FLAG_UNIT_MASK) - effImplicitTargetMask &= ~(TARGET_FLAG_UNIT_MASK); - if (dstSet || providedTargetMask & TARGET_FLAG_DEST_LOCATION) - effImplicitTargetMask &= ~(TARGET_FLAG_DEST_LOCATION); - if (!effImplicitTargetMask) - continue; - break; - case TARGET_OBJECT_TYPE_SRC: - if (srcSet || providedTargetMask & TARGET_FLAG_SOURCE_LOCATION) - continue; - break; - case TARGET_OBJECT_TYPE_DEST: - if (dstSet || providedTargetMask & TARGET_FLAG_DEST_LOCATION) - continue; - break; - case TARGET_OBJECT_TYPE_UNIT: - if (providedTargetMask & TARGET_FLAG_UNIT_MASK) - continue; - break; - case TARGET_OBJECT_TYPE_CORPSE: - if (providedTargetMask & (TARGET_FLAG_CORPSE_MASK | TARGET_FLAG_UNIT_MASK)) - continue; - break; - case TARGET_OBJECT_TYPE_ITEM: - if (providedTargetMask & (TARGET_FLAG_GAMEOBJECT_ITEM | TARGET_FLAG_ITEM)) - continue; - break; - case TARGET_OBJECT_TYPE_GOBJ: - if (providedTargetMask & TARGET_FLAG_GAMEOBJECT_MASK) - continue; - break; - case TARGET_OBJECT_TYPE_GOBJ_ITEM: - if (providedTargetMask & (TARGET_FLAG_GAMEOBJECT_ITEM | TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_ITEM)) - continue; - break; - default: - continue; - } + // add explicit target flags based on spell effects which have EFFECT_IMPLICIT_TARGET_EXPLICIT and no valid target provided + if (Effects[i].GetImplicitTargetType() != EFFECT_IMPLICIT_TARGET_EXPLICIT) + continue; - // extend explicit target mask only if valid targets for effect could not be provided by target types - targetMask |= effImplicitTargetMask &~(providedTargetMask); - } + // extend explicit target mask only if valid targets for effect could not be provided by target types + targetMask |= Effects[i].GetMissingTargetMask(srcSet, dstSet, targetMask); } return targetMask; } diff --git a/src/server/game/Spells/SpellInfo.h b/src/server/game/Spells/SpellInfo.h index 77d27a908d3..f7bdbd52c5d 100644 --- a/src/server/game/Spells/SpellInfo.h +++ b/src/server/game/Spells/SpellInfo.h @@ -66,16 +66,7 @@ enum SpellCastTargetFlags | TARGET_FLAG_UNIT_ENEMY | TARGET_FLAG_UNIT_ALLY | TARGET_FLAG_UNIT_DEAD | TARGET_FLAG_UNIT_MINIPET | TARGET_FLAG_UNIT_PASSENGER, TARGET_FLAG_GAMEOBJECT_MASK = TARGET_FLAG_GAMEOBJECT | TARGET_FLAG_GAMEOBJECT_ITEM, TARGET_FLAG_CORPSE_MASK = TARGET_FLAG_CORPSE_ALLY | TARGET_FLAG_CORPSE_ENEMY, -}; - -enum SpellEffectTargetTypes -{ - SPELL_REQUIRE_NONE, - SPELL_REQUIRE_UNIT, - SPELL_REQUIRE_DEST, - SPELL_REQUIRE_ITEM, - SPELL_REQUIRE_CASTER, - SPELL_REQUIRE_GOBJECT, + TARGET_FLAG_ITEM_MASK = TARGET_FLAG_TRADE_ITEM | TARGET_FLAG_ITEM | TARGET_FLAG_GAMEOBJECT_ITEM, }; enum SpellTargetSelectionCategories @@ -100,7 +91,7 @@ enum SpellTargetReferenceTypes enum SpellTargetObjectTypes { - TARGET_OBJECT_TYPE_NONE, + TARGET_OBJECT_TYPE_NONE = 0, TARGET_OBJECT_TYPE_SRC, TARGET_OBJECT_TYPE_DEST, TARGET_OBJECT_TYPE_UNIT, @@ -109,6 +100,9 @@ enum SpellTargetObjectTypes TARGET_OBJECT_TYPE_GOBJ_ITEM, TARGET_OBJECT_TYPE_ITEM, TARGET_OBJECT_TYPE_CORPSE, + // only for effect target type + TARGET_OBJECT_TYPE_CORPSE_ENEMY, + TARGET_OBJECT_TYPE_CORPSE_ALLY, }; enum SpellTargetSelectionCheckTypes @@ -153,6 +147,14 @@ enum SpellSelectTargetTypes TARGET_TYPE_CHANNEL, }; +enum SpellEffectImplicitTargetTypes +{ + EFFECT_IMPLICIT_TARGET_NONE = 0, + EFFECT_IMPLICIT_TARGET_EXPLICIT, + EFFECT_IMPLICIT_TARGET_CASTER, + EFFECT_IMPLICIT_TARGET_PET, +}; + // Spell clasification enum SpellSpecificType { @@ -294,22 +296,16 @@ public: bool HasRadius() const; float CalcRadius(Unit* caster = NULL, Spell* = NULL) const; - SpellEffectTargetTypes GetRequiredTargetType() const; + uint32 GetMissingTargetMask(bool srcSet = false, bool destSet = false, uint32 mask = 0) const; - SpellTargetObjectTypes GetImplicitTargetObjectType() const; - SpellTargetObjectTypes GetRequiredTargetObjectType() const; + SpellEffectImplicitTargetTypes GetImplicitTargetType() const; + SpellTargetObjectTypes GetUsedTargetObjectType() const; private: - static bool InitStaticData(); - static void InitRequiredTargetTypeData(); - - static bool Init; - static SpellEffectTargetTypes RequiredTargetType[TOTAL_SPELL_EFFECTS]; - struct StaticData { - SpellTargetObjectTypes ImplicitObjectType; // defines if explicit target can be added to effect target list if there's no valid target type provided for effect - SpellTargetObjectTypes RequiredObjectType; // defines valid target object type for spell effect + SpellEffectImplicitTargetTypes ImplicitTargetType; // defines what target can be added to effect target list if there's no valid target type provided for effect + SpellTargetObjectTypes UsedTargetObjectType; // defines valid target object type for spell effect }; static StaticData _data[TOTAL_SPELL_EFFECTS]; }; diff --git a/src/server/scripts/Commands/CMakeLists.txt b/src/server/scripts/Commands/CMakeLists.txt index 19c42ba92ad..b17350c265d 100644 --- a/src/server/scripts/Commands/CMakeLists.txt +++ b/src/server/scripts/Commands/CMakeLists.txt @@ -20,6 +20,7 @@ set(scripts_STAT_SRCS Commands/cs_gps.cpp Commands/cs_honor.cpp Commands/cs_learn.cpp + Commands/cs_misc.cpp Commands/cs_modify.cpp Commands/cs_npc.cpp Commands/cs_quest.cpp diff --git a/src/server/scripts/Commands/cs_misc.cpp b/src/server/scripts/Commands/cs_misc.cpp new file mode 100644 index 00000000000..fe4dc2af1e2 --- /dev/null +++ b/src/server/scripts/Commands/cs_misc.cpp @@ -0,0 +1,72 @@ +/*
+ * Copyright (C) 2008-2011 TrinityCore <http://www.trinitycore.org/>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ScriptPCH.h"
+#include "Chat.h"
+
+class misc_commandscript : public CommandScript
+{
+public:
+ misc_commandscript() : CommandScript("misc_commandscript") { }
+
+ ChatCommand* GetCommands() const
+ {
+ static ChatCommand commandTable[] =
+ {
+ { "dev", SEC_ADMINISTRATOR, false, &HandleDevCommand, "", NULL },
+ { NULL, 0, false, NULL, "", NULL }
+ };
+ return commandTable;
+ }
+
+ static bool HandleDevCommand(ChatHandler* handler, char const* args)
+ {
+ if (!*args)
+ {
+ if (handler->GetSession()->GetPlayer()->HasFlag(PLAYER_FLAGS, PLAYER_FLAGS_DEVELOPER))
+ handler->GetSession()->SendNotification(LANG_DEV_ON);
+ else
+ handler->GetSession()->SendNotification(LANG_DEV_OFF);
+ return true;
+ }
+
+ std::string argstr = (char*)args;
+
+ if (argstr == "on")
+ {
+ handler->GetSession()->GetPlayer()->SetFlag(PLAYER_FLAGS, PLAYER_FLAGS_DEVELOPER);
+ handler->GetSession()->SendNotification(LANG_DEV_ON);
+ return true;
+ }
+
+ if (argstr == "off")
+ {
+ handler->GetSession()->GetPlayer()->RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_DEVELOPER);
+ handler->GetSession()->SendNotification(LANG_DEV_OFF);
+ return true;
+ }
+
+ handler->SendSysMessage(LANG_USE_BOL);
+ handler->SetSentErrorMessage(true);
+ return false;
+ }
+};
+
+void AddSC_misc_commandscript()
+{
+ new misc_commandscript();
+}
diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp index 8c9741f407f..51a125d8c79 100755 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_northrend_beasts.cpp @@ -95,7 +95,7 @@ enum BossSpells SPELL_BURNING_SPRAY = 66902, SPELL_SWEEP_1 = 67646, SPELL_EMERGE_0 = 66947, - SPELL_SUBMERGE_0 = 53421, + SPELL_SUBMERGE_0 = 66948, SPELL_ENRAGE = 68335, SPELL_SLIME_POOL_EFFECT = 66882, //In 60s it diameter grows from 10y to 40y (r=r+0.25 per second) @@ -149,6 +149,27 @@ public: Summons.DespawnAll(); } + void EnterEvadeMode() + { + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_MAIN_GATE_DOOR)); + ScriptedAI::EnterEvadeMode(); + } + + void MovementInform(uint32 uiType, uint32 uiId) + { + if (uiType != POINT_MOTION_TYPE) return; + + switch (uiId) + { + case 0: + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_MAIN_GATE_DOOR)); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); + me->SetReactState(REACT_AGGRESSIVE); + me->SetInCombatWithZone(); + break; + } + } + void JustDied(Unit* /*killer*/) { if (m_pInstance) @@ -158,7 +179,10 @@ public: void JustReachedHome() { if (m_pInstance) + { + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_MAIN_GATE_DOOR)); m_pInstance->SetData(TYPE_NORTHREND_BEASTS, FAIL); + } me->DespawnOrUnsummon(); } @@ -265,6 +289,12 @@ public: me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); } + void EnterEvadeMode() + { + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_MAIN_GATE_DOOR)); + ScriptedAI::EnterEvadeMode(); + } + void EnterCombat(Unit* who) { m_uiTargetGUID = who->GetGUID(); @@ -397,7 +427,9 @@ struct boss_jormungarAI : public ScriptedAI void JustReachedHome() { if (instanceScript && instanceScript->GetData(TYPE_NORTHREND_BEASTS) != FAIL) + { instanceScript->SetData(TYPE_NORTHREND_BEASTS, FAIL); + } me->DespawnOrUnsummon(); } @@ -608,7 +640,12 @@ public: struct boss_dreadscaleAI : public boss_jormungarAI { - boss_dreadscaleAI(Creature* creature) : boss_jormungarAI(creature) { } + boss_dreadscaleAI(Creature* creature) : boss_jormungarAI(creature) + { + instanceScript = creature->GetInstanceScript(); + } + + InstanceScript* instanceScript; void Reset() { @@ -624,6 +661,42 @@ public: submergeTimer = 45 * IN_MILLISECONDS; stage = 0; } + + void MovementInform(uint32 uiType, uint32 uiId) + { + if (uiType != POINT_MOTION_TYPE) return; + + switch (uiId) + { + case 0: + instanceScript->DoUseDoorOrButton(instanceScript->GetData64(GO_MAIN_GATE_DOOR)); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); + me->SetReactState(REACT_AGGRESSIVE); + me->SetInCombatWithZone(); + if (Creature* otherWorm = Unit::GetCreature(*me, instanceScript->GetData64(otherWormEntry))) + { + otherWorm->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); + otherWorm->SetReactState(REACT_AGGRESSIVE); + otherWorm->SetVisible(true); + otherWorm->SetInCombatWithZone(); + } + break; + } + } + + void EnterEvadeMode() + { + instanceScript->DoUseDoorOrButton(instanceScript->GetData64(GO_MAIN_GATE_DOOR)); + boss_jormungarAI::EnterEvadeMode(); + } + + void JustReachedHome() + { + if (instanceScript) + instanceScript->DoUseDoorOrButton(instanceScript->GetData64(GO_MAIN_GATE_DOOR)); + + boss_jormungarAI::JustReachedHome(); + } }; CreatureAI* GetAI(Creature* creature) const @@ -746,13 +819,28 @@ public: case 1: // Finish trample m_bMovementFinish = true; break; + case 2: + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_MAIN_GATE_DOOR)); + me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); + me->SetReactState(REACT_AGGRESSIVE); + me->SetInCombatWithZone(); + break; } } + void EnterEvadeMode() + { + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_MAIN_GATE_DOOR)); + ScriptedAI::EnterEvadeMode(); + } + void JustReachedHome() { if (m_pInstance) + { + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_MAIN_GATE_DOOR)); m_pInstance->SetData(TYPE_NORTHREND_BEASTS, FAIL); + } me->DespawnOrUnsummon(); } diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp index d5dd7cf27dd..1c32debc45a 100755 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/boss_twin_valkyr.cpp @@ -53,50 +53,39 @@ enum Equipment enum Summons { - NPC_UNLEASHED_DARK = 34628, - NPC_UNLEASHED_LIGHT = 34630, + NPC_BULLET_CONTROLLER = 34743, - // Future Development - NPC_BULLET_CONTROLLER = 34743, // Npc controller for all bullets - - NPC_BULLET_STALKER_DARK = 34704, // Npc spawner for dark bullets - NPC_BULLET_STALKER_LIGHT = 34720, // Npc spawner for light bullets + NPC_BULLET_DARK = 34628, + NPC_BULLET_LIGHT = 34630, }; enum BossSpells { - SPELL_CONTROLLER_PERIODIC = 66149, // Future Development - SPELL_LIGHT_TWIN_SPIKE = 66075, SPELL_LIGHT_SURGE = 65766, SPELL_LIGHT_SHIELD = 65858, SPELL_LIGHT_TWIN_PACT = 65876, SPELL_LIGHT_VORTEX = 66046, SPELL_LIGHT_TOUCH = 67297, + SPELL_LIGHT_ESSENCE = 65686, + SPELL_EMPOWERED_LIGHT = 65748, + SPELL_TWIN_EMPATHY_LIGHT = 66133, + SPELL_UNLEASHED_LIGHT = 65795, SPELL_DARK_TWIN_SPIKE = 66069, SPELL_DARK_SURGE = 65768, SPELL_DARK_SHIELD = 65874, SPELL_DARK_TWIN_PACT = 65875, - SPELL_POWER_TWINS = 65879, SPELL_DARK_VORTEX = 66058, SPELL_DARK_TOUCH = 67282, - - SPELL_TWIN_POWER = 65916, - SPELL_LIGHT_ESSENCE = 65686, SPELL_DARK_ESSENCE = 65684, - SPELL_BERSERK = 64238, - SPELL_NONE = 0, - SPELL_EMPOWERED_DARK = 65724, - SPELL_EMPOWERED_LIGHT = 65748, - - SPELL_UNLEASHED_DARK = 65808, - SPELL_UNLEASHED_LIGHT = 65795, - - SPELL_TWIN_EMPATHY_1 = 66132, - SPELL_TWIN_EMPATHY_2 = 66133, - + SPELL_TWIN_EMPATHY_DARK = 66132, + SPELL_UNLEASHED_DARK = 65808, + + SPELL_CONTROLLER_PERIODIC = 66149, + SPELL_POWER_TWINS = 65879, + SPELL_BERSERK = 64238, SPELL_POWERING_UP = 67590, SPELL_SURGE_OF_SPEED = 65828, }; @@ -104,10 +93,10 @@ enum BossSpells #define SPELL_DARK_ESSENCE_HELPER RAID_MODE<uint32>(65684, 67176, 67177, 67178) #define SPELL_LIGHT_ESSENCE_HELPER RAID_MODE<uint32>(65686, 67222, 67223, 67224) -#define SPELL_POWERING_UP_HELPER RAID_MODE(67590, 67602, 67603, 67604) +#define SPELL_POWERING_UP_HELPER RAID_MODE<uint32>(67590, 67602, 67603, 67604) -#define SPELL_EMPOWERED_DARK_HELPER RAID_MODE<uint32>(65724,67213,67214,67215) -#define SPELL_EMPOWERED_LIGHT_HELPER RAID_MODE<uint32>(65748, 67216, 67217, 67218) +#define SPELL_UNLEASHED_DARK_HELPER RAID_MODE<uint32>(65808, 67172, 67173, 67174) +#define SPELL_UNLEASHED_LIGHT_HELPER RAID_MODE<uint32>(65795, 67238, 67239, 67240) enum Actions { @@ -119,6 +108,37 @@ enum Actions ## boss_twin_base ######*/ +class OrbsDespawner : public BasicEvent +{ + public: + explicit OrbsDespawner(Creature* creature) : _creature(creature) + { + } + + bool Execute(uint64 /*currTime*/, uint32 /*diff*/) + { + Trinity::CreatureWorker<OrbsDespawner> worker(_creature, *this); + _creature->VisitNearbyGridObject(5000.0f, worker); + return true; + } + + void operator()(Creature* creature) const + { + switch (creature->GetEntry()) + { + case NPC_BULLET_DARK: + case NPC_BULLET_LIGHT: + creature->DespawnOrUnsummon(); + return; + default: + return; + } + } + + private: + Creature* _creature; +}; + struct boss_twin_baseAI : public ScriptedAI { boss_twin_baseAI(Creature* creature) : ScriptedAI(creature), Summons(me) @@ -133,9 +153,7 @@ struct boss_twin_baseAI : public ScriptedAI uint8 m_uiStage; bool m_bIsBerserk; - uint8 m_uiWaveCount; uint32 m_uiWeapon; - uint32 m_uiColorballsTimer; uint32 m_uiSpecialAbilityTimer; uint32 m_uiSpikeTimer; uint32 m_uiTouchTimer; @@ -144,12 +162,8 @@ struct boss_twin_baseAI : public ScriptedAI int32 m_uiVortexSay; int32 m_uiVortexEmote; uint32 m_uiSisterNpcId; - uint32 m_uiColorballNpcId; uint32 m_uiMyEmphatySpellId; - uint32 m_uiEssenceNpcId; - uint32 m_uiMyEssenceSpellId; uint32 m_uiOtherEssenceSpellId; - uint32 m_uiEmpoweredWeaknessSpellId; uint32 m_uiSurgeSpellId; uint32 m_uiVortexSpellId; uint32 m_uiShieldSpellId; @@ -157,9 +171,6 @@ struct boss_twin_baseAI : public ScriptedAI uint32 m_uiSpikeSpellId; uint32 m_uiTouchSpellId; - Position HomeLocation; - Position EssenceLocation[2]; - void Reset() { me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); me->SetReactState(REACT_PASSIVE); @@ -169,8 +180,6 @@ struct boss_twin_baseAI : public ScriptedAI me->SetFlying(true); */ m_bIsBerserk = false; - m_uiWaveCount = 1; - m_uiColorballsTimer = 15*IN_MILLISECONDS; m_uiSpecialAbilityTimer = MINUTE*IN_MILLISECONDS; m_uiSpikeTimer = 20*IN_MILLISECONDS; m_uiTouchTimer = urand(10, 15)*IN_MILLISECONDS; @@ -182,9 +191,9 @@ struct boss_twin_baseAI : public ScriptedAI void JustReachedHome() { if (m_pInstance) - { m_pInstance->SetData(TYPE_VALKIRIES, FAIL); - } + + Summons.DespawnAll(); me->DespawnOrUnsummon(); } @@ -194,11 +203,8 @@ struct boss_twin_baseAI : public ScriptedAI switch (uiId) { - case 0: - me->GetMotionMaster()->MovePoint(1, HomeLocation.GetPositionX(), HomeLocation.GetPositionY(), HomeLocation.GetPositionZ()); - me->SetHomePosition(HomeLocation); - break; case 1: + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_MAIN_GATE_DOOR)); me->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); me->SetReactState(REACT_AGGRESSIVE); break; @@ -217,13 +223,6 @@ struct boss_twin_baseAI : public ScriptedAI void JustSummoned(Creature* summoned) { - switch (summoned->GetEntry()) - { - case NPC_UNLEASHED_DARK: - case NPC_UNLEASHED_LIGHT: - summoned->SetCorpseDelay(0); - break; - } Summons.Summon(summoned); } @@ -239,25 +238,13 @@ struct boss_twin_baseAI : public ScriptedAI m_pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_DARK_ESSENCE_HELPER); m_pInstance->DoRemoveAurasDueToSpellOnPlayers(SPELL_POWERING_UP_HELPER); break; + case NPC_BULLET_CONTROLLER: + me->m_Events.AddEvent(new OrbsDespawner(me), me->m_Events.CalculateTime(100)); + break; } Summons.Despawn(summoned); } - void SummonColorballs(uint8 quantity) - { - float x0 = ToCCommonLoc[1].GetPositionX(), y0 = ToCCommonLoc[1].GetPositionY(), r = 47.0f; - float y = y0; - for (uint8 i = 0; i < quantity; i++) - { - float x = float(urand(uint32(x0 - r), uint32(x0 + r))); - if (urand(0, 1)) - y = y0 + sqrt(pow(r, 2) - pow((x-x0), 2)); - else - y = y0 - sqrt(pow(r, 2) - pow((x-x0), 2)); - me->SummonCreature(m_uiColorballNpcId, x, y, me->GetPositionZ(), TEMPSUMMON_CORPSE_DESPAWN); - } - } - void JustDied(Unit* /*killer*/) { DoScriptText(SAY_DEATH, me); @@ -267,10 +254,17 @@ struct boss_twin_baseAI : public ScriptedAI { if (!pSister->isAlive()) { + me->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + pSister->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + m_pInstance->SetData(TYPE_VALKIRIES, DONE); Summons.DespawnAll(); } - else m_pInstance->SetData(TYPE_VALKIRIES, SPECIAL); + else + { + me->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE); + m_pInstance->SetData(TYPE_VALKIRIES, SPECIAL); + } } } Summons.DespawnAll(); @@ -288,15 +282,13 @@ struct boss_twin_baseAI : public ScriptedAI if (m_pInstance) { if (Creature* pSister = GetSister()) + { me->AddAura(m_uiMyEmphatySpellId, pSister); - + pSister->SetInCombatWithZone(); + } m_pInstance->SetData(TYPE_VALKIRIES, IN_PROGRESS); } - if (me->isAlive()) - { - me->SummonCreature(m_uiEssenceNpcId, EssenceLocation[0].GetPositionX(), EssenceLocation[0].GetPositionY(), EssenceLocation[0].GetPositionZ()); - me->SummonCreature(m_uiEssenceNpcId, EssenceLocation[1].GetPositionX(), EssenceLocation[1].GetPositionY(), EssenceLocation[1].GetPositionZ()); - } + DoScriptText(SAY_AGGRO, me); DoCast(me, m_uiSurgeSpellId); } @@ -310,12 +302,11 @@ struct boss_twin_baseAI : public ScriptedAI break; case ACTION_PACT: m_uiStage = me->GetEntry() == NPC_LIGHTBANE ? 1 : 2; - DoCast(me, SPELL_TWIN_POWER); break; } } - void EnableDualWield(bool mode) + void EnableDualWield(bool mode = true) { SetEquipmentSlots(false, m_uiWeapon, mode ? m_uiWeapon : EQUIP_UNEQUIP, EQUIP_UNEQUIP); me->SetCanDualWield(mode); @@ -384,23 +375,6 @@ struct boss_twin_baseAI : public ScriptedAI else m_uiTouchTimer -= uiDiff; - if (m_uiColorballsTimer <= uiDiff) - { - if (m_uiWaveCount >= 2) - { - SummonColorballs(12); - m_uiWaveCount = 0; - } - else - { - SummonColorballs(2); - m_uiWaveCount++; - } - m_uiColorballsTimer = 15*IN_MILLISECONDS; - } - else - m_uiColorballsTimer -= uiDiff; - if (!m_bIsBerserk && m_uiBerserkTimer <= uiDiff) { DoCast(me, SPELL_BERSERK); @@ -430,7 +404,12 @@ public: struct boss_fjolaAI : public boss_twin_baseAI { - boss_fjolaAI(Creature* creature) : boss_twin_baseAI(creature) {} + boss_fjolaAI(Creature* creature) : boss_twin_baseAI(creature) + { + m_pInstance = (InstanceScript*)creature->GetInstanceScript(); + } + + InstanceScript* m_pInstance; void Reset() { boss_twin_baseAI::Reset(); @@ -441,12 +420,8 @@ public: m_uiVortexEmote = EMOTE_LIGHT_VORTEX; m_uiVortexSay = SAY_LIGHT_VORTEX; m_uiSisterNpcId = NPC_DARKBANE; - m_uiColorballNpcId = NPC_UNLEASHED_LIGHT; - m_uiEssenceNpcId = NPC_LIGHT_ESSENCE; - m_uiMyEmphatySpellId = SPELL_TWIN_EMPATHY_1; - m_uiMyEssenceSpellId = SPELL_LIGHT_ESSENCE_HELPER; + m_uiMyEmphatySpellId = SPELL_TWIN_EMPATHY_DARK; m_uiOtherEssenceSpellId = SPELL_DARK_ESSENCE_HELPER; - m_uiEmpoweredWeaknessSpellId = SPELL_EMPOWERED_DARK_HELPER; m_uiSurgeSpellId = SPELL_LIGHT_SURGE; m_uiVortexSpellId = SPELL_LIGHT_VORTEX; m_uiShieldSpellId = SPELL_LIGHT_SHIELD; @@ -454,10 +429,6 @@ public: m_uiTouchSpellId = SPELL_LIGHT_TOUCH; m_uiSpikeSpellId = SPELL_LIGHT_TWIN_SPIKE; - HomeLocation = ToCCommonLoc[8]; - EssenceLocation[0] = TwinValkyrsLoc[2]; - EssenceLocation[1] = TwinValkyrsLoc[3]; - if (m_pInstance) { m_pInstance->DoStopTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, EVENT_START_TWINS_FIGHT); @@ -466,11 +437,27 @@ public: void EnterCombat(Unit* who) { - boss_twin_baseAI::EnterCombat(who); if (m_pInstance) { m_pInstance->DoStartTimedAchievement(ACHIEVEMENT_TIMED_TYPE_EVENT, EVENT_START_TWINS_FIGHT); } + + me->SummonCreature(NPC_BULLET_CONTROLLER, ToCCommonLoc[1].GetPositionX(), ToCCommonLoc[1].GetPositionY(), ToCCommonLoc[1].GetPositionZ(), 0.0f, TEMPSUMMON_MANUAL_DESPAWN); + boss_twin_baseAI::EnterCombat(who); + } + + void EnterEvadeMode() + { + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_MAIN_GATE_DOOR)); + boss_twin_baseAI::EnterEvadeMode(); + } + + void JustReachedHome() + { + if (m_pInstance) + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_MAIN_GATE_DOOR)); + + boss_twin_baseAI::JustReachedHome(); } }; @@ -503,22 +490,14 @@ public: m_uiVortexEmote = EMOTE_DARK_VORTEX; m_uiVortexSay = SAY_DARK_VORTEX; m_uiSisterNpcId = NPC_LIGHTBANE; - m_uiColorballNpcId = NPC_UNLEASHED_DARK; - m_uiEssenceNpcId = NPC_DARK_ESSENCE; - m_uiMyEmphatySpellId = SPELL_TWIN_EMPATHY_2; - m_uiMyEssenceSpellId = SPELL_DARK_ESSENCE_HELPER; + m_uiMyEmphatySpellId = SPELL_TWIN_EMPATHY_LIGHT; m_uiOtherEssenceSpellId = SPELL_LIGHT_ESSENCE_HELPER; - m_uiEmpoweredWeaknessSpellId = SPELL_EMPOWERED_LIGHT_HELPER; m_uiSurgeSpellId = SPELL_DARK_SURGE; m_uiVortexSpellId = SPELL_DARK_VORTEX; m_uiShieldSpellId = SPELL_DARK_SHIELD; m_uiTwinPactSpellId = SPELL_DARK_TWIN_PACT; m_uiTouchSpellId = SPELL_DARK_TOUCH; m_uiSpikeSpellId = SPELL_DARK_TWIN_SPIKE; - - HomeLocation = ToCCommonLoc[9]; - EssenceLocation[0] = TwinValkyrsLoc[0]; - EssenceLocation[1] = TwinValkyrsLoc[1]; } }; @@ -648,10 +627,13 @@ public: else m_uiRangeCheckTimer -= uiDiff; } - void SpellHitTarget(Unit* who, const SpellInfo* /*spell*/) + void SpellHitTarget(Unit* who, SpellInfo const* spell) { - if (who->HasAura(SPELL_DARK_ESSENCE_HELPER)) - who->CastSpell(who, SPELL_POWERING_UP, true); + if (spell->Id == SPELL_UNLEASHED_DARK_HELPER) + { + if (who->HasAura(SPELL_DARK_ESSENCE_HELPER)) + who->CastSpell(who, SPELL_POWERING_UP, true); + } } }; @@ -687,15 +669,47 @@ public: else m_uiRangeCheckTimer -= uiDiff; } - void SpellHitTarget(Unit* who, const SpellInfo* /*spell*/) + void SpellHitTarget(Unit* who, SpellInfo const* spell) { - if (who->HasAura(SPELL_LIGHT_ESSENCE_HELPER)) - who->CastSpell(who, SPELL_POWERING_UP, true); + if (spell->Id == SPELL_UNLEASHED_LIGHT_HELPER) + { + if (who->HasAura(SPELL_LIGHT_ESSENCE_HELPER)) + who->CastSpell(who, SPELL_POWERING_UP, true); + } } }; }; +class mob_bullet_controller : public CreatureScript +{ +public: + mob_bullet_controller() : CreatureScript("mob_bullet_controller") { } + + CreatureAI* GetAI(Creature* creature) const + { + return new mob_bullet_controllerAI(creature); + } + + struct mob_bullet_controllerAI : public Scripted_NoMovementAI + { + mob_bullet_controllerAI(Creature* creature) : Scripted_NoMovementAI(creature) + { + Reset(); + } + + void Reset() + { + DoCastAOE(SPELL_CONTROLLER_PERIODIC); + } + + void UpdateAI(const uint32 /*uiDiff*/) + { + UpdateVictim(); + } + }; +}; + class spell_powering_up : public SpellScriptLoader { public: @@ -860,6 +874,7 @@ void AddSC_boss_twin_valkyr() new mob_unleashed_light(); new mob_unleashed_dark(); new mob_essence_of_twin(); + new mob_bullet_controller(); new spell_powering_up(); new spell_valkyr_essences(); new spell_power_of_the_twins(); diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp index 34c065f5649..dd772a14b5d 100755 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.cpp @@ -553,17 +553,16 @@ class npc_tirion_toc : public CreatureScript DoScriptText(SAY_STAGE_0_02, me); m_uiUpdateTimer = 5000; m_pInstance->SetData(TYPE_EVENT, 150); - m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_MAIN_GATE_DOOR)); break; case 150: me->SetUInt32Value(UNIT_NPC_EMOTESTATE, EMOTE_STATE_NONE); if (m_pInstance->GetData(TYPE_BEASTS) != DONE) { - me->SummonCreature(NPC_GORMOK, ToCCommonLoc[10].GetPositionX(), ToCCommonLoc[10].GetPositionY(), ToCCommonLoc[10].GetPositionZ(), 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30*IN_MILLISECONDS); - if (Creature* pTemp = Unit::GetCreature((*me), m_pInstance->GetData64(NPC_GORMOK))) + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_MAIN_GATE_DOOR)); + + if (Creature* pTemp = me->SummonCreature(NPC_GORMOK, ToCSpawnLoc[0].GetPositionX(), ToCSpawnLoc[0].GetPositionY(), ToCSpawnLoc[0].GetPositionZ(), 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, 30*IN_MILLISECONDS)) { pTemp->GetMotionMaster()->MovePoint(0, ToCCommonLoc[5].GetPositionX(), ToCCommonLoc[5].GetPositionY(), ToCCommonLoc[5].GetPositionZ()); - pTemp->AddUnitMovementFlag(MOVEMENTFLAG_WALKING); pTemp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); pTemp->SetReactState(REACT_PASSIVE); } @@ -572,13 +571,6 @@ class npc_tirion_toc : public CreatureScript m_pInstance->SetData(TYPE_EVENT, 155); break; case 155: - if (Creature* pTemp = Unit::GetCreature((*me), m_pInstance->GetData64(NPC_GORMOK))) - { - pTemp->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); - pTemp->SetReactState(REACT_AGGRESSIVE); - pTemp->SetInCombatWithZone(); - } - m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_MAIN_GATE_DOOR)); m_pInstance->SetData(TYPE_BEASTS, IN_PROGRESS); m_uiUpdateTimer = 5000; m_pInstance->SetData(TYPE_EVENT, 160); @@ -591,24 +583,20 @@ class npc_tirion_toc : public CreatureScript case 205: m_uiUpdateTimer = 3000; m_pInstance->SetData(TYPE_EVENT, 210); - m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_MAIN_GATE_DOOR)); break; case 210: if (m_pInstance->GetData(TYPE_BEASTS) != DONE) { - me->SummonCreature(NPC_DREADSCALE, ToCCommonLoc[3].GetPositionX(), ToCCommonLoc[3].GetPositionY(), ToCCommonLoc[3].GetPositionZ(), 5, TEMPSUMMON_MANUAL_DESPAWN); - me->SummonCreature(NPC_ACIDMAW, ToCCommonLoc[4].GetPositionX(), ToCCommonLoc[4].GetPositionY(), ToCCommonLoc[4].GetPositionZ(), 5, TEMPSUMMON_MANUAL_DESPAWN); - if (Creature* pTemp = Unit::GetCreature((*me), m_pInstance->GetData64(NPC_DREADSCALE))) + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_MAIN_GATE_DOOR)); + if (Creature* pTemp = me->SummonCreature(NPC_DREADSCALE, ToCSpawnLoc[1].GetPositionX(), ToCSpawnLoc[1].GetPositionY(), ToCSpawnLoc[1].GetPositionZ(), 5, TEMPSUMMON_MANUAL_DESPAWN)) { pTemp->GetMotionMaster()->MovePoint(0, ToCCommonLoc[8].GetPositionX(), ToCCommonLoc[8].GetPositionY(), ToCCommonLoc[8].GetPositionZ()); - pTemp->AddUnitMovementFlag(MOVEMENTFLAG_WALKING); pTemp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); pTemp->SetReactState(REACT_PASSIVE); } - if (Creature* pTemp = Unit::GetCreature((*me), m_pInstance->GetData64(NPC_ACIDMAW))) + if (Creature* pTemp = me->SummonCreature(NPC_ACIDMAW, ToCCommonLoc[9].GetPositionX(), ToCCommonLoc[9].GetPositionY(), ToCCommonLoc[9].GetPositionZ(), 5, TEMPSUMMON_MANUAL_DESPAWN)) { - pTemp->GetMotionMaster()->MovePoint(0, ToCCommonLoc[9].GetPositionX(), ToCCommonLoc[9].GetPositionY(), ToCCommonLoc[9].GetPositionZ()); - pTemp->AddUnitMovementFlag(MOVEMENTFLAG_WALKING); + pTemp->SetVisible(true); pTemp->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); pTemp->SetReactState(REACT_PASSIVE); } @@ -617,20 +605,7 @@ class npc_tirion_toc : public CreatureScript m_pInstance->SetData(TYPE_EVENT, 220); break; case 220: - if (Creature* pTemp = Unit::GetCreature((*me), m_pInstance->GetData64(NPC_DREADSCALE))) - { - pTemp->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); - pTemp->SetReactState(REACT_AGGRESSIVE); - pTemp->SetInCombatWithZone(); - } - if (Creature* pTemp = Unit::GetCreature((*me), m_pInstance->GetData64(NPC_ACIDMAW))) - { - pTemp->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); - pTemp->SetReactState(REACT_AGGRESSIVE); - pTemp->SetInCombatWithZone(); - } m_pInstance->SetData(TYPE_EVENT, 230); - m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_MAIN_GATE_DOOR)); break; case 300: DoScriptText(SAY_STAGE_0_05, me); @@ -640,23 +615,23 @@ class npc_tirion_toc : public CreatureScript case 305: m_uiUpdateTimer = 3000; m_pInstance->SetData(TYPE_EVENT, 310); - m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_MAIN_GATE_DOOR)); break; case 310: if (m_pInstance->GetData(TYPE_BEASTS) != DONE) { - me->SummonCreature(NPC_ICEHOWL, ToCCommonLoc[10].GetPositionX(), ToCCommonLoc[10].GetPositionY(), ToCCommonLoc[10].GetPositionZ(), 5, TEMPSUMMON_DEAD_DESPAWN); - if (Creature* pTemp = Unit::GetCreature((*me), m_pInstance->GetData64(NPC_ICEHOWL))) + m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_MAIN_GATE_DOOR)); + if (Creature* pTemp = me->SummonCreature(NPC_ICEHOWL, ToCSpawnLoc[0].GetPositionX(), ToCSpawnLoc[0].GetPositionY(), ToCSpawnLoc[0].GetPositionZ(), 5, TEMPSUMMON_DEAD_DESPAWN)) { - pTemp->GetMotionMaster()->MovePoint(0, ToCCommonLoc[5].GetPositionX(), ToCCommonLoc[5].GetPositionY(), ToCCommonLoc[5].GetPositionZ()); - pTemp->SetInCombatWithZone(); + pTemp->GetMotionMaster()->MovePoint(2, ToCCommonLoc[5].GetPositionX(), ToCCommonLoc[5].GetPositionY(), ToCCommonLoc[5].GetPositionZ()); + me->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NON_ATTACKABLE | UNIT_FLAG_OOC_NOT_ATTACKABLE | UNIT_FLAG_NOT_SELECTABLE); + me->SetReactState(REACT_PASSIVE); + } } m_uiUpdateTimer = 5000; m_pInstance->SetData(TYPE_EVENT, 315); break; case 315: - m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_MAIN_GATE_DOOR)); m_pInstance->SetData(TYPE_EVENT, 320); break; case 400: @@ -673,7 +648,7 @@ class npc_tirion_toc : public CreatureScript DoScriptText(SAY_STAGE_1_01, me); m_uiUpdateTimer = 7000; m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_MAIN_GATE_DOOR)); - me->SummonCreature(NPC_FIZZLEBANG, ToCCommonLoc[10].GetPositionX(), ToCCommonLoc[10].GetPositionY(), ToCCommonLoc[10].GetPositionZ(), 2, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); + me->SummonCreature(NPC_FIZZLEBANG, ToCSpawnLoc[0].GetPositionX(), ToCSpawnLoc[0].GetPositionY(), ToCSpawnLoc[0].GetPositionZ(), 2, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME); m_pInstance->SetData(TYPE_EVENT, 0); break; case 1180: @@ -713,16 +688,14 @@ class npc_tirion_toc : public CreatureScript break; //Summoning crusaders case 3091: - me->SummonCreature(NPC_CHAMPIONS_CONTROLLER, ToCCommonLoc[1]); - if (Creature* pChampionController = Unit::GetCreature((*me), m_pInstance->GetData64(NPC_CHAMPIONS_CONTROLLER))) + if (Creature* pChampionController = me->SummonCreature(NPC_CHAMPIONS_CONTROLLER, ToCCommonLoc[1])) pChampionController->AI()->SetData(0, HORDE); m_uiUpdateTimer = 3000; m_pInstance->SetData(TYPE_EVENT, 3092); break; //Summoning crusaders case 3090: - me->SummonCreature(NPC_CHAMPIONS_CONTROLLER, ToCCommonLoc[1]); - if (Creature* pChampionController = Unit::GetCreature((*me), m_pInstance->GetData64(NPC_CHAMPIONS_CONTROLLER))) + if (Creature* pChampionController = me->SummonCreature(NPC_CHAMPIONS_CONTROLLER, ToCCommonLoc[1])) pChampionController->AI()->SetData(0, ALLIANCE); m_uiUpdateTimer = 3000; m_pInstance->SetData(TYPE_EVENT, 3092); @@ -745,14 +718,14 @@ class npc_tirion_toc : public CreatureScript break; case 4010: DoScriptText(SAY_STAGE_3_02, me); - if(Creature* pTemp = me->SummonCreature(NPC_LIGHTBANE, ToCCommonLoc[3].GetPositionX(), ToCCommonLoc[3].GetPositionY(), ToCCommonLoc[3].GetPositionZ(), 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME)) + if(Creature* pTemp = me->SummonCreature(NPC_LIGHTBANE, ToCSpawnLoc[1].GetPositionX(), ToCSpawnLoc[1].GetPositionY(), ToCSpawnLoc[1].GetPositionZ(), 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME)) { pTemp->SetVisible(false); pTemp->SetReactState(REACT_PASSIVE); pTemp->SummonCreature(NPC_LIGHT_ESSENCE, TwinValkyrsLoc[0].GetPositionX(), TwinValkyrsLoc[0].GetPositionY(), TwinValkyrsLoc[0].GetPositionZ()); pTemp->SummonCreature(NPC_LIGHT_ESSENCE, TwinValkyrsLoc[1].GetPositionX(), TwinValkyrsLoc[1].GetPositionY(), TwinValkyrsLoc[1].GetPositionZ()); } - if(Creature* pTemp = me->SummonCreature(NPC_DARKBANE, ToCCommonLoc[4].GetPositionX(), ToCCommonLoc[4].GetPositionY(), ToCCommonLoc[4].GetPositionZ(), 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME)) + if(Creature* pTemp = me->SummonCreature(NPC_DARKBANE, ToCSpawnLoc[2].GetPositionX(), ToCSpawnLoc[2].GetPositionY(), ToCSpawnLoc[2].GetPositionZ(), 5, TEMPSUMMON_CORPSE_TIMED_DESPAWN, DESPAWN_TIME)) { pTemp->SetVisible(false); pTemp->SetReactState(REACT_PASSIVE); @@ -766,14 +739,12 @@ class npc_tirion_toc : public CreatureScript m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_MAIN_GATE_DOOR)); if (Creature* pTemp = Unit::GetCreature((*me), m_pInstance->GetData64(NPC_LIGHTBANE))) { - pTemp->GetMotionMaster()->MovePoint(0, ToCCommonLoc[6].GetPositionX(), ToCCommonLoc[6].GetPositionY(), ToCCommonLoc[6].GetPositionZ()); - pTemp->AddUnitMovementFlag(MOVEMENTFLAG_WALKING); + pTemp->GetMotionMaster()->MovePoint(1, ToCCommonLoc[8].GetPositionX(), ToCCommonLoc[8].GetPositionY(), ToCCommonLoc[8].GetPositionZ()); pTemp->SetVisible(true); } if (Creature* pTemp = Unit::GetCreature((*me), m_pInstance->GetData64(NPC_DARKBANE))) { - pTemp->GetMotionMaster()->MovePoint(0, ToCCommonLoc[7].GetPositionX(), ToCCommonLoc[7].GetPositionY(), ToCCommonLoc[7].GetPositionZ()); - pTemp->AddUnitMovementFlag(MOVEMENTFLAG_WALKING); + pTemp->GetMotionMaster()->MovePoint(1, ToCCommonLoc[9].GetPositionX(), ToCCommonLoc[9].GetPositionY(), ToCCommonLoc[9].GetPositionZ()); pTemp->SetVisible(true); } m_uiUpdateTimer = 5000; @@ -781,7 +752,6 @@ class npc_tirion_toc : public CreatureScript break; case 4016: m_pInstance->SetData(TYPE_EVENT, 4017); - m_pInstance->DoUseDoorOrButton(m_pInstance->GetData64(GO_MAIN_GATE_DOOR)); break; case 4040: m_uiUpdateTimer = 60000; @@ -795,7 +765,7 @@ class npc_tirion_toc : public CreatureScript case 5005: m_uiUpdateTimer = 8000; m_pInstance->SetData(TYPE_EVENT, 5010); - me->SummonCreature(NPC_LICH_KING_1, ToCCommonLoc[2].GetPositionX(), ToCCommonLoc[2].GetPositionY(), ToCCommonLoc[2].GetPositionZ(), 5); + me->SummonCreature(NPC_LICH_KING_1, ToCSpawnLoc[0].GetPositionX(), ToCSpawnLoc[0].GetPositionY(), ToCSpawnLoc[0].GetPositionZ(), 5); break; case 5020: DoScriptText(SAY_STAGE_4_03, me); diff --git a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h index a0ee721a26a..99525b6fb32 100644 --- a/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h +++ b/src/server/scripts/Northrend/CrusadersColiseum/TrialOfTheCrusader/trial_of_the_crusader.h @@ -35,6 +35,13 @@ enum DESPAWN_TIME = 300000, }; +const Position ToCSpawnLoc[]= +{ + {563.912f, 261.625f, 394.73f, 4.70437f}, // 0 Center + {575.451f, 261.496f, 394.73f, 4.6541f}, // 1 Left + {549.951f, 261.55f, 394.73f, 4.74835f}, // 2 Right +}; + const Position ToCCommonLoc[]= { {559.257996f, 90.266197f, 395.122986f, 0}, // 0 Barrent diff --git a/src/server/scripts/Northrend/Ulduar/ulduar/boss_kologarn.cpp b/src/server/scripts/Northrend/Ulduar/ulduar/boss_kologarn.cpp index e75baffe600..aa419c2fdbc 100644 --- a/src/server/scripts/Northrend/Ulduar/ulduar/boss_kologarn.cpp +++ b/src/server/scripts/Northrend/Ulduar/ulduar/boss_kologarn.cpp @@ -158,11 +158,10 @@ class boss_kologarn : public CreatureScript left = apply; if (!apply && isEncounterInProgress) { + who->ToCreature()->DisappearAndDie(); DoScriptText(SAY_LEFT_ARM_GONE, me); events.ScheduleEvent(EVENT_RESPAWN_LEFT_ARM, 40000); } - else - instance->SetData64(DATA_LEFT_ARM, who->GetGUID()); } else if (who->GetEntry() == NPC_RIGHT_ARM) @@ -170,11 +169,10 @@ class boss_kologarn : public CreatureScript right = apply; if (!apply && isEncounterInProgress) { + who->ToCreature()->DisappearAndDie(); DoScriptText(SAY_RIGHT_ARM_GONE, me); events.ScheduleEvent(EVENT_RESPAWN_RIGHT_ARM, 40000); } - else - instance->SetData64(DATA_RIGHT_ARM, who->GetGUID()); } if (!isEncounterInProgress) @@ -249,80 +247,69 @@ class boss_kologarn : public CreatureScript if (me->HasUnitState(UNIT_STAT_CASTING)) return; - switch (events.GetEvent()) + while (uint32 eventId = events.ExecuteEvent()) { - case EVENT_MELEE_CHECK: - if (!me->IsWithinMeleeRange(me->getVictim())) - DoCast(SPELL_PETRIFY_BREATH); - events.RepeatEvent(1000); - break; - case EVENT_SWEEP: - if (left) - DoCast(me->FindNearestCreature(NPC_ARM_SWEEP_STALKER, 500.0f, true), SPELL_ARM_SWEEP, true); - events.RepeatEvent(25000); - break; - case EVENT_SMASH: - if (left && right) - DoCastVictim(SPELL_TWO_ARM_SMASH); - else if (left || right) - DoCastVictim(SPELL_ONE_ARM_SMASH); - events.RepeatEvent(15000); - break; - case EVENT_STONE_SHOUT: - DoCast(SPELL_STONE_SHOUT); - events.RepeatEvent(2000); - break; - case EVENT_ENRAGE: - DoCast(SPELL_BERSERK); - DoScriptText(SAY_BERSERK, me); - events.CancelEvent(EVENT_ENRAGE); - break; - case EVENT_RESPAWN_LEFT_ARM: - { - if (Creature* arm = Unit::GetCreature(*me, instance->GetData64(DATA_LEFT_ARM))) - RespawnArm(arm->ToCreature()); - events.CancelEvent(EVENT_RESPAWN_LEFT_ARM); - break; - } - case EVENT_RESPAWN_RIGHT_ARM: - { - if (Creature* arm = Unit::GetCreature(*me, instance->GetData64(DATA_RIGHT_ARM))) - RespawnArm(arm->ToCreature()); - events.CancelEvent(EVENT_RESPAWN_RIGHT_ARM); - break; - } - case EVENT_STONE_GRIP: + switch (eventId) { - if (right) + case EVENT_MELEE_CHECK: + if (!me->IsWithinMeleeRange(me->getVictim())) + DoCast(SPELL_PETRIFY_BREATH); + events.ScheduleEvent(EVENT_MELEE_CHECK, 1 * IN_MILLISECONDS); + break; + case EVENT_SWEEP: + if (left) + DoCast(me->FindNearestCreature(NPC_ARM_SWEEP_STALKER, 500.0f, true), SPELL_ARM_SWEEP, true); + events.ScheduleEvent(EVENT_SWEEP, 25 * IN_MILLISECONDS); + break; + case EVENT_SMASH: + if (left && right) + DoCastVictim(SPELL_TWO_ARM_SMASH); + else if (left || right) + DoCastVictim(SPELL_ONE_ARM_SMASH); + events.ScheduleEvent(EVENT_SMASH, 15 * IN_MILLISECONDS); + break; + case EVENT_STONE_SHOUT: + DoCast(SPELL_STONE_SHOUT); + events.ScheduleEvent(EVENT_STONE_SHOUT, 2 * IN_MILLISECONDS); + break; + case EVENT_ENRAGE: + DoCast(SPELL_BERSERK); + DoScriptText(SAY_BERSERK, me); + break; + case EVENT_RESPAWN_LEFT_ARM: + case EVENT_RESPAWN_RIGHT_ARM: { - DoCast(SPELL_STONE_GRIP); - DoScriptText(SAY_GRAB_PLAYER, me); + if (vehicle) + { + int8 seat = eventId == EVENT_RESPAWN_LEFT_ARM ? 0 : 1; + uint32 entry = eventId == EVENT_RESPAWN_LEFT_ARM ? NPC_LEFT_ARM : NPC_RIGHT_ARM; + vehicle->InstallAccessory(entry, seat, true, TEMPSUMMON_MANUAL_DESPAWN, 0); + } + break; } - events.RepeatEvent(25000); - } - break; - case EVENT_FOCUSED_EYEBEAM: - if (Unit* eyebeamTargetUnit = SelectTarget(SELECT_TARGET_FARTHEST, 0, 0, true)) + case EVENT_STONE_GRIP: { - eyebeamTarget = eyebeamTargetUnit->GetGUID(); - DoCast(SPELL_SUMMON_FOCUSED_EYEBEAM); + if (right) + { + DoCast(SPELL_STONE_GRIP); + DoScriptText(SAY_GRAB_PLAYER, me); + } + events.ScheduleEvent(EVENT_STONE_GRIP, 25 * IN_MILLISECONDS); } - events.RepeatEvent(urand(15000, 35000)); break; + case EVENT_FOCUSED_EYEBEAM: + if (Unit* eyebeamTargetUnit = SelectTarget(SELECT_TARGET_FARTHEST, 0, 0, true)) + { + eyebeamTarget = eyebeamTargetUnit->GetGUID(); + DoCast(me, SPELL_SUMMON_FOCUSED_EYEBEAM, true); + } + events.ScheduleEvent(EVENT_FOCUSED_EYEBEAM, urand(15, 35) * IN_MILLISECONDS); + break; + } } DoMeleeAttackIfReady(); } - - void RespawnArm(Creature* arm) - { - if (!arm->isAlive()) - arm->Respawn(); - - int32 seatId = arm->GetEntry() == NPC_LEFT_ARM ? 0 : 1; - arm->CastCustomSpell(SPELL_ARM_ENTER_VEHICLE, SPELLVALUE_BASE_POINT0, seatId+1, me, true); - arm->CastSpell(arm, SPELL_ARM_ENTER_VISUAL, true); - } }; CreatureAI* GetAI(Creature* creature) const @@ -629,6 +616,34 @@ class spell_kologarn_stone_shout : public SpellScriptLoader } }; +class spell_kologarn_summon_focused_eyebeam : public SpellScriptLoader +{ + public: + spell_kologarn_summon_focused_eyebeam() : SpellScriptLoader("spell_kologarn_summon_focused_eyebeam") { } + + class spell_kologarn_summon_focused_eyebeam_SpellScript : public SpellScript + { + PrepareSpellScript(spell_kologarn_summon_focused_eyebeam_SpellScript); + + void HandleForceCast(SpellEffIndex eff) + { + PreventHitDefaultEffect(eff); + GetCaster()->CastSpell(GetCaster(), GetSpellInfo()->Effects[eff].TriggerSpell, true); + } + + void Register() + { + OnEffect += SpellEffectFn(spell_kologarn_summon_focused_eyebeam_SpellScript::HandleForceCast, EFFECT_0, SPELL_EFFECT_FORCE_CAST); + OnEffect += SpellEffectFn(spell_kologarn_summon_focused_eyebeam_SpellScript::HandleForceCast, EFFECT_1, SPELL_EFFECT_FORCE_CAST); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_kologarn_summon_focused_eyebeam_SpellScript(); + } +}; + void AddSC_boss_kologarn() { new boss_kologarn(); @@ -639,4 +654,5 @@ void AddSC_boss_kologarn() new spell_ulduar_stone_grip_absorb(); new spell_ulduar_stone_grip(); new spell_kologarn_stone_shout(); + new spell_kologarn_summon_focused_eyebeam(); } diff --git a/src/server/scripts/Northrend/Ulduar/ulduar/boss_xt002.cpp b/src/server/scripts/Northrend/Ulduar/ulduar/boss_xt002.cpp index a6f67c6f970..09fcabbd147 100644 --- a/src/server/scripts/Northrend/Ulduar/ulduar/boss_xt002.cpp +++ b/src/server/scripts/Northrend/Ulduar/ulduar/boss_xt002.cpp @@ -258,7 +258,7 @@ class boss_xt002 : public CreatureScript void UpdateAI(const uint32 diff) { - if (!UpdateVictim()) + if (!UpdateVictim() || !CheckInRoom()) return; events.Update(diff); @@ -274,18 +274,18 @@ class boss_xt002 : public CreatureScript if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) DoCast(target, RAID_MODE(SPELL_SEARING_LIGHT_10, SPELL_SEARING_LIGHT_25)); - events.RepeatEvent(TIMER_SEARING_LIGHT); + events.ScheduleEvent(EVENT_SEARING_LIGHT, TIMER_SEARING_LIGHT); break; case EVENT_GRAVITY_BOMB: if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0)) DoCast(target, RAID_MODE(SPELL_GRAVITY_BOMB_10, SPELL_GRAVITY_BOMB_25)); - events.RepeatEvent(TIMER_GRAVITY_BOMB); + events.ScheduleEvent(EVENT_GRAVITY_BOMB, TIMER_GRAVITY_BOMB); break; case EVENT_TYMPANIC_TANTRUM: DoScriptText(SAY_TYMPANIC_TANTRUM, me); DoCast(SPELL_TYMPANIC_TANTRUM); - events.RepeatEvent(urand(TIMER_TYMPANIC_TANTRUM_MIN, TIMER_TYMPANIC_TANTRUM_MAX)); + events.ScheduleEvent(EVENT_TYMPANIC_TANTRUM, urand(TIMER_TYMPANIC_TANTRUM_MIN, TIMER_TYMPANIC_TANTRUM_MAX)); break; case EVENT_DISPOSE_HEART: SetPhaseOne(); @@ -352,7 +352,7 @@ class boss_xt002 : public CreatureScript { DoScriptText(SAY_HEART_OPENED, me); - DoCast(SPELL_SUBMERGE); // WIll make creature untargetable + DoCast(me, SPELL_SUBMERGE); // WIll make creature untargetable me->AttackStop(); me->SetReactState(REACT_PASSIVE); @@ -383,7 +383,7 @@ class boss_xt002 : public CreatureScript { DoScriptText(SAY_HEART_CLOSED, me); - DoCast(SPELL_STAND); + DoCast(me, SPELL_STAND); me->SetReactState(REACT_AGGRESSIVE); _phase = 1; @@ -974,12 +974,12 @@ class spell_xt002_submerged : public SpellScriptLoader void HandleScript(SpellEffIndex /*eff*/) { - Unit* caster = GetCaster(); - if (!caster) + Creature* target = GetHitCreature(); + if (!target) return; - caster->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); - caster->SetByteValue(UNIT_FIELD_BYTES_1, 0, UNIT_STAND_STATE_SUBMERGED); + target->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); + target->SetByteValue(UNIT_FIELD_BYTES_1, 0, UNIT_STAND_STATE_SUBMERGED); } void Register() @@ -1005,7 +1005,7 @@ class spell_xt002_stand : public SpellScriptLoader void HandleScript(SpellEffIndex /*eff*/) { - Unit* target = GetTargetUnit(); + Creature* target = GetHitCreature(); if (!target) return; diff --git a/src/server/scripts/Northrend/Ulduar/ulduar/instance_ulduar.cpp b/src/server/scripts/Northrend/Ulduar/ulduar/instance_ulduar.cpp index 748de08f5e0..93a865f6c2e 100644 --- a/src/server/scripts/Northrend/Ulduar/ulduar/instance_ulduar.cpp +++ b/src/server/scripts/Northrend/Ulduar/ulduar/instance_ulduar.cpp @@ -22,8 +22,9 @@ static DoorData const doorData[] = { - { GO_LEVIATHAN_DOOR, BOSS_LEVIATHAN, DOOR_TYPE_ROOM, BOUNDARY_S }, - { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE }, + { GO_LEVIATHAN_DOOR, BOSS_LEVIATHAN, DOOR_TYPE_ROOM, BOUNDARY_S }, + { GO_XT_002_DOOR, BOSS_XT002, DOOR_TYPE_ROOM, BOUNDARY_S }, + { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE }, }; class instance_ulduar : public InstanceMapScript @@ -49,8 +50,6 @@ class instance_ulduar : public InstanceMapScript uint64 XTToyPileGUIDs[4]; uint64 AssemblyGUIDs[3]; uint64 KologarnGUID; - uint64 LeftArmGUID; - uint64 RightArmGUID; uint64 AuriayaGUID; uint64 MimironGUID; uint64 HodirGUID; @@ -94,8 +93,6 @@ class instance_ulduar : public InstanceMapScript ExpeditionCommanderGUID = 0; XT002GUID = 0; KologarnGUID = 0; - LeftArmGUID = 0; - RightArmGUID = 0; AuriayaGUID = 0; MimironGUID = 0; HodirGUID = 0; @@ -316,6 +313,9 @@ class instance_ulduar : public InstanceMapScript if (GetBossState(BOSS_LEVIATHAN) == DONE) gameObject->SetGoState(GO_STATE_ACTIVE_ALTERNATIVE); break; + case GO_XT_002_DOOR: + AddDoor(gameObject, true); + break; case GO_VEZAX_DOOR: VezaxDoorGUID = gameObject->GetGUID(); HandleGameObject(0, false, gameObject); @@ -356,6 +356,8 @@ class instance_ulduar : public InstanceMapScript case GO_LEVIATHAN_DOOR: AddDoor(gameObject, false); break; + case GO_XT_002_DOOR: + AddDoor(gameObject, false); default: break; } @@ -435,7 +437,10 @@ class instance_ulduar : public InstanceMapScript if (state == DONE) { if (GameObject* gameObject = instance->GetGameObject(KologarnChestGUID)) + { gameObject->SetRespawnTime(gameObject->GetRespawnDelay()); + gameObject->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NOT_SELECTABLE); + } HandleGameObject(KologarnBridgeGUID, false); } if (state == IN_PROGRESS) @@ -501,15 +506,6 @@ class instance_ulduar : public InstanceMapScript void SetData64(uint32 type, uint64 data) { - switch (type) - { - case DATA_LEFT_ARM: - LeftArmGUID = data; - break; - case DATA_RIGHT_ARM: - RightArmGUID = data; - break; - } } uint64 GetData64(uint32 data) @@ -533,10 +529,6 @@ class instance_ulduar : public InstanceMapScript return XTToyPileGUIDs[data - DATA_TOY_PILE_0]; case BOSS_KOLOGARN: return KologarnGUID; - case DATA_LEFT_ARM: - return LeftArmGUID; - case DATA_RIGHT_ARM: - return RightArmGUID; case BOSS_AURIAYA: return AuriayaGUID; case BOSS_MIMIRON: diff --git a/src/server/scripts/Northrend/Ulduar/ulduar/ulduar.h b/src/server/scripts/Northrend/Ulduar/ulduar/ulduar.h index 5602018f782..7090f808706 100644 --- a/src/server/scripts/Northrend/Ulduar/ulduar/ulduar.h +++ b/src/server/scripts/Northrend/Ulduar/ulduar/ulduar.h @@ -131,6 +131,7 @@ enum UlduarGameObjects GO_FREYA_CHEST = 194324, GO_LEVIATHAN_DOOR = 194905, GO_LEVIATHAN_GATE = 194630, + GO_XT_002_DOOR = 194631, GO_VEZAX_DOOR = 194750, GO_MOLE_MACHINE = 194316, GO_RAZOR_HARPOON_1 = 194542, diff --git a/src/server/scripts/Spells/spell_generic.cpp b/src/server/scripts/Spells/spell_generic.cpp index dfdf03c421e..248dd31c2a8 100644 --- a/src/server/scripts/Spells/spell_generic.cpp +++ b/src/server/scripts/Spells/spell_generic.cpp @@ -1313,6 +1313,52 @@ class spell_gen_vehicle_scaling : public SpellScriptLoader } }; + +class spell_gen_oracle_wolvar_reputation: public SpellScriptLoader +{ +public: + spell_gen_oracle_wolvar_reputation() : SpellScriptLoader("spell_gen_oracle_wolvar_reputation") { } + + class spell_gen_oracle_wolvar_reputation_SpellScript : public SpellScript + { + PrepareSpellScript(spell_gen_oracle_wolvar_reputation_SpellScript) + + void HandleDummy(SpellEffIndex effIndex) + { + + if (Player* player = GetCaster()->ToPlayer()) + { + + uint32 factionId = GetSpellInfo()->Effects[effIndex].CalcValue(); + int32 repChange = GetSpellInfo()->Effects[EFFECT_1].CalcValue(); + + FactionEntry const* factionEntry = sFactionStore.LookupEntry(factionId); + + if (!factionEntry) + return; + + // Set rep to baserep + basepoints (expecting spillover for oposite faction -> become hated) + // Not when player already has equal or higher rep with this faction + if (player->GetReputationMgr().GetBaseReputation(factionEntry) < repChange) + player->GetReputationMgr().SetReputation(factionEntry, repChange); + + // EFFECT_INDEX_2 most likely update at war state, we already handle this in SetReputation + } + + } + + void Register() + { + OnEffect += SpellEffectFn(spell_gen_oracle_wolvar_reputation_SpellScript::HandleDummy, EFFECT_0, SPELL_EFFECT_DUMMY); + } + }; + + SpellScript* GetSpellScript() const + { + return new spell_gen_oracle_wolvar_reputation_SpellScript(); + } +}; + void AddSC_generic_spell_scripts() { new spell_gen_absorb0_hitlimit1(); @@ -1343,4 +1389,5 @@ void AddSC_generic_spell_scripts() new spell_gen_allow_cast_from_item_only(); new spell_gen_launch(); new spell_gen_vehicle_scaling(); + new spell_gen_oracle_wolvar_reputation(); } |
