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:
@@ -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');
|
||||
*/
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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();
|
||||
|
||||
Executable → Regular
+8
-1
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
@@ -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,
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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))
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user