feat: add abnormal effects

This commit is contained in:
k0t9i
2023-01-25 01:56:21 +04:00
parent d6c15ee0c2
commit e0c7445ef7
12 changed files with 296 additions and 6 deletions

View File

@@ -7,12 +7,14 @@
#include "Factories/PlayerFactory.h"
#include "Factories/SkillFactory.h"
#include "Factories/ItemFactory.h"
#include "Factories/AbnormalEffectFactory.h"
#include "Repositories/DropRepository.h"
#include "Repositories/HeroRepository.h"
#include "Repositories/NPCRepository.h"
#include "Repositories/PlayerRepository.h"
#include "Repositories/SkillRepository.h"
#include "Repositories/ItemRepository.h"
#include "Repositories/AbnormalEffectRepository.h"
#include "GameStructs/NetworkHandlerWrapper.h"
#include "GameStructs/GameEngineWrapper.h"
#include "GameStructs/L2GameDataWrapper.h"
@@ -101,6 +103,16 @@ namespace Interlude
);
return result;
}
AbnormalEffectRepository& GetAbnormalEffectRepository() const override
{
static auto factory = AbnormalEffectFactory(GetL2GameData(), GetFName());
static EntityHandler handler;
static auto result = AbnormalEffectRepository(
factory,
handler
);
return result;
}
NetworkHandlerWrapper& GetNetworkHandler() const override
{
static NetworkHandlerWrapper result;

View File

@@ -0,0 +1,48 @@
#pragma once
#include <memory>
#include <map>
#include <chrono>
#include "../GameStructs/L2GameDataWrapper.h"
#include "../GameStructs/FName.h"
#include "../../../Common/Common.h"
#include "Domain/Entities/AbnormalEffect.h"
using namespace L2Bot::Domain;
namespace Interlude
{
class AbnormalEffectFactory
{
public:
AbnormalEffectFactory(const L2GameDataWrapper& l2GameData, const FName& fName) :
m_L2GameData(l2GameData),
m_FName(fName)
{
}
AbnormalEffectFactory() = delete;
virtual ~AbnormalEffectFactory() = default;
std::unique_ptr<Entities::AbnormalEffect> Create(const uint32_t skillId, const uint32_t level) const
{
const auto data = m_L2GameData.GetMSData(skillId, level);
const auto name = data && data->name ? data->name : L"";
const auto description = data && data->description ? data->description : L"";
const auto iconEntry = data ? m_FName.GetEntry(data->iconNameIndex) : nullptr;
return std::make_unique<Entities::AbnormalEffect>(
skillId,
static_cast<uint8_t>(level),
ConvertFromWideChar(name),
ConvertFromWideChar(description),
iconEntry ? ConvertFromWideChar(iconEntry->value) : ""
);
}
private:
const L2GameDataWrapper& m_L2GameData;
const FName& m_FName;
};
}

View File

@@ -0,0 +1,120 @@
#pragma once
#include <map>
#include <chrono>
#include <shared_mutex>
#include "Domain/Repositories/EntityRepositoryInterface.h"
#include "../Factories/AbnormalEffectFactory.h"
#include "../../../Events/AbnormalEffectChangedEvent.h"
#include "../../../Events/HeroDeletedEvent.h"
#include "../../../Events/EventDispatcher.h"
#include "../GameStructs/NetworkHandlerWrapper.h"
#include "../../../Services/EntityHandler.h"
using namespace L2Bot::Domain;
namespace Interlude
{
class AbnormalEffectRepository : public Repositories::EntityRepositoryInterface
{
public:
const std::vector<std::shared_ptr<DTO::EntityState>> GetEntities() override
{
std::unique_lock<std::shared_timed_mutex>(m_Mutex);
std::map<uint32_t, Entities::AbnormalEffect*> skillPtrs;
for (const auto& kvp : m_Effects)
{
skillPtrs[kvp.first] = kvp.second.get();
}
const auto objects = m_EntityHandler.GetEntities<Entities::AbnormalEffect*>(skillPtrs, [this](Entities::AbnormalEffect* item) {
return std::make_unique<Entities::AbnormalEffect>(item);
});
auto result = std::vector<std::shared_ptr<DTO::EntityState>>();
for (const auto kvp : objects)
{
result.push_back(kvp.second);
}
return result;
}
AbnormalEffectRepository(const AbnormalEffectFactory& factory, EntityHandler& handler) :
m_Factory(factory),
m_EntityHandler(handler)
{
EventDispatcher::GetInstance().Subscribe(AbnormalEffectChangedEvent::name, [this](const Event& evt) {
OnEffectToggled(evt);
});
EventDispatcher::GetInstance().Subscribe(HeroDeletedEvent::name, [this](const Event& evt) {
OnHeroDeleted(evt);
});
}
AbnormalEffectRepository() = delete;
virtual ~AbnormalEffectRepository()
{
Reset();
}
void Reset() override
{
std::shared_lock<std::shared_timed_mutex>(m_Mutex);
m_Effects.clear();
}
void OnHeroDeleted(const Event& evt)
{
std::shared_lock<std::shared_timed_mutex>(m_Mutex);
if (evt.GetName() == HeroDeletedEvent::name)
{
Reset();
}
}
void OnEffectToggled(const Event& evt)
{
std::shared_lock<std::shared_timed_mutex>(m_Mutex);
if (evt.GetName() == AbnormalEffectChangedEvent::name)
{
const auto casted = static_cast<const AbnormalEffectChangedEvent&>(evt);
const auto skillInfo = casted.GetSkillInfo();
std::map<uint32_t, int32_t> ids;
for (size_t i = 0; i < skillInfo.size(); i += 3)
{
const auto effectId = skillInfo[i];
const auto level = skillInfo[i + 1];
auto effect = m_Factory.Create(effectId, level);
m_Effects.emplace(effect->GetId(), std::move(effect));
ids[effectId] = effectId;
}
for (auto it = m_Effects.begin(); it != m_Effects.end();)
{
const auto& effect = it->second;
if (ids.find(effect->GetId()) == ids.end())
{
it = m_Effects.erase(it);
}
else
{
++it;
}
}
}
}
private:
const AbnormalEffectFactory& m_Factory;
std::map<uint32_t, std::unique_ptr<Entities::AbnormalEffect>> m_Effects;
std::shared_timed_mutex m_Mutex;
EntityHandler& m_EntityHandler;
};
}

View File

@@ -190,9 +190,9 @@ namespace Interlude
ids[skillInfo[i]] = skillInfo[i + 2];
}
for (auto it = m_Skills.begin(); it != m_Skills.end();)
for (const auto& kvp : m_Skills)
{
const auto& skill = it->second;
const auto& skill = kvp.second;
const auto needToToggle = ids.find(skill->GetId()) != ids.end();
// buff time less than zero means this is a aura
@@ -206,10 +206,6 @@ namespace Interlude
{
skill->UpdateToggle(true);
}
else
{
++it;
}
}
}
}

View File

@@ -22,6 +22,7 @@ public:
virtual Repositories::EntityRepositoryInterface& GetPlayerRepository() const = 0;
virtual Repositories::EntityRepositoryInterface& GetSkillRepository() const = 0;
virtual Repositories::EntityRepositoryInterface& GetItemRepository() const = 0;
virtual Repositories::EntityRepositoryInterface& GetAbnormalEffectRepository() const = 0;
virtual NetworkHandlerInterface& GetNetworkHandler() const = 0;
virtual GameEngineInterface& GetGameEngine() const = 0;
virtual L2GameDataInterface& GetL2GameData() const = 0;