Added tile class and "avoid at distance" support to RMGen.
This was SVN commit r2659.
This commit is contained in:
parent
436de9b0ff
commit
b071585610
@ -27,13 +27,10 @@ JSFunctionSpec globalFunctions[] = {
|
||||
{"placeObject", placeObject, 5},
|
||||
{"createArea", createArea, 3},
|
||||
{"createObjectGroup", createObjectGroup, 2},
|
||||
{"createTileClass", createTileClass, 0},
|
||||
{0, 0, 0}
|
||||
};
|
||||
|
||||
// Some global variables used for the API
|
||||
map<Area*, int> areaToId;
|
||||
vector<Area*> areas;
|
||||
|
||||
// Helper function to validate argument types; the types string can contain the following:
|
||||
// i (integers), s (strings), n (numbers), . (anything); for example ValidateArgs("iin",...)
|
||||
// would check that arguments 1 and 2 are integers while the third is a number.
|
||||
@ -279,10 +276,7 @@ JSBool createArea(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *
|
||||
*rval = INT_TO_JSVAL(0);
|
||||
}
|
||||
else {
|
||||
areas.push_back(area);
|
||||
int id = areas.size();
|
||||
areaToId[area] = id;
|
||||
*rval = INT_TO_JSVAL(id);
|
||||
*rval = INT_TO_JSVAL(theMap->areas.size());
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
@ -309,16 +303,24 @@ JSBool createObjectGroup(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
||||
constr = new NullConstraint();
|
||||
}
|
||||
|
||||
vector<Object*>* ret = theMap->createObjectGroup(placer, constr);
|
||||
bool ret = theMap->createObjectGroup(placer, constr);
|
||||
|
||||
delete placer;
|
||||
delete constr;
|
||||
|
||||
if(!ret) {
|
||||
*rval = INT_TO_JSVAL(0);
|
||||
}
|
||||
else {
|
||||
*rval = INT_TO_JSVAL(1);
|
||||
}
|
||||
*rval = ret;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool createTileClass(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
CheckInit(true, cx, __FUNCTION__);
|
||||
if(argc != 0) {
|
||||
JS_ReportError(cx, "createTileClass: expected 0 arguments but got %d", argc);
|
||||
}
|
||||
|
||||
int id = theMap->createTileClass();
|
||||
|
||||
*rval = INT_TO_JSVAL(id);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
@ -30,4 +30,7 @@ JSBool placeObject(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval
|
||||
JSBool createArea(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
JSBool createObjectGroup(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
|
||||
// Tile class functions
|
||||
JSBool createTileClass(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
|
||||
#endif
|
@ -11,6 +11,20 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
bool GetTileClassField(JSContext* cx, jsval obj, const char* name, TileClass*& ret) {
|
||||
jsval val;
|
||||
if(!GetJsvalField(cx, obj, name, val)) return false;
|
||||
if(JSVAL_IS_NULL(val)) {
|
||||
ret = 0;
|
||||
return true;
|
||||
}
|
||||
if(!JSVAL_IS_INT(val)) return false;
|
||||
int id = JSVAL_TO_INT(val);
|
||||
if(id < 0 || id > theMap->tileClasses.size()) return false;
|
||||
ret = (id==0? 0 : theMap->tileClasses[id-1]);
|
||||
return true;
|
||||
}
|
||||
|
||||
int GetType(JSContext* cx, jsval val) {
|
||||
int ret;
|
||||
if(!GetIntField(cx, val, "TYPE", ret)) return 0;
|
||||
@ -87,6 +101,7 @@ AreaPainter* ParseAreaPainter(JSContext* cx, jsval val) {
|
||||
float elevation;
|
||||
int type;
|
||||
int blendRadius;
|
||||
TileClass* tileClass;
|
||||
vector<Terrain*> terrains;
|
||||
vector<int> widths;
|
||||
|
||||
@ -111,6 +126,10 @@ AreaPainter* ParseAreaPainter(JSContext* cx, jsval val) {
|
||||
if(!GetFloatField(cx, val, "elevation", elevation)) return 0;
|
||||
return new ElevationPainter(elevation);
|
||||
|
||||
case TYPE_TILE_CLASS_PAINTER:
|
||||
if(!GetTileClassField(cx, val, "tileClass", tileClass)) return 0;
|
||||
return new TileClassPainter(tileClass);
|
||||
|
||||
case TYPE_SMOOTH_ELEVATION_PAINTER:
|
||||
if(!GetIntField(cx, val, "type", type)) return 0;
|
||||
if(!GetFloatField(cx, val, "elevation", elevation)) return 0;
|
||||
@ -168,6 +187,7 @@ ObjectGroupPlacer* ParseObjectGroupPlacer(JSContext* cx, jsval val) {
|
||||
jsval jsv;
|
||||
vector<jsval> array;
|
||||
int x, y;
|
||||
TileClass* tileClass;
|
||||
vector<SimpleGroup::Element*> elements;
|
||||
|
||||
switch(GetType(cx, val)) {
|
||||
@ -175,6 +195,7 @@ ObjectGroupPlacer* ParseObjectGroupPlacer(JSContext* cx, jsval val) {
|
||||
// convert x and y
|
||||
if(!GetIntField(cx, val, "x", x)) return 0;
|
||||
if(!GetIntField(cx, val, "y", y)) return 0;
|
||||
if(!GetTileClassField(cx, val, "tileClass", tileClass)) return 0;
|
||||
// convert the elements (which will be JS SimpleElement objects)
|
||||
if(!GetJsvalField(cx, val, "elements", jsv)) return 0;
|
||||
if(!ParseArray(cx, jsv, array)) return 0;
|
||||
@ -188,7 +209,7 @@ ObjectGroupPlacer* ParseObjectGroupPlacer(JSContext* cx, jsval val) {
|
||||
if(!GetFloatField(cx, array[i], "distance", distance)) return 0;
|
||||
elements[i] = new SimpleGroup::Element(type, count, distance);
|
||||
}
|
||||
return new SimpleGroup(elements, x, y);
|
||||
return new SimpleGroup(elements, tileClass, x, y);
|
||||
|
||||
default:
|
||||
return 0;
|
||||
@ -198,6 +219,8 @@ ObjectGroupPlacer* ParseObjectGroupPlacer(JSContext* cx, jsval val) {
|
||||
Constraint* ParseConstraint(JSContext* cx, jsval val) {
|
||||
vector<jsval> array;
|
||||
int areaId;
|
||||
TileClass* tileClass;
|
||||
float distance;
|
||||
string texture;
|
||||
jsval jsv, jsv2;
|
||||
|
||||
@ -229,6 +252,11 @@ Constraint* ParseConstraint(JSContext* cx, jsval val) {
|
||||
if(!GetStringField(cx, val, "texture", texture)) return 0;
|
||||
return new AvoidTextureConstraint(theMap->getId(texture));
|
||||
|
||||
case TYPE_AVOID_TILE_CLASS_CONSTRAINT:
|
||||
if(!GetFloatField(cx, val, "distance", distance)) return 0;
|
||||
if(!GetTileClassField(cx, val, "tileClass", tileClass)) return 0;
|
||||
return new AvoidTileClassConstraint(tileClass, distance);
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
@ -20,7 +20,9 @@ const int
|
||||
TYPE_AVOID_TEXTURE_CONSTRAINT = 7,
|
||||
TYPE_ELEVATION_PAINTER = 8,
|
||||
TYPE_SMOOTH_ELEVATION_PAINTER = 9,
|
||||
TYPE_SIMPLE_GROUP = 10;
|
||||
TYPE_SIMPLE_GROUP = 10,
|
||||
TYPE_AVOID_TILE_CLASS_CONSTRAINT = 11,
|
||||
TYPE_TILE_CLASS_PAINTER = 12;
|
||||
|
||||
// Helper functions to convert objects from JS versions
|
||||
|
||||
|
@ -4,7 +4,6 @@
|
||||
#include "object.h"
|
||||
#include "pmp_file.h"
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
Map::Map(int size, Terrain* baseTerrain, float baseHeight) {
|
||||
@ -280,13 +279,12 @@ Area* Map::createArea(AreaPlacer* placer, AreaPainter* painter, Constraint* cons
|
||||
return a;
|
||||
}
|
||||
|
||||
vector<Object*>* Map::createObjectGroup(ObjectGroupPlacer* placer, Constraint* constr) {
|
||||
vector<Object*>* objects = new vector<Object*>;
|
||||
if(!placer->place(this, constr, *objects)) {
|
||||
return 0;
|
||||
}
|
||||
for(int i=0; i<objects->size(); i++) {
|
||||
addObject((*objects)[i]);
|
||||
}
|
||||
return objects;
|
||||
bool Map::createObjectGroup(ObjectGroupPlacer* placer, Constraint* constr) {
|
||||
return placer->place(this, constr);
|
||||
}
|
||||
|
||||
int Map::createTileClass() {
|
||||
tileClasses.push_back(new TileClass(size));
|
||||
return tileClasses.size();
|
||||
}
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "object.h"
|
||||
#include "terrain.h"
|
||||
#include "objectgroupplacer.h"
|
||||
#include "tileclass.h"
|
||||
|
||||
class Map {
|
||||
public:
|
||||
@ -20,6 +21,7 @@ public:
|
||||
std::map<int, std::string> idToName;
|
||||
std::vector<Object*> objects;
|
||||
std::vector<Area*> areas;
|
||||
std::vector<TileClass*> tileClasses;
|
||||
|
||||
Map(int size, Terrain* baseTerrain, float baseHeight);
|
||||
Map(std::string fileName, int loadLevel);
|
||||
@ -44,7 +46,9 @@ public:
|
||||
void addObject(class Object* ent);
|
||||
|
||||
Area* createArea(AreaPlacer* placer, AreaPainter* painter, Constraint* constr);
|
||||
std::vector<Object*>* createObjectGroup(ObjectGroupPlacer* placer, Constraint* constr);
|
||||
bool createObjectGroup(ObjectGroupPlacer* placer, Constraint* constr);
|
||||
|
||||
int createTileClass(); // returns ID of the new class
|
||||
};
|
||||
|
||||
#endif
|
@ -7,7 +7,7 @@
|
||||
class ObjectGroupPlacer
|
||||
{
|
||||
public:
|
||||
virtual bool place(class Map* m, Constraint* constr, std::vector<Object*>& ret) = 0;
|
||||
virtual bool place(class Map* m, Constraint* constr) = 0;
|
||||
|
||||
ObjectGroupPlacer(void);
|
||||
virtual ~ObjectGroupPlacer(void);
|
||||
|
49
source/tools/rmgen/rangecount.cpp
Normal file
49
source/tools/rmgen/rangecount.cpp
Normal file
@ -0,0 +1,49 @@
|
||||
#include "stdafx.h"
|
||||
#include "rangecount.h"
|
||||
|
||||
RangeCount::RangeCount(int size) {
|
||||
nn = 1;
|
||||
while(nn < size) {
|
||||
nn *= 2;
|
||||
}
|
||||
vals = new int[2*nn];
|
||||
memset(vals, 0, 2*nn*sizeof(int));
|
||||
}
|
||||
|
||||
RangeCount::~RangeCount() {
|
||||
delete[] vals;
|
||||
}
|
||||
|
||||
int RangeCount::get(int pos) {
|
||||
return vals[nn + pos];
|
||||
}
|
||||
|
||||
void RangeCount::set(int pos, int amt) {
|
||||
add(pos, amt-get(pos));
|
||||
}
|
||||
|
||||
void RangeCount::add(int pos, int amt) {
|
||||
for(int s=nn; s>0; s/=2) {
|
||||
vals[s + pos] += amt;
|
||||
pos /= 2;
|
||||
}
|
||||
}
|
||||
|
||||
int RangeCount::get(int start, int end) {
|
||||
int ret = 0;
|
||||
int i;
|
||||
for(i=1; start+i<=end; i*=2) {
|
||||
if(start & i) {
|
||||
ret += vals[nn/i + start/i];
|
||||
start += i;
|
||||
}
|
||||
}
|
||||
while(i) {
|
||||
if(start+i <= end) {
|
||||
ret += vals[nn/i + start/i];
|
||||
start += i;
|
||||
}
|
||||
i /= 2;
|
||||
}
|
||||
return ret;
|
||||
}
|
17
source/tools/rmgen/rangecount.h
Normal file
17
source/tools/rmgen/rangecount.h
Normal file
@ -0,0 +1,17 @@
|
||||
#ifndef __RANGECOUNT_H__
|
||||
#define __RANGECOUNT_H__
|
||||
|
||||
class RangeCount {
|
||||
private:
|
||||
int* vals; // has size 2*nn
|
||||
int nn; // smallest power of 2 >= size
|
||||
public:
|
||||
RangeCount(int size);
|
||||
~RangeCount();
|
||||
void set(int pos, int amt);
|
||||
void add(int pos, int amt);
|
||||
int get(int pos);
|
||||
int get(int start, int end);
|
||||
};
|
||||
|
||||
#endif
|
@ -156,6 +156,9 @@
|
||||
<File
|
||||
RelativePath=".\random.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\rangecount.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\rectplacer.cpp">
|
||||
</File>
|
||||
@ -192,6 +195,9 @@
|
||||
<File
|
||||
RelativePath=".\terrain.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\tileclass.cpp">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
@ -242,6 +248,9 @@
|
||||
<File
|
||||
RelativePath=".\random.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\rangecount.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\rectplacer.h">
|
||||
</File>
|
||||
@ -266,6 +275,9 @@
|
||||
<File
|
||||
RelativePath=".\terrain.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\tileclass.h">
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
|
@ -3,36 +3,16 @@
|
||||
|
||||
using namespace std;
|
||||
|
||||
// NullConstraint
|
||||
// NullConstraint /////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool NullConstraint::allows(Map* m, int x, int y)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// AvoidAreaConstraint
|
||||
|
||||
AvoidAreaConstraint::AvoidAreaConstraint(Area* area) {
|
||||
this->area = area;
|
||||
}
|
||||
|
||||
bool AvoidAreaConstraint::allows(Map* m, int x, int y)
|
||||
{
|
||||
return m->area[x][y] != area;
|
||||
}
|
||||
|
||||
// AvoidTextureConstraint
|
||||
|
||||
AvoidTextureConstraint::AvoidTextureConstraint(int textureId) {
|
||||
this->textureId = textureId;
|
||||
}
|
||||
|
||||
bool AvoidTextureConstraint::allows(Map* m, int x, int y)
|
||||
{
|
||||
return m->texture[x][y] != textureId;
|
||||
}
|
||||
|
||||
// AndConstraint
|
||||
// AndConstraint /////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AndConstraint::AndConstraint(const vector<Constraint*>& constraints) {
|
||||
this->constraints = constraints;
|
||||
@ -53,3 +33,46 @@ bool AndConstraint::allows(Map* m, int x, int y)
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// AvoidAreaConstraint //////////////////////////////////////////////////////////////////
|
||||
|
||||
AvoidAreaConstraint::AvoidAreaConstraint(Area* area) {
|
||||
this->area = area;
|
||||
}
|
||||
|
||||
bool AvoidAreaConstraint::allows(Map* m, int x, int y)
|
||||
{
|
||||
return m->area[x][y] != area;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// AvoidTextureConstraint ///////////////////////////////////////////////////////////////
|
||||
|
||||
AvoidTextureConstraint::AvoidTextureConstraint(int textureId) {
|
||||
this->textureId = textureId;
|
||||
}
|
||||
|
||||
bool AvoidTextureConstraint::allows(Map* m, int x, int y)
|
||||
{
|
||||
return m->texture[x][y] != textureId;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// AvoidTileClassConstraint /////////////////////////////////////////////////////////////
|
||||
|
||||
AvoidTileClassConstraint::AvoidTileClassConstraint(TileClass* tileClass, float distance) {
|
||||
this->tileClass = tileClass;
|
||||
this->distance = distance;
|
||||
}
|
||||
|
||||
bool AvoidTileClassConstraint::allows(Map* m, int x, int y)
|
||||
{
|
||||
return !tileClass->hasTilesInRadius(x, y, distance);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -4,12 +4,22 @@
|
||||
#include "constraint.h"
|
||||
#include "map.h"
|
||||
#include "area.h"
|
||||
#include "tileclass.h"
|
||||
|
||||
class NullConstraint : public Constraint {
|
||||
public:
|
||||
virtual bool allows(Map* m, int x, int y);
|
||||
};
|
||||
|
||||
class AndConstraint : public Constraint {
|
||||
private:
|
||||
std::vector<Constraint*> constraints;
|
||||
public:
|
||||
AndConstraint(const std::vector<Constraint*>& constraints);
|
||||
~AndConstraint();
|
||||
virtual bool allows(Map* m, int x, int y);
|
||||
};
|
||||
|
||||
class AvoidAreaConstraint : public Constraint {
|
||||
private:
|
||||
Area* area;
|
||||
@ -26,13 +36,14 @@ public:
|
||||
virtual bool allows(Map* m, int x, int y);
|
||||
};
|
||||
|
||||
class AndConstraint : public Constraint {
|
||||
class AvoidTileClassConstraint : public Constraint {
|
||||
private:
|
||||
std::vector<Constraint*> constraints;
|
||||
TileClass* tileClass;
|
||||
float distance;
|
||||
public:
|
||||
AndConstraint(const std::vector<Constraint*>& constraints);
|
||||
~AndConstraint();
|
||||
AvoidTileClassConstraint(TileClass* tileClass, float distance);
|
||||
virtual bool allows(Map* m, int x, int y);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
@ -22,8 +22,8 @@ bool SimpleGroup::Element::place(int cx, int cy, Map* m, Constraint* constr, vec
|
||||
for(int i=0; i<count; i++) {
|
||||
while(true) {
|
||||
float ang = RandFloat()*2*PI;
|
||||
float x = cx + distance*cos(ang);
|
||||
float y = cy + distance*sin(ang);
|
||||
float x = cx + distance*cos(ang) + 0.5f;
|
||||
float y = cy + distance*sin(ang) + 0.5f;
|
||||
int ix = (int) x;
|
||||
int iy = (int) y;
|
||||
if(m->validT(ix, iy) && constr->allows(m, ix, iy)) {
|
||||
@ -41,17 +41,24 @@ bool SimpleGroup::Element::place(int cx, int cy, Map* m, Constraint* constr, vec
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SimpleGroup::place(Map* m, Constraint* constr, vector<Object*>& ret) {
|
||||
bool SimpleGroup::place(Map* m, Constraint* constr) {
|
||||
vector<Object*> ret;
|
||||
for(int i=0; i<elements.size(); i++) {
|
||||
if(!elements[i]->place(x, y, m, constr, ret)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
for(int i=0; i<ret.size(); i++) {
|
||||
m->addObject(ret[i]);
|
||||
if(tileClass != 0) {
|
||||
tileClass->add((int) ret[i]->x, (int) ret[i]->y);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
SimpleGroup::SimpleGroup(vector<SimpleGroup::Element*>& e, int _x, int _y):
|
||||
elements(e), x(_x), y(_y)
|
||||
SimpleGroup::SimpleGroup(vector<SimpleGroup::Element*>& e, TileClass* tc, int _x, int _y):
|
||||
elements(e), x(_x), y(_y), tileClass(tc)
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
#define __SIMPLEGROUP_H__
|
||||
|
||||
#include "objectgroupplacer.h"
|
||||
#include "tileclass.h"
|
||||
|
||||
class SimpleGroup : public ObjectGroupPlacer
|
||||
{
|
||||
@ -21,10 +22,11 @@ public:
|
||||
|
||||
std::vector<Element*> elements;
|
||||
int x, y;
|
||||
TileClass* tileClass;
|
||||
|
||||
virtual bool place(class Map* m, Constraint* constr, std::vector<Object*>& ret);
|
||||
virtual bool place(class Map* m, Constraint* constr);
|
||||
|
||||
SimpleGroup(std::vector<Element*>& elements, int x, int y);
|
||||
SimpleGroup(std::vector<Element*>& elements, TileClass* tileClass, int x, int y);
|
||||
virtual ~SimpleGroup(void);
|
||||
};
|
||||
|
||||
|
@ -52,3 +52,19 @@ void MultiPainter::paint(Map* m, Area* a)
|
||||
painters[i]->paint(m, a);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TileClassPainter
|
||||
|
||||
TileClassPainter::TileClassPainter(TileClass* tc)
|
||||
{
|
||||
this->tileClass = tc;
|
||||
}
|
||||
|
||||
void TileClassPainter::paint(Map* m, Area* a)
|
||||
{
|
||||
for (int i=0; i<a->points.size(); i++) {
|
||||
Point p = a->points[i];
|
||||
tileClass->add(p.x, p.y);
|
||||
}
|
||||
}
|
@ -5,6 +5,7 @@
|
||||
#include "map.h"
|
||||
#include "area.h"
|
||||
#include "terrain.h"
|
||||
#include "tileclass.h"
|
||||
|
||||
class TerrainPainter : public AreaPainter {
|
||||
Terrain* terrain;
|
||||
@ -20,6 +21,13 @@ public:
|
||||
virtual void paint(Map* m, Area* a);
|
||||
};
|
||||
|
||||
class TileClassPainter : public AreaPainter {
|
||||
TileClass* tileClass;
|
||||
public:
|
||||
TileClassPainter(TileClass* tc);
|
||||
virtual void paint(Map* m, Area* a);
|
||||
};
|
||||
|
||||
class MultiPainter : public AreaPainter {
|
||||
std::vector<AreaPainter*> painters;
|
||||
public:
|
||||
|
66
source/tools/rmgen/tileclass.cpp
Normal file
66
source/tools/rmgen/tileclass.cpp
Normal file
@ -0,0 +1,66 @@
|
||||
#include "stdafx.h"
|
||||
#include "tileclass.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
TileClass::TileClass(int mapSize) {
|
||||
this->mapSize = mapSize;
|
||||
for(int i=0; i<mapSize; i++) {
|
||||
rc.push_back(new RangeCount(mapSize));
|
||||
}
|
||||
}
|
||||
|
||||
TileClass::~TileClass() {
|
||||
for(int i=0; i<mapSize; i++) {
|
||||
delete rc[i];
|
||||
}
|
||||
}
|
||||
|
||||
void TileClass::add(int x, int y) {
|
||||
rc[y]->add(x, 1);
|
||||
|
||||
tiles.insert(Point(x, y));
|
||||
}
|
||||
|
||||
void TileClass::remove(int x, int y) {
|
||||
rc[y]->add(x, -1);
|
||||
|
||||
if(rc[y]->get(x) == 0) {
|
||||
tiles.erase(Point(x, y));
|
||||
}
|
||||
}
|
||||
|
||||
bool TileClass::hasTilesInRadius(float cx, float cy, float r) {
|
||||
// special check for really small classes
|
||||
if(tiles.size() < 4*r) {
|
||||
for(set<Point>::iterator it = tiles.begin(); it != tiles.end(); it++) {
|
||||
Point p = *it;
|
||||
float dx = p.x - cx;
|
||||
float dy = p.y - cy;
|
||||
if(dx*dx + dy*dy <= r*r) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
for(float y = cy-r; y <= cy+r; y++) {
|
||||
int iy = (int) y;
|
||||
if(iy < 0 || iy >= mapSize) {
|
||||
continue;
|
||||
}
|
||||
|
||||
float dy = y - cy;
|
||||
float dx = sqrt(r*r - dy*dy);
|
||||
float x1 = cx - dx;
|
||||
float x2 = cx + dx;
|
||||
int minX = max(0, (int) x1);
|
||||
int maxX = min(mapSize-1, (int) x2);
|
||||
if(rc[iy]->get(minX, maxX+1) > 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
27
source/tools/rmgen/tileclass.h
Normal file
27
source/tools/rmgen/tileclass.h
Normal file
@ -0,0 +1,27 @@
|
||||
#ifndef __TILECLASS_H__
|
||||
#define __TILECLASS_H__
|
||||
|
||||
#include "point.h"
|
||||
#include "rangecount.h"
|
||||
|
||||
// Represents a multiset of tiles, used for constraints. That is, each tile
|
||||
// can be in the class one or more times. Provides operations to add/remove a tile
|
||||
// (if a tile is added N times it has to be removed N times to be cleared), and to
|
||||
// efficiently find whether any tiles in the class are within distance D of a point
|
||||
// (this will take O(D log D) time).
|
||||
class TileClass {
|
||||
private:
|
||||
int mapSize;
|
||||
std::vector<RangeCount*> rc; // range count on each row
|
||||
std::set<Point> tiles; // the distinct tiles in the class
|
||||
public:
|
||||
TileClass(int mapSize);
|
||||
~TileClass();
|
||||
|
||||
void add(int x, int y);
|
||||
void remove(int x, int y);
|
||||
|
||||
bool hasTilesInRadius(float cx, float cy, float r);
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user