mirror of
https://github.com/whoahq/whoa.git
synced 2026-02-02 00:32:45 +03:00
Some checks are pending
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:cl compiler_name:MSVC cxx:cl os:windows-latest system_name:Windows test_path:WhoaTest]) (push) Waiting to run
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:clang compiler_name:Clang cxx:clang++ os:macos-latest system_name:macOS test_path:WhoaTest]) (push) Waiting to run
Push / ${{ matrix.build.system_name }} / ${{ matrix.build.build_type }} / ${{ matrix.build.compiler_name }} (map[build_type:Release cc:gcc compiler_name:GCC cxx:g++ os:ubuntu-latest system_name:Linux test_path:WhoaTest]) (push) Waiting to run
172 lines
4.5 KiB
C++
172 lines
4.5 KiB
C++
#include "object/client/Util.hpp"
|
|
#include "object/client/CClientObjCreate.hpp"
|
|
#include "object/client/CGContainer_C.hpp"
|
|
#include "object/client/CGCorpse_C.hpp"
|
|
#include "object/client/CGDynamicObject_C.hpp"
|
|
#include "object/client/CGGameObject_C.hpp"
|
|
#include "object/client/CGItem_C.hpp"
|
|
#include "object/client/CGObject_C.hpp"
|
|
#include "object/client/CGPlayer_C.hpp"
|
|
#include "object/client/CGUnit_C.hpp"
|
|
#include "object/client/ObjMgr.hpp"
|
|
#include <common/Time.hpp>
|
|
|
|
CGObject_C* FindActiveObject(WOWGUID guid) {
|
|
return ClntObjMgrGetCurrent()->m_objects.Ptr(guid, CHashKeyGUID(guid));
|
|
}
|
|
|
|
/**
|
|
* Given an object type and collection age, free the object at the head of that type's FIFO queue
|
|
* if it was disabled longer ago than the collection age. Only frees at most one object per call.
|
|
*/
|
|
void GarbageCollect(OBJECT_TYPE_ID typeID, uint32_t collectAgeMs) {
|
|
auto object = ClntObjMgrGetCurrent()->m_lazyCleanupFifo[typeID - 1].Head();
|
|
|
|
if (!object) {
|
|
return;
|
|
}
|
|
|
|
uint32_t disableAgeMs = OsGetAsyncTimeMsPrecise() - object->m_disableTimeMs;
|
|
|
|
if (disableAgeMs < collectAgeMs) {
|
|
return;
|
|
}
|
|
|
|
ClntObjMgrGetCurrent()->m_lazyCleanupObjects.Unlink(object);
|
|
object->m_link.Unlink();
|
|
|
|
ClntObjMgrFreeObject(object);
|
|
}
|
|
|
|
CGObject_C* GetUpdateObject(WOWGUID guid, int32_t* reenable) {
|
|
*reenable = false;
|
|
|
|
// Active object
|
|
|
|
auto activeObject = FindActiveObject(guid);
|
|
|
|
if (activeObject) {
|
|
activeObject->SetDisablePending(false);
|
|
|
|
return activeObject;
|
|
}
|
|
|
|
// Disabled object
|
|
|
|
auto disabledObject = ClntObjMgrGetCurrent()->m_lazyCleanupObjects.Ptr(guid, CHashKeyGUID(guid));
|
|
|
|
if (disabledObject) {
|
|
ClntObjMgrGetCurrent()->m_lazyCleanupObjects.Unlink(disabledObject);
|
|
disabledObject->m_link.Unlink();
|
|
|
|
ClntObjMgrGetCurrent()->m_objects.Insert(disabledObject, guid, CHashKeyGUID(guid));
|
|
|
|
// These link checks are guaranteed to pass because of the unlink above (both lists share
|
|
// the same link). This check is either from an inlined function or is cruft left behind
|
|
// after a refactor.
|
|
if (
|
|
!ClntObjMgrGetCurrent()->m_visibleObjects.IsLinked(disabledObject)
|
|
&& !ClntObjMgrGetCurrent()->m_reenabledObjects.IsLinked(disabledObject)
|
|
) {
|
|
*reenable = true;
|
|
ClntObjMgrGetCurrent()->m_reenabledObjects.LinkToTail(disabledObject);
|
|
}
|
|
|
|
return disabledObject;
|
|
}
|
|
|
|
// Object not found
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
int32_t HandleObjectOutOfRangePass1(CGObject_C* object, OUT_OF_RANGE_TYPE type) {
|
|
// TODO arena unit out of range handling
|
|
|
|
object->HandleOutOfRange(type);
|
|
|
|
if (object->IsObjectLocked()) {
|
|
object->SetDisablePending(true);
|
|
|
|
return false;
|
|
}
|
|
|
|
object->SetDisablePending(false);
|
|
object->Disable();
|
|
|
|
return true;
|
|
}
|
|
|
|
void HandleObjectOutOfRangePass2(CGObject_C* object) {
|
|
// TODO ClearObjectMirrorHandlers(object);
|
|
|
|
ClntObjMgrGetCurrent()->m_objects.Unlink(object);
|
|
|
|
if (ClntObjMgrGetCurrent()->m_visibleObjects.IsLinked(object)) {
|
|
ClntObjMgrGetCurrent()->m_visibleObjects.UnlinkNode(object);
|
|
}
|
|
|
|
ClntObjMgrGetCurrent()->m_lazyCleanupObjects.Insert(object, object->m_hashval, CHashKeyGUID(object->m_key));
|
|
ClntObjMgrGetCurrent()->m_lazyCleanupFifo[object->m_typeID - 1].LinkToTail(object);
|
|
}
|
|
|
|
void InitObject(CGObject_C* object, uint32_t time, CClientObjCreate& objCreate) {
|
|
switch (object->m_typeID) {
|
|
case ID_ITEM: {
|
|
new (object) CGItem_C(time, objCreate);
|
|
|
|
break;
|
|
}
|
|
|
|
case ID_CONTAINER: {
|
|
new (object) CGContainer_C(time, objCreate);
|
|
|
|
break;
|
|
}
|
|
|
|
case ID_UNIT: {
|
|
new (object) CGUnit_C(time, objCreate);
|
|
object->AddWorldObject();
|
|
|
|
break;
|
|
}
|
|
|
|
case ID_PLAYER: {
|
|
new (object) CGPlayer_C(time, objCreate);
|
|
object->AddWorldObject();
|
|
|
|
break;
|
|
}
|
|
|
|
case ID_GAMEOBJECT: {
|
|
new (object) CGGameObject_C(time, objCreate);
|
|
object->AddWorldObject();
|
|
|
|
break;
|
|
}
|
|
|
|
case ID_DYNAMICOBJECT: {
|
|
new (object) CGDynamicObject_C(time, objCreate);
|
|
object->AddWorldObject();
|
|
|
|
break;
|
|
}
|
|
|
|
case ID_CORPSE: {
|
|
new (object) CGCorpse_C(time, objCreate);
|
|
object->AddWorldObject();
|
|
|
|
break;
|
|
}
|
|
|
|
default: {
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
int32_t SkipPartialObjectUpdate(CDataStore* msg) {
|
|
// TODO
|
|
return 0;
|
|
}
|