Core/PhaseMgr: Implemented Phase Definitions, Terrainswap and multiphasing

* fixes cataclysm aura effect SPELL_AURA_PHASE without phasemasks defined in miscValueA
* implements CONDITION_SOURCE_TYPE_PHASE_DEFINITION

Thanks to:
 - Cyberbrest: For the hard research work about multiphasing.
 - Venugh: He helped me with a lot of strange compile Errors.
 - Shauren: For the 4.3.4 phaseshift packet.
 - Booksize: He showed me how terrainswap works

Signed-off-by: Naios <[email protected]>
This commit is contained in:
Naios
2012-10-15 20:31:41 +02:00
parent c757f811f2
commit 61dce1a02e
25 changed files with 973 additions and 83 deletions
@@ -0,0 +1,66 @@
DROP TABLE IF EXISTS `phase_definitions`;
CREATE TABLE `phase_definitions` (
`zoneId` mediumint(7) unsigned NOT NULL DEFAULT '0',
`entry` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
`phasemask` bigint(20) unsigned NOT NULL DEFAULT '0',
`phaseId` tinyint(3) unsigned NOT NULL DEFAULT '0',
`terrainswapmap` smallint(5) unsigned NOT NULL DEFAULT '0',
`flags` tinyint(3) unsigned DEFAULT '0',
`comment` text,
PRIMARY KEY (`zoneId`, `entry`)
)
AUTO_INCREMENT=1
ENGINE=MyISAM
COLLATE='utf8_general_ci';
INSERT INTO `phase_definitions` (`zoneId`, `entry`, `phasemask`, `phaseId`, `terrainswapmap`, `flags`, `comment`) VALUES
(1519, 1, 129, 0, 0, 0, 'Stormwind: [A] Heros Call: Vashj''ir'),
(1519, 2, 257, 0, 0, 0, 'Stormwind: [A] Heros Call: Hyjal'),
(1519, 3, 513, 0, 0, 0, 'Stormwind: [A] Heros Call: Deepholm'),
(1519, 4, 1025, 0, 0, 0, 'Stormwind: [A] Heros Call: Uldum'),
(1519, 5, 2049, 0, 0, 0, 'Stormwind: [A] Heros Call: Twilight Highlands'),
(1637, 1, 129, 0, 0, 0, 'Orgrimmar: [H] Warchiefs Command: Vashj''ir'),
(1637, 2, 257, 0, 0, 0, 'Orgrimmar: [H] Warchiefs Command: Hyjal'),
(1637, 3, 513, 0, 0, 0, 'Orgrimmar: [H] Warchiefs Command: Deepholm'),
(1637, 4, 1025, 0, 0, 0, 'Orgrimmar: [H] Warchiefs Command: Uldum'),
(1637, 5, 2049, 0, 0, 0, 'Orgrimmar: [H] Warchiefs Command: Twilight Highlands'),
(616 , 1, 0 , 165, 719, 0, 'Mount Hyjal: Default Terrainswap');
DROP TABLE IF EXISTS `spell_phase`;
CREATE TABLE `spell_phase` (
`id` mediumint(7) unsigned NOT NULL DEFAULT '0',
`phasemask` bigint(20) unsigned NOT NULL DEFAULT '1',
`terrainswapmap` smallint(5) unsigned NOT NULL DEFAULT '0',
PRIMARY KEY (`id`)
)
AUTO_INCREMENT=1
ENGINE=MyISAM
COLLATE='utf8_general_ci';
DELETE FROM `trinity_string` WHERE `entry` BETWEEN 176 AND 182;
INSERT INTO `trinity_string` (`entry`, `content_default`) VALUES
(176, '|cff0099FFPhaseMgr: Report for player: %s, zoneId: %u, level: %u, team: %u, phaseupdateflag: %u|r'),
(177, '|cff663399PhaseMgr: There are no definitions defined for zoneId %u.|r'),
(178, '|cff0066FFPhaseMgr: Success (entry: %u) - added %s %u to the players phase.|r'),
(179, '|cffFF0000PhaseMgr: Condition for phase %u (entry: %u, zoneId: %u) failed.|r'),
(180, '|cffFF0000PhaseMgr: Condition for phase %u (entry: %u, zoneId: %u) has last phasemask flag. Skipped other definitions.|r'),
(181, '|cff6699FFPhaseMgr: The player gets phasemask %u through definitions, %u through phasing auras, and phase %u through custom phase.|r'),
(182, '|cff0099FFPhaseMgr: The player has phasemask %u (real: %u).|r');
DELETE FROM `command` WHERE `name` IN('debug phase', 'debug send setphaseshift');
INSERT INTO `command` (`name`, `security`, `help`) VALUES
('debug phase', 1, 'Syntax: .debug phase\r\n\r\nSends a phase debug report of a player to you.');
/*
Conditions (SourceGroup -> ZoneId, SourceEntry -> Entry)
If you visit the Gm Island as a alliance race you are automatically phased into phase 2.
DELETE FROM `conditions` WHERE `SourceTypeOrReferenceId`=23 AND `SourceGroup`=876 AND `SourceEntry`=1;
INSERT INTO `conditions` (`SourceTypeOrReferenceId`, `SourceGroup`, `SourceEntry`, `SourceId`, `ElseGroup`, `ConditionTypeOrReference`, `ConditionTarget`, `ConditionValue1`, `ConditionValue2`, `ConditionValue3`, `NegativeCondition`, `ErrorTextId`, `ScriptName`, `Comment`) VALUES
(23, 876, 1, 0, 0, 6, 0, 469, 0, 0, 0, 0, '', 'Phase Definitions Example: Phase is only visible for Alliance Members');
DELETE FROM `phase_definitions` WHERE `zoneId`=876 AND `entry`=1;
INSERT INTO `phase_definitions` (`zoneId`, `entry`, `phasemask`, `phaseId`, `terrainswapmap`, `flags`, `comment`) VALUES
(876, 1, 2, 0, 0, 0, '[Example] Gm Island');
*/
+47 -1
View File
@@ -611,7 +611,8 @@ bool ConditionMgr::CanHaveSourceGroupSet(ConditionSourceType sourceType) const
sourceType == CONDITION_SOURCE_TYPE_VEHICLE_SPELL ||
sourceType == CONDITION_SOURCE_TYPE_SPELL_IMPLICIT_TARGET ||
sourceType == CONDITION_SOURCE_TYPE_SPELL_CLICK_EVENT ||
sourceType == CONDITION_SOURCE_TYPE_SMART_EVENT);
sourceType == CONDITION_SOURCE_TYPE_SMART_EVENT ||
sourceType == CONDITION_SOURCE_TYPE_PHASE_DEFINITION);
}
bool ConditionMgr::CanHaveSourceIdSet(ConditionSourceType sourceType) const
@@ -687,6 +688,23 @@ ConditionList ConditionMgr::GetConditionsForSmartEvent(int32 entryOrGuid, uint32
return cond;
}
ConditionList ConditionMgr::GetConditionsForPhaseDefinition(uint32 zone, uint32 entry)
{
ConditionList cond;
PhaseDefinitionConditionContainer::const_iterator itr = PhaseDefinitionsConditionStore.find(zone);
if (itr != PhaseDefinitionsConditionStore.end())
{
ConditionTypeContainer::const_iterator i = (*itr).second.find(entry);
if (i != (*itr).second.end())
{
cond = (*i).second;
sLog->outDebug(LOG_FILTER_CONDITIONSYS, "GetConditionsForPhaseDefinition: found conditions for zone %u entry %u spell %u", zone, entry);
}
}
return cond;
}
void ConditionMgr::LoadConditions(bool isReload)
{
uint32 oldMSTime = getMSTime();
@@ -898,6 +916,13 @@ void ConditionMgr::LoadConditions(bool isReload)
++count;
continue;
}
case CONDITION_SOURCE_TYPE_PHASE_DEFINITION:
{
PhaseDefinitionsConditionStore[cond->SourceGroup][cond->SourceEntry].push_back(cond);
valid = true;
++count;
continue;
}
default:
break;
}
@@ -1389,6 +1414,13 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
return false;
}
break;
case CONDITION_SOURCE_TYPE_PHASE_DEFINITION:
if (!PhaseMgr::IsConditionTypeSupported(cond->ConditionType))
{
sLog->outError(LOG_FILTER_SQL, "Condition source type `CONDITION_SOURCE_TYPE_PHASE_DEFINITION` does not support condition type %u, ignoring.", cond->ConditionType);
return false;
}
break;
case CONDITION_SOURCE_TYPE_GOSSIP_MENU:
case CONDITION_SOURCE_TYPE_GOSSIP_MENU_OPTION:
case CONDITION_SOURCE_TYPE_SMART_EVENT:
@@ -1399,6 +1431,7 @@ bool ConditionMgr::isSourceTypeValid(Condition* cond)
return true;
}
bool ConditionMgr::isConditionTypeValid(Condition* cond)
{
if (cond->ConditionType == CONDITION_NONE || cond->ConditionType >= CONDITION_MAX)
@@ -1940,6 +1973,19 @@ void ConditionMgr::Clean()
SpellClickEventConditionStore.clear();
for (PhaseDefinitionConditionContainer::iterator itr = PhaseDefinitionsConditionStore.begin(); itr != PhaseDefinitionsConditionStore.end(); ++itr)
{
for (ConditionTypeContainer::iterator it = itr->second.begin(); it != itr->second.end(); ++it)
{
for (ConditionList::const_iterator i = it->second.begin(); i != it->second.end(); ++i)
delete *i;
it->second.clear();
}
itr->second.clear();
}
PhaseDefinitionsConditionStore.clear();
// this is a BIG hack, feel free to fix it if you can figure out the ConditionMgr ;)
for (std::list<Condition*>::const_iterator itr = AllocatedMemoryStore.begin(); itr != AllocatedMemoryStore.end(); ++itr)
delete *itr;
+5 -1
View File
@@ -124,7 +124,8 @@ enum ConditionSourceType
CONDITION_SOURCE_TYPE_QUEST_SHOW_MARK = 20,
CONDITION_SOURCE_TYPE_VEHICLE_SPELL = 21,
CONDITION_SOURCE_TYPE_SMART_EVENT = 22,
CONDITION_SOURCE_TYPE_MAX = 23 //MAX
CONDITION_SOURCE_TYPE_PHASE_DEFINITION = 23,
CONDITION_SOURCE_TYPE_MAX = 24 //MAX
};
enum ComparisionType
@@ -211,6 +212,7 @@ typedef std::map<uint32, ConditionList> ConditionTypeContainer;
typedef std::map<ConditionSourceType, ConditionTypeContainer> ConditionContainer;
typedef std::map<uint32, ConditionTypeContainer> CreatureSpellConditionContainer;
typedef std::map<std::pair<int32, uint32 /*SAI source_type*/>, ConditionTypeContainer> SmartEventConditionContainer;
typedef std::map<int32 /*zoneId*/, ConditionTypeContainer> PhaseDefinitionConditionContainer;
typedef std::map<uint32, ConditionList> ConditionReferenceContainer;//only used for references
@@ -237,6 +239,7 @@ class ConditionMgr
ConditionList GetConditionsForSpellClickEvent(uint32 creatureId, uint32 spellId);
ConditionList GetConditionsForSmartEvent(int32 entryOrGuid, uint32 eventId, uint32 sourceType);
ConditionList GetConditionsForVehicleSpell(uint32 creatureId, uint32 spellId);
ConditionList GetConditionsForPhaseDefinition(uint32 zone, uint32 entry);
private:
bool isSourceTypeValid(Condition* cond);
@@ -254,6 +257,7 @@ class ConditionMgr
CreatureSpellConditionContainer VehicleSpellConditionStore;
CreatureSpellConditionContainer SpellClickEventConditionStore;
SmartEventConditionContainer SmartEventConditionStore;
PhaseDefinitionConditionContainer PhaseDefinitionsConditionStore;
};
template <class T> bool CompareValues(ComparisionType type, T val1, T val2)
+2 -2
View File
@@ -1408,8 +1408,8 @@ struct LockEntry
struct PhaseEntry
{
uint32 ID; // 0
char* Name; // 1
uint32 phaseShift; // 2
char* Name; // 1
uint32 flag; // 2
};
struct MailTemplateEntry
+42 -32
View File
@@ -649,7 +649,7 @@ void KillRewarder::Reward()
#ifdef _MSC_VER
#pragma warning(disable:4355)
#endif
Player::Player(WorldSession* session): Unit(true), m_achievementMgr(this), m_reputationMgr(this)
Player::Player(WorldSession* session): Unit(true), m_achievementMgr(this), m_reputationMgr(this), phaseMgr(this)
{
#ifdef _MSC_VER
#pragma warning(default:4355)
@@ -2938,18 +2938,6 @@ void Player::SetGameMaster(bool on)
}
else
{
// restore phase
uint32 newPhase = 0;
AuraEffectList const& phases = GetAuraEffectsByType(SPELL_AURA_PHASE);
if (!phases.empty())
for (AuraEffectList::const_iterator itr = phases.begin(); itr != phases.end(); ++itr)
newPhase |= (*itr)->GetMiscValue();
if (!newPhase)
newPhase = PHASEMASK_NORMAL;
SetPhaseMask(newPhase, false);
m_ExtraFlags &= ~ PLAYER_EXTRA_GM_ON;
setFactionForRace(getRace());
RemoveFlag(PLAYER_FLAGS, PLAYER_FLAGS_GM);
@@ -2970,6 +2958,9 @@ void Player::SetGameMaster(bool on)
getHostileRefManager().setOnlineOfflineState(true);
m_serverSideVisibilityDetect.SetValue(SERVERSIDE_VISIBILITY_GM, SEC_PLAYER);
phaseMgr.AddUpdateFlag(PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED);
phaseMgr.Update();
}
UpdateObjectVisibility();
@@ -3202,6 +3193,11 @@ void Player::GiveLevel(uint8 level)
UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_REACH_LEVEL);
PhaseUpdateData phaseUdateData;
phaseUdateData.AddConditionType(CONDITION_LEVEL);
phaseMgr.NotifyConditionChanged(phaseUdateData);
// Refer-A-Friend
if (GetSession()->GetRecruiterId())
if (level < sWorld->getIntConfig(CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL))
@@ -7628,6 +7624,8 @@ void Player::UpdateArea(uint32 newArea)
// so apply them accordingly
m_areaUpdateId = newArea;
phaseMgr.AddUpdateFlag(PHASE_UPDATE_FLAG_AREA_UPDATE);
AreaTableEntry const* area = GetAreaEntryByAreaID(newArea);
pvpInfo.inFFAPvPArea = area && (area->flags & AREA_FLAG_ARENA);
UpdatePvPState(true);
@@ -7644,10 +7642,14 @@ void Player::UpdateArea(uint32 newArea)
}
else
RemoveByteFlag(UNIT_FIELD_BYTES_2, 1, UNIT_BYTE2_FLAG_SANCTUARY);
phaseMgr.RemoveUpdateFlag(PHASE_UPDATE_FLAG_AREA_UPDATE);
}
void Player::UpdateZone(uint32 newZone, uint32 newArea)
{
phaseMgr.AddUpdateFlag(PHASE_UPDATE_FLAG_ZONE_UPDATE);
if (m_zoneUpdateId != newZone)
{
sOutdoorPvPMgr->HandlePlayerLeaveZone(this, m_zoneUpdateId);
@@ -7757,6 +7759,8 @@ void Player::UpdateZone(uint32 newZone, uint32 newArea)
UpdateLocalChannels(newZone);
UpdateZoneDependentAuras(newZone);
phaseMgr.RemoveUpdateFlag(PHASE_UPDATE_FLAG_ZONE_UPDATE);
}
//If players are too far away from the duel flag... they lose the duel
@@ -15010,6 +15014,11 @@ void Player::AddQuest(Quest const* quest, Object* questGiver)
CastSpell(this, itr->second->spellId, true);
}
PhaseUpdateData phaseUdateData;
phaseUdateData.AddQuestUpdate(quest_id);
phaseMgr.NotifyConditionChanged(phaseUdateData);
UpdateForQuestWorldObjects();
}
@@ -15178,6 +15187,11 @@ void Player::RewardQuest(Quest const* quest, uint32 reward, Object* questGiver,
m_RewardedQuests.insert(quest_id);
m_RewardedQuestsSave[quest_id] = true;
PhaseUpdateData phaseUdateData;
phaseUdateData.AddQuestUpdate(quest_id);
phaseMgr.NotifyConditionChanged(phaseUdateData);
// StoreNewItem, mail reward, etc. save data directly to the database
// to prevent exploitable data desynchronisation we save the quest status to the database too
// (to prevent rewarding this quest another time while rewards were already given out)
@@ -15767,6 +15781,11 @@ void Player::SetQuestStatus(uint32 quest_id, QuestStatus status)
m_QuestStatusSave[quest_id] = true;
}
PhaseUpdateData phaseUdateData;
phaseUdateData.AddQuestUpdate(quest_id);
phaseMgr.NotifyConditionChanged(phaseUdateData);
UpdateForQuestWorldObjects();
}
@@ -15777,6 +15796,11 @@ void Player::RemoveActiveQuest(uint32 quest_id)
{
m_QuestStatus.erase(itr);
m_QuestStatusSave[quest_id] = false;
PhaseUpdateData phaseUdateData;
phaseUdateData.AddQuestUpdate(quest_id);
phaseMgr.NotifyConditionChanged(phaseUdateData);
return;
}
}
@@ -15788,6 +15812,11 @@ void Player::RemoveRewardedQuest(uint32 quest_id)
{
m_RewardedQuests.erase(rewItr);
m_RewardedQuestsSave[quest_id] = false;
PhaseUpdateData phaseUdateData;
phaseUdateData.AddQuestUpdate(quest_id);
phaseMgr.NotifyConditionChanged(phaseUdateData);
}
}
@@ -24420,25 +24449,6 @@ void Player::_LoadSkills(PreparedQueryResult result)
}
}
uint32 Player::GetPhaseMaskForSpawn() const
{
uint32 phase = PHASEMASK_NORMAL;
if (!isGameMaster())
phase = GetPhaseMask();
else
{
AuraEffectList const& phases = GetAuraEffectsByType(SPELL_AURA_PHASE);
if (!phases.empty())
phase = phases.front()->GetMiscValue();
}
// some aura phases include 1 normal map in addition to phase itself
if (uint32 n_phase = phase & ~PHASEMASK_NORMAL)
return n_phase;
return PHASEMASK_NORMAL;
}
InventoryResult Player::CanEquipUniqueItem(Item* pItem, uint8 eslot, uint32 limit_count) const
{
ItemTemplate const* pProto = pItem->GetTemplate();
+8 -1
View File
@@ -37,6 +37,9 @@
#include "Unit.h"
#include "Util.h" // for Tokens typedef
#include "WorldSession.h"
#include "PhaseMgr.h"
// for template
#include "SpellMgr.h"
#include<string>
@@ -54,6 +57,7 @@ class PlayerMenu;
class PlayerSocial;
class SpellCastTargets;
class UpdateMask;
class PhaseMgr;
typedef std::deque<Mail*> PlayerMails;
@@ -1342,7 +1346,8 @@ class Player : public Unit, public GridObject<Player>
Pet* GetPet() const;
Pet* SummonPet(uint32 entry, float x, float y, float z, float ang, PetType petType, uint32 despwtime);
void RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent = false);
uint32 GetPhaseMaskForSpawn() const; // used for proper set phase for DB at GM-mode creature/GO spawn
PhaseMgr& GetPhaseMgr() { return phaseMgr; }
void Say(const std::string& text, const uint32 language);
void Yell(const std::string& text, const uint32 language);
@@ -3083,6 +3088,8 @@ class Player : public Unit, public GridObject<Player>
uint32 _pendingBindTimer;
uint32 _activeCheats;
PhaseMgr phaseMgr;
};
void AddItemsSetItem(Player*player, Item* item);
+95 -2
View File
@@ -8652,7 +8652,7 @@ void ObjectMgr::LoadFactionChangeTitles()
}
uint32 count = 0;
do
{
Field* fields = result->Fetch();
@@ -8666,7 +8666,7 @@ void ObjectMgr::LoadFactionChangeTitles()
sLog->outError(LOG_FILTER_SQL, "Title %u referenced in `player_factionchange_title` does not exist, pair skipped!", horde);
else
FactionChange_Titles[alliance] = horde;
++count;
}
while (result->NextRow());
@@ -8674,6 +8674,99 @@ void ObjectMgr::LoadFactionChangeTitles()
sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u faction change title pairs in %u ms", count, GetMSTimeDiffToNow(oldMSTime));
}
void ObjectMgr::LoadPhaseDefinitions()
{
_PhaseDefinitionStore.clear();
uint32 oldMSTime = getMSTime();
// 0 1 2 3 4 5
QueryResult result = WorldDatabase.Query("SELECT zoneId, entry, phasemask, phaseId, terrainswapmap, flags FROM `phase_definitions` ORDER BY `entry` ASC");
if (!result)
{
sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 phasing definitions. DB table `phase_definitions` is empty.");
return;
}
uint32 count = 0;
do
{
Field *fields = result->Fetch();
PhaseDefinition PhaseDefinition;
PhaseDefinition.zoneId = fields[0].GetUInt32();
PhaseDefinition.entry = fields[1].GetUInt32();
PhaseDefinition.phasemask = fields[2].GetUInt32();
PhaseDefinition.phaseId = fields[3].GetUInt32();
PhaseDefinition.terrainswapmap = fields[4].GetUInt32();
PhaseDefinition.flags = fields[5].GetUInt32();
// Checks
if ((PhaseDefinition.flags & PHASE_FLAG_OVERWRITE_EXISTING) && (PhaseDefinition.flags & PHASE_FLAG_NEGATE_PHASE))
{
sLog->outError(LOG_FILTER_SQL, "Flags defined in phase_definitions in zoneId %d and entry %u does contain PHASE_FLAG_OVERWRITE_EXISTING and PHASE_FLAG_NEGATE_PHASE. Setting flags to PHASE_FLAG_OVERWRITE_EXISTING", PhaseDefinition.zoneId, PhaseDefinition.entry);
PhaseDefinition.flags &= ~PHASE_FLAG_NEGATE_PHASE;
}
_PhaseDefinitionStore[PhaseDefinition.zoneId].push_back(PhaseDefinition);
++count;
}
while (result->NextRow());
sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u phasing definitions in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
}
void ObjectMgr::LoadSpellPhaseInfo()
{
_SpellPhaseStore.clear();
uint32 oldMSTime = getMSTime();
// 0 1 2
QueryResult result = WorldDatabase.Query("SELECT id, phasemask, terrainswapmap FROM `spell_phase`");
if (!result)
{
sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded 0 spell dbc infos. DB table `spell_phase` is empty.");
return;
}
uint32 count = 0;
do
{
Field *fields = result->Fetch();
SpellPhaseInfo spellPhaseInfo;
spellPhaseInfo.spellId = fields[0].GetUInt32();
SpellInfo const* spell = sSpellMgr->GetSpellInfo(spellPhaseInfo.spellId);
if (!spell)
{
sLog->outError(LOG_FILTER_SQL, "Spell %u defined in `spell_phase` does not exists, skipped.", spellPhaseInfo.spellId);
continue;
}
if (!spell->HasAura(SPELL_AURA_PHASE))
{
sLog->outError(LOG_FILTER_SQL, "Spell %u defined in `spell_phase` does not have aura effect type SPELL_AURA_PHASE, useless value.", spellPhaseInfo.spellId);
continue;
}
spellPhaseInfo.phasemask = fields[1].GetUInt32();
spellPhaseInfo.terrainswapmap = fields[2].GetUInt32();
_SpellPhaseStore[spellPhaseInfo.spellId] = spellPhaseInfo;
++count;
}
while (result->NextRow());
sLog->outInfo(LOG_FILTER_SERVER_LOADING, ">> Loaded %u spell dbc infos in %u ms.", count, GetMSTimeDiffToNow(oldMSTime));
}
GameObjectTemplate const* ObjectMgr::GetGameObjectTemplate(uint32 entry)
{
GameObjectTemplateContainer::const_iterator itr = _gameObjectTemplateStore.find(entry);
+11
View File
@@ -42,8 +42,10 @@
#include <limits>
#include "ConditionMgr.h"
#include <functional>
#include "PhaseMgr.h"
class Item;
class PhaseMgr;
// GCC have alternative #pragma pack(N) syntax and old gcc version not support pack(push, N), also any gcc version not support it at some platform
#if defined(__GNUC__)
@@ -906,6 +908,12 @@ class ObjectMgr
void LoadTrainerSpell();
void AddSpellToTrainer(uint32 entry, uint32 spell, uint32 spellCost, uint32 reqSkill, uint32 reqSkillValue, uint32 reqLevel);
void LoadPhaseDefinitions();
void LoadSpellPhaseInfo();
PhaseDefinitionStore const* GetPhaseDefinitionStore() { return &_PhaseDefinitionStore; }
SpellPhaseStore const* GetSpellPhaseStore() { return &_SpellPhaseStore; }
std::string GeneratePetName(uint32 entry);
uint32 GetBaseXP(uint8 level);
uint32 GetXPForLevel(uint8 level) const;
@@ -1222,6 +1230,9 @@ class ObjectMgr
PageTextContainer _pageTextStore;
InstanceTemplateContainer _instanceTemplateStore;
PhaseDefinitionStore _PhaseDefinitionStore;
SpellPhaseStore _SpellPhaseStore;
private:
void LoadScripts(ScriptsType type);
void CheckScripts(ScriptsType type, std::set<int32>& ids);
+44 -3
View File
@@ -1753,10 +1753,51 @@ void WorldSession::HandleReadyForAccountDataTimes(WorldPacket& /*recvData*/)
SendAccountDataTimes(GLOBAL_CACHE_MASK);
}
void WorldSession::SendSetPhaseShift(uint32 PhaseShift)
void WorldSession::SendSetPhaseShift(std::set<uint32> const& phaseIds, std::set<uint32> const& terrainswaps)
{
WorldPacket data(SMSG_SET_PHASE_SHIFT, 4);
data << uint32(PhaseShift);
ObjectGuid guid = _player->GetGUID();
WorldPacket data(SMSG_SET_PHASE_SHIFT, 1 + 8 + 4 + 4 + 4 + 4 + 2 * phaseIds.size() + 4 + terrainswaps.size() * 2);
data.WriteBit(guid[2]);
data.WriteBit(guid[3]);
data.WriteBit(guid[1]);
data.WriteBit(guid[6]);
data.WriteBit(guid[4]);
data.WriteBit(guid[5]);
data.WriteBit(guid[0]);
data.WriteBit(guid[7]);
data.WriteByteSeq(guid[7]);
data.WriteByteSeq(guid[4]);
data << uint32(0);
//for (uint8 i = 0; i < worldMapAreaCount; ++i)
// data << uint16(0); // WorldMapArea.dbc id (controls map display)
data.WriteByteSeq(guid[1]);
data << uint32(0); // flags (not phasemask)
data.WriteByteSeq(guid[2]);
data.WriteByteSeq(guid[6]);
data << uint32(0); // Inactive terrain swaps
//for (uint8 i = 0; i < inactiveSwapsCount; ++i)
// data << uint16(0);
data << uint32(phaseIds.size()) * 2; // Phase.dbc ids
for (std::set<uint32>::const_iterator itr = phaseIds.begin(); itr != phaseIds.end(); ++itr)
data << uint16(*itr);
data.WriteByteSeq(guid[3]);
data.WriteByteSeq(guid[0]);
data << uint32(terrainswaps.size()) * 2; // Active terrain swaps
for (std::set<uint32>::const_iterator itr = terrainswaps.begin(); itr != terrainswaps.end(); ++itr)
data << uint16(*itr);
data.WriteByteSeq(guid[5]);
SendPacket(&data);
}
@@ -450,3 +450,14 @@ void InstanceScript::UpdateEncounterState(EncounterCreditType type, uint32 credi
}
}
}
void InstanceScript::UpdatePhasing()
{
PhaseUpdateData phaseUdateData;
phaseUdateData.AddConditionType(CONDITION_INSTANCE_DATA);
Map::PlayerList const& players = instance->GetPlayers();
for (Map::PlayerList::const_iterator itr = players.begin(); itr != players.end(); ++itr)
if (Player* player = itr->getSource())
player->GetPhaseMgr().NotifyConditionChanged(phaseUdateData);
}
@@ -217,6 +217,9 @@ class InstanceScript : public ZoneScript
virtual void FillInitialWorldStates(WorldPacket& /*data*/) {}
// ReCheck PhaseTemplate related conditions
void UpdatePhasing();
protected:
void SetBossNumber(uint32 number) { bosses.resize(number); }
void LoadDoorData(DoorData const* data);
+371
View File
@@ -0,0 +1,371 @@
/*
* Copyright (C) 2008-2012 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 "PhaseMgr.h"
#include "Chat.h"
//////////////////////////////////////////////////////////////////
// Updating
PhaseMgr::PhaseMgr(Player* _player) : player(_player), phaseData(_player), _UpdateFlags(0)
{
_PhaseDefinitionStore = sObjectMgr->GetPhaseDefinitionStore();
_SpellPhaseStore = sObjectMgr->GetSpellPhaseStore();
}
void PhaseMgr::Update()
{
if (IsUpdateInProgress())
return;
if (_UpdateFlags & PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED)
phaseData.SendPhaseshiftToPlayer();
if (_UpdateFlags & PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED)
phaseData.SendPhaseMaskToPlayer();
_UpdateFlags = 0;
}
void PhaseMgr::RemoveUpdateFlag(PhaseUpdateFlag updateFlag)
{
_UpdateFlags &= ~updateFlag;
if (updateFlag == PHASE_UPDATE_FLAG_ZONE_UPDATE)
{
// Update zone changes
if (phaseData.HasActiveDefinitions())
{
phaseData.ResetDefinitions();
_UpdateFlags |= (PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED | PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED);
}
if (_PhaseDefinitionStore->find(player->GetZoneId()) != _PhaseDefinitionStore->end())
Recalculate();
}
Update();
}
/////////////////////////////////////////////////////////////////
// Notifier
void PhaseMgr::NotifyConditionChanged(PhaseUpdateData const& updateData)
{
if (NeedsPhaseUpdateWithData(updateData))
{
Recalculate();
Update();
}
}
//////////////////////////////////////////////////////////////////
// Phasing Definitions
void PhaseMgr::Recalculate()
{
if (phaseData.HasActiveDefinitions())
{
phaseData.ResetDefinitions();
_UpdateFlags |= (PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED | PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED);
}
PhaseDefinitionStore::const_iterator itr = _PhaseDefinitionStore->find(player->GetZoneId());
if (itr != _PhaseDefinitionStore->end())
for (PhaseDefinitionContainer::const_iterator phase = itr->second.begin(); phase != itr->second.end(); ++phase)
if (CheckDefinition(&(*phase)))
{
phaseData.AddPhaseDefinition(&(*phase));
if (phase->phasemask)
_UpdateFlags |= PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED;
if (phase->phaseId || phase->terrainswapmap)
_UpdateFlags |= PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED;
if (phase->IsLastDefinition())
break;
}
}
inline bool PhaseMgr::CheckDefinition(PhaseDefinition const* phaseDefinition)
{
return sConditionMgr->IsObjectMeetToConditions(player, sConditionMgr->GetConditionsForPhaseDefinition(phaseDefinition->zoneId, phaseDefinition->entry));
}
bool PhaseMgr::NeedsPhaseUpdateWithData(PhaseUpdateData const updateData) const
{
PhaseDefinitionStore::const_iterator itr = _PhaseDefinitionStore->find(player->GetZoneId());
if (itr != _PhaseDefinitionStore->end())
{
for (PhaseDefinitionContainer::const_iterator phase = itr->second.begin(); phase != itr->second.end(); ++phase)
{
ConditionList conditionList = sConditionMgr->GetConditionsForPhaseDefinition(phase->zoneId, phase->entry);
for (ConditionList::const_iterator condition = conditionList.begin(); condition != conditionList.end(); ++condition)
if (updateData.IsConditionRelated(*condition))
return true;
}
}
return false;
}
//////////////////////////////////////////////////////////////////
// Auras
void PhaseMgr::RegisterPhasingAuraEffect(AuraEffect const* auraEffect)
{
PhaseInfo phaseInfo;
if (auraEffect->GetMiscValue())
{
_UpdateFlags |= PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED;
phaseInfo.phasemask = auraEffect->GetMiscValue();
}
else
{
SpellPhaseStore::const_iterator itr = _SpellPhaseStore->find(auraEffect->GetId());
if (itr != _SpellPhaseStore->end())
{
if (itr->second.phasemask)
{
_UpdateFlags |= PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED;
phaseInfo.phasemask = itr->second.phasemask;
}
if (itr->second.terrainswapmap)
phaseInfo.terrainswapmap = itr->second.terrainswapmap;
}
}
phaseInfo.phaseId = auraEffect->GetMiscValueB();
if (phaseInfo.NeedsClientSideUpdate())
_UpdateFlags |= PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED;
phaseData.AddAuraInfo(auraEffect->GetId(), phaseInfo);
Update();
}
void PhaseMgr::UnRegisterPhasingAuraEffect(AuraEffect const* auraEffect)
{
_UpdateFlags |= phaseData.RemoveAuraInfo(auraEffect->GetId());
Update();
}
//////////////////////////////////////////////////////////////////
// Commands
void PhaseMgr::SendDebugReportToPlayer(Player* const debugger)
{
ChatHandler(debugger).PSendSysMessage(LANG_PHASING_REPORT_STATUS, player->GetName(), player->GetZoneId(), player->getLevel(), player->GetTeamId(), _UpdateFlags);
PhaseDefinitionStore::const_iterator itr = _PhaseDefinitionStore->find(player->GetZoneId());
if (itr == _PhaseDefinitionStore->end())
ChatHandler(debugger).PSendSysMessage(LANG_PHASING_NO_DEFINITIONS, player->GetZoneId());
else
{
for (PhaseDefinitionContainer::const_iterator phase = itr->second.begin(); phase != itr->second.end(); ++phase)
{
if (CheckDefinition(&(*phase)))
ChatHandler(debugger).PSendSysMessage(LANG_PHASING_SUCCESS, phase->entry, phase->IsNegatingPhasemask() ? "negated Phase" : "Phase", phase->phasemask);
else
ChatHandler(debugger).PSendSysMessage(LANG_PHASING_FAILED, phase->phasemask, phase->entry, phase->zoneId);
if (phase->IsLastDefinition())
{
ChatHandler(debugger).PSendSysMessage(LANG_PHASING_LAST_PHASE, phase->phasemask, phase->entry, phase->zoneId);
break;
}
}
}
ChatHandler(debugger).PSendSysMessage(LANG_PHASING_LIST, phaseData._PhasemaskThroughDefinitions, phaseData._PhasemaskThroughAuras, phaseData._CustomPhasemask);
ChatHandler(debugger).PSendSysMessage(LANG_PHASING_PHASEMASK, phaseData.GetPhaseMaskForSpawn(), player->GetPhaseMask());
}
void PhaseMgr::SetCustomPhase(uint32 const phaseMask)
{
phaseData._CustomPhasemask = phaseMask;
_UpdateFlags |= PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED;
Update();
}
//////////////////////////////////////////////////////////////////
// Phase Data
uint32 PhaseData::GetCurrentPhasemask() const
{
if (player->isGameMaster())
return PHASEMASK_ANYWHERE;
if (_CustomPhasemask)
return _CustomPhasemask;
return GetPhaseMaskForSpawn();
}
inline uint32 PhaseData::GetPhaseMaskForSpawn() const
{
uint32 const phase = (_PhasemaskThroughDefinitions | _PhasemaskThroughAuras);
return (phase ? phase : PHASEMASK_NORMAL);
}
void PhaseData::SendPhaseMaskToPlayer()
{
// Server side update
uint32 const phasemask = GetCurrentPhasemask();
if (player->GetPhaseMask() == phasemask)
return;
player->SetPhaseMask(phasemask, false);
if (player->IsVisible())
player->UpdateObjectVisibility();
}
void PhaseData::SendPhaseshiftToPlayer()
{
// Client side update
std::set<uint32> phaseIds;
std::set<uint32> terrainswaps;
for (PhaseInfoContainer::const_iterator itr = spellPhaseInfo.begin(); itr != spellPhaseInfo.end(); ++itr)
{
if (itr->second.terrainswapmap)
terrainswaps.insert(itr->second.terrainswapmap);
if (itr->second.phaseId)
phaseIds.insert(itr->second.phaseId);
}
// Phase Definitions
for (std::list<PhaseDefinition const*>::const_iterator itr = activePhaseDefinitions.begin(); itr != activePhaseDefinitions.end(); ++itr)
{
if ((*itr)->phaseId)
phaseIds.insert((*itr)->phaseId);
if ((*itr)->terrainswapmap)
terrainswaps.insert((*itr)->terrainswapmap);
}
player->GetSession()->SendSetPhaseShift(phaseIds, terrainswaps);
}
void PhaseData::AddPhaseDefinition(PhaseDefinition const* phaseDefinition)
{
if (phaseDefinition->IsOverwritingExistingPhases())
{
activePhaseDefinitions.clear();
_PhasemaskThroughDefinitions = phaseDefinition->phasemask;
}
else
{
if (phaseDefinition->IsNegatingPhasemask())
_PhasemaskThroughDefinitions &= ~phaseDefinition->phasemask;
else
_PhasemaskThroughDefinitions |= phaseDefinition->phasemask;
}
activePhaseDefinitions.push_back(phaseDefinition);
}
void PhaseData::AddAuraInfo(uint32 const spellId, PhaseInfo phaseInfo)
{
if (phaseInfo.phasemask)
_PhasemaskThroughAuras |= phaseInfo.phasemask;
spellPhaseInfo[spellId] = phaseInfo;
}
uint32 PhaseData::RemoveAuraInfo(uint32 const spellId)
{
PhaseInfoContainer::const_iterator rAura = spellPhaseInfo.find(spellId);
if (rAura != spellPhaseInfo.end())
{
uint32 updateflag = 0;
if (rAura->second.NeedsClientSideUpdate())
updateflag |= PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED;
if (rAura->second.NeedsServerSideUpdate())
{
_PhasemaskThroughAuras = 0;
updateflag |= PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED;
spellPhaseInfo.erase(rAura);
for (PhaseInfoContainer::const_iterator itr = spellPhaseInfo.begin(); itr != spellPhaseInfo.end(); ++itr)
_PhasemaskThroughAuras |= itr->second.phasemask;
}
return updateflag;
}
else
return 0;
}
//////////////////////////////////////////////////////////////////
// Phase Update Data
void PhaseUpdateData::AddQuestUpdate(uint32 const questId)
{
AddConditionType(CONDITION_QUESTREWARDED);
AddConditionType(CONDITION_QUESTTAKEN);
AddConditionType(CONDITION_QUEST_COMPLETE);
AddConditionType(CONDITION_QUEST_NONE);
_questId = questId;
}
bool PhaseUpdateData::IsConditionRelated(Condition const* condition) const
{
switch (condition->ConditionType)
{
case CONDITION_QUESTREWARDED:
case CONDITION_QUESTTAKEN:
case CONDITION_QUEST_COMPLETE:
case CONDITION_QUEST_NONE:
return condition->ConditionValue1 == _questId && ((1 << condition->ConditionType) & _conditionTypeFlags);
default:
return (1 << condition->ConditionType) & _conditionTypeFlags;
}
}
bool PhaseMgr::IsConditionTypeSupported(ConditionTypes const conditionType)
{
switch (conditionType)
{
case CONDITION_QUESTREWARDED:
case CONDITION_QUESTTAKEN:
case CONDITION_QUEST_COMPLETE:
case CONDITION_QUEST_NONE:
case CONDITION_TEAM:
case CONDITION_CLASS:
case CONDITION_RACE:
case CONDITION_INSTANCE_DATA:
case CONDITION_LEVEL:
return true;
default:
return false;
}
}
+173
View File
@@ -0,0 +1,173 @@
/*
* Copyright (C) 2008-2012 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/>.
*/
#ifndef TRINITY_PHASEMGR_H
#define TRINITY_PHASEMGR_H
#include "SharedDefines.h"
#include "SpellAuras.h"
#include "SpellAuraEffects.h"
class ObjectMgr;
class Player;
// Phasing (visibility)
enum PhasingFlags
{
PHASE_FLAG_OVERWRITE_EXISTING = 0x01, // don't stack with existing phases, overwrites existing phases
PHASE_FLAG_NO_MORE_PHASES = 0x02, // stop calculating phases after this phase was applied (no more phases will be applied)
PHASE_FLAG_NEGATE_PHASE = 0x04 // negate instead to add the phasemask
};
enum PhaseUpdateFlag
{
PHASE_UPDATE_FLAG_ZONE_UPDATE = 0x01,
PHASE_UPDATE_FLAG_AREA_UPDATE = 0x02,
// Internal flags
PHASE_UPDATE_FLAG_CLIENTSIDE_CHANGED = 0x08,
PHASE_UPDATE_FLAG_SERVERSIDE_CHANGED = 0x10,
};
struct PhaseDefinition
{
uint32 zoneId;
uint32 entry;
uint32 phasemask;
uint32 phaseId;
uint32 terrainswapmap;
uint8 flags;
bool IsOverwritingExistingPhases() const { return flags & PHASE_FLAG_OVERWRITE_EXISTING; }
bool IsLastDefinition() const { return flags & PHASE_FLAG_NO_MORE_PHASES; }
bool IsNegatingPhasemask() const { return flags & PHASE_FLAG_NEGATE_PHASE; }
};
typedef std::list<PhaseDefinition> PhaseDefinitionContainer;
typedef UNORDERED_MAP<uint32 /*zoneId*/, PhaseDefinitionContainer> PhaseDefinitionStore;
struct SpellPhaseInfo
{
uint32 spellId;
uint32 phasemask;
uint32 terrainswapmap;
};
typedef UNORDERED_MAP<uint32 /*spellId*/, SpellPhaseInfo> SpellPhaseStore;
struct PhaseInfo
{
PhaseInfo() : phasemask(0), terrainswapmap(0), phaseId(0) {}
uint32 phasemask;
uint32 terrainswapmap;
uint32 phaseId;
bool NeedsServerSideUpdate() const { return phasemask; }
bool NeedsClientSideUpdate() const { return terrainswapmap || phaseId; }
};
typedef UNORDERED_MAP<uint32 /*spellId*/, PhaseInfo> PhaseInfoContainer;
struct PhaseData
{
PhaseData(Player* _player) : player(_player), _PhasemaskThroughDefinitions(0), _PhasemaskThroughAuras(0), _CustomPhasemask(0) {}
uint32 _PhasemaskThroughDefinitions;
uint32 _PhasemaskThroughAuras;
uint32 _CustomPhasemask;
uint32 GetCurrentPhasemask() const;
inline uint32 GetPhaseMaskForSpawn() const;
void ResetDefinitions() { _PhasemaskThroughDefinitions = 0; activePhaseDefinitions.clear(); }
void AddPhaseDefinition(PhaseDefinition const* phaseDefinition);
bool HasActiveDefinitions() const { return !activePhaseDefinitions.empty(); }
void AddAuraInfo(uint32 const spellId, PhaseInfo phaseInfo);
uint32 RemoveAuraInfo(uint32 const spellId);
void SendPhaseMaskToPlayer();
void SendPhaseshiftToPlayer();
private:
Player* player;
std::list<PhaseDefinition const*> activePhaseDefinitions;
PhaseInfoContainer spellPhaseInfo;
};
struct PhaseUpdateData
{
void AddConditionType(ConditionTypes const conditionType) { _conditionTypeFlags |= (1 << conditionType); }
void AddQuestUpdate(uint32 const questId);
bool IsConditionRelated(Condition const* condition) const;
private:
uint32 _conditionTypeFlags;
uint32 _questId;
};
class PhaseMgr
{
public:
PhaseMgr(Player* _player);
~PhaseMgr() {}
uint32 GetCurrentPhasemask() { return phaseData.GetCurrentPhasemask(); };
inline uint32 GetPhaseMaskForSpawn() { return phaseData.GetCurrentPhasemask(); }
// Phase definitions update handling
void NotifyConditionChanged(PhaseUpdateData const& updateData);
void NotifyStoresReloaded() { Recalculate(); Update(); }
void Update();
// Aura phase effects
void RegisterPhasingAuraEffect(AuraEffect const* auraEffect);
void UnRegisterPhasingAuraEffect(AuraEffect const* auraEffect);
// Update flags (delayed phasing)
void AddUpdateFlag(PhaseUpdateFlag const updateFlag) { _UpdateFlags |= updateFlag; }
void RemoveUpdateFlag(PhaseUpdateFlag const updateFlag);
// Needed for modify phase command
void SetCustomPhase(uint32 const phaseMask);
// Debug
void SendDebugReportToPlayer(Player* const debugger);
static bool IsConditionTypeSupported(ConditionTypes const conditionType);
private:
void Recalculate();
inline bool CheckDefinition(PhaseDefinition const* phaseDefinition);
bool NeedsPhaseUpdateWithData(PhaseUpdateData const updateData) const;
inline bool IsUpdateInProgress() const { return (_UpdateFlags & PHASE_UPDATE_FLAG_ZONE_UPDATE) || (_UpdateFlags & PHASE_UPDATE_FLAG_AREA_UPDATE); }
PhaseDefinitionStore const* _PhaseDefinitionStore;
SpellPhaseStore const* _SpellPhaseStore;
Player* player;
PhaseData phaseData;
uint8 _UpdateFlags;
};
#endif
+9 -1
View File
@@ -174,7 +174,15 @@ enum TrinityStrings
LANG_YOU_CHANGE_RUNIC_POWER = 173,
LANG_YOURS_RUNIC_POWER_CHANGED = 174,
LANG_LIQUID_STATUS = 175,
// Room for more level 1 176-199 not used
LANG_PHASING_REPORT_STATUS = 176,
LANG_PHASING_NO_DEFINITIONS = 177, // Phasing
LANG_PHASING_SUCCESS = 178,
LANG_PHASING_FAILED = 179,
LANG_PHASING_LAST_PHASE = 180,
LANG_PHASING_LIST = 181,
LANG_PHASING_PHASEMASK = 182,
// Room for more level 1 183-199 not used
// level 2 chat
LANG_NO_SELECTION = 200,
+1 -1
View File
@@ -1157,7 +1157,7 @@ void OpcodeTable::Initialize()
DEFINE_OPCODE_HANDLER(SMSG_SET_FLAT_SPELL_MODIFIER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_SET_FORCED_REACTIONS, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_SET_PCT_SPELL_MODIFIER, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_SET_PHASE_SHIFT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_SET_PHASE_SHIFT, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_SET_PLAYER_DECLINED_NAMES_RESULT, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_SET_PLAY_HOVER_ANIM, STATUS_UNHANDLED, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
DEFINE_OPCODE_HANDLER(SMSG_SET_PROFICIENCY, STATUS_NEVER, PROCESS_INPLACE, &WorldSession::Handle_ServerSide );
+1 -1
View File
@@ -253,7 +253,7 @@ class WorldSession
void SendPetNameInvalid(uint32 error, const std::string& name, DeclinedName *declinedName);
void SendPartyResult(PartyOperation operation, const std::string& member, PartyResult res, uint32 val = 0);
void SendAreaTriggerMessage(const char* Text, ...) ATTR_PRINTF(2, 3);
void SendSetPhaseShift(uint32 phaseShift);
void SendSetPhaseShift(std::set<uint32> const& phaseIds, std::set<uint32> const& terrainswaps);
void SendQueryTimeResponse();
void SendAuthResponse(uint8 code, bool queued, uint32 queuePos = 0);
@@ -1808,27 +1808,21 @@ void AuraEffect::HandlePhase(AuraApplication const* aurApp, uint8 mode, bool app
Unit* target = aurApp->GetTarget();
// no-phase is also phase state so same code for apply and remove
uint32 newPhase = 0;
Unit::AuraEffectList const& phases = target->GetAuraEffectsByType(SPELL_AURA_PHASE);
if (!phases.empty())
for (Unit::AuraEffectList::const_iterator itr = phases.begin(); itr != phases.end(); ++itr)
newPhase |= (*itr)->GetMiscValue();
if (Player* player = target->ToPlayer())
{
if (!newPhase)
newPhase = PHASEMASK_NORMAL;
// GM-mode have mask 0xFFFFFFFF
if (player->isGameMaster())
newPhase = 0xFFFFFFFF;
player->SetPhaseMask(newPhase, false);
player->GetSession()->SendSetPhaseShift(newPhase);
if (apply)
player->GetPhaseMgr().RegisterPhasingAuraEffect(this);
else
player->GetPhaseMgr().UnRegisterPhasingAuraEffect(this);
}
else
{
uint32 newPhase = 0;
Unit::AuraEffectList const& phases = target->GetAuraEffectsByType(SPELL_AURA_PHASE);
if (!phases.empty())
for (Unit::AuraEffectList::const_iterator itr = phases.begin(); itr != phases.end(); ++itr)
newPhase |= (*itr)->GetMiscValue();
if (!newPhase)
{
newPhase = PHASEMASK_NORMAL;
+14
View File
@@ -1368,6 +1368,9 @@ void World::SetInitialWorldSettings()
sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Spell Group Stack Rules...");
sSpellMgr->LoadSpellGroupStackRules();
sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Spell Phase Dbc Info...");
sObjectMgr->LoadSpellPhaseInfo();
sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading NPC Texts...");
sObjectMgr->LoadGossipText();
@@ -1616,6 +1619,9 @@ void World::SetInitialWorldSettings()
sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading World States..."); // must be loaded before battleground, outdoor PvP and conditions
LoadWorldStates();
sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Phase definitions...");
sObjectMgr->LoadPhaseDefinitions();
sLog->outInfo(LOG_FILTER_SERVER_LOADING, "Loading Conditions...");
sConditionMgr->LoadConditions();
@@ -3022,3 +3028,11 @@ CharacterNameData const* World::GetCharacterNameData(uint32 guid) const
else
return NULL;
}
void World::UpdatePhaseDefinitions()
{
SessionMap::const_iterator itr;
for (itr = m_sessions.begin(); itr != m_sessions.end(); ++itr)
if (itr->second && itr->second->GetPlayer() && itr->second->GetPlayer()->IsInWorld())
itr->second->GetPlayer()->GetPhaseMgr().NotifyStoresReloaded();
}
+2
View File
@@ -784,6 +784,8 @@ class World
uint32 GetCleaningFlags() const { return m_CleaningFlags; }
void SetCleaningFlags(uint32 flags) { m_CleaningFlags = flags; }
void ResetEventSeasonalQuests(uint16 event_id);
void UpdatePhaseDefinitions();
protected:
void _UpdateGameTime();
// callback for UpdateRealmCharacters
+27 -2
View File
@@ -90,6 +90,7 @@ public:
{ "areatriggers", SEC_ADMINISTRATOR, false, &HandleDebugAreaTriggersCommand, "", NULL },
{ "los", SEC_MODERATOR, false, &HandleDebugLoSCommand, "", NULL },
{ "moveflags", SEC_ADMINISTRATOR, false, &HandleDebugMoveflagsCommand, "", NULL },
{ "phase", SEC_MODERATOR, false, &HandleDebugPhaseCommand, "", NULL },
{ NULL, SEC_PLAYER, false, NULL, "", NULL }
};
static ChatCommand commandTable[] =
@@ -948,8 +949,21 @@ public:
if (!*args)
return false;
uint32 PhaseShift = atoi(args);
handler->GetSession()->SendSetPhaseShift(PhaseShift);
char* t = strtok((char*)args, " ");
char* p = strtok(NULL, " ");
if (!t)
return false;
std::set<uint32> terrainswap;
std::set<uint32> phaseId;
terrainswap.insert((uint32)atoi(t));
if (p)
phaseId.insert((uint32)atoi(p));
handler->GetSession()->SendSetPhaseShift(phaseId, terrainswap);
return true;
}
@@ -1330,6 +1344,17 @@ public:
handler->PSendSysMessage("Waypoint SQL written to SQL Developer log");
return true;
}
static bool HandleDebugPhaseCommand(ChatHandler* handler, char const* args)
{
Unit* unit = handler->getSelectedUnit();
Player* player = handler->GetSession()->GetPlayer();
if(unit && unit->GetTypeId() == TYPEID_PLAYER)
player = unit->ToPlayer();
player->GetPhaseMgr().SendDebugReportToPlayer(handler->GetSession()->GetPlayer());
return true;
}
};
void AddSC_debug_commandscript()
+2 -2
View File
@@ -149,7 +149,7 @@ public:
GameObject* object = new GameObject;
uint32 guidLow = sObjectMgr->GenerateLowGuid(HIGHGUID_GAMEOBJECT);
if (!object->Create(guidLow, objectInfo->entry, map, player->GetPhaseMaskForSpawn(), x, y, z, o, 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY))
if (!object->Create(guidLow, objectInfo->entry, map, player->GetPhaseMgr().GetPhaseMaskForSpawn(), x, y, z, o, 0.0f, 0.0f, 0.0f, 0.0f, 0, GO_STATE_READY))
{
delete object;
return false;
@@ -162,7 +162,7 @@ public:
}
// fill the gameobject data and save to the db
object->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), player->GetPhaseMaskForSpawn());
object->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), player->GetPhaseMgr().GetPhaseMaskForSpawn());
// this will generate a new guid if the object is in an instance
if (!object->LoadGameObjectFromDB(guidLow, map))
+9 -8
View File
@@ -1277,14 +1277,15 @@ public:
uint32 phasemask = (uint32)atoi((char*)args);
Unit* target = handler->getSelectedUnit();
if (!target)
target = handler->GetSession()->GetPlayer();
// check online security
else if (target->GetTypeId() == TYPEID_PLAYER && handler->HasLowerSecurity(target->ToPlayer(), 0))
return false;
target->SetPhaseMask(phasemask, true);
if (target)
{
if (target->GetTypeId() == TYPEID_PLAYER)
target->ToPlayer()->GetPhaseMgr().SetCustomPhase(phasemask);
else
target->SetPhaseMask(phasemask, true);
}
else
handler->GetSession()->GetPlayer()->GetPhaseMgr().SetCustomPhase(phasemask);
return true;
}
+2 -2
View File
@@ -151,13 +151,13 @@ public:
}
Creature* creature = new Creature();
if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, (uint32)teamval, x, y, z, o))
if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMgr().GetPhaseMaskForSpawn(), id, 0, (uint32)teamval, x, y, z, o))
{
delete creature;
return false;
}
creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMgr().GetPhaseMaskForSpawn());
uint32 db_guid = creature->GetDBTableGUIDLow();
+10
View File
@@ -115,6 +115,7 @@ public:
{ "npc_trainer", SEC_ADMINISTRATOR, true, &HandleReloadNpcTrainerCommand, "", NULL },
{ "npc_vendor", SEC_ADMINISTRATOR, true, &HandleReloadNpcVendorCommand, "", NULL },
{ "page_text", SEC_ADMINISTRATOR, true, &HandleReloadPageTextsCommand, "", NULL },
{ "phasedefinitions", SEC_ADMINISTRATOR, true, &HandleReloadPhaseDefinitionsCommand, "", NULL },
{ "pickpocketing_loot_template", SEC_ADMINISTRATOR, true, &HandleReloadLootTemplatesPickpocketingCommand, "", NULL},
{ "points_of_interest", SEC_ADMINISTRATOR, true, &HandleReloadPointsOfInterestCommand, "", NULL },
{ "prospecting_loot_template", SEC_ADMINISTRATOR, true, &HandleReloadLootTemplatesProspectingCommand, "", NULL },
@@ -1250,6 +1251,15 @@ public:
handler->SendGlobalGMSysMessage("Vehicle template accessories reloaded.");
return true;
}
static bool HandleReloadPhaseDefinitionsCommand(ChatHandler* handler, const char* /*args*/)
{
sLog->outInfo(LOG_FILTER_GENERAL, "Reloading phase_definitions table...");
sObjectMgr->LoadPhaseDefinitions();
sWorld->UpdatePhaseDefinitions();
handler->SendGlobalGMSysMessage("Phase Definitions reloaded.");
return true;
}
};
void AddSC_reload_commandscript()
+8 -8
View File
@@ -688,7 +688,7 @@ public:
}
// re-create
Creature* wpCreature2 = new Creature;
if (!wpCreature2->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), VISUAL_WAYPOINT, 0, 0, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation()))
if (!wpCreature2->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMgr().GetPhaseMaskForSpawn(), VISUAL_WAYPOINT, 0, 0, chr->GetPositionX(), chr->GetPositionY(), chr->GetPositionZ(), chr->GetOrientation()))
{
handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
delete wpCreature2;
@@ -696,7 +696,7 @@ public:
return false;
}
wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMgr().GetPhaseMaskForSpawn());
// To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
//TODO: Should we first use "Create" then use "LoadFromDB"?
if (!wpCreature2->LoadCreatureFromDB(wpCreature2->GetDBTableGUIDLow(), map))
@@ -912,7 +912,7 @@ public:
float o = chr->GetOrientation();
Creature* wpCreature = new Creature;
if (!wpCreature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o))
if (!wpCreature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMgr().GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o))
{
handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
delete wpCreature;
@@ -928,7 +928,7 @@ public:
WorldDatabase.Execute(stmt);
wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMgr().GetPhaseMaskForSpawn());
// To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
if (!wpCreature->LoadCreatureFromDB(wpCreature->GetDBTableGUIDLow(), map))
{
@@ -976,14 +976,14 @@ public:
Map* map = chr->GetMap();
Creature* creature = new Creature;
if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o))
if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMgr().GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o))
{
handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
delete creature;
return false;
}
creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMgr().GetPhaseMaskForSpawn());
if (!creature->LoadCreatureFromDB(creature->GetDBTableGUIDLow(), map))
{
handler->PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
@@ -1025,14 +1025,14 @@ public:
Map* map = chr->GetMap();
Creature* creature = new Creature;
if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o))
if (!creature->Create(sObjectMgr->GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMgr().GetPhaseMaskForSpawn(), id, 0, 0, x, y, z, o))
{
handler->PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id);
delete creature;
return false;
}
creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMgr().GetPhaseMaskForSpawn());
if (!creature->LoadCreatureFromDB(creature->GetDBTableGUIDLow(), map))
{
handler->PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id);