implement SurroundMap & update AreaMap2D

This commit is contained in:
MihailRis
2024-09-10 20:34:26 +03:00
parent dc79c150da
commit fdefbda49f
5 changed files with 100 additions and 22 deletions
+43 -5
View File
@@ -4,25 +4,63 @@
#include <cstring>
#include <stdexcept>
SurroundMap::SurroundMap(int loadDistance, ubyte maxLevel)
SurroundMap::SurroundMap(int loadDistance, int8_t maxLevel)
: areaMap((loadDistance + maxLevel) * 2 + 1,
(loadDistance + maxLevel) * 2 + 1),
levelCallbacks(maxLevel),
maxLevel(maxLevel)
{}
void SurroundMap::setLevelCallback(int level, LevelCallback callback) {
levelCallbacks.at(level) = callback;
void SurroundMap::setLevelCallback(int8_t level, LevelCallback callback) {
auto& wrapper = levelCallbacks.at(level);
wrapper.callback = callback;
wrapper.active = callback != nullptr;
}
void SurroundMap::setOutCallback(util::AreaMap2D<ubyte>::OutCallback callback) {
void SurroundMap::setOutCallback(util::AreaMap2D<int8_t>::OutCallback callback) {
areaMap.setOutCallback(callback);
}
void SurroundMap::upgrade(int x, int y, int8_t level) {
auto& callback = levelCallbacks[level];
int size = maxLevel - level + 1;
for (int ly = -size+1; ly < size; ly++) {
for (int lx = -size+1; lx < size; lx++) {
int posX = lx + x;
int posY = ly + y;
int8_t sourceLevel = areaMap.get(posX, posY, 0);
if (sourceLevel < level-1) {
throw std::runtime_error("invalid map state");
}
if (sourceLevel >= level) {
continue;
}
areaMap.set(posX, posY, level);
if (callback.active) {
callback.callback(posX, posY);
}
}
}
}
void SurroundMap::completeAt(int x, int y) {
// TODO
if (!areaMap.isInside(x - maxLevel + 1, y - maxLevel + 1) ||
!areaMap.isInside(x + maxLevel - 1, y + maxLevel - 1)) {
throw std::invalid_argument(
"upgrade square is not fully inside of area");
}
for (int8_t level = 1; level <= maxLevel; level++) {
upgrade(x, y, level);
}
}
void SurroundMap::setCenter(int x, int y) {
areaMap.setCenter(x, y);
}
int8_t SurroundMap::at(int x, int y) {
if (auto ptr = areaMap.getIf(x, y)) {
return *ptr;
}
throw std::invalid_argument("position is out of area");
}
+24 -7
View File
@@ -1,6 +1,7 @@
#pragma once
#include <unordered_map>
#include <functional>
#define GLM_ENABLE_EXPERIMENTAL
#include <glm/gtx/hash.hpp>
@@ -10,18 +11,34 @@
class SurroundMap {
public:
using LevelCallback = std::function<void(ubyte)>;
using LevelCallback = std::function<void(int, int)>;
struct LevelCallbackWrapper {
LevelCallback callback;
bool active;
};
private:
util::AreaMap2D<ubyte> areaMap;
std::vector<LevelCallback> levelCallbacks;
ubyte maxLevel;
util::AreaMap2D<int8_t> areaMap;
std::vector<LevelCallbackWrapper> levelCallbacks;
int8_t maxLevel;
void upgrade(int x, int y, int8_t level);
public:
SurroundMap(int loadDistance, ubyte maxLevel);
SurroundMap(int loadDistance, int8_t maxLevel);
void setLevelCallback(int level, LevelCallback callback);
void setOutCallback(util::AreaMap2D<ubyte>::OutCallback callback);
/// @brief Callback called on point level increments
void setLevelCallback(int8_t level, LevelCallback callback);
/// @brief Callback called when non-zero value moves out of area
void setOutCallback(util::AreaMap2D<int8_t>::OutCallback callback);
/// @brief Upgrade point to maxLevel
/// @throws std::invalid_argument - upgrade square is not fully inside
void completeAt(int x, int y);
/// @brief Set map area center
void setCenter(int x, int y);
/// @brief Get level at position
/// @throws std::invalid_argument - position is out of area
int8_t at(int x, int y);
};