[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`;
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';
--
@ -727,6 +727,7 @@ CREATE TABLE `corpse` (
`orientation` float NOT NULL default '0',
`zone` int(11) unsigned NOT NULL default '38' COMMENT 'Zone Identifier',
`map` int(11) unsigned NOT NULL default '0' COMMENT 'Map Identifier',
`phaseMask` smallint(5) unsigned NOT NULL default '1',
`data` longtext,
`time` bigint(20) 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`;
CREATE TABLE `db_version` (
`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';
--
@ -488,6 +488,7 @@ CREATE TABLE `creature` (
`id` mediumint(8) unsigned NOT NULL default '0' COMMENT 'Creature Identifier',
`map` smallint(5) unsigned NOT NULL default '0' COMMENT 'Map Identifier',
`spawnMask` tinyint(3) unsigned NOT NULL default '1',
`phaseMask` smallint(5) unsigned NOT NULL default '1',
`modelid` mediumint(8) unsigned NOT NULL default '0',
`equipment_id` mediumint(9) 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',
`map` smallint(5) unsigned NOT NULL default '0' COMMENT 'Map Identifier',
`spawnMask` tinyint(3) unsigned NOT NULL default '1',
`phaseMask` smallint(5) unsigned NOT NULL default '1',
`position_x` float NOT NULL default '0',
`position_y` 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_02_mangos_spell_proc_event.sql \
7205_01_mangos_spell_chain.sql \
7207_01_mangos_creature.sql \
7207_02_mangos_gameobject.sql \
7207_03_characters_corpse.sql \
README
## Additional files to include when running 'make dist'
@ -298,4 +301,7 @@ EXTRA_DIST = \
7199_01_mangos_spell_bonus_data.sql \
7199_02_mangos_spell_proc_event.sql \
7205_01_mangos_spell_chain.sql \
7207_01_mangos_creature.sql \
7207_02_mangos_gameobject.sql \
7207_03_characters_corpse.sql \
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
// so we must create it specific for this instance
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.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;
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);
delete pCreature;

View file

@ -69,26 +69,26 @@ bool Corpse::Create( uint32 guidlow )
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());
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())
{
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;
}
SetFloatValue( OBJECT_FIELD_SCALE_X, 1 );
SetFloatValue( CORPSE_FIELD_POS_X, x );
SetFloatValue( CORPSE_FIELD_POS_Y, y );
SetFloatValue( CORPSE_FIELD_POS_Z, z );
SetFloatValue( CORPSE_FIELD_FACING, ang );
SetFloatValue( CORPSE_FIELD_POS_X, GetPositionX() );
SetFloatValue( CORPSE_FIELD_POS_Y, GetPositionY() );
SetFloatValue( CORPSE_FIELD_POS_Z, GetPositionZ() );
SetFloatValue( CORPSE_FIELD_FACING, GetOrientation() );
SetUInt64Value( CORPSE_FIELD_OWNER, owner->GetGUID() );
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()
{
// prevent DB data inconsistance problems and duplicates
// prevent DB data inconsistence problems and duplicates
CharacterDatabase.BeginTransaction();
DeleteFromDB();
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() << ", "
<< GetOrientation() << ", " << GetZoneId() << ", " << GetMapId() << ", '";
for(uint16 i = 0; i < m_valuesCount; 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.CommitTransaction();
}
@ -141,8 +142,8 @@ bool Corpse::LoadFromDB(uint32 guid, QueryResult *result)
{
bool external = (result != NULL);
if (!external)
// 0 1 2 3 4 5 6 7 8
result = CharacterDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map,data,time,corpse_type,instance FROM corpse WHERE guid = '%u'",guid);
// 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,phaseMask FROM corpse WHERE guid = '%u'",guid);
if( ! result )
{
@ -164,8 +165,8 @@ bool Corpse::LoadFromDB(uint32 guid, QueryResult *result)
bool Corpse::LoadFromDB(uint32 guid, Field *fields)
{
// 0 1 2 3 4 5 6 7 8
//result = CharacterDatabase.PQuery("SELECT position_x,position_y,position_z,orientation,map,data,time,corpse_type,instance FROM corpse WHERE guid = '%u'",guid);
// 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,phaseMask FROM corpse WHERE guid = '%u'",guid);
float positionX = fields[0].GetFloat();
float positionY = fields[1].GetFloat();
float positionZ = fields[2].GetFloat();
@ -186,6 +187,7 @@ bool Corpse::LoadFromDB(uint32 guid, Field *fields)
return false;
}
uint32 instanceid = fields[8].GetUInt32();
uint32 phaseMask = fields[9].GetUInt32();
// overwrite possible wrong/corrupted guid
SetUInt64Value(OBJECT_FIELD_GUID, MAKE_NEW_GUID(guid, 0, HIGHGUID_CORPSE));
@ -193,6 +195,7 @@ bool Corpse::LoadFromDB(uint32 guid, Field *fields)
// place
SetInstanceId(instanceid);
SetMapId(mapid);
SetPhaseMask(phaseMask,false);
Relocate(positionX,positionY,positionZ,ort);
if(!IsPositionValid())

View file

@ -56,7 +56,7 @@ class Corpse : public WorldObject
void RemoveFromWorld();
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();
bool LoadFromDB(uint32 guid, QueryResult *result);

View file

@ -530,10 +530,11 @@ bool Creature::AIM_Initialize()
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());
SetInstanceId(map->GetInstanceId());
SetPhaseMask(phaseMask,false);
//oX = x; oY = y; dX = x; dY = y; m_moveTime = 0; m_startMove = 0;
const bool bResult = CreateFromProto(guidlow, Entry, team, data);
@ -1063,10 +1064,10 @@ void Creature::SaveToDB()
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
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.id = GetEntry();
data.mapid = mapid;
data.phaseMask = phaseMask;
data.displayid = displayId;
data.equipmentId = GetEquipmentId();
data.posX = GetPositionX();
@ -1291,7 +1293,7 @@ bool Creature::LoadFromDB(uint32 guid, Map *map)
if (map->GetInstanceId() != 0) guid = objmgr.GenerateLowGuid(HIGHGUID_UNIT);
uint16 team = 0;
if(!Create(guid,map,data->id,team,data))
if(!Create(guid,map,data->phaseMask,data->id,team,data))
return false;
Relocate(data->posX,data->posY,data->posZ,data->orientation);

View file

@ -247,6 +247,7 @@ struct CreatureData
{
uint32 id; // entry in creature_template
uint16 mapid;
uint16 phaseMask;
uint32 displayid;
int32 equipmentId;
float posX;
@ -405,7 +406,7 @@ class MANGOS_DLL_SPEC Creature : public Unit
void AddToWorld();
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);
void SelectLevel(const CreatureInfo *cinfo);
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);
void SaveToDB();
// 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
Loot loot;

View file

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

View file

@ -89,11 +89,12 @@ void GameObject::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);
SetMapId(map->GetId());
SetInstanceId(map->GetInstanceId());
SetPhaseMask(phaseMask,false);
if(!IsPositionValid())
{
@ -504,10 +505,10 @@ void GameObject::SaveToDB()
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();
@ -522,6 +523,7 @@ void GameObject::SaveToDB(uint32 mapid, uint8 spawnMask)
// data->guid = guid don't must be update at save
data.id = GetEntry();
data.mapid = mapid;
data.phaseMask = phaseMask;
data.posX = GetFloatValue(GAMEOBJECT_POS_X);
data.posY = GetFloatValue(GAMEOBJECT_POS_Y);
data.posZ = GetFloatValue(GAMEOBJECT_POS_Z);
@ -572,6 +574,7 @@ bool GameObject::LoadFromDB(uint32 guid, Map *map)
uint32 entry = data->id;
//uint32 map_id = data->mapid; // already used before call
uint32 phaseMask = data->phaseMask;
float x = data->posX;
float y = data->posY;
float z = data->posZ;
@ -588,7 +591,7 @@ bool GameObject::LoadFromDB(uint32 guid, Map *map)
m_DBTableGuid = guid;
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;
switch(GetGOInfo()->type)

View file

@ -375,7 +375,8 @@ struct GameObjectLocale
struct GameObjectData
{
uint32 id; // entry in gamobject_template
uint32 mapid;
uint16 mapid;
uint16 phaseMask;
float posX;
float posY;
float posZ;
@ -423,7 +424,7 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
void AddToWorld();
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);
static GameObject* GetGameObject(WorldObject& object, uint64 guid);
GameObjectInfo const* GetGOInfo() const;
@ -453,7 +454,7 @@ class MANGOS_DLL_SPEC GameObject : public WorldObject
const char* GetNameForLocaleIdx(int32 locale_idx) const;
void SaveToDB();
void SaveToDB(uint32 mapid, uint8 spawnMask);
void SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask);
bool LoadFromDB(uint32 guid, Map *map);
void DeleteFromDB();
void SetLootState(LootState s) { m_lootState = s; }

View file

@ -873,7 +873,7 @@ bool ChatHandler::HandleNpcAddCommand(const char* args)
Map *map = chr->GetMap();
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;
return false;
@ -888,7 +888,7 @@ bool ChatHandler::HandleNpcAddCommand(const char* args)
return false;
}
pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
uint32 db_guid = pCreature->GetDBTableGUIDLow();
@ -2531,7 +2531,7 @@ bool ChatHandler::HandleWpModifyCommand(const char* args)
// create the waypoint creature
wpGuid = 0;
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);
delete wpCreature;
@ -2547,7 +2547,7 @@ bool ChatHandler::HandleWpModifyCommand(const char* args)
}
else
{
wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
// To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(), map);
map->Add(wpCreature);
@ -2653,7 +2653,7 @@ bool ChatHandler::HandleWpModifyCommand(const char* args)
wpCreature->AddObjectToRemoveList();
// re-create
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);
delete wpCreature2;
@ -2669,7 +2669,7 @@ bool ChatHandler::HandleWpModifyCommand(const char* args)
return false;
}
wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
wpCreature2->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
// To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
wpCreature2->LoadFromDB(wpCreature2->GetDBTableGUIDLow(), map);
map->Add(wpCreature2);
@ -2958,7 +2958,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
float o = chr->GetOrientation();
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);
delete wpCreature;
@ -2981,7 +2981,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
// 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);
wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
wpCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
// To call _LoadGoods(); _LoadQuests(); CreateTrainerSpells();
wpCreature->LoadFromDB(wpCreature->GetDBTableGUIDLow(),map);
map->Add(wpCreature);
@ -3016,7 +3016,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
Map *map = chr->GetMap();
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);
delete pCreature;
@ -3034,7 +3034,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
return false;
}
pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map);
map->Add(pCreature);
//player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "First Waypoint");
@ -3076,7 +3076,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
Map *map = chr->GetMap();
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);
delete pCreature;
@ -3094,7 +3094,7 @@ bool ChatHandler::HandleWpShowCommand(const char* args)
return false;
}
pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()));
pCreature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMaskForSpawn());
pCreature->LoadFromDB(pCreature->GetDBTableGUIDLow(), map);
map->Add(pCreature);
//player->PlayerTalkClass->SendPointOfInterest(x, y, 6, 6, 0, "Last Waypoint");
@ -3453,7 +3453,7 @@ bool ChatHandler::HandleGameObjectCommand(const char* args)
GameObject* pGameObj = new 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;
return false;
@ -3467,7 +3467,7 @@ bool ChatHandler::HandleGameObjectCommand(const char* args)
}
// 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
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);
m_mapId = mapid;
m_phaseMask = phaseMask;
}
uint32 WorldObject::GetZoneId() const
@ -1468,7 +1469,7 @@ Creature* WorldObject::SummonCreature(uint32 id, float x, float y, float z, floa
if (GetTypeId()==TYPEID_PLAYER)
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;
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
}
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*/ ) { }
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)
{
@ -407,7 +407,7 @@ class MANGOS_DLL_SPEC WorldObject : public Object
void SetMapId(uint32 newMap) { m_mapId = newMap; }
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; }
bool InSamePhase(WorldObject const* obj) const { return InSamePhase(obj->GetPhaseMask()); }
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->SetMapId(corpse->GetMapId());
bones->SetInstanceId(corpse->GetInstanceId());
bones->SetPhaseMask(corpse->GetPhaseMask(),false);
bones->SetUInt32Value(CORPSE_FIELD_FLAGS, CORPSE_FLAG_UNK2 | CORPSE_FLAG_BONES);
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,"
// 4 5 6 7 8 9 10 11
"equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, spawndist, currentwaypoint,"
// 12 13 14 15 16 17
"curhealth, curmana, DeathState, MovementType, spawnMask, event "
// 12 13 14 15 16 17 18
"curhealth, curmana, DeathState, MovementType, spawnMask, phaseMask, event "
"FROM creature LEFT OUTER JOIN game_event_creature ON creature.guid = game_event_creature.guid");
if(!result)
@ -1091,7 +1091,8 @@ void ObjectMgr::LoadCreatures()
data.is_dead = fields[14].GetBool();
data.movementType = fields[15].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);
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
AddCreatureToGrid(guid, &data);
++count;
@ -1199,8 +1234,8 @@ void ObjectMgr::LoadGameobjects()
// 0 1 2 3 4 5 6
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
"rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state, spawnMask, event "
// 7 8 9 10 11 12 13 14 15 16
"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");
if(!result)
@ -1239,7 +1274,8 @@ void ObjectMgr::LoadGameobjects()
data.animprogress = fields[12].GetUInt32();
data.go_state = fields[13].GetUInt32();
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);
if(!gInfo)
@ -1248,6 +1284,12 @@ void ObjectMgr::LoadGameobjects()
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
AddGameobjectToGrid(guid, &data);
++count;

View file

@ -135,7 +135,7 @@ bool Pet::LoadPetFromDB( Player* owner, uint32 petentry, uint32 petnumber, bool
Map *map = owner->GetMap();
uint32 guid = objmgr.GenerateLowGuid(HIGHGUID_PET);
uint32 pet_number = fields[0].GetUInt32();
if(!Create(guid, map, petentry, pet_number))
if(!Create(guid, map, owner->GetPhaseMask(), petentry, pet_number))
{
delete result;
return false;
@ -716,7 +716,7 @@ bool Pet::CreateBaseAtCreature(Creature* creature)
sLog.outBasic("Create pet");
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;
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());
SetInstanceId(map->GetInstanceId());
SetPhaseMask(phaseMask,false);
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 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 LoadPetFromDB( Player* owner,uint32 petentry = 0,uint32 petnumber = 0, bool current = false );
void SavePetToDB(PetSaveMode mode);

View file

@ -1985,13 +1985,13 @@ void Player::SetGameMaster(bool on)
getHostilRefManager().setOnlineOfflineState(false);
CombatStop();
SetPhaseMask(PHASEMASK_ANYWHERE); // see and visible in all phases
SetPhaseMask(PHASEMASK_ANYWHERE,false); // see and visible in all phases
}
else
{
// restore 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;
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 );
SetPvPDeath(false);
if(!corpse->Create(objmgr.GenerateLowGuid(HIGHGUID_CORPSE), this, GetMapId(), GetPositionX(),
GetPositionY(), GetPositionZ(), GetOrientation()))
if(!corpse->Create(objmgr.GenerateLowGuid(HIGHGUID_CORPSE), this))
{
delete corpse;
return;
@ -19455,3 +19454,24 @@ void Player::_LoadSkills()
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()); }
GuardianPetList const& GetGuardians() const { return m_guardianPets; }
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 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
if(!((Player*)m_target)->isGameMaster())
m_target->SetPhaseMask(apply ? GetMiscValue() : PHASEMASK_NORMAL);
m_target->SetPhaseMask(apply ? GetMiscValue() : PHASEMASK_NORMAL,false);
}
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)
if(m_target->GetVisibility()!=VISIBILITY_OFF)

View file

@ -782,7 +782,7 @@ void Spell::EffectDummy(uint32 i)
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->GetOrientation(), 0, 0, 0, 0, 100, 1) )
{
@ -3233,7 +3233,8 @@ void Spell::EffectSummon(uint32 i)
Map *map = m_caster->GetMap();
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]);
delete spawnCreature;
@ -3657,7 +3658,8 @@ void Spell::EffectSummonGuardian(uint32 i)
Map *map = m_caster->GetMap();
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]);
delete spawnCreature;
@ -4075,7 +4077,8 @@ void Spell::EffectSummonPet(uint32 i)
Map *map = m_caster->GetMap();
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;
return;
@ -4506,7 +4509,7 @@ void Spell::EffectSummonObjectWild(uint32 i)
Map *map = target->GetMap();
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;
return;
@ -4554,7 +4557,7 @@ void Spell::EffectSummonObjectWild(uint32 i)
{
GameObject* linkedGO = new GameObject;
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->SetSpellId(m_spellInfo->Id);
@ -5166,7 +5169,8 @@ void Spell::EffectDuel(uint32 i)
uint32 gameobject_id = m_spellInfo->EffectMiscValue[i];
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->GetPositionY()+(unitTarget->GetPositionY()-m_caster->GetPositionY())/2 ,
m_caster->GetPositionZ(),
@ -5349,7 +5353,8 @@ void Spell::EffectSummonTotem(uint32 i)
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;
return;
@ -5560,7 +5565,8 @@ void Spell::EffectSummonObject(uint32 i)
m_caster->GetClosePoint(x,y,z,DEFAULT_WORLD_OBJECT_SIZE);
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;
return;
@ -5822,8 +5828,8 @@ void Spell::EffectSummonCritter(uint32 i)
Map *map = m_caster->GetMap();
uint32 pet_number = objmgr.GeneratePetNumber();
if(!critter->Create(objmgr.GenerateLowGuid(HIGHGUID_PET),
map, pet_entry, pet_number))
if(!critter->Create(objmgr.GenerateLowGuid(HIGHGUID_PET), map, m_caster->GetPhaseMask(),
pet_entry, pet_number))
{
sLog.outError("Spell::EffectSummonCritter, spellid %u: no such creature entry %u", m_spellInfo->Id, pet_entry);
delete critter;
@ -6154,7 +6160,7 @@ void Spell::EffectTransmitted(uint32 effIndex)
GameObject* pGameObj = new GameObject;
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;
return;
@ -6225,7 +6231,7 @@ void Spell::EffectTransmitted(uint32 effIndex)
{
GameObject* linkedGO = new GameObject;
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->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);
SetMapId(mapid);
// instance id and phaseMask isn't set to values different from std.
if(!IsPositionValid())
{

View file

@ -11317,3 +11317,11 @@ void Unit::RemoveAurasAtChanneledTarget(SpellEntry const* spellInfo)
++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
bool isVisibleForOrDetect(Unit const* u, bool detect, bool inVisibleList = false, bool is3dDistance = true) const;
bool canDetectInvisibilityOf(Unit const* u) const;
void SetPhaseMask(uint32 newPhaseMask, bool update);// overwrite WorldObject::SetPhaseMask
// virtual functions for all world objects types
bool isVisibleForInState(Player const* u, bool inVisibleList) const;

View file

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