aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sql/updates/world/2014_06_26_02_world_misc.sql7
-rw-r--r--sql/updates/world/2014_06_27_00_world_misc.sql4
-rw-r--r--sql/updates/world/2014_06_27_00_world_smart_scripts.sql8
-rw-r--r--src/server/game/Entities/Creature/Creature.cpp45
-rw-r--r--src/server/game/Entities/Creature/Creature.h3
-rw-r--r--src/server/game/Entities/Player/Player.cpp29
-rw-r--r--src/server/game/Entities/Unit/Unit.cpp12
-rw-r--r--src/server/game/Handlers/CharacterHandler.cpp4
-rw-r--r--src/server/game/Handlers/LootHandler.cpp9
-rw-r--r--src/server/game/Handlers/MailHandler.cpp7
-rw-r--r--src/server/game/Loot/LootMgr.h3
-rw-r--r--src/server/game/Miscellaneous/SharedDefines.h2
-rw-r--r--src/server/game/Spells/Spell.cpp22
-rw-r--r--src/server/game/Spells/SpellEffects.cpp18
-rw-r--r--src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp8
-rw-r--r--src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp8
-rw-r--r--src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp8
-rw-r--r--src/server/scripts/EasternKingdoms/MagistersTerrace/boss_vexallus.cpp256
-rw-r--r--src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp438
-rw-r--r--src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.h38
-rw-r--r--src/server/scripts/Spells/spell_warlock.cpp4
-rw-r--r--src/server/worldserver/worldserver.conf.dist2
22 files changed, 445 insertions, 490 deletions
diff --git a/sql/updates/world/2014_06_26_02_world_misc.sql b/sql/updates/world/2014_06_26_02_world_misc.sql
new file mode 100644
index 00000000000..dade11c549d
--- /dev/null
+++ b/sql/updates/world/2014_06_26_02_world_misc.sql
@@ -0,0 +1,7 @@
+-- Pure Energy
+SET @ENTRY := 24745;
+UPDATE `creature_template` SET `flags_extra`=0 WHERE `entry`=@ENTRY;
+
+DELETE FROM `creature_template_addon` WHERE `entry`=@ENTRY;
+INSERT INTO `creature_template_addon` (`entry`, `mount`, `bytes1`, `bytes2`, `auras`) VALUES
+(@ENTRY, 0, 0x0, 0x0, '44326 46156');
diff --git a/sql/updates/world/2014_06_27_00_world_misc.sql b/sql/updates/world/2014_06_27_00_world_misc.sql
new file mode 100644
index 00000000000..275ecbbf4a0
--- /dev/null
+++ b/sql/updates/world/2014_06_27_00_world_misc.sql
@@ -0,0 +1,4 @@
+--
+UPDATE `creature` SET `equipment_id`=0 WHERE `equipment_id`=86 AND `id`=24484;
+DELETE FROM `creature_addon` WHERE `guid`=97892;
+UPDATE `smart_scripts` SET `link`=0 WHERE `entryorguid`=-126866 AND `source_type`=0 AND `id` IN (7,15);
diff --git a/sql/updates/world/2014_06_27_00_world_smart_scripts.sql b/sql/updates/world/2014_06_27_00_world_smart_scripts.sql
new file mode 100644
index 00000000000..e1340a68a62
--- /dev/null
+++ b/sql/updates/world/2014_06_27_00_world_smart_scripts.sql
@@ -0,0 +1,8 @@
+--
+UPDATE `smart_scripts` SET `target_type`=1 WHERE `entryorguid`=27899 AND `source_type`=0 AND `id`=25 AND `link`=0;
+UPDATE `smart_scripts` SET `target_type`=1 WHERE `entryorguid`=25773 AND `source_type`=0 AND `id`=2 AND `link`=0;
+UPDATE `smart_scripts` SET `target_type`=1 WHERE `entryorguid`=30135 AND `source_type`=0 AND `id`=2 AND `link`=0;
+UPDATE `smart_scripts` SET `target_type`=1 WHERE `entryorguid`=29974 AND `source_type`=0 AND `id`=2 AND `link`=0;
+UPDATE `smart_scripts` SET `target_type`=1 WHERE `entryorguid`=17299 AND `source_type`=0 AND `id`=0 AND `link`=0;
+UPDATE `smart_scripts` SET `target_type`=1 WHERE `entryorguid`=2719901 AND `source_type`=9 AND `id`=7 AND `link`=0;
+UPDATE `smart_scripts` SET `target_type`=1 WHERE `entryorguid`=30144 AND `source_type`=0 AND `id`=2 AND `link`=0;
diff --git a/src/server/game/Entities/Creature/Creature.cpp b/src/server/game/Entities/Creature/Creature.cpp
index fbbea8b38c4..d1148f6cfb2 100644
--- a/src/server/game/Entities/Creature/Creature.cpp
+++ b/src/server/game/Entities/Creature/Creature.cpp
@@ -142,8 +142,8 @@ bool ForcedDespawnDelayEvent::Execute(uint64 /*e_time*/, uint32 /*p_time*/)
}
Creature::Creature(bool isWorldObject): Unit(isWorldObject), MapObject(),
-lootForPickPocketed(false), _pickpocketLootRestore(0), lootForBody(false), lootForSkinned(false), _skinner(0), m_groupLootTimer(0), lootingGroupLowGUID(0),
-m_PlayerDamageReq(0), m_lootRecipient(0), m_lootRecipientGroup(0), m_corpseRemoveTime(0), m_respawnTime(0),
+_pickpocketLootRestore(0), m_groupLootTimer(0), lootingGroupLowGUID(0), m_PlayerDamageReq(0),
+m_lootRecipient(0), m_lootRecipientGroup(0), _skinner(0), m_corpseRemoveTime(0), m_respawnTime(0),
m_respawnDelay(300), m_corpseDelay(60), m_respawnradius(0.0f), m_reactState(REACT_AGGRESSIVE),
m_defaultMovementType(IDLE_MOTION_TYPE), m_DBTableGuid(0), m_equipmentId(0), m_originalEquipmentId(0), m_AlreadyCallAssistance(false),
m_AlreadySearchedAssistance(false), m_regenHealth(true), m_AI_locked(false), m_meleeDamageSchoolMask(SPELL_SCHOOL_MASK_NORMAL),
@@ -551,9 +551,9 @@ void Creature::Update(uint32 diff)
time_t now = time(NULL);
// Check if we should refill the pickpocketing loot
- if (lootForPickPocketed && _pickpocketLootRestore && _pickpocketLootRestore <= now)
+ if (loot.loot_type == LOOT_PICKPOCKETING && _pickpocketLootRestore && _pickpocketLootRestore <= now)
{
- lootForPickPocketed = false;
+ loot.clear();
_pickpocketLootRestore = 0;
}
@@ -1485,11 +1485,6 @@ void Creature::setDeathState(DeathState s)
setActive(false);
- if (!IsPet() && GetCreatureTemplate()->SkinLootId)
- if (LootTemplates_Skinning.HaveLootFor(GetCreatureTemplate()->SkinLootId))
- if (hasLootRecipient())
- SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE);
-
if (HasSearchedAssistance())
{
SetNoSearchAssistance(false);
@@ -1548,9 +1543,7 @@ void Creature::Respawn(bool force)
GetName().c_str(), GetGUIDLow(), GetGUID(), GetEntry());
m_respawnTime = 0;
_pickpocketLootRestore = 0;
- lootForPickPocketed = false;
- lootForBody = false;
- lootForSkinned = false;
+ loot.clear();
if (m_originalEntry != GetEntry())
UpdateEntry(m_originalEntry);
@@ -2284,23 +2277,23 @@ void Creature::GetRespawnPosition(float &x, float &y, float &z, float* ori, floa
void Creature::AllLootRemovedFromCorpse()
{
- if (!HasFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE))
- {
- time_t now = time(NULL);
- if (m_corpseRemoveTime <= now)
- return;
+ if (loot.loot_type != LOOT_SKINNING && !IsPet() && GetCreatureTemplate()->SkinLootId && hasLootRecipient())
+ if (LootTemplates_Skinning.HaveLootFor(GetCreatureTemplate()->SkinLootId))
+ SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE);
- float decayRate = sWorld->getRate(RATE_CORPSE_DECAY_LOOTED);
- CreatureTemplate const* cinfo = GetCreatureTemplate();
+ time_t now = time(NULL);
+ if (m_corpseRemoveTime <= now)
+ return;
- // corpse skinnable, but without skinning flag, and then skinned, corpse will despawn next update
- if (cinfo && cinfo->SkinLootId)
- m_corpseRemoveTime = time(NULL);
- else
- m_corpseRemoveTime = now + m_corpseDelay * decayRate;
+ float decayRate = sWorld->getRate(RATE_CORPSE_DECAY_LOOTED);
- m_respawnTime = m_corpseRemoveTime + m_respawnTime;
- }
+ // corpse skinnable, but without skinning flag, and then skinned, corpse will despawn next update
+ if (loot.loot_type == LOOT_SKINNING)
+ m_corpseRemoveTime = time(NULL);
+ else
+ m_corpseRemoveTime = now + m_corpseDelay * decayRate;
+
+ m_respawnTime = m_corpseRemoveTime + m_respawnTime;
}
uint8 Creature::getLevelForTarget(WorldObject const* target) const
diff --git a/src/server/game/Entities/Creature/Creature.h b/src/server/game/Entities/Creature/Creature.h
index 85850170603..86fafb330a7 100644
--- a/src/server/game/Entities/Creature/Creature.h
+++ b/src/server/game/Entities/Creature/Creature.h
@@ -548,9 +548,6 @@ class Creature : public Unit, public GridObject<Creature>, public MapObject
virtual void DeleteFromDB(); // overriden in Pet
Loot loot;
- bool lootForPickPocketed;
- bool lootForBody;
- bool lootForSkinned;
void StartPickPocketRefillTimer();
void ResetPickPocketRefillTimer() { _pickpocketLootRestore = 0; }
void SetSkinner(uint64 guid) { _skinner = guid; }
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index e1a1b367b7b..cf6e94328b7 100644
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -9182,9 +9182,8 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
if (loot_type == LOOT_PICKPOCKETING)
{
- if (!creature->lootForPickPocketed)
+ if (loot->loot_type != LOOT_PICKPOCKETING)
{
- creature->lootForPickPocketed = true;
creature->StartPickPocketRefillTimer();
loot->clear();
@@ -9205,12 +9204,9 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
if (!recipient)
return;
- if (!creature->lootForBody)
+ if (loot->loot_type == LOOT_NONE)
{
- creature->lootForBody = true;
-
// for creature, loot is filled when creature is killed.
-
if (Group* group = recipient->GetGroup())
{
switch (group->GetLootMethod())
@@ -9231,15 +9227,17 @@ void Player::SendLoot(uint64 guid, LootType loot_type)
}
}
- // possible only if creature->lootForBody && loot->empty() at spell cast check
- if (loot_type == LOOT_SKINNING)
+ // if loot is already skinning loot then don't do anything else
+ if (loot->loot_type == LOOT_SKINNING)
{
- if (!creature->lootForSkinned)
- {
- creature->lootForSkinned = true;
- loot->clear();
- loot->FillLoot(creature->GetCreatureTemplate()->SkinLootId, LootTemplates_Skinning, this, true);
- }
+ loot_type = LOOT_SKINNING;
+ permission = creature->GetSkinner() == GetGUID() ? OWNER_PERMISSION : NONE_PERMISSION;
+ }
+ else if (loot_type == LOOT_SKINNING)
+ {
+ loot->clear();
+ loot->FillLoot(creature->GetCreatureTemplate()->SkinLootId, LootTemplates_Skinning, this, true);
+ creature->SetSkinner(GetGUID());
permission = OWNER_PERMISSION;
}
// set group rights only for loot_type != LOOT_SKINNING
@@ -17978,6 +17976,9 @@ bool Player::isAllowedToLoot(const Creature* creature)
if (loot->isLooted()) // nothing to loot or everything looted.
return false;
+ if (loot->loot_type == LOOT_SKINNING)
+ return creature->GetSkinner() == GetGUID();
+
Group* thisGroup = GetGroup();
if (!thisGroup)
return this == creature->GetLootRecipient();
diff --git a/src/server/game/Entities/Unit/Unit.cpp b/src/server/game/Entities/Unit/Unit.cpp
index e4eca6b970b..6c66e900be7 100644
--- a/src/server/game/Entities/Unit/Unit.cpp
+++ b/src/server/game/Entities/Unit/Unit.cpp
@@ -13669,11 +13669,8 @@ void Unit::Kill(Unit* victim, bool durabilityLoss)
if (creature)
{
Loot* loot = &creature->loot;
- if (creature->lootForPickPocketed)
- {
+ if (creature->loot.loot_type == LOOT_PICKPOCKETING)
creature->ResetPickPocketRefillTimer();
- creature->lootForPickPocketed = false;
- }
loot->clear();
if (uint32 lootid = creature->GetCreatureTemplate()->lootid)
@@ -13794,9 +13791,12 @@ void Unit::Kill(Unit* victim, bool durabilityLoss)
if (!creature->IsPet())
{
creature->DeleteThreatList();
- CreatureTemplate const* cInfo = creature->GetCreatureTemplate();
- if (cInfo && (cInfo->lootid || cInfo->maxgold > 0))
+
+ // must be after setDeathState which resets dynamic flags
+ if (!creature->loot.empty())
creature->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
+ else
+ creature->AllLootRemovedFromCorpse();
}
// Call KilledUnit for creatures, this needs to be called after the lootable flag is set
diff --git a/src/server/game/Handlers/CharacterHandler.cpp b/src/server/game/Handlers/CharacterHandler.cpp
index 70547136bf8..70e01238663 100644
--- a/src/server/game/Handlers/CharacterHandler.cpp
+++ b/src/server/game/Handlers/CharacterHandler.cpp
@@ -775,9 +775,9 @@ void WorldSession::HandleCharDeleteOpcode(WorldPacket& recvData)
std::string IP_str = GetRemoteAddress();
TC_LOG_INFO("entities.player.character", "Account: %d, IP: %s deleted character: %s, GUID: %u, Level: %u", accountId, IP_str.c_str(), name.c_str(), GUID_LOPART(guid), level);
-
+
// To prevent hook failure, place hook before removing reference from DB
- sScriptMgr->OnPlayerDelete(guid, initAccountId); // To prevent race conditioning, but as it also makes sense, we hand the accountId over for successful delete.
+ sScriptMgr->OnPlayerDelete(guid, initAccountId); // To prevent race conditioning, but as it also makes sense, we hand the accountId over for successful delete.
// Shouldn't interfere with character deletion though
if (sLog->ShouldLog("entities.player.dump", LOG_LEVEL_INFO)) // optimize GetPlayerDump call
diff --git a/src/server/game/Handlers/LootHandler.cpp b/src/server/game/Handlers/LootHandler.cpp
index a4fde51b498..7c3d9e99eee 100644
--- a/src/server/game/Handlers/LootHandler.cpp
+++ b/src/server/game/Handlers/LootHandler.cpp
@@ -82,7 +82,7 @@ void WorldSession::HandleAutostoreLootItemOpcode(WorldPacket& recvData)
{
Creature* creature = GetPlayer()->GetMap()->GetCreature(lguid);
- bool lootAllowed = creature && creature->IsAlive() == (player->getClass() == CLASS_ROGUE && creature->lootForPickPocketed);
+ bool lootAllowed = creature && creature->IsAlive() == (player->getClass() == CLASS_ROGUE && creature->loot.loot_type == LOOT_PICKPOCKETING);
if (!lootAllowed || !creature->IsWithinDistInMap(_player, INTERACTION_DISTANCE))
{
@@ -149,7 +149,7 @@ void WorldSession::HandleLootMoneyOpcode(WorldPacket& /*recvData*/)
case HIGHGUID_VEHICLE:
{
Creature* creature = player->GetMap()->GetCreature(guid);
- bool lootAllowed = creature && creature->IsAlive() == (player->getClass() == CLASS_ROGUE && creature->lootForPickPocketed);
+ bool lootAllowed = creature && creature->IsAlive() == (player->getClass() == CLASS_ROGUE && creature->loot.loot_type == LOOT_PICKPOCKETING);
if (lootAllowed && creature->IsWithinDistInMap(player, INTERACTION_DISTANCE))
{
loot = &creature->loot;
@@ -357,7 +357,7 @@ void WorldSession::DoLootRelease(uint64 lguid)
{
Creature* creature = GetPlayer()->GetMap()->GetCreature(lguid);
- bool lootAllowed = creature && creature->IsAlive() == (player->getClass() == CLASS_ROGUE && creature->lootForPickPocketed);
+ bool lootAllowed = creature && creature->IsAlive() == (player->getClass() == CLASS_ROGUE && creature->loot.loot_type == LOOT_PICKPOCKETING);
if (!lootAllowed || !creature->IsWithinDistInMap(_player, INTERACTION_DISTANCE))
return;
@@ -365,9 +365,6 @@ void WorldSession::DoLootRelease(uint64 lguid)
if (loot->isLooted())
{
creature->RemoveFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
-
- if (loot->loot_type == LOOT_SKINNING)
- creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE);
// skip pickpocketing loot for speed, skinning timer reduction is no-op in fact
if (!creature->IsAlive())
diff --git a/src/server/game/Handlers/MailHandler.cpp b/src/server/game/Handlers/MailHandler.cpp
index 536d6a7dc95..3c4e5feb771 100644
--- a/src/server/game/Handlers/MailHandler.cpp
+++ b/src/server/game/Handlers/MailHandler.cpp
@@ -181,6 +181,13 @@ void WorldSession::HandleSendMail(WorldPacket& recvData)
uint64 reqmoney = cost + money;
+ // Check for overflow
+ if (reqmoney < money)
+ {
+ player->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_ENOUGH_MONEY);
+ return;
+ }
+
if (!player->HasEnoughMoney(reqmoney) && !player->IsGameMaster())
{
player->SendMailResult(0, MAIL_SEND, MAIL_ERR_NOT_ENOUGH_MONEY);
diff --git a/src/server/game/Loot/LootMgr.h b/src/server/game/Loot/LootMgr.h
index 9be745e622d..cb3b9082c20 100644
--- a/src/server/game/Loot/LootMgr.h
+++ b/src/server/game/Loot/LootMgr.h
@@ -76,6 +76,8 @@ enum PermissionTypes
enum LootType
{
+ LOOT_NONE = 0,
+
LOOT_CORPSE = 1,
LOOT_PICKPOCKETING = 2,
LOOT_FISHING = 3,
@@ -341,6 +343,7 @@ struct Loot
gold = 0;
unlootedCount = 0;
roundRobinPlayer = 0;
+ loot_type = LOOT_NONE;
i_LootValidatorRefManager.clearReferences();
}
diff --git a/src/server/game/Miscellaneous/SharedDefines.h b/src/server/game/Miscellaneous/SharedDefines.h
index 475e8ee3fa8..22b2d58585c 100644
--- a/src/server/game/Miscellaneous/SharedDefines.h
+++ b/src/server/game/Miscellaneous/SharedDefines.h
@@ -2987,7 +2987,7 @@ enum CreatureTypeFlags
CREATURE_TYPEFLAGS_EXOTIC = 0x00010000, // Can be tamed by hunter as exotic pet
CREATURE_TYPEFLAGS_UNK17 = 0x00020000, // ? Related to vehicles/pvp?
CREATURE_TYPEFLAGS_UNK18 = 0x00040000, // ? Related to vehicle/siege weapons?
- CREATURE_TYPEFLAGS_UNK19 = 0x00080000,
+ CREATURE_TYPEFLAGS_PROJECTILE_COLLISION = 0x00080000, // Projectiles can collide with this creature - interacts with TARGET_DEST_TRAJ
CREATURE_TYPEFLAGS_UNK20 = 0x00100000,
CREATURE_TYPEFLAGS_UNK21 = 0x00200000,
CREATURE_TYPEFLAGS_UNK22 = 0x00400000,
diff --git a/src/server/game/Spells/Spell.cpp b/src/server/game/Spells/Spell.cpp
index 2a01a8046ed..56ae9061033 100644
--- a/src/server/game/Spells/Spell.cpp
+++ b/src/server/game/Spells/Spell.cpp
@@ -1507,10 +1507,24 @@ void Spell::SelectImplicitTrajTargets(SpellEffIndex effIndex)
std::list<WorldObject*>::const_iterator itr = targets.begin();
for (; itr != targets.end(); ++itr)
{
+ if (!m_caster->HasInLine(*itr, 5.0f))
+ continue;
+
+ if (m_spellInfo->CheckTarget(m_caster, *itr, true) != SPELL_CAST_OK)
+ continue;
+
if (Unit* unitTarget = (*itr)->ToUnit())
- if (m_caster == *itr || m_caster->IsOnVehicle(unitTarget) || (unitTarget)->GetVehicle())//(*itr)->IsOnVehicle(m_caster))
+ {
+ if (m_caster == *itr || m_caster->IsOnVehicle(unitTarget) || unitTarget->GetVehicle())
continue;
+ if (Creature* creatureTarget = unitTarget->ToCreature())
+ {
+ if (!(creatureTarget->GetCreatureTemplate()->type_flags & CREATURE_TYPEFLAGS_PROJECTILE_COLLISION))
+ continue;
+ }
+ }
+
const float size = std::max((*itr)->GetObjectSize() * 0.7f, 1.0f); // 1/sqrt(3)
/// @todo all calculation should be based on src instead of m_caster
const float objDist2d = m_targets.GetSrcPos()->GetExactDist2d(*itr) * std::cos(m_targets.GetSrcPos()->GetRelativeAngle(*itr));
@@ -5120,13 +5134,11 @@ SpellCastResult Spell::CheckCast(bool strict)
return SPELL_FAILED_TARGET_UNSKINNABLE;
Creature* creature = m_targets.GetUnitTarget()->ToCreature();
- if (creature->GetCreatureType() != CREATURE_TYPE_CRITTER && creature->loot.loot_type != LOOT_SKINNING && !creature->loot.isLooted())
+ if (creature->GetCreatureType() != CREATURE_TYPE_CRITTER && !creature->loot.isLooted())
return SPELL_FAILED_TARGET_NOT_LOOTED;
uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
- bool alreadySkinned = creature->loot.loot_type == LOOT_SKINNING && creature->GetSkinner() == m_caster->GetGUID();
-
int32 skillValue = m_caster->ToPlayer()->GetSkillValue(skill);
int32 TargetLevel = m_targets.GetUnitTarget()->getLevel();
int32 ReqValue = (skillValue < 100 ? (TargetLevel-10) * 10 : TargetLevel * 5);
@@ -5136,7 +5148,7 @@ SpellCastResult Spell::CheckCast(bool strict)
// chance for fail at orange skinning attempt
if ((m_selfContainer && (*m_selfContainer) == this) &&
skillValue < sWorld->GetConfigMaxSkillValue() &&
- (ReqValue < 0 ? 0 : ReqValue) > irand(skillValue - 25, skillValue + 37) && !alreadySkinned)
+ (ReqValue < 0 ? 0 : ReqValue) > irand(skillValue - 25, skillValue + 37))
return SPELL_FAILED_TRY_AGAIN;
break;
diff --git a/src/server/game/Spells/SpellEffects.cpp b/src/server/game/Spells/SpellEffects.cpp
index 8d8abc9eb36..ebd0a269223 100644
--- a/src/server/game/Spells/SpellEffects.cpp
+++ b/src/server/game/Spells/SpellEffects.cpp
@@ -4435,28 +4435,16 @@ void Spell::EffectSkinning(SpellEffIndex /*effIndex*/)
uint32 skill = creature->GetCreatureTemplate()->GetRequiredLootSkill();
- bool awardPoints = true;
-
- // Check if a skinning loot table was already generated for this creature
- if (creature->loot.loot_type == LOOT_SKINNING)
- {
- if (creature->GetSkinner() != m_caster->GetGUID())
- return;
-
- awardPoints = false; // Do not grant skill points for this loot, they were already granted the first time.
- }
- else
- creature->SetSkinner(m_caster->GetGUID());
-
m_caster->ToPlayer()->SendLoot(creature->GetGUID(), LOOT_SKINNING);
+ creature->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_SKINNABLE);
+ creature->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
int32 reqValue = targetLevel < 10 ? 0 : targetLevel < 20 ? (targetLevel-10)*10 : targetLevel*5;
int32 skillValue = m_caster->ToPlayer()->GetPureSkillValue(skill);
// Double chances for elites
- if (awardPoints)
- m_caster->ToPlayer()->UpdateGatherSkill(skill, skillValue, reqValue, creature->isElite() ? 2 : 1);
+ m_caster->ToPlayer()->UpdateGatherSkill(skill, skillValue, reqValue, creature->isElite() ? 2 : 1);
}
void Spell::EffectCharge(SpellEffIndex /*effIndex*/)
diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp
index 3c4b372808b..7944011c7a0 100644
--- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp
+++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_felblood_kaelthas.cpp
@@ -150,14 +150,14 @@ public:
Phase = 0;
- instance->SetData(DATA_KAELTHAS_EVENT, NOT_STARTED);
+ instance->SetBossState(DATA_KAELTHAS, NOT_STARTED);
}
void JustDied(Unit* /*killer*/) override
{
Talk(SAY_DEATH);
- instance->SetData(DATA_KAELTHAS_EVENT, DONE);
+ instance->SetBossState(DATA_KAELTHAS, DONE);
// Enable the Translocation Orb Exit
if (GameObject* escapeOrb = ObjectAccessor::GetGameObject(*me, instance->GetData64(DATA_ESCAPE_ORB)))
@@ -172,7 +172,7 @@ public:
void EnterCombat(Unit* /*who*/) override
{
- instance->SetData(DATA_KAELTHAS_EVENT, IN_PROGRESS);
+ instance->SetBossState(DATA_KAELTHAS, IN_PROGRESS);
}
void MoveInLineOfSight(Unit* who) override
@@ -515,7 +515,7 @@ public:
return;
}
//Don't really die in all phases of Kael'Thas
- if (instance->GetData(DATA_KAELTHAS_EVENT) == 0)
+ if (instance->GetBossState(DATA_KAELTHAS) == 0)
{
//prevent death
damage = 0;
diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp
index 8dc8ff799ba..2af9d9b1567 100644
--- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp
+++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_priestess_delrissa.cpp
@@ -153,7 +153,7 @@ public:
//this mean she at some point evaded
void JustReachedHome() override
{
- instance->SetData(DATA_DELRISSA_EVENT, FAIL);
+ instance->SetBossState(DATA_DELRISSA, FAIL);
}
void EnterCombat(Unit* who) override
@@ -172,7 +172,7 @@ public:
}
}
- instance->SetData(DATA_DELRISSA_EVENT, IN_PROGRESS);
+ instance->SetBossState(DATA_DELRISSA, IN_PROGRESS);
}
void InitializeLackeys()
@@ -240,7 +240,7 @@ public:
Talk(SAY_DEATH);
if (instance->GetData(DATA_DELRISSA_DEATH_COUNT) == MAX_ACTIVE_LACKEY)
- instance->SetData(DATA_DELRISSA_EVENT, DONE);
+ instance->SetBossState(DATA_DELRISSA, DONE);
else
{
if (me->HasFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE))
@@ -434,7 +434,7 @@ struct boss_priestess_lackey_commonAI : public ScriptedAI
if (!pDelrissa->HasFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE))
pDelrissa->SetFlag(UNIT_DYNAMIC_FLAGS, UNIT_DYNFLAG_LOOTABLE);
- instance->SetData(DATA_DELRISSA_EVENT, DONE);
+ instance->SetBossState(DATA_DELRISSA, DONE);
}
}
}
diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp
index d77f5db9cea..d6c0f95f967 100644
--- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp
+++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_selin_fireheart.cpp
@@ -119,7 +119,7 @@ public:
}
// Set Inst data for encounter
- instance->SetData(DATA_SELIN_EVENT, NOT_STARTED);
+ instance->SetBossState(DATA_SELIN, NOT_STARTED);
DrainLifeTimer = urand(3000, 7000);
DrainManaTimer = DrainLifeTimer + 5000;
@@ -194,7 +194,7 @@ public:
void EnterCombat(Unit* /*who*/) override
{
Talk(SAY_AGGRO);
- instance->SetData(DATA_SELIN_EVENT, IN_PROGRESS);
+ instance->SetBossState(DATA_SELIN, IN_PROGRESS);
}
void KilledUnit(Unit* /*victim*/) override
@@ -228,7 +228,7 @@ public:
{
Talk(SAY_DEATH);
- instance->SetData(DATA_SELIN_EVENT, DONE); // Encounter complete!
+ instance->SetBossState(DATA_SELIN, DONE); // Encounter complete!
ShatterRemainingCrystals();
}
@@ -351,7 +351,7 @@ public:
}
}
}
- } else TC_LOG_ERROR("scripts", ERROR_INST_DATA);
+ }
}
};
};
diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_vexallus.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_vexallus.cpp
index 58b9ef12095..b9930820303 100644
--- a/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_vexallus.cpp
+++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/boss_vexallus.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
* 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
@@ -16,13 +15,6 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Boss_Vexallus
-SD%Complete: 90
-SDComment: Heroic and Normal support. Needs further testing.
-SDCategory: Magister's Terrace
-EndScriptData */
-
#include "ScriptMgr.h"
#include "ScriptedCreature.h"
#include "magisters_terrace.h"
@@ -41,26 +33,22 @@ enum Yells
enum Spells
{
- // Pure energy spell info
- SPELL_ENERGY_BOLT = 46156,
- SPELL_ENERGY_FEEDBACK = 44335,
-
- // Vexallus spell info
SPELL_CHAIN_LIGHTNING = 44318,
- SPELL_H_CHAIN_LIGHTNING = 46380, // heroic spell
SPELL_OVERLOAD = 44353,
SPELL_ARCANE_SHOCK = 44319,
- SPELL_H_ARCANE_SHOCK = 46381, // heroic spell
SPELL_SUMMON_PURE_ENERGY = 44322, // mod scale -10
H_SPELL_SUMMON_PURE_ENERGY1 = 46154, // mod scale -5
H_SPELL_SUMMON_PURE_ENERGY2 = 46159 // mod scale -5
-
};
-enum Creatures
+enum Events
{
- NPC_PURE_ENERGY = 24745,
+ EVENT_ENERGY_BOLT = 1,
+ EVENT_ENERGY_FEEDBACK,
+ EVENT_CHAIN_LIGHTNING,
+ EVENT_OVERLOAD,
+ EVENT_ARCANE_SHOCK
};
enum Misc
@@ -71,170 +59,160 @@ enum Misc
class boss_vexallus : public CreatureScript
{
-public:
- boss_vexallus() : CreatureScript("boss_vexallus") { }
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return GetInstanceAI<boss_vexallusAI>(creature);
- };
-
- struct boss_vexallusAI : public BossAI
- {
- boss_vexallusAI(Creature* creature) : BossAI(creature, DATA_VEXALLUS_EVENT)
- {
- instance = creature->GetInstanceScript();
- }
-
- InstanceScript* instance;
+ public:
+ boss_vexallus() : CreatureScript("boss_vexallus") { }
- uint32 ChainLightningTimer;
- uint32 ArcaneShockTimer;
- uint32 OverloadTimer;
- uint32 IntervalHealthAmount;
- bool Enraged;
-
- void Reset() override
+ struct boss_vexallusAI : public BossAI
{
- summons.DespawnAll();
- ChainLightningTimer = 8000;
- ArcaneShockTimer = 5000;
- OverloadTimer = 1200;
- IntervalHealthAmount = 1;
- Enraged = false;
-
- instance->SetData(DATA_VEXALLUS_EVENT, NOT_STARTED);
- }
+ boss_vexallusAI(Creature* creature) : BossAI(creature, DATA_VEXALLUS)
+ {
+ _intervalHealthAmount = 1;
+ _enraged = false;
+ }
- void KilledUnit(Unit* /*victim*/) override
- {
- Talk(SAY_KILL);
- }
+ void Reset() override
+ {
+ _Reset();
+ _intervalHealthAmount = 1;
+ _enraged = false;
+ }
- void JustDied(Unit* /*killer*/) override
- {
- summons.DespawnAll();
- instance->SetData(DATA_VEXALLUS_EVENT, DONE);
- }
+ void KilledUnit(Unit* /*victim*/) override
+ {
+ Talk(SAY_KILL);
+ }
- void EnterCombat(Unit* /*who*/) override
- {
- Talk(SAY_AGGRO);
+ void JustDied(Unit* /*killer*/) override
+ {
+ _JustDied();
+ }
- instance->SetData(DATA_VEXALLUS_EVENT, IN_PROGRESS);
- }
+ void EnterCombat(Unit* /*who*/) override
+ {
+ Talk(SAY_AGGRO);
+ _EnterCombat();
- void JustSummoned(Creature* summoned) override
- {
- if (Unit* temp = SelectTarget(SELECT_TARGET_RANDOM, 0))
- summoned->GetMotionMaster()->MoveFollow(temp, 0, 0);
+ events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 8000);
+ events.ScheduleEvent(EVENT_ARCANE_SHOCK, 5000);
+ }
- //spells are SUMMON_TYPE_GUARDIAN, so using setOwner should be ok
- summoned->CastSpell(summoned, SPELL_ENERGY_BOLT, false, 0, 0, me->GetGUID());
- }
+ void JustSummoned(Creature* summoned) override
+ {
+ if (Unit* temp = SelectTarget(SELECT_TARGET_RANDOM, 0))
+ summoned->GetMotionMaster()->MoveFollow(temp, 0, 0);
- void UpdateAI(uint32 diff) override
- {
- if (!UpdateVictim())
- return;
+ summons.Summon(summoned);
+ }
- if (!Enraged)
+ void DamageTaken(Unit* /*who*/, uint32& /*damage*/) override
{
- //used for check, when Vexallus cast adds 85%, 70%, 55%, 40%, 25%
- if (!HealthAbovePct(100 - INTERVAL_MODIFIER * IntervalHealthAmount))
+ if (_enraged)
+ return;
+
+ // 85%, 70%, 55%, 40%, 25%
+ if (!HealthAbovePct(100 - INTERVAL_MODIFIER * _intervalHealthAmount))
{
- //increase amount, unless we're at 10%, then we switch and return
- if (IntervalHealthAmount == INTERVAL_SWITCH)
+ // increase amount, unless we're at 10%, then we switch and return
+ if (_intervalHealthAmount == INTERVAL_SWITCH)
{
- Enraged = true;
+ _enraged = true;
+ events.Reset();
+ events.ScheduleEvent(EVENT_OVERLOAD, 1200);
return;
}
else
- ++IntervalHealthAmount;
+ ++_intervalHealthAmount;
Talk(SAY_ENERGY);
Talk(EMOTE_DISCHARGE_ENERGY);
if (IsHeroic())
{
- DoCast(me, H_SPELL_SUMMON_PURE_ENERGY1, false);
- DoCast(me, H_SPELL_SUMMON_PURE_ENERGY2, false);
+ DoCast(me, H_SPELL_SUMMON_PURE_ENERGY1);
+ DoCast(me, H_SPELL_SUMMON_PURE_ENERGY2);
}
else
- DoCast(me, SPELL_SUMMON_PURE_ENERGY, false);
-
- //below are workaround summons, remove when summoning spells w/implicitTarget 73 implemented in the core
- me->SummonCreature(NPC_PURE_ENERGY, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_CORPSE_DESPAWN, 0);
-
- if (IsHeroic())
- me->SummonCreature(NPC_PURE_ENERGY, 0.0f, 0.0f, 0.0f, 0.0f, TEMPSUMMON_CORPSE_DESPAWN, 0);
+ DoCast(me, SPELL_SUMMON_PURE_ENERGY);
}
+ }
- if (ChainLightningTimer <= diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- DoCast(target, SPELL_CHAIN_LIGHTNING);
+ void UpdateAI(uint32 diff) override
+ {
+ if (!UpdateVictim())
+ return;
- ChainLightningTimer = 8000;
- } else ChainLightningTimer -= diff;
+ events.Update(diff);
- if (ArcaneShockTimer <= diff)
- {
- if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0))
- if (target)
- DoCast(target, SPELL_ARCANE_SHOCK);
+ if (me->HasUnitState(UNIT_STATE_CASTING))
+ return;
- ArcaneShockTimer = 8000;
- } else ArcaneShockTimer -= diff;
- }
- else
- {
- if (OverloadTimer <= diff)
+ while (uint32 eventId = events.ExecuteEvent())
{
- DoCastVictim(SPELL_OVERLOAD);
+ switch (eventId)
+ {
+ case EVENT_CHAIN_LIGHTNING:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 0.0f, true))
+ DoCast(target, SPELL_CHAIN_LIGHTNING);
+ events.ScheduleEvent(EVENT_CHAIN_LIGHTNING, 8000);
+ break;
+ case EVENT_ARCANE_SHOCK:
+ if (Unit* target = SelectTarget(SELECT_TARGET_RANDOM, 0, 20.0f, true))
+ DoCast(target, SPELL_ARCANE_SHOCK);
+ events.ScheduleEvent(EVENT_ARCANE_SHOCK, 8000);
+ break;
+ case EVENT_OVERLOAD:
+ DoCastVictim(SPELL_OVERLOAD);
+ events.ScheduleEvent(EVENT_OVERLOAD, 2000);
+ break;
+ default:
+ break;
+ }
+ }
- OverloadTimer = 2000;
- } else OverloadTimer -= diff;
+ DoMeleeAttackIfReady();
}
- DoMeleeAttackIfReady();
- }
- };
+ private:
+ uint32 _intervalHealthAmount;
+ bool _enraged;
+ };
+
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return GetInstanceAI<boss_vexallusAI>(creature);
+ };
};
-class npc_pure_energy : public CreatureScript
+enum NpcPureEnergy
{
-public:
- npc_pure_energy() : CreatureScript("npc_pure_energy") { }
-
- CreatureAI* GetAI(Creature* creature) const override
- {
- return new npc_pure_energyAI(creature);
- };
-
- struct npc_pure_energyAI : public ScriptedAI
- {
- npc_pure_energyAI(Creature* creature) : ScriptedAI(creature)
- {
- me->SetDisplayId(me->GetCreatureTemplate()->Modelid2);
- }
+ SPELL_ENERGY_BOLT = 46156,
+ SPELL_ENERGY_FEEDBACK = 44335,
+ SPELL_PURE_ENERGY_PASSIVE = 44326
+};
- void Reset() override { }
+class npc_pure_energy : public CreatureScript
+{
+ public:
+ npc_pure_energy() : CreatureScript("npc_pure_energy") { }
- void JustDied(Unit* slayer) override
+ struct npc_pure_energyAI : public ScriptedAI
{
- if (Unit* temp = me->GetOwner())
+ npc_pure_energyAI(Creature* creature) : ScriptedAI(creature)
{
- if (temp && temp->IsAlive())
- slayer->CastSpell(slayer, SPELL_ENERGY_FEEDBACK, true, 0, 0, temp->GetGUID());
+ me->SetDisplayId(me->GetCreatureTemplate()->Modelid2);
}
- }
- void EnterCombat(Unit* /*who*/) override { }
- void MoveInLineOfSight(Unit* /*who*/) override { }
+ void JustDied(Unit* killer) override
+ {
+ killer->CastSpell(killer, SPELL_ENERGY_FEEDBACK, true);
+ me->RemoveAurasDueToSpell(SPELL_PURE_ENERGY_PASSIVE);
+ }
+ };
- void AttackStart(Unit* /*who*/) override { }
- };
+ CreatureAI* GetAI(Creature* creature) const override
+ {
+ return new npc_pure_energyAI(creature);
+ };
};
void AddSC_boss_vexallus()
diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp b/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp
index daea647609d..e0050420a08 100644
--- a/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp
+++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/instance_magisters_terrace.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
- * Copyright (C) 2006-2009 ScriptDev2 <https://scriptdev2.svn.sourceforge.net/>
*
* 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
@@ -16,19 +15,10 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-/* ScriptData
-SDName: Instance_Magisters_Terrace
-SD%Complete: 60
-SDComment: Designed only for Selin Fireheart
-SDCategory: Magister's Terrace
-EndScriptData */
-
#include "ScriptMgr.h"
#include "InstanceScript.h"
#include "magisters_terrace.h"
-#define MAX_ENCOUNTER 4
-
/*
0 - Selin Fireheart
1 - Vexallus
@@ -36,281 +26,239 @@ EndScriptData */
3 - Kael'thas Sunstrider
*/
-enum Creatures
+DoorData const doorData[] =
{
- NPC_SELIN = 24723,
- NPC_DELRISSA = 24560,
- NPC_FELCRYSTALS = 24722
-};
-
-enum GameObjects
-{
- GO_VEXALLUS_DOOR = 187896,
- GO_SELIN_DOOR = 187979,
- GO_SELIN_ENCOUNTER_DOOR = 188065,
- GO_DELRISSA_DOOR = 187770,
- GO_KAEL_DOOR = 188064,
- GO_KAEL_STATUE_1 = 188165,
- GO_KAEL_STATUE_2 = 188166,
- GO_ESCAPE_ORB = 188173
+ { GO_SELIN_DOOR, DATA_SELIN, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
+ { GO_SELIN_ENCOUNTER_DOOR, DATA_SELIN, DOOR_TYPE_ROOM, BOUNDARY_NONE },
+ { GO_VEXALLUS_DOOR, DATA_VEXALLUS, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
+ { GO_DELRISSA_DOOR, DATA_DELRISSA, DOOR_TYPE_PASSAGE, BOUNDARY_NONE },
+ { GO_KAEL_DOOR, DATA_KAELTHAS, DOOR_TYPE_ROOM, BOUNDARY_NONE },
+ { 0, 0, DOOR_TYPE_ROOM, BOUNDARY_NONE } // END
};
class instance_magisters_terrace : public InstanceMapScript
{
-public:
- instance_magisters_terrace() : InstanceMapScript("instance_magisters_terrace", 585) { }
-
- struct instance_magisters_terrace_InstanceMapScript : public InstanceScript
- {
- instance_magisters_terrace_InstanceMapScript(Map* map) : InstanceScript(map) { }
-
- uint32 Encounter[MAX_ENCOUNTER];
- uint32 DelrissaDeathCount;
+ public:
+ instance_magisters_terrace() : InstanceMapScript("instance_magisters_terrace", 585) { }
- std::vector<uint64> FelCrystals;
-
- uint64 SelinGUID;
- uint64 DelrissaGUID;
- uint64 VexallusDoorGUID;
- uint64 SelinDoorGUID;
- uint64 SelinEncounterDoorGUID;
- uint64 DelrissaDoorGUID;
- uint64 KaelDoorGUID;
- uint64 KaelStatue[2];
- uint64 EscapeOrbGUID;
- uint32 StatuesState;
- uint8 felCristalIndex;
-
- void Initialize() override
+ struct instance_magisters_terrace_InstanceMapScript : public InstanceScript
{
- memset(&Encounter, 0, sizeof(Encounter));
-
- FelCrystals.clear();
+ instance_magisters_terrace_InstanceMapScript(Map* map) : InstanceScript(map)
+ {
+ SetBossNumber(EncounterCount);
+ LoadDoorData(doorData);
- DelrissaDeathCount = 0;
+ FelCrystals.clear();
+ DelrissaDeathCount = 0;
- SelinGUID = 0;
- DelrissaGUID = 0;
- VexallusDoorGUID = 0;
- SelinDoorGUID = 0;
- SelinEncounterDoorGUID = 0;
- DelrissaDoorGUID = 0;
- KaelDoorGUID = 0;
- KaelStatue[0] = 0;
- KaelStatue[1] = 0;
- EscapeOrbGUID = 0;
- StatuesState = 0;
- felCristalIndex = 0;
- }
+ SelinGUID = 0;
+ DelrissaGUID = 0;
+ EscapeOrbGUID = 0;
+ FelCristalIndex = 0;
- bool IsEncounterInProgress() const override
- {
- for (uint8 i = 0; i < MAX_ENCOUNTER; ++i)
- if (Encounter[i] == IN_PROGRESS)
- return true;
- return false;
- }
+ memset(KaelStatue, 0, 2 * sizeof(uint64));
+ }
- uint32 GetData(uint32 identifier) const
- {
- switch (identifier)
+ uint32 GetData(uint32 type) const override
{
- case DATA_SELIN_EVENT:
- return Encounter[0];
- case DATA_VEXALLUS_EVENT:
- return Encounter[1];
- case DATA_DELRISSA_EVENT:
- return Encounter[2];
- case DATA_KAELTHAS_EVENT:
- return Encounter[3];
- case DATA_DELRISSA_DEATH_COUNT:
- return DelrissaDeathCount;
- case DATA_FEL_CRYSTAL_SIZE:
- return FelCrystals.size();
+ switch (type)
+ {
+ case DATA_DELRISSA_DEATH_COUNT:
+ return DelrissaDeathCount;
+ case DATA_FEL_CRYSTAL_SIZE:
+ return uint32(FelCrystals.size());
+ default:
+ break;
+ }
+ return 0;
}
- return 0;
- }
- void SetData(uint32 identifier, uint32 data)
- {
- switch (identifier)
+ void SetData(uint32 type, uint32 data) override
{
- case DATA_SELIN_EVENT:
- if (data == DONE)
- {
- HandleGameObject(SelinEncounterDoorGUID, true);
- HandleGameObject(SelinDoorGUID, true);
- }
- else if (data == IN_PROGRESS)
- HandleGameObject(SelinEncounterDoorGUID, false);
- else if (data == NOT_STARTED)
- HandleGameObject(SelinEncounterDoorGUID, true);
-
- Encounter[0] = data;
- break;
- case DATA_VEXALLUS_EVENT:
- if (data == DONE)
- HandleGameObject(VexallusDoorGUID, true);
- Encounter[1] = data;
- break;
- case DATA_DELRISSA_EVENT:
- if (data == DONE)
- HandleGameObject(DelrissaDoorGUID, true);
- if (data == IN_PROGRESS)
- DelrissaDeathCount = 0;
- Encounter[2] = data;
- break;
- case DATA_KAELTHAS_EVENT:
- if (data == NOT_STARTED || data == DONE)
- HandleGameObject(KaelDoorGUID, true);
- else if (data == IN_PROGRESS)
- HandleGameObject(KaelDoorGUID, false);
- Encounter[3] = data;
- break;
- case DATA_DELRISSA_DEATH_COUNT:
- if (data == SPECIAL)
- ++DelrissaDeathCount;
- else
- DelrissaDeathCount = 0;
- break;
- case DATA_KAELTHAS_STATUES:
- HandleGameObject(KaelStatue[0], data);
- HandleGameObject(KaelStatue[1], data);
- StatuesState = data;
- break;
+ switch (type)
+ {
+ case DATA_DELRISSA_DEATH_COUNT:
+ if (data == SPECIAL)
+ ++DelrissaDeathCount;
+ else
+ DelrissaDeathCount = 0;
+ break;
+ case DATA_KAELTHAS_STATUES:
+ HandleGameObject(KaelStatue[0], data);
+ HandleGameObject(KaelStatue[1], data);
+ break;
+ default:
+ break;
+ }
}
- SaveToDB();
- }
-
- void OnCreatureCreate(Creature* creature) override
- {
- switch (creature->GetEntry())
+ void OnCreatureCreate(Creature* creature) override
{
- case NPC_SELIN:
- SelinGUID = creature->GetGUID();
- break;
- case NPC_DELRISSA:
- DelrissaGUID = creature->GetGUID();
- break;
- case NPC_FELCRYSTALS:
- FelCrystals.push_back(creature->GetGUID());
- break;
+ switch (creature->GetEntry())
+ {
+ case NPC_SELIN:
+ SelinGUID = creature->GetGUID();
+ break;
+ case NPC_DELRISSA:
+ DelrissaGUID = creature->GetGUID();
+ break;
+ case NPC_FELCRYSTALS:
+ FelCrystals.push_back(creature->GetGUID());
+ break;
+ default:
+ break;
+ }
}
- }
- void OnGameObjectCreate(GameObject* go) override
- {
- switch (go->GetEntry())
+ void OnGameObjectCreate(GameObject* go) override
{
- case GO_VEXALLUS_DOOR:
- VexallusDoorGUID = go->GetGUID();
- break;
- case GO_SELIN_DOOR:
- SelinDoorGUID = go->GetGUID();
- break;
- case GO_SELIN_ENCOUNTER_DOOR:
- SelinEncounterDoorGUID = go->GetGUID();
- break;
- case GO_DELRISSA_DOOR:
- DelrissaDoorGUID = go->GetGUID();
- break;
- case GO_KAEL_DOOR:
- KaelDoorGUID = go->GetGUID();
- break;
- case GO_KAEL_STATUE_1:
- KaelStatue[0] = go->GetGUID();
- break;
- case GO_KAEL_STATUE_2:
- KaelStatue[1] = go->GetGUID();
- break;
- case GO_ESCAPE_ORB:
- EscapeOrbGUID = go->GetGUID();
- break;
+ switch (go->GetEntry())
+ {
+ case GO_VEXALLUS_DOOR:
+ case GO_SELIN_DOOR:
+ case GO_SELIN_ENCOUNTER_DOOR:
+ case GO_DELRISSA_DOOR:
+ case GO_KAEL_DOOR:
+ AddDoor(go, true);
+ break;
+ case GO_KAEL_STATUE_1:
+ KaelStatue[0] = go->GetGUID();
+ break;
+ case GO_KAEL_STATUE_2:
+ KaelStatue[1] = go->GetGUID();
+ break;
+ case GO_ESCAPE_ORB:
+ EscapeOrbGUID = go->GetGUID();
+ break;
+ default:
+ break;
+ }
}
- }
-
- std::string GetSaveData() override
- {
- OUT_SAVE_INST_DATA;
-
- std::ostringstream saveStream;
- saveStream << Encounter[0] << ' ' << Encounter[1] << ' ' << Encounter[2] << ' ' << Encounter[3] << ' ' << StatuesState;
- OUT_SAVE_INST_DATA_COMPLETE;
- return saveStream.str();
- }
+ void OnGameObjectRemove(GameObject* go) override
+ {
+ switch (go->GetEntry())
+ {
+ case GO_VEXALLUS_DOOR:
+ case GO_SELIN_DOOR:
+ case GO_SELIN_ENCOUNTER_DOOR:
+ case GO_DELRISSA_DOOR:
+ case GO_KAEL_DOOR:
+ AddDoor(go, false);
+ break;
+ default:
+ break;
+ }
+ }
- void Load(const char* str) override
- {
- if (!str)
+ bool SetBossState(uint32 type, EncounterState state) override
{
- OUT_LOAD_INST_DATA_FAIL;
- return;
+ if (!InstanceScript::SetBossState(type, state))
+ return false;
+
+ switch (type)
+ {
+ case DATA_DELRISSA:
+ if (type == IN_PROGRESS)
+ DelrissaDeathCount = 0;
+ break;
+ default:
+ break;
+ }
+ return true;
}
- OUT_LOAD_INST_DATA(str);
+ std::string GetSaveData() override
+ {
+ OUT_SAVE_INST_DATA;
- std::istringstream loadStream(str);
+ std::ostringstream saveStream;
+ saveStream << "M T " << GetBossSaveData();
- for (uint32 i = 0; i < MAX_ENCOUNTER; ++i)
- {
- uint32 tmpState;
- loadStream >> tmpState;
- if (tmpState == IN_PROGRESS || tmpState > SPECIAL)
- tmpState = NOT_STARTED;
- SetData(i, tmpState);
+ OUT_SAVE_INST_DATA_COMPLETE;
+ return saveStream.str();
}
- loadStream >> StatuesState;
- SetData(DATA_KAELTHAS_STATUES, StatuesState);
+ void Load(const char* str) override
+ {
+ if (!str)
+ {
+ OUT_LOAD_INST_DATA_FAIL;
+ return;
+ }
- OUT_LOAD_INST_DATA_COMPLETE;
- }
+ OUT_LOAD_INST_DATA(str);
- uint64 GetData64(uint32 identifier) const
- {
- switch (identifier)
- {
- case DATA_SELIN:
- return SelinGUID;
- case DATA_DELRISSA:
- return DelrissaGUID;
- case DATA_VEXALLUS_DOOR:
- return VexallusDoorGUID;
- case DATA_DELRISSA_DOOR:
- return DelrissaDoorGUID;
- case DATA_KAEL_DOOR:
- return KaelDoorGUID;
- case DATA_KAEL_STATUE_LEFT:
- return KaelStatue[0];
- case DATA_KAEL_STATUE_RIGHT:
- return KaelStatue[1];
- case DATA_ESCAPE_ORB:
- return EscapeOrbGUID;
- case DATA_FEL_CRYSTAL:
- if (FelCrystals.size() < felCristalIndex)
+ char dataHead1, dataHead2;
+
+ std::istringstream loadStream(str);
+ loadStream >> dataHead1 >> dataHead2;
+ if (dataHead1 == 'M' && dataHead2 == 'T')
+ {
+ for (uint32 i = 0; i < EncounterCount; ++i)
{
- TC_LOG_ERROR("scripts", "Magisters Terrace: No Fel Crystals loaded in Inst Data");
- return 0;
+ uint32 tmpState;
+ loadStream >> tmpState;
+ if (tmpState == IN_PROGRESS || tmpState > SPECIAL)
+ tmpState = NOT_STARTED;
+ SetBossState(i, EncounterState(tmpState));
}
+ }
+ else
+ OUT_LOAD_INST_DATA_FAIL;
- return FelCrystals.at(felCristalIndex);
+ OUT_LOAD_INST_DATA_COMPLETE;
+ }
+
+ uint64 GetData64(uint32 type) const override
+ {
+ switch (type)
+ {
+ case DATA_SELIN:
+ return SelinGUID;
+ case DATA_DELRISSA:
+ return DelrissaGUID;
+ case DATA_KAEL_STATUE_LEFT:
+ return KaelStatue[0];
+ case DATA_KAEL_STATUE_RIGHT:
+ return KaelStatue[1];
+ case DATA_ESCAPE_ORB:
+ return EscapeOrbGUID;
+ case DATA_FEL_CRYSTAL:
+ if (FelCrystals.size() < FelCristalIndex)
+ {
+ TC_LOG_ERROR("scripts", "Magisters Terrace: No Fel Crystals loaded in Inst Data");
+ return 0;
+ }
+
+ return FelCrystals.at(FelCristalIndex);
+ default:
+ break;
+ }
+ return 0;
}
- return 0;
- }
- void SetData64(uint32 identifier, uint64 value)
+ void SetData64(uint32 type, uint64 value) override
+ {
+ if (type == DATA_FEL_CRYSTAL)
+ FelCristalIndex = value;
+ }
+
+ protected:
+ std::vector<uint64> FelCrystals;
+
+ uint64 SelinGUID;
+ uint64 DelrissaGUID;
+ uint64 KaelStatue[2];
+ uint64 EscapeOrbGUID;
+ uint32 DelrissaDeathCount;
+ uint8 FelCristalIndex;
+ };
+
+ InstanceScript* GetInstanceScript(InstanceMap* map) const override
{
- if (identifier == DATA_FEL_CRYSTAL)
- felCristalIndex = value;
+ return new instance_magisters_terrace_InstanceMapScript(map);
}
- };
-
- InstanceScript* GetInstanceScript(InstanceMap* map) const override
- {
- return new instance_magisters_terrace_InstanceMapScript(map);
- }
};
void AddSC_instance_magisters_terrace()
diff --git a/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.h b/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.h
index ddfaa91bc98..d3517dfccf6 100644
--- a/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.h
+++ b/src/server/scripts/EasternKingdoms/MagistersTerrace/magisters_terrace.h
@@ -19,24 +19,17 @@
#ifndef DEF_MAGISTERS_TERRACE_H
#define DEF_MAGISTERS_TERRACE_H
-#define ERROR_INST_DATA "TSCR Error: Instance Data not set properly for Magister's Terrace instance (map 585). Encounters will be buggy."
+uint32 const EncounterCount = 4;
-enum Data
+enum DataTypes
{
- DATA_SELIN_EVENT,
- DATA_VEXALLUS_EVENT,
- DATA_DELRISSA_EVENT,
- DATA_KAELTHAS_EVENT,
-
DATA_SELIN,
- DATA_FEL_CRYSTAL,
- DATA_FEL_CRYSTAL_SIZE,
-
- DATA_VEXALLUS_DOOR,
+ DATA_VEXALLUS,
DATA_DELRISSA,
- DATA_DELRISSA_DOOR,
+ DATA_KAELTHAS,
- DATA_KAEL_DOOR,
+ DATA_FEL_CRYSTAL,
+ DATA_FEL_CRYSTAL_SIZE,
DATA_KAEL_STATUE_LEFT,
DATA_KAEL_STATUE_RIGHT,
@@ -45,4 +38,23 @@ enum Data
DATA_ESCAPE_ORB
};
+enum CreatureIds
+{
+ NPC_SELIN = 24723,
+ NPC_DELRISSA = 24560,
+ NPC_FELCRYSTALS = 24722
+};
+
+enum GameObjectIds
+{
+ GO_VEXALLUS_DOOR = 187896,
+ GO_SELIN_DOOR = 187979,
+ GO_SELIN_ENCOUNTER_DOOR = 188065,
+ GO_DELRISSA_DOOR = 187770,
+ GO_KAEL_DOOR = 188064,
+ GO_KAEL_STATUE_1 = 188165,
+ GO_KAEL_STATUE_2 = 188166,
+ GO_ESCAPE_ORB = 188173
+};
+
#endif
diff --git a/src/server/scripts/Spells/spell_warlock.cpp b/src/server/scripts/Spells/spell_warlock.cpp
index 86ece72cc56..4c6e2b942da 100644
--- a/src/server/scripts/Spells/spell_warlock.cpp
+++ b/src/server/scripts/Spells/spell_warlock.cpp
@@ -688,7 +688,7 @@ class spell_warl_haunt : public SpellScriptLoader
{
PrepareSpellScript(spell_warl_haunt_SpellScript);
- void HandleOnHit()
+ void HandleAfterHit()
{
if (Aura* aura = GetHitAura())
if (AuraEffect* aurEff = aura->GetEffect(EFFECT_1))
@@ -697,7 +697,7 @@ class spell_warl_haunt : public SpellScriptLoader
void Register() override
{
- OnHit += SpellHitFn(spell_warl_haunt_SpellScript::HandleOnHit);
+ AfterHit += SpellHitFn(spell_warl_haunt_SpellScript::HandleAfterHit);
}
};
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index 8b1cd858ea2..18c4d63b879 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -1319,7 +1319,7 @@ Rate.Creature.Elite.WORLDBOSS.HP = 1
#
# Creature.PickPocketRefillDelay
-# Description: Time in seconds that the server will wait before refilling the pickpocket loot
+# Description: Time in seconds that the server will wait before refilling the pickpocket loot
# for a creature
# Default: 600