implement SurroundMap & update AreaMap2D
This commit is contained in:
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user