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},
|
{"placeObject", placeObject, 5},
|
||||||
{"createArea", createArea, 3},
|
{"createArea", createArea, 3},
|
||||||
{"createObjectGroup", createObjectGroup, 2},
|
{"createObjectGroup", createObjectGroup, 2},
|
||||||
|
{"createTileClass", createTileClass, 0},
|
||||||
{0, 0, 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:
|
// Helper function to validate argument types; the types string can contain the following:
|
||||||
// i (integers), s (strings), n (numbers), . (anything); for example ValidateArgs("iin",...)
|
// 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.
|
// 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);
|
*rval = INT_TO_JSVAL(0);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
areas.push_back(area);
|
*rval = INT_TO_JSVAL(theMap->areas.size());
|
||||||
int id = areas.size();
|
|
||||||
areaToId[area] = id;
|
|
||||||
*rval = INT_TO_JSVAL(id);
|
|
||||||
}
|
}
|
||||||
return JS_TRUE;
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
@ -309,16 +303,24 @@ JSBool createObjectGroup(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
|
|||||||
constr = new NullConstraint();
|
constr = new NullConstraint();
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<Object*>* ret = theMap->createObjectGroup(placer, constr);
|
bool ret = theMap->createObjectGroup(placer, constr);
|
||||||
|
|
||||||
delete placer;
|
delete placer;
|
||||||
delete constr;
|
delete constr;
|
||||||
|
|
||||||
if(!ret) {
|
*rval = ret;
|
||||||
*rval = INT_TO_JSVAL(0);
|
return JS_TRUE;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
*rval = INT_TO_JSVAL(1);
|
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;
|
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 createArea(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||||
JSBool createObjectGroup(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
|
#endif
|
@ -11,6 +11,20 @@
|
|||||||
|
|
||||||
using namespace std;
|
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 GetType(JSContext* cx, jsval val) {
|
||||||
int ret;
|
int ret;
|
||||||
if(!GetIntField(cx, val, "TYPE", ret)) return 0;
|
if(!GetIntField(cx, val, "TYPE", ret)) return 0;
|
||||||
@ -87,6 +101,7 @@ AreaPainter* ParseAreaPainter(JSContext* cx, jsval val) {
|
|||||||
float elevation;
|
float elevation;
|
||||||
int type;
|
int type;
|
||||||
int blendRadius;
|
int blendRadius;
|
||||||
|
TileClass* tileClass;
|
||||||
vector<Terrain*> terrains;
|
vector<Terrain*> terrains;
|
||||||
vector<int> widths;
|
vector<int> widths;
|
||||||
|
|
||||||
@ -111,6 +126,10 @@ AreaPainter* ParseAreaPainter(JSContext* cx, jsval val) {
|
|||||||
if(!GetFloatField(cx, val, "elevation", elevation)) return 0;
|
if(!GetFloatField(cx, val, "elevation", elevation)) return 0;
|
||||||
return new ElevationPainter(elevation);
|
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:
|
case TYPE_SMOOTH_ELEVATION_PAINTER:
|
||||||
if(!GetIntField(cx, val, "type", type)) return 0;
|
if(!GetIntField(cx, val, "type", type)) return 0;
|
||||||
if(!GetFloatField(cx, val, "elevation", elevation)) return 0;
|
if(!GetFloatField(cx, val, "elevation", elevation)) return 0;
|
||||||
@ -168,6 +187,7 @@ ObjectGroupPlacer* ParseObjectGroupPlacer(JSContext* cx, jsval val) {
|
|||||||
jsval jsv;
|
jsval jsv;
|
||||||
vector<jsval> array;
|
vector<jsval> array;
|
||||||
int x, y;
|
int x, y;
|
||||||
|
TileClass* tileClass;
|
||||||
vector<SimpleGroup::Element*> elements;
|
vector<SimpleGroup::Element*> elements;
|
||||||
|
|
||||||
switch(GetType(cx, val)) {
|
switch(GetType(cx, val)) {
|
||||||
@ -175,6 +195,7 @@ ObjectGroupPlacer* ParseObjectGroupPlacer(JSContext* cx, jsval val) {
|
|||||||
// convert x and y
|
// convert x and y
|
||||||
if(!GetIntField(cx, val, "x", x)) return 0;
|
if(!GetIntField(cx, val, "x", x)) return 0;
|
||||||
if(!GetIntField(cx, val, "y", y)) 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)
|
// convert the elements (which will be JS SimpleElement objects)
|
||||||
if(!GetJsvalField(cx, val, "elements", jsv)) return 0;
|
if(!GetJsvalField(cx, val, "elements", jsv)) return 0;
|
||||||
if(!ParseArray(cx, jsv, array)) 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;
|
if(!GetFloatField(cx, array[i], "distance", distance)) return 0;
|
||||||
elements[i] = new SimpleGroup::Element(type, count, distance);
|
elements[i] = new SimpleGroup::Element(type, count, distance);
|
||||||
}
|
}
|
||||||
return new SimpleGroup(elements, x, y);
|
return new SimpleGroup(elements, tileClass, x, y);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
@ -198,6 +219,8 @@ ObjectGroupPlacer* ParseObjectGroupPlacer(JSContext* cx, jsval val) {
|
|||||||
Constraint* ParseConstraint(JSContext* cx, jsval val) {
|
Constraint* ParseConstraint(JSContext* cx, jsval val) {
|
||||||
vector<jsval> array;
|
vector<jsval> array;
|
||||||
int areaId;
|
int areaId;
|
||||||
|
TileClass* tileClass;
|
||||||
|
float distance;
|
||||||
string texture;
|
string texture;
|
||||||
jsval jsv, jsv2;
|
jsval jsv, jsv2;
|
||||||
|
|
||||||
@ -229,6 +252,11 @@ Constraint* ParseConstraint(JSContext* cx, jsval val) {
|
|||||||
if(!GetStringField(cx, val, "texture", texture)) return 0;
|
if(!GetStringField(cx, val, "texture", texture)) return 0;
|
||||||
return new AvoidTextureConstraint(theMap->getId(texture));
|
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:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,9 @@ const int
|
|||||||
TYPE_AVOID_TEXTURE_CONSTRAINT = 7,
|
TYPE_AVOID_TEXTURE_CONSTRAINT = 7,
|
||||||
TYPE_ELEVATION_PAINTER = 8,
|
TYPE_ELEVATION_PAINTER = 8,
|
||||||
TYPE_SMOOTH_ELEVATION_PAINTER = 9,
|
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
|
// Helper functions to convert objects from JS versions
|
||||||
|
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
#include "object.h"
|
#include "object.h"
|
||||||
#include "pmp_file.h"
|
#include "pmp_file.h"
|
||||||
|
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
Map::Map(int size, Terrain* baseTerrain, float baseHeight) {
|
Map::Map(int size, Terrain* baseTerrain, float baseHeight) {
|
||||||
@ -280,13 +279,12 @@ Area* Map::createArea(AreaPlacer* placer, AreaPainter* painter, Constraint* cons
|
|||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<Object*>* Map::createObjectGroup(ObjectGroupPlacer* placer, Constraint* constr) {
|
bool Map::createObjectGroup(ObjectGroupPlacer* placer, Constraint* constr) {
|
||||||
vector<Object*>* objects = new vector<Object*>;
|
return placer->place(this, constr);
|
||||||
if(!placer->place(this, constr, *objects)) {
|
}
|
||||||
return 0;
|
|
||||||
}
|
int Map::createTileClass() {
|
||||||
for(int i=0; i<objects->size(); i++) {
|
tileClasses.push_back(new TileClass(size));
|
||||||
addObject((*objects)[i]);
|
return tileClasses.size();
|
||||||
}
|
}
|
||||||
return objects;
|
|
||||||
}
|
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "object.h"
|
#include "object.h"
|
||||||
#include "terrain.h"
|
#include "terrain.h"
|
||||||
#include "objectgroupplacer.h"
|
#include "objectgroupplacer.h"
|
||||||
|
#include "tileclass.h"
|
||||||
|
|
||||||
class Map {
|
class Map {
|
||||||
public:
|
public:
|
||||||
@ -20,6 +21,7 @@ public:
|
|||||||
std::map<int, std::string> idToName;
|
std::map<int, std::string> idToName;
|
||||||
std::vector<Object*> objects;
|
std::vector<Object*> objects;
|
||||||
std::vector<Area*> areas;
|
std::vector<Area*> areas;
|
||||||
|
std::vector<TileClass*> tileClasses;
|
||||||
|
|
||||||
Map(int size, Terrain* baseTerrain, float baseHeight);
|
Map(int size, Terrain* baseTerrain, float baseHeight);
|
||||||
Map(std::string fileName, int loadLevel);
|
Map(std::string fileName, int loadLevel);
|
||||||
@ -44,7 +46,9 @@ public:
|
|||||||
void addObject(class Object* ent);
|
void addObject(class Object* ent);
|
||||||
|
|
||||||
Area* createArea(AreaPlacer* placer, AreaPainter* painter, Constraint* constr);
|
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
|
#endif
|
@ -7,7 +7,7 @@
|
|||||||
class ObjectGroupPlacer
|
class ObjectGroupPlacer
|
||||||
{
|
{
|
||||||
public:
|
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);
|
ObjectGroupPlacer(void);
|
||||||
virtual ~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
|
<File
|
||||||
RelativePath=".\random.cpp">
|
RelativePath=".\random.cpp">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\rangecount.cpp">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\rectplacer.cpp">
|
RelativePath=".\rectplacer.cpp">
|
||||||
</File>
|
</File>
|
||||||
@ -192,6 +195,9 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath=".\terrain.cpp">
|
RelativePath=".\terrain.cpp">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\tileclass.cpp">
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Header Files"
|
Name="Header Files"
|
||||||
@ -242,6 +248,9 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath=".\random.h">
|
RelativePath=".\random.h">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\rangecount.h">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\rectplacer.h">
|
RelativePath=".\rectplacer.h">
|
||||||
</File>
|
</File>
|
||||||
@ -266,6 +275,9 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath=".\terrain.h">
|
RelativePath=".\terrain.h">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath=".\tileclass.h">
|
||||||
|
</File>
|
||||||
</Filter>
|
</Filter>
|
||||||
<Filter
|
<Filter
|
||||||
Name="Resource Files"
|
Name="Resource Files"
|
||||||
|
@ -3,36 +3,16 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
// NullConstraint
|
// NullConstraint /////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
bool NullConstraint::allows(Map* m, int x, int y)
|
bool NullConstraint::allows(Map* m, int x, int y)
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// AvoidAreaConstraint
|
|
||||||
|
|
||||||
AvoidAreaConstraint::AvoidAreaConstraint(Area* area) {
|
|
||||||
this->area = area;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AvoidAreaConstraint::allows(Map* m, int x, int y)
|
// AndConstraint /////////////////////////////////////////////////////////////////////////
|
||||||
{
|
|
||||||
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(const vector<Constraint*>& constraints) {
|
AndConstraint::AndConstraint(const vector<Constraint*>& constraints) {
|
||||||
this->constraints = constraints;
|
this->constraints = constraints;
|
||||||
@ -52,4 +32,47 @@ bool AndConstraint::allows(Map* m, int x, int y)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
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 "constraint.h"
|
||||||
#include "map.h"
|
#include "map.h"
|
||||||
#include "area.h"
|
#include "area.h"
|
||||||
|
#include "tileclass.h"
|
||||||
|
|
||||||
class NullConstraint : public Constraint {
|
class NullConstraint : public Constraint {
|
||||||
public:
|
public:
|
||||||
virtual bool allows(Map* m, int x, int y);
|
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 {
|
class AvoidAreaConstraint : public Constraint {
|
||||||
private:
|
private:
|
||||||
Area* area;
|
Area* area;
|
||||||
@ -26,13 +36,14 @@ public:
|
|||||||
virtual bool allows(Map* m, int x, int y);
|
virtual bool allows(Map* m, int x, int y);
|
||||||
};
|
};
|
||||||
|
|
||||||
class AndConstraint : public Constraint {
|
class AvoidTileClassConstraint : public Constraint {
|
||||||
private:
|
private:
|
||||||
std::vector<Constraint*> constraints;
|
TileClass* tileClass;
|
||||||
|
float distance;
|
||||||
public:
|
public:
|
||||||
AndConstraint(const std::vector<Constraint*>& constraints);
|
AvoidTileClassConstraint(TileClass* tileClass, float distance);
|
||||||
~AndConstraint();
|
|
||||||
virtual bool allows(Map* m, int x, int y);
|
virtual bool allows(Map* m, int x, int y);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#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++) {
|
for(int i=0; i<count; i++) {
|
||||||
while(true) {
|
while(true) {
|
||||||
float ang = RandFloat()*2*PI;
|
float ang = RandFloat()*2*PI;
|
||||||
float x = cx + distance*cos(ang);
|
float x = cx + distance*cos(ang) + 0.5f;
|
||||||
float y = cy + distance*sin(ang);
|
float y = cy + distance*sin(ang) + 0.5f;
|
||||||
int ix = (int) x;
|
int ix = (int) x;
|
||||||
int iy = (int) y;
|
int iy = (int) y;
|
||||||
if(m->validT(ix, iy) && constr->allows(m, ix, iy)) {
|
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;
|
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++) {
|
for(int i=0; i<elements.size(); i++) {
|
||||||
if(!elements[i]->place(x, y, m, constr, ret)) {
|
if(!elements[i]->place(x, y, m, constr, ret)) {
|
||||||
return false;
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleGroup::SimpleGroup(vector<SimpleGroup::Element*>& e, int _x, int _y):
|
SimpleGroup::SimpleGroup(vector<SimpleGroup::Element*>& e, TileClass* tc, int _x, int _y):
|
||||||
elements(e), x(_x), y(_y)
|
elements(e), x(_x), y(_y), tileClass(tc)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
#define __SIMPLEGROUP_H__
|
#define __SIMPLEGROUP_H__
|
||||||
|
|
||||||
#include "objectgroupplacer.h"
|
#include "objectgroupplacer.h"
|
||||||
|
#include "tileclass.h"
|
||||||
|
|
||||||
class SimpleGroup : public ObjectGroupPlacer
|
class SimpleGroup : public ObjectGroupPlacer
|
||||||
{
|
{
|
||||||
@ -21,10 +22,11 @@ public:
|
|||||||
|
|
||||||
std::vector<Element*> elements;
|
std::vector<Element*> elements;
|
||||||
int x, y;
|
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);
|
virtual ~SimpleGroup(void);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -51,4 +51,20 @@ void MultiPainter::paint(Map* m, Area* a)
|
|||||||
for (int i=0; i<painters.size(); i++) {
|
for (int i=0; i<painters.size(); i++) {
|
||||||
painters[i]->paint(m, 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 "map.h"
|
||||||
#include "area.h"
|
#include "area.h"
|
||||||
#include "terrain.h"
|
#include "terrain.h"
|
||||||
|
#include "tileclass.h"
|
||||||
|
|
||||||
class TerrainPainter : public AreaPainter {
|
class TerrainPainter : public AreaPainter {
|
||||||
Terrain* terrain;
|
Terrain* terrain;
|
||||||
@ -20,6 +21,13 @@ public:
|
|||||||
virtual void paint(Map* m, Area* a);
|
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 {
|
class MultiPainter : public AreaPainter {
|
||||||
std::vector<AreaPainter*> painters;
|
std::vector<AreaPainter*> painters;
|
||||||
public:
|
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