diff options
author | Vincent-Michael <Vincent_Michael@gmx.de> | 2014-06-27 19:39:23 +0200 |
---|---|---|
committer | Vincent-Michael <Vincent_Michael@gmx.de> | 2014-06-27 19:39:23 +0200 |
commit | f3de6f028403b6b6eb59b8cb59cb15419ea47932 (patch) | |
tree | 0b391c0e5c2c344bfb661e42cbd8a680735c9f8e /src | |
parent | a2b860b7814ca216565a432e07579dd77f004a86 (diff) | |
parent | 52023b1e6b1fefaf4be95fa201fc1dd2ecca55a7 (diff) |
Merge branch 'master' of github.com:TrinityCore/TrinityCore into 4.3.4
Diffstat (limited to 'src')
19 files changed, 426 insertions, 490 deletions
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 |