[7207] Phase system development continue for DB/in_game objects

* Store phase mask for creatures/gameobjects/corpse in DB
* Propertly set phase for summoned creatures/gameobjects/pets/corpses/spell related dynobjects
* Select proper phase for spawned creature/gameobjects and save it in DB

TODO: in game commands.
This commit is contained in:
VladimirMangos 2009-01-30 18:56:49 +03:00
parent b5da610388
commit aa24bd836e
29 changed files with 204 additions and 82 deletions

View file

@ -21,7 +21,7 @@
DROP TABLE IF EXISTS `character_db_version`; DROP TABLE IF EXISTS `character_db_version`;
CREATE TABLE `character_db_version` ( CREATE TABLE `character_db_version` (
`required_7198_01_characters_characters` bit(1) default NULL `required_7207_03_characters_corpse` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB'; ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Last applied sql update to DB';
-- --
@ -727,6 +727,7 @@ CREATE TABLE `corpse` (
`orientation` float NOT NULL default '0', `orientation` float NOT NULL default '0',
`zone` int(11) unsigned NOT NULL default '38' COMMENT 'Zone Identifier', `zone` int(11) unsigned NOT NULL default '38' COMMENT 'Zone Identifier',
`map` int(11) unsigned NOT NULL default '0' COMMENT 'Map Identifier', `map` int(11) unsigned NOT NULL default '0' COMMENT 'Map Identifier',
`phaseMask` smallint(5) unsigned NOT NULL default '1',
`data` longtext, `data` longtext,
`time` bigint(20) unsigned NOT NULL default '0', `time` bigint(20) unsigned NOT NULL default '0',
`corpse_type` tinyint(3) unsigned NOT NULL default '0', `corpse_type` tinyint(3) unsigned NOT NULL default '0',

View file

@ -22,7 +22,7 @@
DROP TABLE IF EXISTS `db_version`; DROP TABLE IF EXISTS `db_version`;
CREATE TABLE `db_version` ( CREATE TABLE `db_version` (
`version` varchar(120) default NULL, `version` varchar(120) default NULL,
`required_7205_01_mangos_spell_chain` bit(1) default NULL `required_7207_02_mangos_gameobject` bit(1) default NULL
) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes'; ) ENGINE=MyISAM DEFAULT CHARSET=utf8 ROW_FORMAT=FIXED COMMENT='Used DB version notes';
-- --
@ -488,6 +488,7 @@ CREATE TABLE `creature` (
`id` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Creature Identifier', `id` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Creature Identifier',
`map` smallint(5) unsigned NOT NULL default '0' COMMENT 'Map Identifier', `map` smallint(5) unsigned NOT NULL default '0' COMMENT 'Map Identifier',
`spawnMask` tinyint(3) unsigned NOT NULL default '1', `spawnMask` tinyint(3) unsigned NOT NULL default '1',
`phaseMask` smallint(5) unsigned NOT NULL default '1',
`modelid` mediumint(8) unsigned NOT NULL default '0', `modelid` mediumint(8) unsigned NOT NULL default '0',
`equipment_id` mediumint(9) NOT NULL default '0', `equipment_id` mediumint(9) NOT NULL default '0',
`position_x` float NOT NULL default '0', `position_x` float NOT NULL default '0',
@ -1244,6 +1245,7 @@ CREATE TABLE `gameobject` (
`id` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Gameobject Identifier', `id` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Gameobject Identifier',
`map` smallint(5) unsigned NOT NULL default '0' COMMENT 'Map Identifier', `map` smallint(5) unsigned NOT NULL default '0' COMMENT 'Map Identifier',
`spawnMask` tinyint(3) unsigned NOT NULL default '1', `spawnMask` tinyint(3) unsigned NOT NULL default '1',
`phaseMask` smallint(5) unsigned NOT NULL default '1',
`position_x` float NOT NULL default '0', `position_x` float NOT NULL default '0',
`position_y` float NOT NULL default '0', `position_y` float NOT NULL default '0',
`position_z` float NOT NULL default '0', `position_z` float NOT NULL default '0',

View file

@ -0,0 +1,4 @@
ALTER TABLE db_version CHANGE COLUMN required_7205_01_mangos_spell_chain required_7207_01_mangos_creature bit;
ALTER TABLE creature
ADD COLUMN `phaseMask` smallint(5) unsigned NOT NULL default '1' AFTER `spawnMask`;

View file

@ -0,0 +1,4 @@
ALTER TABLE db_version CHANGE COLUMN required_7207_01_mangos_creature required_7207_02_mangos_gameobject bit;
ALTER TABLE gameobject
ADD COLUMN `phaseMask` smallint(5) unsigned NOT NULL default '1' AFTER `spawnMask`;

View file

@ -0,0 +1,4 @@
ALTER TABLE character_db_version CHANGE COLUMN required_7198_01_characters_characters required_7207_03_characters_corpse bit;
ALTER TABLE corpse
ADD COLUMN `phaseMask` smallint(5) unsigned NOT NULL default '1' AFTER `map`;

View file

@ -159,6 +159,9 @@ pkgdata_DATA = \
7199_01_mangos_spell_bonus_data.sql \ 7199_01_mangos_spell_bonus_data.sql \
7199_02_mangos_spell_proc_event.sql \ 7199_02_mangos_spell_proc_event.sql \
7205_01_mangos_spell_chain.sql \ 7205_01_mangos_spell_chain.sql \
7207_01_mangos_creature.sql \
7207_02_mangos_gameobject.sql \
7207_03_characters_corpse.sql \
README README
## Additional files to include when running 'make dist' ## Additional files to include when running 'make dist'
@ -298,4 +301,7 @@ EXTRA_DIST = \
7199_01_mangos_spell_bonus_data.sql \ 7199_01_mangos_spell_bonus_data.sql \
7199_02_mangos_spell_proc_event.sql \ 7199_02_mangos_spell_proc_event.sql \
7205_01_mangos_spell_chain.sql \ 7205_01_mangos_spell_chain.sql \
7207_01_mangos_creature.sql \
7207_02_mangos_gameobject.sql \
7207_03_characters_corpse.sql \
README README

View file

@ -1158,7 +1158,8 @@ bool BattleGround::AddObject(uint32 type, uint32 entry, float x, float y, float
// and when loading it (in go::LoadFromDB()), a new guid would be assigned to the object, and a new object would be created // and when loading it (in go::LoadFromDB()), a new guid would be assigned to the object, and a new object would be created
// so we must create it specific for this instance // so we must create it specific for this instance
GameObject * go = new GameObject; GameObject * go = new GameObject;
if(!go->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT),entry, map,x,y,z,o,rotation0,rotation1,rotation2,rotation3,100,1)) if(!go->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT),entry, map,
PHASEMASK_NORMAL, x,y,z,o,rotation0,rotation1,rotation2,rotation3,100,1))
{ {
sLog.outErrorDb("Gameobject template %u not found in database! BattleGround not created!", entry); sLog.outErrorDb("Gameobject template %u not found in database! BattleGround not created!", entry);
sLog.outError("Cannot create gameobject template %u! BattleGround not created!", entry); sLog.outError("Cannot create gameobject template %u! BattleGround not created!", entry);
@ -1265,7 +1266,7 @@ Creature* BattleGround::AddCreature(uint32 entry, uint32 type, uint32 teamval, f
return NULL; return NULL;
Creature* pCreature = new Creature; Creature* pCreature = new Creature;
if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, entry, teamval)) if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, PHASEMASK_NORMAL, entry, teamval))
{ {
sLog.outError("Can't create creature entry: %u",entry); sLog.outError("Can't create creature entry: %u",entry);
delete pCreature; delete pCreature;

View file

@ -69,26 +69,26 @@ bool Corpse::Create( uint32 guidlow )
return true; return true;
} }
bool Corpse::Create( uint32 guidlow, Player *owner, uint32 mapid, float x, float y, float z, float ang ) bool Corpse::Create( uint32 guidlow, Player *owner)
{ {
SetInstanceId(owner->GetInstanceId()); SetInstanceId(owner->GetInstanceId());
WorldObject::_Create(guidlow, HIGHGUID_CORPSE, mapid); WorldObject::_Create(guidlow, HIGHGUID_CORPSE, owner->GetMapId(), owner->GetPhaseMask());
Relocate(x,y,z,ang); Relocate(owner->GetPositionX(), owner->GetPositionY(), owner->GetPositionZ(), owner->GetOrientation());
if(!IsPositionValid()) if(!IsPositionValid())
{ {
sLog.outError("ERROR: Corpse (guidlow %d, owner %s) not created. Suggested coordinates isn't valid (X: %f Y: %f)", sLog.outError("ERROR: Corpse (guidlow %d, owner %s) not created. Suggested coordinates isn't valid (X: %f Y: %f)",
guidlow,owner->GetName(),x,y); guidlow,owner->GetName(),owner->GetPositionX(), owner->GetPositionY());
return false; return false;
} }
SetFloatValue( OBJECT_FIELD_SCALE_X, 1 ); SetFloatValue( OBJECT_FIELD_SCALE_X, 1 );
SetFloatValue( CORPSE_FIELD_POS_X, x ); SetFloatValue( CORPSE_FIELD_POS_X, GetPositionX() );
SetFloatValue( CORPSE_FIELD_POS_Y, y ); SetFloatValue( CORPSE_FIELD_POS_Y, GetPositionY() );
SetFloatValue( CORPSE_FIELD_POS_Z, z ); SetFloatValue( CORPSE_FIELD_POS_Z, GetPositionZ() );
SetFloatValue( CORPSE_FIELD_FACING, ang ); SetFloatValue( CORPSE_FIELD_FACING, GetOrientation() );
SetUInt64Value( CORPSE_FIELD_OWNER, owner->GetGUID() ); SetUInt64Value( CORPSE_FIELD_OWNER, owner->GetGUID() );
m_grid = MaNGOS::ComputeGridPair(GetPositionX(), GetPositionY()); m_grid = MaNGOS::ComputeGridPair(GetPositionX(), GetPositionY());
@ -98,17 +98,18 @@ bool Corpse::Create( uint32 guidlow, Player *owner, uint32 mapid, float x, float
void Corpse::SaveToDB() void Corpse::SaveToDB()
{ {
// prevent DB data inconsistance problems and duplicates // prevent DB data inconsistence problems and duplicates
CharacterDatabase.BeginTransaction(); CharacterDatabase.BeginTransaction();
DeleteFromDB(); DeleteFromDB();
std::ostringstream ss; std::ostringstream ss;
ss << "INSERT INTO corpse (guid,player,position_x,position_y,position_z,orientation,zone,map,data,time,corpse_type,instance) VALUES (" ss << "INSERT INTO corpse (guid,player,position_x,position_y,position_z,orientation,zone,map,data,time,corpse_type,instance,phaseMask) VALUES ("
<< GetGUIDLow() << ", " << GUID_LOPART(GetOwnerGUID()) << ", " << GetPositionX() << ", " << GetPositionY() << ", " << GetPositionZ() << ", " << GetGUIDLow() << ", " << GUID_LOPART(GetOwnerGUID()) << ", " << GetPositionX() << ", " << GetPositionY() << ", " << GetPositionZ() << ", "
<< GetOrientation() << ", " << GetZoneId() << ", " << GetMapId() << ", '"; << GetOrientation() << ", " << GetZoneId() << ", " << GetMapId() << ", '";
for(uint16 i = 0; i < m_valuesCount; i++ ) for(uint16 i = 0; i < m_valuesCount; i++ )
ss << GetUInt32Value(i) << " "; ss << GetUInt32Value(i) << " ";
ss << "'," << uint64(m_time) <<", " << uint32(GetType()) << ", " << int(GetInstanceId()) << ")"; ss << "'," << uint64(m_time) <<", " << uint32(GetType())
<< ", " << int(GetInstanceId()) << ", " << int(GetPhaseMask()) << ")";
CharacterDatabase.Execute( ss.str().c_str() ); CharacterDatabase.Execute( ss.str().c_str() );
CharacterDatabase.CommitTransaction(); CharacterDatabase.CommitTransaction();
} }
@ -141,8 +142,8 @@ bool Corpse::LoadFromDB(uint32 guid, QueryResult *result)
{ {
bool external = (result != NULL); bool external = (result != NULL);
if (!external) if (!external)
// 0 1 2 3 4 5 6 7 8 // 0 1 2 3 4 5 6 7 8 9
result = CharacterDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map,data,time,corpse_type,instance FROM corpse WHERE guid = '%u'",guid); result = CharacterDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map,data,time,corpse_type,instance,phaseMask FROM corpse WHERE guid = '%u'",guid);
if( ! result ) if( ! result )
{ {
@ -164,8 +165,8 @@ bool Corpse::LoadFromDB(uint32 guid, QueryResult *result)
bool Corpse::LoadFromDB(uint32 guid, Field *fields) bool Corpse::LoadFromDB(uint32 guid, Field *fields)
{ {
// 0 1 2 3 4 5 6 7 8 // 0 1 2 3 4 5 6 7 8 9
//result = CharacterDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map,data,time,corpse_type,instance FROM corpse WHERE guid = '%u'",guid); //result = CharacterDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map,data,time,corpse_type,instance,phaseMask FROM corpse WHERE guid = '%u'",guid);
float positionX = fields[0].GetFloat(); float positionX = fields[0].GetFloat();
float positionY = fields[1].GetFloat(); float positionY = fields[1].GetFloat();
float positionZ = fields[2].GetFloat(); float positionZ = fields[2].GetFloat();
@ -186,6 +187,7 @@ bool Corpse::LoadFromDB(uint32 guid, Field *fields)
return false; return false;
} }
uint32 instanceid = fields[8].GetUInt32(); uint32 instanceid = fields[8].GetUInt32();
uint32 phaseMask = fields[9].GetUInt32();
// overwrite possible wrong/corrupted guid // overwrite possible wrong/corrupted guid
SetUInt64Value(OBJECT_FIELD_GUID, MAKE_NEW_GUID(guid, 0, HIGHGUID_CORPSE)); SetUInt64Value(OBJECT_FIELD_GUID, MAKE_NEW_GUID(guid, 0, HIGHGUID_CORPSE));
@ -193,6 +195,7 @@ bool Corpse::LoadFromDB(uint32 guid, Field *fields)
// place // place
SetInstanceId(instanceid); SetInstanceId(instanceid);
SetMapId(mapid); SetMapId(mapid);
SetPhaseMask(phaseMask,false);
Relocate(positionX,positionY,positionZ,ort); Relocate(positionX,positionY,positionZ,ort);
if(!IsPositionValid()) if(!IsPositionValid())

View file

@ -56,7 +56,7 @@ class Corpse : public WorldObject
void RemoveFromWorld(); void RemoveFromWorld();
bool Create( uint32 guidlow ); bool Create( uint32 guidlow );
bool Create( uint32 guidlow, Player *owner, uint32 mapid, float x, float y, float z, float ang ); bool Create( uint32 guidlow, Player *owner );
void SaveToDB(); void SaveToDB();
bool LoadFromDB(uint32 guid, QueryResult *result); bool LoadFromDB(uint32 guid, QueryResult *result);

View file

@ -530,10 +530,11 @@ bool Creature::AIM_Initialize()
return true; return true;
} }
bool Creature::Create (uint32 guidlow, Map *map, uint32 Entry, uint32 team, const CreatureData *data) bool Creature::Create (uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 team, const CreatureData *data)
{ {
SetMapId(map->GetId()); SetMapId(map->GetId());
SetInstanceId(map->GetInstanceId()); SetInstanceId(map->GetInstanceId());
SetPhaseMask(phaseMask,false);
//oX = x; oY = y; dX = x; dY = y; m_moveTime = 0; m_startMove = 0; //oX = x; oY = y; dX = x; dY = y; m_moveTime = 0; m_startMove = 0;
const bool bResult = CreateFromProto(guidlow, Entry, team, data); const bool bResult = CreateFromProto(guidlow, Entry, team, data);
@ -1063,10 +1064,10 @@ void Creature::SaveToDB()
return; return;
} }
SaveToDB(GetMapId(), data->spawnMask); SaveToDB(GetMapId(), data->spawnMask,GetPhaseMask());
} }
void Creature::SaveToDB(uint32 mapid, uint8 spawnMask) void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
{ {
// update in loaded data // update in loaded data
if (!m_DBTableGuid) if (!m_DBTableGuid)
@ -1098,6 +1099,7 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask)
// data->guid = guid don't must be update at save // data->guid = guid don't must be update at save
data.id = GetEntry(); data.id = GetEntry();
data.mapid = mapid; data.mapid = mapid;
data.phaseMask = phaseMask;
data.displayid = displayId; data.displayid = displayId;
data.equipmentId = GetEquipmentId(); data.equipmentId = GetEquipmentId();
data.posX = GetPositionX(); data.posX = GetPositionX();
@ -1291,7 +1293,7 @@ bool Creature::LoadFromDB(uint32 guid, Map *map)
if (map->GetInstanceId() != 0) guid = objmgr.GenerateLowGuid(HIGHGUID_UNIT); if (map->GetInstanceId() != 0) guid = objmgr.GenerateLowGuid(HIGHGUID_UNIT);
uint16 team = 0; uint16 team = 0;
if(!Create(guid,map,data->id,team,data)) if(!Create(guid,map,data->phaseMask,data->id,team,data))
return false; return false;
Relocate(data->posX,data->posY,data->posZ,data->orientation); Relocate(data->posX,data->posY,data->posZ,data->orientation);

View file

@ -247,6 +247,7 @@ struct CreatureData
{ {
uint32 id; // entry in creature_template uint32 id; // entry in creature_template
uint16 mapid; uint16 mapid;
uint16 phaseMask;
uint32 displayid; uint32 displayid;
int32 equipmentId; int32 equipmentId;
float posX; float posX;
@ -405,7 +406,7 @@ class MANGOS_DLL_SPEC Creature : public Unit
void AddToWorld(); void AddToWorld();
void RemoveFromWorld(); void RemoveFromWorld();
bool Create (uint32 guidlow, Map *map, uint32 Entry, uint32 team, const CreatureData *data = NULL); bool Create (uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 team, const CreatureData *data = NULL);
bool LoadCreaturesAddon(bool reload = false); bool LoadCreaturesAddon(bool reload = false);
void SelectLevel(const CreatureInfo *cinfo); void SelectLevel(const CreatureInfo *cinfo);
void LoadEquipment(uint32 equip_entry, bool force=false); void LoadEquipment(uint32 equip_entry, bool force=false);
@ -531,7 +532,7 @@ class MANGOS_DLL_SPEC Creature : public Unit
bool LoadFromDB(uint32 guid, Map *map); bool LoadFromDB(uint32 guid, Map *map);
void SaveToDB(); void SaveToDB();
// overwrited in Pet // overwrited in Pet
virtual void SaveToDB(uint32 mapid, uint8 spawnMask); virtual void SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask);
virtual void DeleteFromDB(); // overwrited in Pet virtual void DeleteFromDB(); // overwrited in Pet
Loot loot; Loot loot;

View file

@ -59,7 +59,7 @@ bool DynamicObject::Create( uint32 guidlow, Unit *caster, uint32 spellId, uint32
{ {
SetInstanceId(caster->GetInstanceId()); SetInstanceId(caster->GetInstanceId());
WorldObject::_Create(guidlow, HIGHGUID_DYNAMICOBJECT, caster->GetMapId()); WorldObject::_Create(guidlow, HIGHGUID_DYNAMICOBJECT, caster->GetMapId(), caster->GetPhaseMask());
Relocate(x,y,z,0); Relocate(x,y,z,0);
if(!IsPositionValid()) if(!IsPositionValid())

View file

@ -89,11 +89,12 @@ void GameObject::RemoveFromWorld()
Object::RemoveFromWorld(); Object::RemoveFromWorld();
} }
bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, uint32 go_state) bool GameObject::Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMask, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, uint32 go_state)
{ {
Relocate(x,y,z,ang); Relocate(x,y,z,ang);
SetMapId(map->GetId()); SetMapId(map->GetId());
SetInstanceId(map->GetInstanceId()); SetInstanceId(map->GetInstanceId());
SetPhaseMask(phaseMask,false);
if(!IsPositionValid()) if(!IsPositionValid())
{ {
@ -504,10 +505,10 @@ void GameObject::SaveToDB()
return; return;
} }
SaveToDB(GetMapId(), data->spawnMask); SaveToDB(GetMapId(), data->spawnMask, data->phaseMask);
} }
void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask) void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
{ {
const GameObjectInfo *goI = GetGOInfo(); const GameObjectInfo *goI = GetGOInfo();
@ -522,6 +523,7 @@ void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask)
// data->guid = guid don't must be update at save // data->guid = guid don't must be update at save
data.id = GetEntry(); data.id = GetEntry();
data.mapid = mapid; data.mapid = mapid;
data.phaseMask = phaseMask;
data.posX = GetFloatValue(GAMEOBJECT_POS_X); data.posX = GetFloatValue(GAMEOBJECT_POS_X);
data.posY = GetFloatValue(GAMEOBJECT_POS_Y); data.posY = GetFloatValue(GAMEOBJECT_POS_Y);
data.posZ = GetFloatValue(GAMEOBJECT_POS_Z); data.posZ = GetFloatValue(GAMEOBJECT_POS_Z);
@ -572,6 +574,7 @@ bool GameObject::LoadFromDB(uint32 guid, Map *map)
uint32 entry = data->id; uint32 entry = data->id;
//uint32 map_id = data->mapid; // already used before call //uint32 map_id = data->mapid; // already used before call
uint32 phaseMask = data->phaseMask;
float x = data->posX; float x = data->posX;
float y = data->posY; float y = data->posY;
float z = data->posZ; float z = data->posZ;
@ -588,7 +591,7 @@ bool GameObject::LoadFromDB(uint32 guid, Map *map)
m_DBTableGuid = guid; m_DBTableGuid = guid;
if (map->GetInstanceId() != 0) guid = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT); if (map->GetInstanceId() != 0) guid = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT);
if (!Create(guid,entry, map, x, y, z, ang, rotation0, rotation1, rotation2, rotation3, animprogress, go_state) ) if (!Create(guid,entry, map, phaseMask, x, y, z, ang, rotation0, rotation1, rotation2, rotation3, animprogress, go_state) )
return false; return false;
switch(GetGOInfo()->type) switch(GetGOInfo()->type)

View file

@ -375,7 +375,8 @@ struct GameObjectLocale
struct GameObjectData struct GameObjectData
{ {
uint32 id; // entry in gamobject_template uint32 id; // entry in gamobject_template
uint32 mapid; uint16 mapid;
uint16 phaseMask;
float posX; float posX;
float posY; float posY;
float posZ; float posZ;
@ -423,7 +424,7 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
void AddToWorld(); void AddToWorld();
void RemoveFromWorld(); void RemoveFromWorld();
bool Create(uint32 guidlow, uint32 name_id, Map *map, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, uint32 go_state); bool Create(uint32 guidlow, uint32 name_id, Map *map, uint32 phaseMask, float x, float y, float z, float ang, float rotation0, float rotation1, float rotation2, float rotation3, uint32 animprogress, uint32 go_state);
void Update(uint32 p_time); void Update(uint32 p_time);
static GameObject* GetGameObject(WorldObject& object, uint64 guid); static GameObject* GetGameObject(WorldObject& object, uint64 guid);
GameObjectInfo const* GetGOInfo() const; GameObjectInfo const* GetGOInfo() const;
@ -453,7 +454,7 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
const char* GetNameForLocaleIdx(int32 locale_idx) const; const char* GetNameForLocaleIdx(int32 locale_idx) const;
void SaveToDB(); void SaveToDB();
void SaveToDB(uint32 mapid, uint8 spawnMask); void SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask);
bool LoadFromDB(uint32 guid, Map *map); bool LoadFromDB(uint32 guid, Map *map);
void DeleteFromDB(); void DeleteFromDB();
void SetLootState(LootState s) { m_lootState = s; } void SetLootState(LootState s) { m_lootState = s; }

View file

@ -873,7 +873,7 @@ bool ChatHandler::HandleNpcAddCommand(const char* args)
Map *map = chr->GetMap(); Map *map = chr->GetMap();
Creature* pCreature = new Creature; Creature* pCreature = new Creature;
if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, (uint32)teamval)) if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, (uint32)teamval))
{ {
delete pCreature; delete pCreature;
return false; return false;
@ -888,7 +888,7 @@ bool ChatHandler::HandleNpcAddCommand(const char* args)
return false; return false;
} }
pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode())); pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
uint32 db_guid = pCreature->GetDBTableGUIDLow(); uint32 db_guid = pCreature->GetDBTableGUIDLow();
@ -2531,7 +2531,7 @@ bool ChatHandler::HandleWpModifyCommand(const char* args)
// create the waypoint creature // create the waypoint creature
wpGuid = 0; wpGuid = 0;
Creature* wpCreature = new Creature; Creature* wpCreature = new Creature;
if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map,VISUAL_WAYPOINT,0)) if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), VISUAL_WAYPOINT,0))
{ {
PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT); PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
delete wpCreature; delete wpCreature;
@ -2547,7 +2547,7 @@ bool ChatHandler::HandleWpModifyCommand(const char* args)
} }
else else
{ {
wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode())); wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
// To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(), map); wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(), map);
map->Add(wpCreature); map->Add(wpCreature);
@ -2653,7 +2653,7 @@ bool ChatHandler::HandleWpModifyCommand(const char* args)
wpCreature->AddObjectToRemoveList(); wpCreature->AddObjectToRemoveList();
// re-create // re-create
Creature* wpCreature2 = new Creature; Creature* wpCreature2 = new Creature;
if (!wpCreature2->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, VISUAL_WAYPOINT, 0)) if (!wpCreature2->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), VISUAL_WAYPOINT, 0))
{ {
PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT); PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, VISUAL_WAYPOINT);
delete wpCreature2; delete wpCreature2;
@ -2669,7 +2669,7 @@ bool ChatHandler::HandleWpModifyCommand(const char* args)
return false; return false;
} }
wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode())); wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
// To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
wpCreature2->LoadFromDB(wpCreature2->GetDBTableGUIDLow(), map); wpCreature2->LoadFromDB(wpCreature2->GetDBTableGUIDLow(), map);
map->Add(wpCreature2); map->Add(wpCreature2);
@ -2958,7 +2958,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
float o = chr->GetOrientation(); float o = chr->GetOrientation();
Creature* wpCreature = new Creature; Creature* wpCreature = new Creature;
if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, 0)) if (!wpCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0))
{ {
PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
delete wpCreature; delete wpCreature;
@ -2981,7 +2981,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
// set "wpguid" column to the visual waypoint // set "wpguid" column to the visual waypoint
WorldDatabase.PExecuteLog("UPDATE creature_movement SET wpguid = '%u' WHERE id = '%u' and point = '%u'", wpCreature->GetGUIDLow(), lowguid, point); WorldDatabase.PExecuteLog("UPDATE creature_movement SET wpguid = '%u' WHERE id = '%u' and point = '%u'", wpCreature->GetGUIDLow(), lowguid, point);
wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode())); wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
// To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells(); // To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(),map); wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(),map);
map->Add(wpCreature); map->Add(wpCreature);
@ -3016,7 +3016,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
Map *map = chr->GetMap(); Map *map = chr->GetMap();
Creature* pCreature = new Creature; Creature* pCreature = new Creature;
if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT),map, id, 0)) if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT),map, chr->GetPhaseMaskForSpawn(), id, 0))
{ {
PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id); PSendSysMessage(LANG_WAYPOINT_VP_NOTCREATED, id);
delete pCreature; delete pCreature;
@ -3034,7 +3034,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
return false; return false;
} }
pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode())); pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map); pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map);
map->Add(pCreature); map->Add(pCreature);
//player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "First Waypoint"); //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "First Waypoint");
@ -3076,7 +3076,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
Map *map = chr->GetMap(); Map *map = chr->GetMap();
Creature* pCreature = new Creature; Creature* pCreature = new Creature;
if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, id, 0)) if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), map, chr->GetPhaseMaskForSpawn(), id, 0))
{ {
PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id); PSendSysMessage(LANG_WAYPOINT_NOTCREATED, id);
delete pCreature; delete pCreature;
@ -3094,7 +3094,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
return false; return false;
} }
pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode())); pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map); pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map);
map->Add(pCreature); map->Add(pCreature);
//player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "Last Waypoint"); //player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "Last Waypoint");
@ -3453,7 +3453,7 @@ bool ChatHandler::HandleGameObjectCommand(const char* args)
GameObject* pGameObj = new GameObject; GameObject* pGameObj = new GameObject;
uint32 db_lowGUID = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT); uint32 db_lowGUID = objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT);
if(!pGameObj->Create(db_lowGUID, goI->id, map, x, y, z, o, 0, 0, rot2, rot3, 0, 1)) if(!pGameObj->Create(db_lowGUID, goI->id, map, chr->GetPhaseMaskForSpawn(), x, y, z, o, 0, 0, rot2, rot3, 0, 1))
{ {
delete pGameObj; delete pGameObj;
return false; return false;
@ -3467,7 +3467,7 @@ bool ChatHandler::HandleGameObjectCommand(const char* args)
} }
// fill the gameobject data and save to the db // fill the gameobject data and save to the db
pGameObj->SaveToDB(map->GetId(), (1 << map->GetSpawnMode())); pGameObj->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()),chr->GetPhaseMaskForSpawn());
// this will generate a new guid if the object is in an instance // this will generate a new guid if the object is in an instance
if(!pGameObj->LoadFromDB(db_lowGUID, map)) if(!pGameObj->LoadFromDB(db_lowGUID, map))

View file

@ -1028,11 +1028,12 @@ WorldObject::WorldObject()
{ {
} }
void WorldObject::_Create( uint32 guidlow, HighGuid guidhigh, uint32 mapid ) void WorldObject::_Create( uint32 guidlow, HighGuid guidhigh, uint32 mapid, uint32 phaseMask )
{ {
Object::_Create(guidlow, 0, guidhigh); Object::_Create(guidlow, 0, guidhigh);
m_mapId = mapid; m_mapId = mapid;
m_phaseMask = phaseMask;
} }
uint32 WorldObject::GetZoneId() const uint32 WorldObject::GetZoneId() const
@ -1468,7 +1469,7 @@ Creature* WorldObject::SummonCreature(uint32 id, float x, float y, float z, floa
if (GetTypeId()==TYPEID_PLAYER) if (GetTypeId()==TYPEID_PLAYER)
team = ((Player*)this)->GetTeam(); team = ((Player*)this)->GetTeam();
if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), GetMap(), id, team)) if (!pCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), GetMap(), GetPhaseMask(), id, team))
{ {
delete pCreature; delete pCreature;
return NULL; return NULL;
@ -1704,3 +1705,11 @@ void WorldObject::GetNearPoint(WorldObject const* searcher, float &x, float &y,
UpdateGroundPositionZ(x,y,z); // update to LOS height if available UpdateGroundPositionZ(x,y,z); // update to LOS height if available
} }
void WorldObject::SetPhaseMask(uint32 newPhaseMask, bool update)
{
m_phaseMask = newPhaseMask;
if(update && IsInWorld())
ObjectAccessor::UpdateObjectVisibility(this);
}

View file

@ -349,7 +349,7 @@ class MANGOS_DLL_SPEC WorldObject : public Object
virtual void Update ( uint32 /*time_diff*/ ) { } virtual void Update ( uint32 /*time_diff*/ ) { }
void _Create( uint32 guidlow, HighGuid guidhigh, uint32 mapid ); void _Create( uint32 guidlow, HighGuid guidhigh, uint32 mapid, uint32 phaseMask);
void Relocate(float x, float y, float z, float orientation) void Relocate(float x, float y, float z, float orientation)
{ {
@ -407,7 +407,7 @@ class MANGOS_DLL_SPEC WorldObject : public Object
void SetMapId(uint32 newMap) { m_mapId = newMap; } void SetMapId(uint32 newMap) { m_mapId = newMap; }
uint32 GetMapId() const { return m_mapId; } uint32 GetMapId() const { return m_mapId; }
void SetPhaseMask(uint32 newPhaseMask) { m_phaseMask = newPhaseMask; } virtual void SetPhaseMask(uint32 newPhaseMask, bool update);
uint32 GetPhaseMask() const { return m_phaseMask; } uint32 GetPhaseMask() const { return m_phaseMask; }
bool InSamePhase(WorldObject const* obj) const { return InSamePhase(obj->GetPhaseMask()); } bool InSamePhase(WorldObject const* obj) const { return InSamePhase(obj->GetPhaseMask()); }
bool InSamePhase(uint32 phasemask) const { return GetPhaseMask()==0 && phasemask==0 || (GetPhaseMask() & phasemask); } bool InSamePhase(uint32 phasemask) const { return GetPhaseMask()==0 && phasemask==0 || (GetPhaseMask() & phasemask); }

View file

@ -475,6 +475,7 @@ ObjectAccessor::ConvertCorpseForPlayer(uint64 player_guid, bool insignia)
bones->Relocate(corpse->GetPositionX(), corpse->GetPositionY(), corpse->GetPositionZ(), corpse->GetOrientation()); bones->Relocate(corpse->GetPositionX(), corpse->GetPositionY(), corpse->GetPositionZ(), corpse->GetOrientation());
bones->SetMapId(corpse->GetMapId()); bones->SetMapId(corpse->GetMapId());
bones->SetInstanceId(corpse->GetInstanceId()); bones->SetInstanceId(corpse->GetInstanceId());
bones->SetPhaseMask(corpse->GetPhaseMask(),false);
bones->SetUInt32Value(CORPSE_FIELD_FLAGS, CORPSE_FLAG_UNK2 | CORPSE_FLAG_BONES); bones->SetUInt32Value(CORPSE_FIELD_FLAGS, CORPSE_FLAG_UNK2 | CORPSE_FLAG_BONES);
bones->SetUInt64Value(CORPSE_FIELD_OWNER, 0); bones->SetUInt64Value(CORPSE_FIELD_OWNER, 0);

View file

@ -1042,8 +1042,8 @@ void ObjectMgr::LoadCreatures()
QueryResult *result = WorldDatabase.Query("SELECT creature.guid, id, map, modelid," QueryResult *result = WorldDatabase.Query("SELECT creature.guid, id, map, modelid,"
// 4 5 6 7 8 9 10 11 // 4 5 6 7 8 9 10 11
"equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, spawndist, currentwaypoint," "equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, spawndist, currentwaypoint,"
// 12 13 14 15 16 17 // 12 13 14 15 16 17 18
"curhealth, curmana, DeathState, MovementType, spawnMask, event " "curhealth, curmana, DeathState, MovementType, spawnMask, phaseMask, event "
"FROM creature LEFT OUTER JOIN game_event_creature ON creature.guid = game_event_creature.guid"); "FROM creature LEFT OUTER JOIN game_event_creature ON creature.guid = game_event_creature.guid");
if(!result) if(!result)
@ -1091,7 +1091,8 @@ void ObjectMgr::LoadCreatures()
data.is_dead = fields[14].GetBool(); data.is_dead = fields[14].GetBool();
data.movementType = fields[15].GetUInt8(); data.movementType = fields[15].GetUInt8();
data.spawnMask = fields[16].GetUInt8(); data.spawnMask = fields[16].GetUInt8();
int16 gameEvent = fields[17].GetInt16(); data.phaseMask = fields[17].GetUInt16();
int16 gameEvent = fields[18].GetInt16();
CreatureInfo const* cInfo = GetCreatureTemplate(data.id); CreatureInfo const* cInfo = GetCreatureTemplate(data.id);
if(!cInfo) if(!cInfo)
@ -1149,6 +1150,40 @@ void ObjectMgr::LoadCreatures()
} }
} }
if(data.phaseMask==0)
{
sLog.outErrorDb("Table `creature` have creature (GUID: %u Entry: %u) with `phaseMask`=0 (not visible for anyone), set to 1.",guid,data.id );
data.phaseMask = 1;
}
else
{
int count = 0;
for(int i=0; i < sizeof(data.phaseMask)*8; ++i)
if(data.phaseMask & (1 << i))
++count;
if(count > 1)
{
uint32 phaseMask = data.phaseMask & ~PHASEMASK_NORMAL;
count = 0;
for(int i=0; i < sizeof(phaseMask)*8; ++i)
if(phaseMask & (1 << i))
++count;
if(count > 1)
{
sLog.outErrorDb("Table `creature` have creature (GUID: %u Entry: %u) with more single bit set in `phaseMask` (not visible for anyone), set to 1.",guid,data.id );
data.phaseMask = phaseMask;
}
else
{
sLog.outErrorDb("Table `creature` have creature (GUID: %u Entry: %u) with more single bit set in `phaseMask` (not visible for anyone), set to %u (possible expected).",guid,data.id,phaseMask);
data.phaseMask = 1;
}
}
}
if (gameEvent==0) // if not this is to be managed by GameEvent System if (gameEvent==0) // if not this is to be managed by GameEvent System
AddCreatureToGrid(guid, &data); AddCreatureToGrid(guid, &data);
++count; ++count;
@ -1199,8 +1234,8 @@ void ObjectMgr::LoadGameobjects()
// 0 1 2 3 4 5 6 // 0 1 2 3 4 5 6
QueryResult *result = WorldDatabase.Query("SELECT gameobject.guid, id, map, position_x, position_y, position_z, orientation," QueryResult *result = WorldDatabase.Query("SELECT gameobject.guid, id, map, position_x, position_y, position_z, orientation,"
// 7 8 9 10 11 12 13 14 15 // 7 8 9 10 11 12 13 14 15 16
"rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, spawnMask, event " "rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, spawnMask, phaseMask, event "
"FROM gameobject LEFT OUTER JOIN game_event_gameobject ON gameobject.guid = game_event_gameobject.guid"); "FROM gameobject LEFT OUTER JOIN game_event_gameobject ON gameobject.guid = game_event_gameobject.guid");
if(!result) if(!result)
@ -1239,7 +1274,8 @@ void ObjectMgr::LoadGameobjects()
data.animprogress = fields[12].GetUInt32(); data.animprogress = fields[12].GetUInt32();
data.go_state = fields[13].GetUInt32(); data.go_state = fields[13].GetUInt32();
data.spawnMask = fields[14].GetUInt8(); data.spawnMask = fields[14].GetUInt8();
int16 gameEvent = fields[15].GetInt16(); data.phaseMask = fields[15].GetUInt16();
int16 gameEvent = fields[16].GetInt16();
GameObjectInfo const* gInfo = GetGameObjectInfo(data.id); GameObjectInfo const* gInfo = GetGameObjectInfo(data.id);
if(!gInfo) if(!gInfo)
@ -1248,6 +1284,12 @@ void ObjectMgr::LoadGameobjects()
continue; continue;
} }
if(data.phaseMask==0)
{
sLog.outErrorDb("Table `gameobject` have gameobject (GUID: %u Entry: %u) with `phaseMask`=0 (not visible for anyone), set to 1.",guid,data.id );
data.phaseMask = 1;
}
if (gameEvent==0) // if not this is to be managed by GameEvent System if (gameEvent==0) // if not this is to be managed by GameEvent System
AddGameobjectToGrid(guid, &data); AddGameobjectToGrid(guid, &data);
++count; ++count;

View file

@ -135,7 +135,7 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
Map *map = owner->GetMap(); Map *map = owner->GetMap();
uint32 guid = objmgr.GenerateLowGuid(HIGHGUID_PET); uint32 guid = objmgr.GenerateLowGuid(HIGHGUID_PET);
uint32 pet_number = fields[0].GetUInt32(); uint32 pet_number = fields[0].GetUInt32();
if(!Create(guid, map, petentry, pet_number)) if(!Create(guid, map, owner->GetPhaseMask(), petentry, pet_number))
{ {
delete result; delete result;
return false; return false;
@ -716,7 +716,7 @@ bool Pet::CreateBaseAtCreature(Creature* creature)
sLog.outBasic("Create pet"); sLog.outBasic("Create pet");
uint32 pet_number = objmgr.GeneratePetNumber(); uint32 pet_number = objmgr.GeneratePetNumber();
if(!Create(guid, creature->GetMap(), creature->GetEntry(), pet_number)) if(!Create(guid, creature->GetMap(), creature->GetPhaseMask(), creature->GetEntry(), pet_number))
return false; return false;
Relocate(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), creature->GetOrientation()); Relocate(creature->GetPositionX(), creature->GetPositionY(), creature->GetPositionZ(), creature->GetOrientation());
@ -1667,10 +1667,11 @@ void Pet::ToggleAutocast(uint32 spellid, bool apply)
} }
} }
bool Pet::Create(uint32 guidlow, Map *map, uint32 Entry, uint32 pet_number) bool Pet::Create(uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 pet_number)
{ {
SetMapId(map->GetId()); SetMapId(map->GetId());
SetInstanceId(map->GetInstanceId()); SetInstanceId(map->GetInstanceId());
SetPhaseMask(phaseMask,false);
Object::_Create(guidlow, pet_number, HIGHGUID_PET); Object::_Create(guidlow, pet_number, HIGHGUID_PET);

View file

@ -130,7 +130,7 @@ class Pet : public Creature
bool isControlled() const { return getPetType()==SUMMON_PET || getPetType()==HUNTER_PET; } bool isControlled() const { return getPetType()==SUMMON_PET || getPetType()==HUNTER_PET; }
bool isTemporarySummoned() const { return m_duration > 0; } bool isTemporarySummoned() const { return m_duration > 0; }
bool Create (uint32 guidlow, Map *map, uint32 Entry, uint32 pet_number); bool Create (uint32 guidlow, Map *map, uint32 phaseMask, uint32 Entry, uint32 pet_number);
bool CreateBaseAtCreature(Creature* creature); bool CreateBaseAtCreature(Creature* creature);
bool LoadPetFromDB( Player* owner,uint32 petentry = 0,uint32 petnumber = 0, bool current = false ); bool LoadPetFromDB( Player* owner,uint32 petentry = 0,uint32 petnumber = 0, bool current = false );
void SavePetToDB(PetSaveMode mode); void SavePetToDB(PetSaveMode mode);

View file

@ -1985,13 +1985,13 @@ void Player::SetGameMaster(bool on)
getHostilRefManager().setOnlineOfflineState(false); getHostilRefManager().setOnlineOfflineState(false);
CombatStop(); CombatStop();
SetPhaseMask(PHASEMASK_ANYWHERE); // see and visible in all phases SetPhaseMask(PHASEMASK_ANYWHERE,false); // see and visible in all phases
} }
else else
{ {
// restore phase // restore phase
AuraList const& phases = GetAurasByType(SPELL_AURA_PHASE); AuraList const& phases = GetAurasByType(SPELL_AURA_PHASE);
SetPhaseMask(!phases.empty() ? phases.front()->GetMiscValue() : PHASEMASK_NORMAL); SetPhaseMask(!phases.empty() ? phases.front()->GetMiscValue() : PHASEMASK_NORMAL,false);
m_ExtraFlags &= ~ PLAYER_EXTRA_GM_ON; m_ExtraFlags &= ~ PLAYER_EXTRA_GM_ON;
setFactionForRace(getRace()); setFactionForRace(getRace());
@ -3936,8 +3936,7 @@ void Player::CreateCorpse()
Corpse *corpse = new Corpse( (m_ExtraFlags & PLAYER_EXTRA_PVP_DEATH) ? CORPSE_RESURRECTABLE_PVP : CORPSE_RESURRECTABLE_PVE ); Corpse *corpse = new Corpse( (m_ExtraFlags & PLAYER_EXTRA_PVP_DEATH) ? CORPSE_RESURRECTABLE_PVP : CORPSE_RESURRECTABLE_PVE );
SetPvPDeath(false); SetPvPDeath(false);
if(!corpse->Create(objmgr.GenerateLowGuid(HIGHGUID_CORPSE), this, GetMapId(), GetPositionX(), if(!corpse->Create(objmgr.GenerateLowGuid(HIGHGUID_CORPSE), this))
GetPositionY(), GetPositionZ(), GetOrientation()))
{ {
delete corpse; delete corpse;
return; return;
@ -19455,3 +19454,24 @@ void Player::_LoadSkills()
SetSkill(SKILL_UNARMED, base_skill,base_skill); SetSkill(SKILL_UNARMED, base_skill,base_skill);
} }
} }
uint32 Player::GetPhaseMaskForSpawn() const
{
uint32 phase = PHASEMASK_NORMAL;
if(!isGameMaster())
phase = GetPhaseMask();
else
{
AuraList const& phases = GetAurasByType(SPELL_AURA_PHASE);
if(phases.empty())
phase = GetPhaseMask();
else
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;
}

View file

@ -1043,6 +1043,7 @@ class MANGOS_DLL_SPEC Player : public Unit
void AddGuardian(Pet* pet) { m_guardianPets.insert(pet->GetGUID()); } void AddGuardian(Pet* pet) { m_guardianPets.insert(pet->GetGUID()); }
GuardianPetList const& GetGuardians() const { return m_guardianPets; } GuardianPetList const& GetGuardians() const { return m_guardianPets; }
void Uncharm(); void Uncharm();
uint32 GetPhaseMaskForSpawn() const; // used for proper set phase for DB at GM-mode creature/GO spawn
void Say(const std::string& text, const uint32 language); void Say(const std::string& text, const uint32 language);
void Yell(const std::string& text, const uint32 language); void Yell(const std::string& text, const uint32 language);

View file

@ -6593,10 +6593,10 @@ void Aura::HandlePhase(bool apply, bool Real)
// GM-mode have mask 0xFFFFFFFF // GM-mode have mask 0xFFFFFFFF
if(!((Player*)m_target)->isGameMaster()) if(!((Player*)m_target)->isGameMaster())
m_target->SetPhaseMask(apply ? GetMiscValue() : PHASEMASK_NORMAL); m_target->SetPhaseMask(apply ? GetMiscValue() : PHASEMASK_NORMAL,false);
} }
else else
m_target->SetPhaseMask(apply ? GetMiscValue() : PHASEMASK_NORMAL); m_target->SetPhaseMask(apply ? GetMiscValue() : PHASEMASK_NORMAL,false);
// need triggering visibility update base at phase update of not GM invisible (other GMs anyway see in any phases) // need triggering visibility update base at phase update of not GM invisible (other GMs anyway see in any phases)
if(m_target->GetVisibility()!=VISIBILITY_OFF) if(m_target->GetVisibility()!=VISIBILITY_OFF)

View file

@ -782,7 +782,7 @@ void Spell::EffectDummy(uint32 i)
Map *map = creatureTarget->GetMap(); Map *map = creatureTarget->GetMap();
if(!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), 179644, map, if(!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), 179644, map, m_caster->GetPhaseMask(),
creatureTarget->GetPositionX(), creatureTarget->GetPositionY(), creatureTarget->GetPositionZ(), creatureTarget->GetPositionX(), creatureTarget->GetPositionY(), creatureTarget->GetPositionZ(),
creatureTarget->GetOrientation(), 0, 0, 0, 0, 100, 1) ) creatureTarget->GetOrientation(), 0, 0, 0, 0, 100, 1) )
{ {
@ -3233,7 +3233,8 @@ void Spell::EffectSummon(uint32 i)
Map *map = m_caster->GetMap(); Map *map = m_caster->GetMap();
uint32 pet_number = objmgr.GeneratePetNumber(); uint32 pet_number = objmgr.GeneratePetNumber();
if(!spawnCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_PET),map,m_spellInfo->EffectMiscValue[i], pet_number)) if(!spawnCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_PET),map,m_caster->GetPhaseMask(),
m_spellInfo->EffectMiscValue[i], pet_number))
{ {
sLog.outErrorDb("Spell::EffectSummon: no such creature entry %u",m_spellInfo->EffectMiscValue[i]); sLog.outErrorDb("Spell::EffectSummon: no such creature entry %u",m_spellInfo->EffectMiscValue[i]);
delete spawnCreature; delete spawnCreature;
@ -3657,7 +3658,8 @@ void Spell::EffectSummonGuardian(uint32 i)
Map *map = m_caster->GetMap(); Map *map = m_caster->GetMap();
uint32 pet_number = objmgr.GeneratePetNumber(); uint32 pet_number = objmgr.GeneratePetNumber();
if(!spawnCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_PET), map,m_spellInfo->EffectMiscValue[i], pet_number)) if(!spawnCreature->Create(objmgr.GenerateLowGuid(HIGHGUID_PET), map,m_caster->GetPhaseMask(),
m_spellInfo->EffectMiscValue[i], pet_number))
{ {
sLog.outError("no such creature entry %u",m_spellInfo->EffectMiscValue[i]); sLog.outError("no such creature entry %u",m_spellInfo->EffectMiscValue[i]);
delete spawnCreature; delete spawnCreature;
@ -4075,7 +4077,8 @@ void Spell::EffectSummonPet(uint32 i)
Map *map = m_caster->GetMap(); Map *map = m_caster->GetMap();
uint32 pet_number = objmgr.GeneratePetNumber(); uint32 pet_number = objmgr.GeneratePetNumber();
if(!NewSummon->Create(objmgr.GenerateLowGuid(HIGHGUID_PET), map, petentry, pet_number)) if(!NewSummon->Create(objmgr.GenerateLowGuid(HIGHGUID_PET), map, m_caster->GetPhaseMask(),
petentry, pet_number))
{ {
delete NewSummon; delete NewSummon;
return; return;
@ -4506,7 +4509,7 @@ void Spell::EffectSummonObjectWild(uint32 i)
Map *map = target->GetMap(); Map *map = target->GetMap();
if(!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), gameobject_id, map, if(!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), gameobject_id, map,
x, y, z, target->GetOrientation(), 0, 0, 0, 0, 100, 1)) m_caster->GetPhaseMask(), x, y, z, target->GetOrientation(), 0, 0, 0, 0, 100, 1))
{ {
delete pGameObj; delete pGameObj;
return; return;
@ -4554,7 +4557,7 @@ void Spell::EffectSummonObjectWild(uint32 i)
{ {
GameObject* linkedGO = new GameObject; GameObject* linkedGO = new GameObject;
if(linkedGO->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), linkedEntry, map, if(linkedGO->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), linkedEntry, map,
x, y, z, target->GetOrientation(), 0, 0, 0, 0, 100, 1)) m_caster->GetPhaseMask(), x, y, z, target->GetOrientation(), 0, 0, 0, 0, 100, 1))
{ {
linkedGO->SetRespawnTime(duration > 0 ? duration/1000 : 0); linkedGO->SetRespawnTime(duration > 0 ? duration/1000 : 0);
linkedGO->SetSpellId(m_spellInfo->Id); linkedGO->SetSpellId(m_spellInfo->Id);
@ -5166,7 +5169,8 @@ void Spell::EffectDuel(uint32 i)
uint32 gameobject_id = m_spellInfo->EffectMiscValue[i]; uint32 gameobject_id = m_spellInfo->EffectMiscValue[i];
Map *map = m_caster->GetMap(); Map *map = m_caster->GetMap();
if(!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), gameobject_id, map, if(!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), gameobject_id,
map, m_caster->GetPhaseMask(),
m_caster->GetPositionX()+(unitTarget->GetPositionX()-m_caster->GetPositionX())/2 , m_caster->GetPositionX()+(unitTarget->GetPositionX()-m_caster->GetPositionX())/2 ,
m_caster->GetPositionY()+(unitTarget->GetPositionY()-m_caster->GetPositionY())/2 , m_caster->GetPositionY()+(unitTarget->GetPositionY()-m_caster->GetPositionY())/2 ,
m_caster->GetPositionZ(), m_caster->GetPositionZ(),
@ -5349,7 +5353,8 @@ void Spell::EffectSummonTotem(uint32 i)
Totem* pTotem = new Totem; Totem* pTotem = new Totem;
if(!pTotem->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), m_caster->GetMap(), m_spellInfo->EffectMiscValue[i], team )) if(!pTotem->Create(objmgr.GenerateLowGuid(HIGHGUID_UNIT), m_caster->GetMap(), m_caster->GetPhaseMask(),
m_spellInfo->EffectMiscValue[i], team ))
{ {
delete pTotem; delete pTotem;
return; return;
@ -5560,7 +5565,8 @@ void Spell::EffectSummonObject(uint32 i)
m_caster->GetClosePoint(x,y,z,DEFAULT_WORLD_OBJECT_SIZE); m_caster->GetClosePoint(x,y,z,DEFAULT_WORLD_OBJECT_SIZE);
Map *map = m_caster->GetMap(); Map *map = m_caster->GetMap();
if(!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), go_id, map, x, y, z, m_caster->GetOrientation(), 0, 0, rot2, rot3, 0, 1)) if(!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), go_id, map,
m_caster->GetPhaseMask(), x, y, z, m_caster->GetOrientation(), 0, 0, rot2, rot3, 0, 1))
{ {
delete pGameObj; delete pGameObj;
return; return;
@ -5822,8 +5828,8 @@ void Spell::EffectSummonCritter(uint32 i)
Map *map = m_caster->GetMap(); Map *map = m_caster->GetMap();
uint32 pet_number = objmgr.GeneratePetNumber(); uint32 pet_number = objmgr.GeneratePetNumber();
if(!critter->Create(objmgr.GenerateLowGuid(HIGHGUID_PET), if(!critter->Create(objmgr.GenerateLowGuid(HIGHGUID_PET), map, m_caster->GetPhaseMask(),
map, pet_entry, pet_number)) pet_entry, pet_number))
{ {
sLog.outError("Spell::EffectSummonCritter, spellid %u: no such creature entry %u", m_spellInfo->Id, pet_entry); sLog.outError("Spell::EffectSummonCritter, spellid %u: no such creature entry %u", m_spellInfo->Id, pet_entry);
delete critter; delete critter;
@ -6154,7 +6160,7 @@ void Spell::EffectTransmitted(uint32 effIndex)
GameObject* pGameObj = new GameObject; GameObject* pGameObj = new GameObject;
if(!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), name_id, cMap, if(!pGameObj->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), name_id, cMap,
fx, fy, fz, m_caster->GetOrientation(), 0, 0, 0, 0, 100, 1)) m_caster->GetPhaseMask(), fx, fy, fz, m_caster->GetOrientation(), 0, 0, 0, 0, 100, 1))
{ {
delete pGameObj; delete pGameObj;
return; return;
@ -6225,7 +6231,7 @@ void Spell::EffectTransmitted(uint32 effIndex)
{ {
GameObject* linkedGO = new GameObject; GameObject* linkedGO = new GameObject;
if(linkedGO->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), linkedEntry, cMap, if(linkedGO->Create(objmgr.GenerateLowGuid(HIGHGUID_GAMEOBJECT), linkedEntry, cMap,
fx, fy, fz, m_caster->GetOrientation(), 0, 0, 0, 0, 100, 1)) m_caster->GetPhaseMask(), fx, fy, fz, m_caster->GetOrientation(), 0, 0, 0, 0, 100, 1))
{ {
linkedGO->SetRespawnTime(duration > 0 ? duration/1000 : 0); linkedGO->SetRespawnTime(duration > 0 ? duration/1000 : 0);
linkedGO->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel() ); linkedGO->SetUInt32Value(GAMEOBJECT_LEVEL, m_caster->getLevel() );

View file

@ -143,6 +143,7 @@ bool Transport::Create(uint32 guidlow, uint32 mapid, float x, float y, float z,
Relocate(x,y,z,ang); Relocate(x,y,z,ang);
SetMapId(mapid); SetMapId(mapid);
// instance id and phaseMask isn't set to values different from std.
if(!IsPositionValid()) if(!IsPositionValid())
{ {

View file

@ -11317,3 +11317,11 @@ void Unit::RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo)
++iter; ++iter;
} }
} }
void Unit::SetPhaseMask(uint32 newPhaseMask, bool update)
{
WorldObject::SetPhaseMask(newPhaseMask,update);
if(Pet* pet = GetPet())
pet->SetPhaseMask(newPhaseMask,true);
}

View file

@ -1237,6 +1237,7 @@ class MANGOS_DLL_SPEC Unit : public WorldObject
// common function for visibility checks for player/creatures with detection code // common function for visibility checks for player/creatures with detection code
bool isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList = false, bool is3dDistance = true) const; bool isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList = false, bool is3dDistance = true) const;
bool canDetectInvisibilityOf(Unit const* u) const; bool canDetectInvisibilityOf(Unit const* u) const;
void SetPhaseMask(uint32 newPhaseMask, bool update);// overwrite WorldObject::SetPhaseMask
// virtual functions for all world objects types // virtual functions for all world objects types
bool isVisibleForInState(Player const* u, bool inVisibleList) const; bool isVisibleForInState(Player const* u, bool inVisibleList) const;

View file

@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__ #ifndef __REVISION_NR_H__
#define __REVISION_NR_H__ #define __REVISION_NR_H__
#define REVISION_NR "7206" #define REVISION_NR "7207"
#endif // __REVISION_NR_H__ #endif // __REVISION_NR_H__