// // 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 #include #include 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; private: using Plane = std::map; std::map 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