92 lines
2.7 KiB
C++
92 lines
2.7 KiB
C++
|
|
//
|
||
|
|
// PLANEMAP
|
||
|
|
//
|
||
|
|
// Stores a map of the items that are on each plane. Doesn't
|
||
|
|
// store terrain, only items.
|
||
|
|
//
|
||
|
|
// A plane is a rectangle, with a finite size: if you stray more
|
||
|
|
// than 80,000,000 meters from the origin, then you are beyond the
|
||
|
|
// edge of the plane.
|
||
|
|
//
|
||
|
|
// There's nothing stopping you from moving a PlaneItem farther
|
||
|
|
// than that. However, if you do move a PlaneItem farther than
|
||
|
|
// that, then it won't show up in radius-scans.
|
||
|
|
//
|
||
|
|
// The PlaneMap doesn't need you to "create" planes. You just
|
||
|
|
// set the plane of a PlaneItem to any string, and that plane will
|
||
|
|
// pop into existence if it wasn't already there.
|
||
|
|
//
|
||
|
|
// If you use the empty string as a plane name, a special case is
|
||
|
|
// triggered: you're "nowhere." Radius scans can never find items
|
||
|
|
// whose plane is the empty string.
|
||
|
|
//
|
||
|
|
// INHERITANCE
|
||
|
|
//
|
||
|
|
// The intent is that class Sprite should derive from PlaneItem.
|
||
|
|
// When you put sprites into a PlaneMap, it will work fine. However,
|
||
|
|
// when you scan the PlaneMap, it will give you PlaneItem pointers,
|
||
|
|
// not Sprite pointers. If you're sure that the PlaneMap contains
|
||
|
|
// only sprites, then you can use static_cast to convert those
|
||
|
|
// PlaneItem pointers to Sprite pointers. Sadly, there's no simple
|
||
|
|
// way to avoid the casting.
|
||
|
|
//
|
||
|
|
// MEMORY MANAGEMENT
|
||
|
|
//
|
||
|
|
// The PlaneMap does not own the PlaneItems. You need to create,
|
||
|
|
// destroy, and manage the PlaneItems yourself.
|
||
|
|
//
|
||
|
|
|
||
|
|
#ifndef PLANEMAP_HPP
|
||
|
|
#define PLANEMAP_HPP
|
||
|
|
|
||
|
|
#include <cstdint>
|
||
|
|
#include <vector>
|
||
|
|
#include <map>
|
||
|
|
|
||
|
|
class PlaneMap;
|
||
|
|
|
||
|
|
class PlaneItem {
|
||
|
|
friend class PlaneMap;
|
||
|
|
private:
|
||
|
|
PlaneMap *grid_;
|
||
|
|
std::string plane_;
|
||
|
|
double x_, y_, z_;
|
||
|
|
public:
|
||
|
|
PlaneItem();
|
||
|
|
~PlaneItem();
|
||
|
|
|
||
|
|
const std::string &plane() const { return plane_; }
|
||
|
|
const double x() const { return x_; }
|
||
|
|
const double y() const { return y_; }
|
||
|
|
const double z() const { return z_; }
|
||
|
|
|
||
|
|
void use_map(PlaneMap *map);
|
||
|
|
void set_pos(const std::string &plane, double x, double y, double z);
|
||
|
|
};
|
||
|
|
|
||
|
|
class PlaneMap {
|
||
|
|
friend class PlaneItem;
|
||
|
|
friend int cunittests_planemap(lua_State *L);
|
||
|
|
public:
|
||
|
|
using Elt = PlaneItem *;
|
||
|
|
using EltVec = std::vector<Elt>;
|
||
|
|
private:
|
||
|
|
using Plane = std::map<int64_t, EltVec>;
|
||
|
|
std::map<std::string, Plane> planes_;
|
||
|
|
void remove(const std::string &plane, int64_t cell, PlaneItem *client);
|
||
|
|
void insert(const std::string &plane, int64_t cell, PlaneItem *client);
|
||
|
|
private:
|
||
|
|
// These functions are only used in unit tests.
|
||
|
|
EltVec get_cell(const std::string &plane, int64_t cell) const;
|
||
|
|
int total_cells() const;
|
||
|
|
void clear() { planes_.clear(); }
|
||
|
|
public:
|
||
|
|
PlaneMap();
|
||
|
|
~PlaneMap();
|
||
|
|
EltVec scan_radius(const std::string &plane, double x, double y, double radius) const;
|
||
|
|
};
|
||
|
|
|
||
|
|
#endif // PLANEMAP_HPP
|
||
|
|
|
||
|
|
|