mirror of
https://github.com/mod-playerbots/azerothcore-wotlk.git
synced 2026-01-15 18:10:26 +00:00
feat(Core/GameObjects): Instance gameobject save data implementation (#11113)
* fix(Core): Save gameobject state on instances Currently, azerothcore doesn't save gameobject states on instances. Whenever there's a re-start or crash, the instance's gameobjects and their states aren't saved, producing un-wanted behaviours and blocking instances at times. Implemented CRUD for new table `instance_saved_data` that holds the states of gameobjects. - When worldserver launches and gameobjects are loaded, this will check if this object's state exists on the DB and sets the previous state. - On instance deletion (reset) these states are also removed based on the instance ID. - Whenever a gameobject state changes inside a dungeon or raid, we save on the database the set state. * Select query to synchronous and used FindMap() * loading gameobject states on create * reseting instance saved data * missing reset methods and on create state * database structure * Update src/server/game/Entities/GameObject/GameObject.cpp Co-authored-by: Kitzunu <24550914+Kitzunu@users.noreply.github.com> * Update src/server/game/Entities/GameObject/GameObject.cpp Co-authored-by: Kitzunu <24550914+Kitzunu@users.noreply.github.com> * Update src/server/game/Entities/GameObject/GameObject.cpp Co-authored-by: Kitzunu <24550914+Kitzunu@users.noreply.github.com> * Update src/server/game/Entities/GameObject/GameObject.cpp Co-authored-by: Kitzunu <24550914+Kitzunu@users.noreply.github.com> * Update src/server/game/Entities/Player/PlayerMisc.cpp Co-authored-by: Kitzunu <24550914+Kitzunu@users.noreply.github.com> * Update src/server/game/Groups/Group.cpp Co-authored-by: Kitzunu <24550914+Kitzunu@users.noreply.github.com> * codestyle * table changes * table style * codestyle * table changes for columns * data sanitization * todo: - Finish loading db data into the containers - Using containers to find data - How to get data from ObjectMGR inside Gameobject? * loading on start up and db changes * Removing unused data structure * Uninitialised integer * Whitespace * clean-up and hooks to save states on memory * Codestyle MySQL deprecated backticks * i dont understand codefactor * build * Update data/sql/updates/pending_db_world/rev_1643395587559675400.sql Co-authored-by: Kitzunu <24550914+Kitzunu@users.noreply.github.com> * Update src/server/game/Globals/ObjectMgr.h Co-authored-by: Kargatum <dowlandtop@yandex.com> * review changes * unecessary removal * pushback instead of emplace * wrong database update * Update ObjectMgr.cpp * missing check * removing entry from the PR * missing removals * last delete * build * aha! Found the culprit for the sudden assert errors * type safety, save only important gameobjects * static cast to unsigned short * Update data/sql/updates/pending_db_characters/rev_1643629468629316100.sql Co-authored-by: Kitzunu <24550914+Kitzunu@users.noreply.github.com> * type changes * queries fix * fix build * enabling which gameobjects to save on the database * deadmines iron clad door * Adjustment to gameobject onj create state and instances: - Gnomeregan doors and Grubbis boss state - Deadmines missing doors - Stratholme gameobjects state saved * forgot emi blastfuse change to despawn * Leaving group logic * codestyle * fixing merge issues * prevent bad behaviour * brain meltdown * Update data/sql/updates/pending_db_characters/rev_1643629468629316100.sql * Update data/sql/updates/pending_db_world/rev_1649359139539727000.sql Co-authored-by: Claudiodfc <54484196+claudiodfc@users.noreply.github.com> Co-authored-by: Kitzunu <24550914+Kitzunu@users.noreply.github.com> Co-authored-by: Kargatum <dowlandtop@yandex.com> Co-authored-by: Skjalf <47818697+Nyeriah@users.noreply.github.com>
This commit is contained in:
@@ -32,7 +32,13 @@ enum DataTypes
|
||||
enum GameObjects
|
||||
{
|
||||
GO_FACTORY_DOOR = 13965,
|
||||
GO_IRON_CLAD_DOOR = 16397
|
||||
GO_HEAVY_DOOR_1 = 17153,
|
||||
GO_HEAVY_DOOR_2 = 17154,
|
||||
GO_IRON_CLAD_DOOR = 16397,
|
||||
GO_DOOR_LEVER_1 = 101831,
|
||||
GO_DOOR_LEVER_2 = 101833,
|
||||
GO_DOOR_LEVER_3 = 101834,
|
||||
GO_CANNON = 16398,
|
||||
};
|
||||
|
||||
template <class AI, class T>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/*
|
||||
/*
|
||||
* This file is part of the AzerothCore Project. See AUTHORS file for Copyright information
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
@@ -39,13 +39,25 @@ public:
|
||||
{
|
||||
switch (gameobject->GetEntry())
|
||||
{
|
||||
case GO_HEAVY_DOOR_1:
|
||||
case GO_HEAVY_DOOR_2:
|
||||
case GO_DOOR_LEVER_1:
|
||||
case GO_DOOR_LEVER_2:
|
||||
case GO_DOOR_LEVER_3:
|
||||
case GO_CANNON:
|
||||
gameobject->UpdateSaveToDb(true);
|
||||
break;
|
||||
case GO_FACTORY_DOOR:
|
||||
gameobject->UpdateSaveToDb(true);
|
||||
if (_encounters[TYPE_RHAHK_ZOR] == DONE)
|
||||
gameobject->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_IRON_CLAD_DOOR:
|
||||
if (_encounters[TYPE_CANNON] == DONE)
|
||||
HandleGameObject(ObjectGuid::Empty, true, gameobject);
|
||||
gameobject->UpdateSaveToDb(true);
|
||||
if (gameobject->GetStateSavedOnInstance() == GO_STATE_ACTIVE)
|
||||
{
|
||||
gameobject->DespawnOrUnsummon();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,4 +28,23 @@ inline AI* GetGnomereganAI(T* obj)
|
||||
return GetInstanceAI<AI>(obj, GnomereganScriptName);
|
||||
}
|
||||
|
||||
enum DataTypes
|
||||
{
|
||||
TYPE_GRUBBIS = 0,
|
||||
MAX_ENCOUNTERS = 1
|
||||
};
|
||||
|
||||
enum GameObjects
|
||||
{
|
||||
GO_CAVE_IN_1 = 146085,
|
||||
GO_CAVE_IN_2 = 146086,
|
||||
GO_WORKSHOP_DOOR = 90858,
|
||||
GO_FINAL_CHAMBER_DOOR = 142207,
|
||||
};
|
||||
|
||||
enum NPCs
|
||||
{
|
||||
NPC_EMI_SHORTFUSE = 7998
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -37,6 +37,74 @@ public:
|
||||
instance_gnomeregan_InstanceMapScript(Map* map) : InstanceScript(map)
|
||||
{
|
||||
}
|
||||
|
||||
void OnCreatureCreate(Creature* creature) override
|
||||
{
|
||||
switch (creature->GetEntry())
|
||||
{
|
||||
case NPC_EMI_SHORTFUSE:
|
||||
if (_encounters[TYPE_GRUBBIS] == DONE)
|
||||
{
|
||||
creature->DespawnOrUnsummon();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void OnGameObjectCreate(GameObject* gameobject) override
|
||||
{
|
||||
switch (gameobject->GetEntry())
|
||||
{
|
||||
case GO_CAVE_IN_1:
|
||||
case GO_CAVE_IN_2:
|
||||
case GO_WORKSHOP_DOOR:
|
||||
case GO_FINAL_CHAMBER_DOOR:
|
||||
gameobject->UpdateSaveToDb(true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void SetData(uint32 type, uint32 data) override
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case TYPE_GRUBBIS:
|
||||
_encounters[type] = data;
|
||||
break;
|
||||
}
|
||||
|
||||
if (data == DONE)
|
||||
SaveToDB();
|
||||
}
|
||||
|
||||
std::string GetSaveData() override
|
||||
{
|
||||
std::ostringstream saveStream;
|
||||
saveStream << "D E " << _encounters[0];
|
||||
return saveStream.str();
|
||||
}
|
||||
|
||||
void Load(const char* in) override
|
||||
{
|
||||
if (!in)
|
||||
return;
|
||||
|
||||
char dataHead1, dataHead2;
|
||||
std::istringstream loadStream(in);
|
||||
loadStream >> dataHead1 >> dataHead2;
|
||||
if (dataHead1 == 'D' && dataHead2 == 'E')
|
||||
{
|
||||
for (uint8 i = 0; i < MAX_ENCOUNTERS; ++i)
|
||||
{
|
||||
loadStream >> _encounters[i];
|
||||
if (_encounters[i] == IN_PROGRESS)
|
||||
_encounters[i] = NOT_STARTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
uint32 _encounters[MAX_ENCOUNTERS];
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -62,6 +62,9 @@ public:
|
||||
case GO_GATE_KIRTONOS:
|
||||
GateKirtonosGUID = go->GetGUID();
|
||||
break;
|
||||
case GO_DOOR_OPENED_WITH_KEY:
|
||||
go->UpdateSaveToDb(true);
|
||||
break;
|
||||
case GO_GATE_GANDLING_DOWN_NORTH:
|
||||
GandlingGatesGUID[0] = go->GetGUID();
|
||||
break;
|
||||
|
||||
@@ -52,6 +52,8 @@ enum GameobjectIds
|
||||
GO_BRAZIER_KIRTONOS = 175564,
|
||||
GO_GATE_KIRTONOS = 175570,
|
||||
|
||||
GO_DOOR_OPENED_WITH_KEY = 175167,
|
||||
|
||||
GO_GATE_GANDLING_ENTRANCE = 177374,
|
||||
|
||||
GO_GATE_GANDLING_DOWN_NORTH = 177371,
|
||||
|
||||
@@ -171,55 +171,74 @@ public:
|
||||
{
|
||||
switch (go->GetEntry())
|
||||
{
|
||||
case GO_CRUSADER_SQUARE_DOOR:
|
||||
case GO_HOARD_DOOR:
|
||||
case GO_HALL_OF_HIGH_COMMAND:
|
||||
case GO_GAUNTLET_DOOR_1:
|
||||
case GO_GAUNTLET_DOOR_2:
|
||||
go->UpdateSaveToDb(true);
|
||||
break;
|
||||
case GO_ZIGGURAT_DOORS1:
|
||||
go->UpdateSaveToDb(true);
|
||||
_zigguratDoorsGUID1 = go->GetGUID();
|
||||
if (GetData(TYPE_ZIGGURAT1) >= 1)
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_ZIGGURAT_DOORS2:
|
||||
go->UpdateSaveToDb(true);
|
||||
_zigguratDoorsGUID2 = go->GetGUID();
|
||||
if (GetData(TYPE_ZIGGURAT2) >= 1)
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_ZIGGURAT_DOORS3:
|
||||
go->UpdateSaveToDb(true);
|
||||
_zigguratDoorsGUID3 = go->GetGUID();
|
||||
if (GetData(TYPE_ZIGGURAT3) >= 1)
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_GAUNTLET_GATE:
|
||||
go->UpdateSaveToDb(true);
|
||||
_gauntletGateGUID = go->GetGUID();
|
||||
if (_zigguratState1 == 2 && _zigguratState2 == 2 && _zigguratState3 == 2)
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_SLAUGTHER_GATE:
|
||||
go->UpdateSaveToDb(true);
|
||||
_slaughterGateGUID = go->GetGUID();
|
||||
if (_zigguratState1 == 2 && _zigguratState2 == 2 && _zigguratState3 == 2)
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_ZIGGURAT_DOORS4:
|
||||
go->UpdateSaveToDb(true);
|
||||
_zigguratDoorsGUID4 = go->GetGUID();
|
||||
if (_slaughterProgress == 4)
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_ZIGGURAT_DOORS5:
|
||||
go->UpdateSaveToDb(true);
|
||||
_zigguratDoorsGUID5 = go->GetGUID();
|
||||
if (_slaughterProgress == 4)
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_SLAUGHTER_GATE_SIDE:
|
||||
go->UpdateSaveToDb(true);
|
||||
if (_slaughterProgress >= 2)
|
||||
go->SetGoState(GO_STATE_ACTIVE);
|
||||
break;
|
||||
case GO_PORT_TRAP_GATE_1:
|
||||
go->UpdateSaveToDb(true);
|
||||
_trapGatesGUIDs[0] = go->GetGUID();
|
||||
break;
|
||||
case GO_PORT_TRAP_GATE_2:
|
||||
go->UpdateSaveToDb(true);
|
||||
_trapGatesGUIDs[1] = go->GetGUID();
|
||||
break;
|
||||
case GO_PORT_TRAP_GATE_3:
|
||||
go->UpdateSaveToDb(true);
|
||||
_trapGatesGUIDs[2] = go->GetGUID();
|
||||
break;
|
||||
case GO_PORT_TRAP_GATE_4:
|
||||
go->UpdateSaveToDb(true);
|
||||
_trapGatesGUIDs[3] = go->GetGUID();
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -57,6 +57,11 @@ enum CreatureIds
|
||||
|
||||
enum GameobjectIds
|
||||
{
|
||||
GO_CRUSADER_SQUARE_DOOR = 175967,
|
||||
GO_HOARD_DOOR = 175968,
|
||||
GO_HALL_OF_HIGH_COMMAND = 176194,
|
||||
GO_GAUNTLET_DOOR_1 = 175357,
|
||||
GO_GAUNTLET_DOOR_2 = 175356,
|
||||
GO_ZIGGURAT_DOORS1 = 175380, // baroness
|
||||
GO_ZIGGURAT_DOORS2 = 175379, // nerub'enkan
|
||||
GO_ZIGGURAT_DOORS3 = 175381, // maleki
|
||||
|
||||
Reference in New Issue
Block a user