mirror of
https://github.com/DarkflameUniverse/DarkflameServer.git
synced 2025-10-15 20:08:14 +00:00
Grim LU
Wincent's attempt at making LU into something it isn't supposed to be, an ARPG.
This commit is contained in:
@@ -3,4 +3,6 @@ set(DZONEMANAGER_SOURCES "dZoneManager.cpp"
|
||||
"Spawner.cpp"
|
||||
"Zone.cpp")
|
||||
|
||||
add_library(dZoneManager STATIC ${DZONEMANAGER_SOURCES})
|
||||
#add_library(dZoneManager STATIC ${DZONEMANAGER_SOURCES})
|
||||
|
||||
set(DZONEMANAGER_SOURCES ${DZONEMANAGER_SOURCES} PARENT_SCOPE)
|
||||
|
@@ -6,6 +6,9 @@
|
||||
#include <functional>
|
||||
#include "GeneralUtils.h"
|
||||
#include "dZoneManager.h"
|
||||
#include "SpawnPatterns.h"
|
||||
|
||||
std::map<LOT, std::vector<std::pair<NiPoint3, float>>> Spawner::m_Ratings;
|
||||
|
||||
Spawner::Spawner(const SpawnerInfo info) {
|
||||
m_Info = info;
|
||||
@@ -69,6 +72,10 @@ Spawner::Spawner(const SpawnerInfo info) {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
m_SpawnPattern = SpawnPatterns::FindSpawnPatterns(m_Info.templateID);
|
||||
|
||||
m_LotsToCheck.push_back(m_Info.templateID);
|
||||
}
|
||||
|
||||
Spawner::~Spawner() {
|
||||
@@ -102,6 +109,95 @@ Entity* Spawner::Spawn(std::vector<SpawnerNode*> freeNodes, const bool force) {
|
||||
m_EntityInfo.spawnerID = m_Info.spawnerID;
|
||||
}
|
||||
|
||||
bool usedSpawnPattern = false;
|
||||
|
||||
if (m_SpawnPattern != nullptr) {
|
||||
auto pattern = m_SpawnPattern->GetSpawnPatterns();
|
||||
|
||||
// Check the area rating
|
||||
// std::map<LOT, std::vector<std::pair<NiPoint3, float>>> m_Ratings
|
||||
for (const auto& lot : m_LotsToCheck)
|
||||
{
|
||||
const auto& it = m_Ratings.find(lot);
|
||||
|
||||
int32_t rating = 0;
|
||||
|
||||
if (it != m_Ratings.end()) {
|
||||
// Check if we are within 50units of a rating
|
||||
for (const auto& ratingIt : it->second)
|
||||
{
|
||||
if (NiPoint3::DistanceSquared(ratingIt.first, m_EntityInfo.pos) <= 100.0f * 100.0f)
|
||||
{
|
||||
rating = ratingIt.second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& it : pattern)
|
||||
{
|
||||
if (it.first > rating) continue;
|
||||
|
||||
// Random number between 0 and 1
|
||||
float random = GeneralUtils::GenerateRandomNumber<float>(0, 1);
|
||||
|
||||
const auto& change = it.second.first;
|
||||
|
||||
if (random >= change) continue;
|
||||
|
||||
usedSpawnPattern = true;
|
||||
|
||||
Entity* first = nullptr;
|
||||
|
||||
for (const auto& spawn : it.second.second)
|
||||
{
|
||||
float angle = GeneralUtils::GenerateRandomNumber<float>(0, 360) * M_PI / 180.0f;
|
||||
float radius = GeneralUtils::GenerateRandomNumber<float>(0, 6);
|
||||
|
||||
float x = radius * cos(angle);
|
||||
float z = radius * sin(angle);
|
||||
|
||||
auto copy = m_EntityInfo;
|
||||
copy.pos.x += x;
|
||||
copy.pos.z += z;
|
||||
copy.lot = spawn;
|
||||
|
||||
if (std::find(m_LotsToCheck.begin(), m_LotsToCheck.end(), spawn) == m_LotsToCheck.end()) {
|
||||
m_LotsToCheck.push_back(spawn);
|
||||
}
|
||||
|
||||
Entity* rezdE = EntityManager::Instance()->CreateEntity(copy, nullptr);
|
||||
|
||||
rezdE->GetGroups() = m_Info.groups;
|
||||
|
||||
EntityManager::Instance()->ConstructEntity(rezdE);
|
||||
|
||||
m_Entities.insert({ rezdE->GetObjectID(), spawnNode });
|
||||
|
||||
spawnNode->entities.push_back(rezdE->GetObjectID());
|
||||
|
||||
for (const auto& cb : m_EntitySpawnedCallbacks) {
|
||||
cb(rezdE);
|
||||
}
|
||||
|
||||
if (first == nullptr) {
|
||||
first = rezdE;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
usedSpawnPattern = true;
|
||||
|
||||
if (m_Entities.size() == m_Info.amountMaintained) {
|
||||
m_NeedsUpdate = false;
|
||||
}
|
||||
|
||||
return first;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Entity* rezdE = EntityManager::Instance()->CreateEntity(m_EntityInfo, nullptr);
|
||||
|
||||
rezdE->GetGroups() = m_Info.groups;
|
||||
@@ -233,6 +329,65 @@ void Spawner::NotifyOfEntityDeath(const LWOOBJID& objectID) {
|
||||
if (m_SpawnOnSmash != nullptr) {
|
||||
m_SpawnOnSmash->Reset();
|
||||
}
|
||||
|
||||
const auto& lot = m_Info.templateID;
|
||||
|
||||
// Add to area rating
|
||||
// std::map<LOT, std::vector<std::pair<NiPoint3, float>>> m_Ratings
|
||||
// First check if the lot is in the map, if not, add it
|
||||
// Than check if there exist any ratings for that lot within 50units of the spawner
|
||||
// If there is, add 1 to the rating
|
||||
// If there isn't, add a new rating
|
||||
const auto& pos = node->position;
|
||||
|
||||
const auto& it2 = m_Ratings.find(lot);
|
||||
|
||||
if (it2 == m_Ratings.end()) {
|
||||
m_Ratings.insert({ lot, { { pos, 1.0f } } });
|
||||
} else {
|
||||
auto& ratings = it2->second;
|
||||
|
||||
bool found = false;
|
||||
for (auto& rating : ratings) {
|
||||
if (NiPoint3::DistanceSquared(rating.first, pos) < 100.0f * 100.0f) {
|
||||
rating.second += 1.0f;
|
||||
|
||||
Game::logger->Log("Spawner", "Rating %f", rating.second);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
ratings.push_back({ pos, 1.0f });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Spawner::UpdateRatings(float deltaTime) {
|
||||
// Loop through all ratings and decrease them by deltaTime
|
||||
for (auto& rating : m_Ratings) {
|
||||
for (auto& rating2 : rating.second) {
|
||||
rating2.second -= deltaTime * 0.1f;
|
||||
}
|
||||
}
|
||||
|
||||
// Loop through all ratings and remove any that are 0 or less
|
||||
for (auto it = m_Ratings.begin(); it != m_Ratings.end();) {
|
||||
for (auto it2 = it->second.begin(); it2 != it->second.end();) {
|
||||
if (it2->second <= 0.0f) {
|
||||
it2 = it->second.erase(it2);
|
||||
} else {
|
||||
++it2;
|
||||
}
|
||||
}
|
||||
|
||||
if (it->second.empty()) {
|
||||
it = m_Ratings.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Spawner::Activate() {
|
||||
|
@@ -10,6 +10,7 @@
|
||||
#include <functional>
|
||||
#include "LDFFormat.h"
|
||||
#include "EntityInfo.h"
|
||||
#include "SpawnPatterns.h"
|
||||
|
||||
struct SpawnerNode {
|
||||
NiPoint3 position = NiPoint3::ZERO;
|
||||
@@ -67,6 +68,8 @@ public:
|
||||
void SetNumToMaintain(int32_t value);
|
||||
bool GetIsSpawnSmashGroup() const { return m_SpawnSmashFoundGroup; };
|
||||
|
||||
static void UpdateRatings(float deltaTime);
|
||||
|
||||
SpawnerInfo m_Info;
|
||||
bool m_Active = true;
|
||||
private:
|
||||
@@ -82,6 +85,12 @@ private:
|
||||
int32_t m_AmountSpawned = 0;
|
||||
bool m_Start = false;
|
||||
Spawner* m_SpawnOnSmash = nullptr;
|
||||
|
||||
SpawnPatterns* m_SpawnPattern = nullptr;
|
||||
|
||||
std::vector<LOT> m_LotsToCheck = {};
|
||||
|
||||
static std::map<LOT, std::vector<std::pair<NiPoint3, float>>> m_Ratings;
|
||||
};
|
||||
|
||||
#endif // SPAWNER_H
|
||||
|
Reference in New Issue
Block a user