diff --git a/src/engine/core/handler.cpp b/src/engine/core/handler.cpp index aa7a1d61c..c73d6651c 100644 --- a/src/engine/core/handler.cpp +++ b/src/engine/core/handler.cpp @@ -39,7 +39,6 @@ #include "gameplay/core/base_stats.h" #include "utils/utils_time.h" #include "gameplay/classes/pc_classes.h" -#include "gameplay/core/obj_decay_manager.h" using classes::CalcCircleSlotsAmount; @@ -459,7 +458,7 @@ void PlaceObjToInventory(ObjData *object, CharData *ch) { if (!ch->IsNpc() || (ch->has_master() && !ch->get_master()->IsNpc())) { object->set_extra_flag(EObjFlag::kTicktimer); // start timer unconditionally when character picks item up. - obj_decay_manager.insert(object); + world_objects.decay_manager().insert(object); ArrangeObjs(object, &ch->carrying); } else { // Вот эта муть, чтобы временно обойти завязку магазинов на порядке предметов в инве моба // Krodo @@ -1303,8 +1302,8 @@ bool PlaceObjToRoom(ObjData *object, RoomRnum room) { object->set_destroyer(kRoomDestroyTimer); } if (object->get_type() != EObjType::kFountain && !object->has_flag(EObjFlag::kNodecay)) { - obj_decay_manager.insert(object); - obj_decay_manager.add_env_check(object); + world_objects.decay_manager().insert(object); + world_objects.decay_manager().add_env_check(object); } return true; } @@ -1394,7 +1393,7 @@ void RemoveObjFromRoom(ObjData *object) { object->set_in_room(kNowhere); object->set_next_content(nullptr); - obj_decay_manager.remove_env_check(object); + world_objects.decay_manager().remove_env_check(object); } void PlaceObjIntoObj(ObjData *obj, ObjData *obj_to) { @@ -1543,7 +1542,6 @@ void ExtractObjFromWorld(ObjData *obj, bool showlog) { check_auction(nullptr, obj); check_exchange(obj); - obj_decay_manager.remove(obj); obj->get_script()->set_purged(); world_objects.remove(obj); // if (showlog); diff --git a/src/engine/db/obj_save.cpp b/src/engine/db/obj_save.cpp index dd123b56c..5d0509e87 100644 --- a/src/engine/db/obj_save.cpp +++ b/src/engine/db/obj_save.cpp @@ -22,7 +22,6 @@ #include "gameplay/mechanics/named_stuff.h" #include "engine/core/utils_char_obj.inl" #include "gameplay/mechanics/stable_objs.h" -#include "gameplay/core/obj_decay_manager.h" #include "gameplay/mechanics/weather.h" #include "utils/utils_time.h" #include "player_index.h" @@ -533,7 +532,7 @@ ObjData::shared_ptr read_one_object_new(char **data, int *error) { } ConvertDrinkconSkillField(object.get(), false); object->remove_incorrect_values_keys(object->get_type()); - obj_decay_manager.insert(object.get()); + world_objects.decay_manager().insert(object.get()); return (object); } diff --git a/src/engine/db/world_objects.cpp b/src/engine/db/world_objects.cpp index 4dcffac21..a6dedb1f7 100644 --- a/src/engine/db/world_objects.cpp +++ b/src/engine/db/world_objects.cpp @@ -189,6 +189,7 @@ void WorldObjects::remove(ObjData *object) { m_zone_to_object_ptr[object_ptr->get_vnum() / 100].erase(object_ptr); m_random_trigger_objs.erase(object); m_named_objs.erase(object); + m_decay_manager.remove(object); m_objects_list.erase(object_i->second); m_object_raw_ptr_to_object_ptr.erase(object); diff --git a/src/engine/db/world_objects.h b/src/engine/db/world_objects.h index 953b32050..3caa9dd31 100644 --- a/src/engine/db/world_objects.h +++ b/src/engine/db/world_objects.h @@ -3,6 +3,7 @@ #include "id.h" #include "engine/entities/obj_data.h" +#include "gameplay/core/obj_decay_manager.h" #include #include @@ -80,6 +81,7 @@ class WorldObjects { void foreach_random_trigger_obj(const std::function &function) const; void foreach_named_obj(const std::function &function) const; void update_obj_indices(ObjData *obj); + ObjDecayManager &decay_manager() { return m_decay_manager; } ObjData::shared_ptr find_if(const predicate_f &predicate) const; ObjData::shared_ptr find_if(const predicate_f &predicate, int number) const; ObjData::shared_ptr find_if_and_dec_number(const predicate_f &predicate, int &number) const; @@ -119,6 +121,7 @@ class WorldObjects { zone_to_object_ptr_t m_zone_to_object_ptr; std::unordered_set m_random_trigger_objs; std::unordered_set m_named_objs; + ObjDecayManager m_decay_manager; WO_IDChangeObserver::shared_ptr m_id_change_observer; WO_RNumChangeObserver::shared_ptr m_rnum_change_observer; diff --git a/src/engine/entities/obj_data.cpp b/src/engine/entities/obj_data.cpp index f891681ab..57f0754a4 100644 --- a/src/engine/entities/obj_data.cpp +++ b/src/engine/entities/obj_data.cpp @@ -6,7 +6,6 @@ #include "engine/db/obj_save.h" #include "engine/db/world_objects.h" -#include "gameplay/core/obj_decay_manager.h" #include "utils/parse.h" #include "engine/core/handler.h" #include "engine/ui/color.h" @@ -632,18 +631,18 @@ void ObjData::set_tag(const char *tag) { void ObjData::set_timer(int timer) { CObjectPrototype::set_timer(timer); - obj_decay_manager.on_timer_changed(this); + world_objects.decay_manager().on_timer_changed(this); } int ObjData::get_timer() const { - if (!obj_decay_manager.contains(this)) { + if (!world_objects.decay_manager().contains(this)) { return CObjectPrototype::get_timer(); } - auto deadline = obj_decay_manager.get_deadline(this); + auto deadline = world_objects.decay_manager().get_deadline(this); if (deadline == UINT64_MAX) { return CObjectPrototype::UNLIMITED_TIMER; } - auto now = obj_decay_manager.current_mud_hour(); + auto now = world_objects.decay_manager().current_mud_hour(); if (deadline <= now) { return 0; } @@ -832,7 +831,7 @@ void ObjData::add_timed_spell(const ESpell spell_id, const int time) { } m_timed_spell.add(this, spell_id, time); if (time > 0) { - obj_decay_manager.add_timed_spell_obj(this); + world_objects.decay_manager().add_timed_spell_obj(this); } } diff --git a/src/engine/ui/cmd/do_get.cpp b/src/engine/ui/cmd/do_get.cpp index fcc1fde4b..f3904eeea 100644 --- a/src/engine/ui/cmd/do_get.cpp +++ b/src/engine/ui/cmd/do_get.cpp @@ -6,7 +6,7 @@ #include "engine/core/utils_char_obj.inl" #include "gameplay/economics/currencies.h" #include "gameplay/mechanics/groups.h" -#include "gameplay/core/obj_decay_manager.h" +#include "engine/db/world_objects.h" #include @@ -225,7 +225,7 @@ int perform_get_from_room(CharData *ch, ObjData *obj) { if (CanTakeObj(ch, obj) && get_otrigger(obj, ch) && bloody::handle_transfer(nullptr, ch, obj)) { RemoveObjFromRoom(obj); if (ch->IsNpc() && !obj->has_flag(EObjFlag::kTicktimer)) { - obj_decay_manager.remove(obj); + world_objects.decay_manager().remove(obj); } PlaceObjToInventory(obj, ch); if (obj->get_carried_by() == ch) { diff --git a/src/gameplay/core/game_limits.cpp b/src/gameplay/core/game_limits.cpp index 463e894d8..a948d97a8 100644 --- a/src/gameplay/core/game_limits.cpp +++ b/src/gameplay/core/game_limits.cpp @@ -42,7 +42,6 @@ #include "gameplay/mechanics/damage.h" #include "gameplay/mechanics/bonus.h" #include "gameplay/ai/mobact.h" -#include "gameplay/core/obj_decay_manager.h" #include @@ -1374,7 +1373,7 @@ void charmee_obj_decay_tell(CharData *charmee, ObjData *obj, ECharmeeObjPos obj_ void obj_point_update() { utils::CExecutionTimer timer; - auto tick_result = obj_decay_manager.process_tick(); + auto tick_result = world_objects.decay_manager().process_tick(); for (auto it : tick_result.env_destroy) { ExtractObjFromWorld(it); @@ -1515,7 +1514,7 @@ void obj_point_update() { ExtractObjFromWorld(j); } } - log("obj_point_update stop, size %ld, delta %f", obj_decay_manager.size(), timer.delta().count()); + log("obj_point_update stop, size %ld, delta %f", world_objects.decay_manager().size(), timer.delta().count()); } diff --git a/src/gameplay/core/obj_decay_manager.cpp b/src/gameplay/core/obj_decay_manager.cpp index a96688cc4..5df7861b9 100644 --- a/src/gameplay/core/obj_decay_manager.cpp +++ b/src/gameplay/core/obj_decay_manager.cpp @@ -6,8 +6,6 @@ #include "gameplay/core/game_limits.h" #include "gameplay/mechanics/stable_objs.h" -ObjDecayManager obj_decay_manager; - void ObjDecayManager::insert(ObjData *obj) { if (!obj) { return; diff --git a/src/gameplay/core/obj_decay_manager.h b/src/gameplay/core/obj_decay_manager.h index 34aa71768..265783fb0 100644 --- a/src/gameplay/core/obj_decay_manager.h +++ b/src/gameplay/core/obj_decay_manager.h @@ -53,8 +53,6 @@ class ObjDecayManager { std::unordered_set m_timed_spell_objs; }; -extern ObjDecayManager obj_decay_manager; - #endif // OBJ_DECAY_MANAGER_H_ // vim: ts=4 sw=4 tw=0 noet syntax=cpp : diff --git a/tests/obj_decay_manager.cpp b/tests/obj_decay_manager.cpp index 5594721d7..75fca60b3 100644 --- a/tests/obj_decay_manager.cpp +++ b/tests/obj_decay_manager.cpp @@ -1,8 +1,10 @@ -#include "gameplay/core/obj_decay_manager.h" +#include "engine/db/world_objects.h" #include "engine/entities/obj_data.h" #include +#define decay_mgr world_objects.decay_manager() + class ObjDecayManagerTest : public ::testing::Test { protected: void SetUp() override { @@ -11,7 +13,7 @@ class ObjDecayManagerTest : public ::testing::Test { void TearDown() override { for (auto &obj : objs_) { - obj_decay_manager.remove(obj.get()); + decay_mgr.remove(obj.get()); } objs_.clear(); } @@ -33,49 +35,49 @@ class ObjDecayManagerTest : public ::testing::Test { TEST_F(ObjDecayManagerTest, InsertAndSize) { auto obj = make_obj(100); - auto before = obj_decay_manager.size(); + auto before = decay_mgr.size(); - obj_decay_manager.insert(obj.get()); - EXPECT_EQ(obj_decay_manager.size(), before + 1); - EXPECT_TRUE(obj_decay_manager.contains(obj.get())); + decay_mgr.insert(obj.get()); + EXPECT_EQ(decay_mgr.size(), before + 1); + EXPECT_TRUE(decay_mgr.contains(obj.get())); } TEST_F(ObjDecayManagerTest, RemoveCleansUp) { auto obj = make_obj(100); - obj_decay_manager.insert(obj.get()); - obj_decay_manager.add_env_check(obj.get()); - obj_decay_manager.add_timed_spell_obj(obj.get()); - - auto ts_before = obj_decay_manager.timed_spell_size(); - obj_decay_manager.remove(obj.get()); - EXPECT_FALSE(obj_decay_manager.contains(obj.get())); - EXPECT_EQ(obj_decay_manager.timed_spell_size(), ts_before - 1); + decay_mgr.insert(obj.get()); + decay_mgr.add_env_check(obj.get()); + decay_mgr.add_timed_spell_obj(obj.get()); + + auto ts_before = decay_mgr.timed_spell_size(); + decay_mgr.remove(obj.get()); + EXPECT_FALSE(decay_mgr.contains(obj.get())); + EXPECT_EQ(decay_mgr.timed_spell_size(), ts_before - 1); } TEST_F(ObjDecayManagerTest, ProcessTick_NoExpiry) { auto obj = make_obj(100); - obj_decay_manager.insert(obj.get()); + decay_mgr.insert(obj.get()); - auto result = obj_decay_manager.process_tick(); + auto result = decay_mgr.process_tick(); EXPECT_TRUE(result.decay_timer.empty()); EXPECT_TRUE(result.env_destroy.empty()); - EXPECT_TRUE(obj_decay_manager.contains(obj.get())); + EXPECT_TRUE(decay_mgr.contains(obj.get())); } TEST_F(ObjDecayManagerTest, ProcessTick_ExpiresAfterTimer) { auto obj = make_obj(3); - obj_decay_manager.insert(obj.get()); + decay_mgr.insert(obj.get()); - obj_decay_manager.process_tick(); // tick 1 - EXPECT_TRUE(obj_decay_manager.contains(obj.get())); + decay_mgr.process_tick(); // tick 1 + EXPECT_TRUE(decay_mgr.contains(obj.get())); - obj_decay_manager.process_tick(); // tick 2 - EXPECT_TRUE(obj_decay_manager.contains(obj.get())); + decay_mgr.process_tick(); // tick 2 + EXPECT_TRUE(decay_mgr.contains(obj.get())); - auto result = obj_decay_manager.process_tick(); // tick 3 - expires + auto result = decay_mgr.process_tick(); // tick 3 - expires EXPECT_EQ(result.decay_timer.size(), 1u); EXPECT_EQ(result.decay_timer.front(), obj.get()); - EXPECT_FALSE(obj_decay_manager.contains(obj.get())); + EXPECT_FALSE(decay_mgr.contains(obj.get())); } TEST_F(ObjDecayManagerTest, MultipleObjects_ExpireInOrder) { @@ -83,102 +85,102 @@ TEST_F(ObjDecayManagerTest, MultipleObjects_ExpireInOrder) { auto obj2 = make_obj(3); auto obj3 = make_obj(2); - obj_decay_manager.insert(obj1.get()); - obj_decay_manager.insert(obj2.get()); - obj_decay_manager.insert(obj3.get()); + decay_mgr.insert(obj1.get()); + decay_mgr.insert(obj2.get()); + decay_mgr.insert(obj3.get()); - auto r1 = obj_decay_manager.process_tick(); + auto r1 = decay_mgr.process_tick(); EXPECT_EQ(r1.decay_timer.size(), 1u); EXPECT_EQ(r1.decay_timer.front(), obj1.get()); - auto r2 = obj_decay_manager.process_tick(); + auto r2 = decay_mgr.process_tick(); EXPECT_EQ(r2.decay_timer.size(), 1u); EXPECT_EQ(r2.decay_timer.front(), obj3.get()); - auto r3 = obj_decay_manager.process_tick(); + auto r3 = decay_mgr.process_tick(); EXPECT_EQ(r3.decay_timer.size(), 1u); EXPECT_EQ(r3.decay_timer.front(), obj2.get()); } TEST_F(ObjDecayManagerTest, Remove_PreventsExpiry) { auto obj = make_obj(2); - obj_decay_manager.insert(obj.get()); - obj_decay_manager.remove(obj.get()); + decay_mgr.insert(obj.get()); + decay_mgr.remove(obj.get()); - obj_decay_manager.process_tick(); - auto result = obj_decay_manager.process_tick(); + decay_mgr.process_tick(); + auto result = decay_mgr.process_tick(); EXPECT_TRUE(result.decay_timer.empty()); } TEST_F(ObjDecayManagerTest, OnTimerChanged_ShortenDeadline) { auto obj = make_obj(100); - obj_decay_manager.insert(obj.get()); + decay_mgr.insert(obj.get()); static_cast(*obj).set_timer(2); - obj_decay_manager.on_timer_changed(obj.get()); + decay_mgr.on_timer_changed(obj.get()); - obj_decay_manager.process_tick(); - auto result = obj_decay_manager.process_tick(); + decay_mgr.process_tick(); + auto result = decay_mgr.process_tick(); EXPECT_EQ(result.decay_timer.size(), 1u); } TEST_F(ObjDecayManagerTest, OnTimerChanged_ExtendDeadline) { auto obj = make_obj(2); - obj_decay_manager.insert(obj.get()); + decay_mgr.insert(obj.get()); static_cast(*obj).set_timer(50); - obj_decay_manager.on_timer_changed(obj.get()); + decay_mgr.on_timer_changed(obj.get()); - obj_decay_manager.process_tick(); - auto result = obj_decay_manager.process_tick(); + decay_mgr.process_tick(); + auto result = decay_mgr.process_tick(); EXPECT_TRUE(result.decay_timer.empty()); - EXPECT_TRUE(obj_decay_manager.contains(obj.get())); + EXPECT_TRUE(decay_mgr.contains(obj.get())); } TEST_F(ObjDecayManagerTest, OnTimerChanged_UntrackedIsNoop) { auto obj = make_obj(100); - auto before = obj_decay_manager.size(); - obj_decay_manager.on_timer_changed(obj.get()); - EXPECT_EQ(obj_decay_manager.size(), before); + auto before = decay_mgr.size(); + decay_mgr.on_timer_changed(obj.get()); + EXPECT_EQ(decay_mgr.size(), before); } TEST_F(ObjDecayManagerTest, InsertDuplicate_UpdatesDeadline) { auto obj = make_obj(10); - obj_decay_manager.insert(obj.get()); - auto size_after_first = obj_decay_manager.size(); + decay_mgr.insert(obj.get()); + auto size_after_first = decay_mgr.size(); static_cast(*obj).set_timer(2); - obj_decay_manager.insert(obj.get()); // second insert = update - EXPECT_EQ(obj_decay_manager.size(), size_after_first); + decay_mgr.insert(obj.get()); // second insert = update + EXPECT_EQ(decay_mgr.size(), size_after_first); - obj_decay_manager.process_tick(); - auto result = obj_decay_manager.process_tick(); + decay_mgr.process_tick(); + auto result = decay_mgr.process_tick(); EXPECT_EQ(result.decay_timer.size(), 1u); } TEST_F(ObjDecayManagerTest, TimedSpellTracking) { auto obj = make_obj(100); - auto before = obj_decay_manager.timed_spell_size(); + auto before = decay_mgr.timed_spell_size(); - obj_decay_manager.add_timed_spell_obj(obj.get()); - EXPECT_EQ(obj_decay_manager.timed_spell_size(), before + 1); + decay_mgr.add_timed_spell_obj(obj.get()); + EXPECT_EQ(decay_mgr.timed_spell_size(), before + 1); - obj_decay_manager.remove_timed_spell_obj(obj.get()); - EXPECT_EQ(obj_decay_manager.timed_spell_size(), before); + decay_mgr.remove_timed_spell_obj(obj.get()); + EXPECT_EQ(decay_mgr.timed_spell_size(), before); } TEST_F(ObjDecayManagerTest, GetDeadline_Tracked) { auto obj = make_obj(5); - obj_decay_manager.insert(obj.get()); + decay_mgr.insert(obj.get()); - auto now = obj_decay_manager.current_mud_hour(); - auto dl = obj_decay_manager.get_deadline(obj.get()); + auto now = decay_mgr.current_mud_hour(); + auto dl = decay_mgr.get_deadline(obj.get()); EXPECT_EQ(dl, now + 5); } TEST_F(ObjDecayManagerTest, GetDeadline_Untracked) { auto obj = make_obj(5); - auto dl = obj_decay_manager.get_deadline(obj.get()); + auto dl = decay_mgr.get_deadline(obj.get()); EXPECT_EQ(dl, UINT64_MAX); }