1
0
forked from 0ad/0ad

Enanced the Cantabrian Highlands map some more, and added a few more comments and utility functions to rmgen and JS API.

This was SVN commit r2714.
This commit is contained in:
Matei 2005-09-13 23:00:56 +00:00
parent 2766242181
commit 093e5c2519
8 changed files with 90 additions and 27 deletions

View File

@ -23,8 +23,8 @@ JSFunctionSpec globalFunctions[] = {
{"getHeight", getHeight, 2},
{"setHeight", setHeight, 3},
{"getMapSize", getMapSize, 0},
{"randInt", randInt, 1},
{"randFloat", randFloat, 0},
{"randInt", randInt, 2},
{"randFloat", randFloat, 1},
{"placeObject", placeObject, 4},
{"createArea", createArea, 3},
{"createObjectGroup", createObjectGroup, 3},
@ -38,7 +38,7 @@ JSFunctionSpec globalFunctions[] = {
void ValidateArgs(const char* types, JSContext* cx, uintN argc, jsval* argv, const char* function) {
int num = strlen(types);
if(argc != num) {
JS_ReportError(cx, "%s: expected %d arguments but got %d", function, num, argc);
JS_ReportError(cx, "%s: requires %d arguments but got %d", function, num, argc);
}
JSObject* obj;
for(int i=0; i<num; i++) {
@ -189,22 +189,57 @@ JSBool setHeight(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *r
JSBool randInt(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
ValidateArgs("i", cx, argc, argv, __FUNCTION__);
int x = JSVAL_TO_INT(argv[0]);
if(x<=0) {
JS_ReportError(cx, "randInt: argument must be positive");
if(argc!=1 && argc!=2) {
JS_ReportError(cx, "randInt: requires 1 or 2 arguments but got %d", argc);
}
int r = RandInt(x);
if(!JSVAL_IS_INT(argv[0])) {
JS_ReportError(cx, "randInt: argument 1 must be an integer");
}
if(argc==2 && !JSVAL_IS_INT(argv[1])) {
JS_ReportError(cx, "randInt: argument 2 must be an integer");
}
int minVal = argc==1 ? 0 : JSVAL_TO_INT(argv[0]);
int maxVal = argc==1 ? JSVAL_TO_INT(argv[0]) : JSVAL_TO_INT(argv[1])-1;
if(maxVal < minVal) {
JS_ReportError(cx, argc==1 ? "randInt: argument must be positive"
: "randInt: argument 2 must be greater than or equal to argument 1");
}
int r = RandInt(minVal, maxVal);
*rval = INT_TO_JSVAL(r);
return JS_TRUE;
}
JSBool randFloat(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
ValidateArgs("", cx, argc, argv, __FUNCTION__);
if(argc!=0 && argc!=2) {
JS_ReportError(cx, "randFloat: requires 0 or 2 arguments but got %d", argc);
}
jsdouble r;
if(argc==0) {
r = RandFloat();
}
else {
if(!JSVAL_IS_NUMBER(argv[0])) {
JS_ReportError(cx, "randFloat: argument 1 must be a number");
}
if(!JSVAL_IS_NUMBER(argv[1])) {
JS_ReportError(cx, "randFloat: argument 2 must be a number");
}
jsdouble minVal, maxVal;
JS_ValueToNumber(cx, argv[0], &minVal);
JS_ValueToNumber(cx, argv[1], &maxVal);
if(maxVal < minVal) {
JS_ReportError(cx, "randFloat: argument 2 must be greater than or equal to argument 1");
}
r = RandFloat(minVal, maxVal);
}
jsdouble r = RandFloat();
JS_NewDoubleValue(cx, r, rval);
return JS_TRUE;
}
@ -315,7 +350,7 @@ JSBool createObjectGroup(JSContext *cx, JSObject *obj, uintN argc, jsval *argv,
delete placer;
delete constr;
*rval = ret;
*rval = BOOLEAN_TO_JSVAL(ret);
return JS_TRUE;
}

View File

@ -19,6 +19,8 @@ ClumpPlacer::~ClumpPlacer()
}
bool ClumpPlacer::place(class Map* m, Constraint* constr, std::vector<Point>& retVec) {
// TODO: use a 2D array or hash set instead of a STL set for speed
if(!m->validT(x, y) || !constr->allows(m, x, y)) {
return false;
}

View File

@ -205,12 +205,15 @@ ObjectGroupPlacer* ParseObjectGroupPlacer(JSContext* cx, jsval val) {
elements.resize(array.size());
for(int i=0; i<array.size(); i++) {
string type;
int count;
float distance;
int minCount, maxCount;
float minDistance, maxDistance;
if(!GetStringField(cx, array[i], "type", type)) return 0;
if(!GetIntField(cx, array[i], "count", count)) return 0;
if(!GetFloatField(cx, array[i], "distance", distance)) return 0;
elements[i] = new SimpleGroup::Element(type, count, distance);
if(!GetIntField(cx, array[i], "minCount", minCount)) return 0;
if(!GetIntField(cx, array[i], "maxCount", maxCount)) return 0;
if(!GetFloatField(cx, array[i], "minDistance", minDistance)) return 0;
if(!GetFloatField(cx, array[i], "maxDistance", maxDistance)) return 0;
elements[i] = new SimpleGroup::Element(type, minCount, maxCount,
minDistance, maxDistance);
}
return new SimpleGroup(elements, tileClass, avoidSelf, x, y);

View File

@ -17,4 +17,12 @@ float RandFloat() {
return float(rng()) * (1.0f/4294967296.0f);
}
float RandFloat(float minVal, float maxVal) {
return minVal + RandFloat() * (maxVal - minVal);
}
int RandInt(int minVal, int maxVal) {
return minVal + RandInt(maxVal - minVal + 1);
}

View File

@ -1,3 +1,5 @@
void SeedRand(unsigned long seed);
int RandInt(int maxVal);
float RandFloat(); // in range [0,1)
int RandInt(int maxVal); // in range [0, maxVal-1]
float RandFloat(); // in range [0, 1)
int RandInt(int minVal, int maxVal); // in range [minVal, maxVal]
float RandFloat(float minVal, float maxVal); // in range [minVal, maxVal)

View File

@ -3,15 +3,22 @@
#include "point.h"
#include "random.h"
#include "map.h"
#include "rmgen.h"
using namespace std;
SimpleGroup::Element::Element(){
}
SimpleGroup::Element::Element(const std::string& t, int c, float d):
type(t), count(c), distance(d)
SimpleGroup::Element::Element(const std::string& t, int minC, int maxC, float minD, float maxD):
type(t), minCount(minC), maxCount(maxC), minDistance(minD), maxDistance(maxD)
{
if(minCount > maxCount) {
JS_ReportError(cx, "SimpleObject: minCount must be less than or equal to maxCount");
}
if(minDistance > maxDistance) {
JS_ReportError(cx, "SimpleObject: minDistance must be less than or equal to maxDistance");
}
}
SimpleGroup::Element::~Element() {
@ -20,11 +27,14 @@ SimpleGroup::Element::~Element() {
bool SimpleGroup::Element::place(int cx, int cy, Map* m, int player, bool avoidSelf,
Constraint* constr, vector<Object*>& ret) {
int failCount = 0;
int count = RandInt(minCount, maxCount);
for(int i=0; i<count; i++) {
while(true) {
float ang = RandFloat()*2*PI;
float x = cx + 0.5f + distance*cos(ang);
float y = cy + 0.5f + distance*sin(ang);
float distance = RandFloat(minDistance, maxDistance);
float angle = RandFloat(0, 2*PI);
float x = cx + 0.5f + distance*cos(angle);
float y = cy + 0.5f + distance*sin(angle);
if(x<0 || y<0 || x>m->size || y>m->size) {
goto bad;

View File

@ -10,11 +10,12 @@ public:
class Element {
public:
std::string type;
int count;
float distance;
int minCount, maxCount;
float minDistance, maxDistance;
Element::Element();
Element::Element(const std::string& type, int count, float distance);
Element::Element(const std::string& type, int minCount, int maxCount,
float minDistance, float maxDistance);
Element::~Element();
bool place(int cx, int cy, class Map* m, int player, bool avoidSelf,

View File

@ -28,6 +28,8 @@ bool SmoothElevationPainter::checkInArea(Map* m, Area* a, int x, int y) {
}
void SmoothElevationPainter::paint(Map* m, Area* a) {
// TODO: Use a 2D array instead of STL maps and sets for speed
map<Point, int> saw;
map<Point, int> dist;