diff --git a/server/gameserver/creature.h b/server/gameserver/creature.h index 0ff67ab..c6b1231 100644 --- a/server/gameserver/creature.h +++ b/server/gameserver/creature.h @@ -3,7 +3,6 @@ #include "weakptr.h" #include "moveableentity.h" #include "buff.h" -#include "weakptr.h" #include "trigger.h" #include "ability.h" diff --git a/server/gameserver/hero.ai.cc b/server/gameserver/hero.ai.cc index df7a1d5..1d742a3 100644 --- a/server/gameserver/hero.ai.cc +++ b/server/gameserver/hero.ai.cc @@ -8,36 +8,6 @@ #include "metamgr.h" #include "player.h" -enum HeroState_e : int -{ - HSE_Idle = 0, - HSE_Thinking = 1, - HSE_Attack = 2, - HSE_RandomWalk = 3, - HSE_Pursuit = 4, - HSE_FollowMaster = 5 -}; - -class HeroAINode -{ -public: - HeroState_e main_state = HSE_Idle; - long long frameno = 0; - long long exec_frame_num = 0; - long long start_shot_frameno = 0; - long long next_random_move_frameno = 0; - int shot_times = 0; - int total_shot_times = 0; - int next_total_shot_times = 0; - - long long param1 = 0; - CreatureWeakPtr target; - CreatureWeakPtr nearest_human; - long long last_check_nearest_human_frameno = 0; - a8::Vec2 shot_dir; - a8::Vec2 target_pos; -}; - HeroAI::HeroAI() { node_ = new HeroAINode(); diff --git a/server/gameserver/hero.ai.h b/server/gameserver/hero.ai.h index 9cc5c73..9ea7954 100644 --- a/server/gameserver/hero.ai.h +++ b/server/gameserver/hero.ai.h @@ -1,10 +1,40 @@ #pragma once +#include + #include "aicomponent.h" #include "weakptr.h" -enum HeroState_e : int; -class HeroAINode; +enum HeroState_e : int +{ + HSE_Idle = 0, + HSE_Thinking = 1, + HSE_Attack = 2, + HSE_RandomWalk = 3, + HSE_Pursuit = 4, + HSE_FollowMaster = 5 +}; + +class HeroAINode +{ +public: + HeroState_e main_state = HSE_Idle; + long long frameno = 0; + long long exec_frame_num = 0; + long long start_shot_frameno = 0; + long long next_random_move_frameno = 0; + int shot_times = 0; + int total_shot_times = 0; + int next_total_shot_times = 0; + + long long param1 = 0; + CreatureWeakPtr target; + CreatureWeakPtr nearest_human; + long long last_check_nearest_human_frameno = 0; + a8::Vec2 shot_dir; + a8::Vec2 target_pos; +}; + class HeroAI : public AIComponent { public: diff --git a/server/gameserver/roomobstacle.cc b/server/gameserver/roomobstacle.cc index 633649f..91b580a 100644 --- a/server/gameserver/roomobstacle.cc +++ b/server/gameserver/roomobstacle.cc @@ -14,6 +14,7 @@ RoomObstacle::RoomObstacle():Obstacle() { + weak_ptr_chunk_.Set(this); } RoomObstacle::~RoomObstacle() @@ -549,3 +550,18 @@ void RoomObstacle::ProcKeepRangeBuff() room->xtimer.DeleteTimer(room->xtimer.GetRunningTimer()); } } + +RoomObstacleWeakPtr RoomObstacle::AllocWeakPtr() +{ + RoomObstacleWeakPtr ptr; + ptr.Attach(this); + return ptr; +} + +RoomObstacleWeakPtr& RoomObstacle::GetWeakPtrRef() +{ + if (!weak_ptr_.Get()) { + weak_ptr_.Attach(this); + } + return weak_ptr_; +} diff --git a/server/gameserver/roomobstacle.h b/server/gameserver/roomobstacle.h index b10596c..d2adc2c 100644 --- a/server/gameserver/roomobstacle.h +++ b/server/gameserver/roomobstacle.h @@ -1,5 +1,6 @@ #pragma once +#include "weakptr.h" #include "gridservice.h" #include "obstacle.h" #include "weakptr.h" @@ -28,6 +29,10 @@ class RoomObstacle : public Obstacle virtual void Die(Room* room) override; Entity* GetRealObject(Room* room); + RoomObstacleWeakPtrChunk* GetWeakPtrChunk() { return &weak_ptr_chunk_; }; + RoomObstacleWeakPtr AllocWeakPtr(); + RoomObstacleWeakPtr& GetWeakPtrRef(); + private: void SpecExplosion(); void ActiveSelfExplosion(); @@ -44,6 +49,9 @@ private: void ProcKeepRangeBuff(); protected: + RoomObstacleWeakPtr weak_ptr_; + RoomObstacleWeakPtrChunk weak_ptr_chunk_; + std::set* grid_list_ = nullptr; int explosion_times_ = 0; bool detached_ = false; diff --git a/server/gameserver/weakptr.cc b/server/gameserver/weakptr.cc index f1912f2..f13d65b 100644 --- a/server/gameserver/weakptr.cc +++ b/server/gameserver/weakptr.cc @@ -1,6 +1,7 @@ #include "precompile.h" #include "weakptr.h" #include "creature.h" +#include "roomobstacle.h" CreatureWeakPtrChunk::CreatureWeakPtrChunk() { @@ -109,3 +110,111 @@ void CreatureWeakPtr::Detach() list_del_init(&entry_); } } + +RoomObstacleWeakPtrChunk::RoomObstacleWeakPtrChunk() +{ + INIT_LIST_HEAD(&ptrs_); +} + +RoomObstacleWeakPtrChunk::~RoomObstacleWeakPtrChunk() +{ + Clear(); +} + +void RoomObstacleWeakPtrChunk::Clear() +{ + struct RoomObstacleWeakPtr *weakptr, *tmp; + struct list_head ptr_list; + + list_replace_init(&ptrs_, &ptr_list); + list_for_each_entry_safe(weakptr, tmp, &ptr_list, entry_) { + weakptr->Reset(); + } +} + +void RoomObstacleWeakPtrChunk::Set(RoomObstacle* c) +{ + ptr_ = c; +} + +RoomObstacleWeakPtr::RoomObstacleWeakPtr() +{ + INIT_LIST_HEAD(&entry_); +} + +RoomObstacleWeakPtr::RoomObstacleWeakPtr(const RoomObstacleWeakPtr& x) +{ + INIT_LIST_HEAD(&entry_); + if (x.ptr_) { + Attach(x.ptr_); + } +} + +RoomObstacleWeakPtr::RoomObstacleWeakPtr(RoomObstacleWeakPtr&& x) +{ + INIT_LIST_HEAD(&entry_); + if (x.ptr_) { + Attach(x.ptr_); + x.Detach(); + } +} + +RoomObstacleWeakPtr& RoomObstacleWeakPtr::operator=(const RoomObstacleWeakPtr& x) +{ + if (ptr_) { + Detach(); + } + if (x.ptr_) { + Attach(x.ptr_); + } + return *this; +} + +RoomObstacleWeakPtr&& RoomObstacleWeakPtr::operator=(RoomObstacleWeakPtr&& x) +{ + if (ptr_) { + Detach(); + } + if (x.ptr_) { + Attach(x.ptr_); + x.Detach(); + } + abort(); + // return *this; +} + +RoomObstacleWeakPtr::~RoomObstacleWeakPtr() +{ + Reset(); +} + +void RoomObstacleWeakPtr::Reset() +{ + if (ptr_) { + Detach(); + } +} + +RoomObstacle* RoomObstacleWeakPtr::Get() +{ + return ptr_; +} + +void RoomObstacleWeakPtr::Attach(RoomObstacle* c) +{ + Reset(); + RoomObstacleWeakPtrChunk* chunk = c->GetWeakPtrChunk(); + if (c != chunk->ptr_) { + abort(); + } + ptr_ = c; + list_add_tail(&entry_, &chunk->ptrs_); +} + +void RoomObstacleWeakPtr::Detach() +{ + if (ptr_) { + ptr_ = nullptr; + list_del_init(&entry_); + } +} diff --git a/server/gameserver/weakptr.h b/server/gameserver/weakptr.h index 25d78e8..3fb14ad 100644 --- a/server/gameserver/weakptr.h +++ b/server/gameserver/weakptr.h @@ -41,3 +41,42 @@ class CreatureWeakPtr friend class CreatureWeakPtrChunk; }; + +class RoomObstacle; + +class RoomObstacleWeakPtrChunk +{ + public: + + RoomObstacleWeakPtrChunk(); + ~RoomObstacleWeakPtrChunk(); + void Clear(); + void Set(RoomObstacle* c); + + private: + RoomObstacle* ptr_ = nullptr; + list_head ptrs_; + friend class RoomObstacleWeakPtr; +}; + +class RoomObstacleWeakPtr +{ + public: + + RoomObstacleWeakPtr(); + RoomObstacleWeakPtr(const RoomObstacleWeakPtr& x); + RoomObstacleWeakPtr(RoomObstacleWeakPtr&& x); + RoomObstacleWeakPtr& operator=(const RoomObstacleWeakPtr& x); + RoomObstacleWeakPtr&& operator=(RoomObstacleWeakPtr&& x); + ~RoomObstacleWeakPtr(); + void Reset(); + RoomObstacle* Get(); + void Attach(RoomObstacle* c); + void Detach(); + + private: + RoomObstacle* ptr_ = nullptr; + list_head entry_; + + friend class RoomObstacleWeakPtrChunk; +};