mirror of
https://github.com/TrinityCore/TrinityCore.git
synced 2026-01-30 21:57:01 +01:00
Core/Phases: implemented new commands:
.npc set phase .npc set phasegroup - implemented saving creature phasing to database
This commit is contained in:
@@ -1006,6 +1006,9 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
|
||||
data.unit_flags = unit_flags;
|
||||
data.dynamicflags = dynamicflags;
|
||||
|
||||
data.phaseid = GetDBPhase() > 0 ? GetDBPhase() : 0;
|
||||
data.phaseGroup = GetDBPhase() < 0 ? abs(GetDBPhase()) : 0;
|
||||
|
||||
// update in DB
|
||||
SQLTransaction trans = WorldDatabase.BeginTransaction();
|
||||
|
||||
@@ -1021,6 +1024,8 @@ void Creature::SaveToDB(uint32 mapid, uint8 spawnMask, uint32 phaseMask)
|
||||
stmt->setUInt16(index++, uint16(mapid));
|
||||
stmt->setUInt8(index++, spawnMask);
|
||||
stmt->setUInt32(index++, GetPhaseMask());
|
||||
stmt->setUInt32(index++, data.phaseid);
|
||||
stmt->setUInt32(index++, data.phaseGroup);
|
||||
stmt->setUInt32(index++, displayId);
|
||||
stmt->setInt32(index++, int32(GetCurrentEquipmentId()));
|
||||
stmt->setFloat(index++, GetPositionX());
|
||||
|
||||
@@ -1286,7 +1286,7 @@ void MovementInfo::OutDebug()
|
||||
WorldObject::WorldObject(bool isWorldObject) : WorldLocation(), LastUsedScriptID(0),
|
||||
m_name(""), m_isActive(false), m_isWorldObject(isWorldObject), m_zoneScript(NULL),
|
||||
m_transport(NULL), m_currMap(NULL), m_InstanceId(0),
|
||||
m_phaseMask(PHASEMASK_NORMAL), m_notifyflags(0), m_executed_notifies(0)
|
||||
m_phaseMask(PHASEMASK_NORMAL), _dbPhase(0), m_notifyflags(0), m_executed_notifies(0)
|
||||
{
|
||||
m_serverSideVisibility.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_ALIVE | GHOST_VISIBILITY_GHOST);
|
||||
m_serverSideVisibilityDetect.SetValue(SERVERSIDE_VISIBILITY_GHOST, GHOST_VISIBILITY_ALIVE);
|
||||
@@ -2720,11 +2720,13 @@ void WorldObject::SetPhaseMask(uint32 newPhaseMask, bool update)
|
||||
|
||||
void WorldObject::SetInPhase(uint32 id, bool update, bool apply)
|
||||
{
|
||||
if (apply)
|
||||
_phases.insert(id);
|
||||
else
|
||||
_phases.erase(id);
|
||||
|
||||
if (id)
|
||||
{
|
||||
if (apply)
|
||||
_phases.insert(id);
|
||||
else
|
||||
_phases.erase(id);
|
||||
}
|
||||
RebuildTerrainSwaps();
|
||||
|
||||
if (update && IsInWorld())
|
||||
@@ -2743,6 +2745,16 @@ void WorldObject::CopyPhaseFrom(WorldObject* obj, bool update)
|
||||
UpdateObjectVisibility();
|
||||
}
|
||||
|
||||
void WorldObject::ClearPhases(bool update)
|
||||
{
|
||||
_phases.clear();
|
||||
|
||||
RebuildTerrainSwaps();
|
||||
|
||||
if (update && IsInWorld())
|
||||
UpdateObjectVisibility();
|
||||
}
|
||||
|
||||
bool WorldObject::IsInPhase(WorldObject const* obj) const
|
||||
{
|
||||
// PhaseId 169 is the default fallback phase
|
||||
|
||||
@@ -594,6 +594,7 @@ class WorldObject : public Object, public WorldLocation
|
||||
virtual void SetPhaseMask(uint32 newPhaseMask, bool update);
|
||||
virtual void SetInPhase(uint32 id, bool update, bool apply);
|
||||
void CopyPhaseFrom(WorldObject* obj, bool update = false);
|
||||
void ClearPhases(bool update = false);
|
||||
void RebuildTerrainSwaps();
|
||||
uint32 GetPhaseMask() const { return m_phaseMask; }
|
||||
bool IsInPhase(uint32 phase) const { return _phases.find(phase) != _phases.end(); }
|
||||
@@ -601,6 +602,10 @@ class WorldObject : public Object, public WorldLocation
|
||||
bool IsInTerrainSwap(uint32 terrainSwap) const { return _terrainSwaps.find(terrainSwap) != _terrainSwaps.end(); }
|
||||
std::set<uint32> const& GetPhases() const { return _phases; }
|
||||
std::set<uint32> const& GetTerrainSwaps() const { return _terrainSwaps; }
|
||||
int GetDBPhase() { return _dbPhase; }
|
||||
|
||||
// if negative it is used as PhaseGroupId
|
||||
void SetDBPhase(int p) { _dbPhase = p; }
|
||||
|
||||
uint32 GetZoneId() const;
|
||||
uint32 GetAreaId() const;
|
||||
@@ -773,6 +778,7 @@ class WorldObject : public Object, public WorldLocation
|
||||
uint32 m_phaseMask; // in area phase state
|
||||
std::set<uint32> _phases;
|
||||
std::set<uint32> _terrainSwaps;
|
||||
int _dbPhase;
|
||||
|
||||
uint16 m_notifyflags;
|
||||
uint16 m_executed_notifies;
|
||||
|
||||
@@ -181,19 +181,19 @@ public:
|
||||
{ "temp", rbac::RBAC_PERM_COMMAND_NPC_ADD_TEMP, false, &HandleNpcAddTempSpawnCommand, "", NULL },
|
||||
//{ "weapon", rbac::RBAC_PERM_COMMAND_NPC_ADD_WEAPON, false, &HandleNpcAddWeaponCommand, "", NULL },
|
||||
{ "", rbac::RBAC_PERM_COMMAND_NPC_ADD, false, &HandleNpcAddCommand, "", NULL },
|
||||
{ NULL, 0, false, NULL, "", NULL }
|
||||
{ NULL, 0, false, NULL, "", NULL }
|
||||
};
|
||||
static ChatCommand npcDeleteCommandTable[] =
|
||||
{
|
||||
{ "item", rbac::RBAC_PERM_COMMAND_NPC_DELETE_ITEM, false, &HandleNpcDeleteVendorItemCommand, "", NULL },
|
||||
{ "", rbac::RBAC_PERM_COMMAND_NPC_DELETE, false, &HandleNpcDeleteCommand, "", NULL },
|
||||
{ NULL, 0, false, NULL, "", NULL }
|
||||
{ NULL, 0, false, NULL, "", NULL }
|
||||
};
|
||||
static ChatCommand npcFollowCommandTable[] =
|
||||
{
|
||||
{ "stop", rbac::RBAC_PERM_COMMAND_NPC_FOLLOW_STOP, false, &HandleNpcUnFollowCommand, "", NULL },
|
||||
{ "", rbac::RBAC_PERM_COMMAND_NPC_FOLLOW, false, &HandleNpcFollowCommand, "", NULL },
|
||||
{ NULL, 0, false, NULL, "", NULL }
|
||||
{ NULL, 0, false, NULL, "", NULL }
|
||||
};
|
||||
static ChatCommand npcSetCommandTable[] =
|
||||
{
|
||||
@@ -206,12 +206,13 @@ public:
|
||||
{ "model", rbac::RBAC_PERM_COMMAND_NPC_SET_MODEL, false, &HandleNpcSetModelCommand, "", NULL },
|
||||
{ "movetype", rbac::RBAC_PERM_COMMAND_NPC_SET_MOVETYPE, false, &HandleNpcSetMoveTypeCommand, "", NULL },
|
||||
{ "phase", rbac::RBAC_PERM_COMMAND_NPC_SET_PHASE, false, &HandleNpcSetPhaseCommand, "", NULL },
|
||||
{ "phasegroup", rbac::RBAC_PERM_COMMAND_NPC_SET_DATA, false, &HandleNpcSetPhaseGroup, "", NULL },
|
||||
{ "spawndist", rbac::RBAC_PERM_COMMAND_NPC_SET_SPAWNDIST, false, &HandleNpcSetSpawnDistCommand, "", NULL },
|
||||
{ "spawntime", rbac::RBAC_PERM_COMMAND_NPC_SET_SPAWNTIME, false, &HandleNpcSetSpawnTimeCommand, "", NULL },
|
||||
{ "data", rbac::RBAC_PERM_COMMAND_NPC_SET_DATA, false, &HandleNpcSetDataCommand, "", NULL },
|
||||
//{ "name", rbac::RBAC_PERM_COMMAND_NPC_SET_NAME, false, &HandleNpcSetNameCommand, "", NULL },
|
||||
//{ "subname", rbac::RBAC_PERM_COMMAND_NPC_SET_SUBNAME, false, &HandleNpcSetSubNameCommand, "", NULL },
|
||||
{ NULL, 0, false, NULL, "", NULL }
|
||||
{ NULL, 0, false, NULL, "", NULL }
|
||||
};
|
||||
static ChatCommand npcCommandTable[] =
|
||||
{
|
||||
@@ -228,7 +229,7 @@ public:
|
||||
{ "delete", rbac::RBAC_PERM_COMMAND_NPC_DELETE, false, NULL, "", npcDeleteCommandTable },
|
||||
{ "follow", rbac::RBAC_PERM_COMMAND_NPC_FOLLOW, false, NULL, "", npcFollowCommandTable },
|
||||
{ "set", rbac::RBAC_PERM_COMMAND_NPC_SET, false, NULL, "", npcSetCommandTable },
|
||||
{ NULL, 0, false, NULL, "", NULL }
|
||||
{ NULL, 0, false, NULL, "", NULL }
|
||||
};
|
||||
static ChatCommand commandTable[] =
|
||||
{
|
||||
@@ -272,6 +273,8 @@ public:
|
||||
|
||||
Creature* creature = trans->CreateNPCPassenger(guid, &data);
|
||||
|
||||
// creature->CopyPhaseFrom(chr); // will not be saved, and probably useless
|
||||
|
||||
creature->SaveToDB(trans->GetGOInfo()->moTransport.mapID, 1 << map->GetSpawnMode(), chr->GetPhaseMask());
|
||||
|
||||
sObjectMgr->AddCreatureToGrid(guid, &data);
|
||||
@@ -285,7 +288,7 @@ public:
|
||||
return false;
|
||||
}
|
||||
|
||||
creature->CopyPhaseFrom(chr);
|
||||
//creature->CopyPhaseFrom(chr); // creature is not directly added to world, only to db, so this is useless here
|
||||
|
||||
creature->SaveToDB(map->GetId(), (1 << map->GetSpawnMode()), chr->GetPhaseMask());
|
||||
|
||||
@@ -1099,7 +1102,37 @@ public:
|
||||
}
|
||||
|
||||
//npc phase handling
|
||||
//change phase of creature or pet
|
||||
//change phase of creature
|
||||
static bool HandleNpcSetPhaseGroup(ChatHandler* handler, char const* args)
|
||||
{
|
||||
if (!*args)
|
||||
return false;
|
||||
|
||||
uint32 phaseGroupId = (uint32)atoi((char*)args);
|
||||
|
||||
Creature* creature = handler->getSelectedCreature();
|
||||
if (!creature || creature->IsPet())
|
||||
{
|
||||
handler->SendSysMessage(LANG_SELECT_CREATURE);
|
||||
handler->SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
creature->ClearPhases();
|
||||
|
||||
for (uint32 id : GetPhasesForGroup(phaseGroupId))
|
||||
creature->SetInPhase(id, false, true); // don't send update here for multiple phases, only send it once after adding all phases
|
||||
|
||||
creature->UpdateObjectVisibility();
|
||||
creature->SetDBPhase(-int(phaseGroupId));
|
||||
|
||||
creature->SaveToDB();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//npc phase handling
|
||||
//change phase of creature
|
||||
static bool HandleNpcSetPhaseCommand(ChatHandler* handler, char const* args)
|
||||
{
|
||||
if (!*args)
|
||||
@@ -1108,17 +1141,18 @@ public:
|
||||
uint32 phase = (uint32) atoi((char*)args);
|
||||
|
||||
Creature* creature = handler->getSelectedCreature();
|
||||
if (!creature)
|
||||
if (!creature || creature->IsPet())
|
||||
{
|
||||
handler->SendSysMessage(LANG_SELECT_CREATURE);
|
||||
handler->SetSentErrorMessage(true);
|
||||
return false;
|
||||
}
|
||||
|
||||
creature->SetInPhase(phase, true, !creature->IsInPhase(phase));
|
||||
creature->ClearPhases();
|
||||
creature->SetInPhase(phase, true, true);
|
||||
creature->SetDBPhase(phase);
|
||||
|
||||
if (!creature->IsPet())
|
||||
creature->SaveToDB();
|
||||
creature->SaveToDB();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ void WorldDatabaseConnection::DoPrepareStatements()
|
||||
PrepareStatement(WORLD_SEL_CREATURE_BY_ID, "SELECT guid FROM creature WHERE id = ?", CONNECTION_SYNCH);
|
||||
PrepareStatement(WORLD_SEL_GAMEOBJECT_NEAREST, "SELECT guid, id, position_x, position_y, position_z, map, (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) AS order_ FROM gameobject WHERE map = ? AND (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) <= ? ORDER BY order_", CONNECTION_SYNCH);
|
||||
PrepareStatement(WORLD_SEL_CREATURE_NEAREST, "SELECT guid, id, position_x, position_y, position_z, map, (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) AS order_ FROM creature WHERE map = ? AND (POW(position_x - ?, 2) + POW(position_y - ?, 2) + POW(position_z - ?, 2)) <= ? ORDER BY order_", CONNECTION_SYNCH);
|
||||
PrepareStatement(WORLD_INS_CREATURE, "INSERT INTO creature (guid, id , map, spawnMask, phaseMask, modelid, equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, spawndist, currentwaypoint, curhealth, curmana, MovementType, npcflag, unit_flags, dynamicflags) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(WORLD_INS_CREATURE, "INSERT INTO creature (guid, id , map, spawnMask, phaseMask, PhaseId, PhaseGroup, modelid, equipment_id, position_x, position_y, position_z, orientation, spawntimesecs, spawndist, currentwaypoint, curhealth, curmana, MovementType, npcflag, unit_flags, dynamicflags) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
PrepareStatement(WORLD_DEL_GAME_EVENT_CREATURE, "DELETE FROM game_event_creature WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(WORLD_DEL_GAME_EVENT_MODEL_EQUIP, "DELETE FROM game_event_model_equip WHERE guid = ?", CONNECTION_ASYNC);
|
||||
PrepareStatement(WORLD_INS_GAMEOBJECT, "INSERT INTO gameobject (guid, id, map, spawnMask, phaseMask, position_x, position_y, position_z, orientation, rotation0, rotation1, rotation2, rotation3, spawntimesecs, animprogress, state) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", CONNECTION_ASYNC);
|
||||
|
||||
Reference in New Issue
Block a user