Remove rmgen tool.
Log error description when sound engine fails (instead of cryptic LibError code). This was SVN commit r9219.
This commit is contained in:
parent
a3812af176
commit
469d0fe5c5
@ -34,6 +34,7 @@
|
||||
#include "ps/XML/Xeromyces.h"
|
||||
#include "ps/CLogger.h"
|
||||
#include "ps/Filesystem.h"
|
||||
#include "ps/Util.h"
|
||||
|
||||
|
||||
static const bool DISABLE_INTENSITY = true; // disable for now since it's broken
|
||||
@ -121,7 +122,7 @@ static void HandleError(const std::wstring& message, const VfsPath& pathname, Li
|
||||
{
|
||||
if(err == ERR::AGAIN)
|
||||
return; // open failed because sound is disabled (don't log this)
|
||||
LOGERROR(L"%ls: pathname=%ls, error=%ld", message.c_str(), pathname.string().c_str(), err);
|
||||
LOGERROR(L"%ls: pathname=%ls, error=%ls", message.c_str(), pathname.string().c_str(), ErrorString(err));
|
||||
}
|
||||
|
||||
void CSoundGroup::PlayNext(const CVector3D& position)
|
||||
|
@ -1,43 +0,0 @@
|
||||
#ifndef MATH_UTIL_H
|
||||
#define MATH_UTIL_H
|
||||
|
||||
#ifndef PI
|
||||
#define PI 3.14159265358979323846f
|
||||
#endif
|
||||
|
||||
#define DEGTORAD(a) ((a) * (PI/180.0f))
|
||||
#define RADTODEG(a) ((a) * (180.0f/PI))
|
||||
#define SQR(x) ((x) * (x))
|
||||
|
||||
template <typename T>
|
||||
T Interpolate(T& a, T& b, float l)
|
||||
{
|
||||
return a + (b - a) * l;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline T clamp(T value, T min, T max)
|
||||
{
|
||||
if (value <= min) return min;
|
||||
else if (value >= max) return max;
|
||||
else return value;
|
||||
}
|
||||
|
||||
static inline int RoundUpToPowerOf2(int x)
|
||||
{
|
||||
if ((x & (x-1)) == 0)
|
||||
return x;
|
||||
int d = x;
|
||||
while (d & (d-1))
|
||||
d &= (d-1);
|
||||
return d << 1;
|
||||
}
|
||||
|
||||
inline float sgn(float a)
|
||||
{
|
||||
if (a > 0.0f) return 1.0f;
|
||||
if (a < 0.0f) return -1.0f;
|
||||
return 0.0f;
|
||||
}
|
||||
|
||||
#endif
|
@ -1,32 +0,0 @@
|
||||
========================================================================
|
||||
CONSOLE APPLICATION : rmgen Project Overview
|
||||
========================================================================
|
||||
|
||||
AppWizard has created this rmgen application for you.
|
||||
This file contains a summary of what you will find in each of the files that
|
||||
make up your rmgen application.
|
||||
|
||||
|
||||
rmgen.vcproj
|
||||
This is the main project file for VC++ projects generated using an Application Wizard.
|
||||
It contains information about the version of Visual C++ that generated the file, and
|
||||
information about the platforms, configurations, and project features selected with the
|
||||
Application Wizard.
|
||||
|
||||
rmgen.cpp
|
||||
This is the main application source file.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
Other standard files:
|
||||
|
||||
StdAfx.h, StdAfx.cpp
|
||||
These files are used to build a precompiled header (PCH) file
|
||||
named rmgen.pch and a precompiled types file named StdAfx.obj.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
Other notes:
|
||||
|
||||
AppWizard uses "TODO:" comments to indicate parts of the source code you
|
||||
should add to or customize.
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
@ -1,96 +0,0 @@
|
||||
//***********************************************************
|
||||
// Name: Vector2D.h
|
||||
// Description: Provides an interface for a vector in R4 and
|
||||
// allows vector and scalar operations on it
|
||||
//
|
||||
//***********************************************************
|
||||
|
||||
#ifndef VECTOR2D_H
|
||||
#define VECTOR2D_H
|
||||
|
||||
|
||||
#include <math.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// CVector2D_Maths:
|
||||
class CVector2D_Maths
|
||||
{
|
||||
public:
|
||||
CVector2D_Maths() {}
|
||||
CVector2D_Maths(float x,float y) { X=x; Y=y; }
|
||||
CVector2D_Maths(const CVector2D_Maths& p) { X=p.X; Y=p.Y; }
|
||||
|
||||
operator float*() {
|
||||
return &X;
|
||||
}
|
||||
|
||||
operator const float*() const {
|
||||
return &X;
|
||||
}
|
||||
|
||||
CVector2D_Maths operator-() const {
|
||||
return CVector2D_Maths(-X, -Y);
|
||||
}
|
||||
|
||||
CVector2D_Maths operator+(const CVector2D_Maths& t) const {
|
||||
return CVector2D_Maths(X+t.X, Y+t.Y);
|
||||
}
|
||||
|
||||
CVector2D_Maths operator-(const CVector2D_Maths& t) const {
|
||||
return CVector2D_Maths(X-t.X, Y-t.Y);
|
||||
}
|
||||
|
||||
CVector2D_Maths operator*(float f) const {
|
||||
return CVector2D_Maths(X*f, Y*f);
|
||||
}
|
||||
|
||||
CVector2D_Maths operator/(float f) const {
|
||||
float inv=1.0f/f;
|
||||
return CVector2D_Maths(X*inv, Y*inv);
|
||||
}
|
||||
|
||||
CVector2D_Maths& operator+=(const CVector2D_Maths& t) {
|
||||
X+=t.X; Y+=t.Y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CVector2D_Maths& operator-=(const CVector2D_Maths& t) {
|
||||
X-=t.X; Y-=t.Y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CVector2D_Maths& operator*=(float f) {
|
||||
X*=f; Y*=f;
|
||||
return *this;
|
||||
}
|
||||
|
||||
CVector2D_Maths& operator/=(float f) {
|
||||
float invf=1.0f/f;
|
||||
X*=invf; Y*=invf;
|
||||
return *this;
|
||||
}
|
||||
|
||||
float Dot(const CVector2D_Maths& a) const {
|
||||
return X*a.X + Y*a.Y;
|
||||
}
|
||||
|
||||
float LengthSquared() const {
|
||||
return Dot(*this);
|
||||
}
|
||||
|
||||
float Length() const {
|
||||
return (float) sqrt(LengthSquared());
|
||||
}
|
||||
|
||||
void Normalize() {
|
||||
float mag=Length();
|
||||
X/=mag; Y/=mag;
|
||||
}
|
||||
|
||||
public:
|
||||
float X, Y;
|
||||
};
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#endif
|
@ -1,135 +0,0 @@
|
||||
//***********************************************************
|
||||
// Name: Vector3D.Cpp
|
||||
/
|
||||
// Description: Provides an interface for a vector in R3 and
|
||||
// allows vector and scalar operations on it
|
||||
//
|
||||
//***********************************************************
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
#include "Vector3D.h"
|
||||
|
||||
#include <math.h>
|
||||
#include "MathUtil.h"
|
||||
|
||||
int CVector3D::operator ! () const
|
||||
{
|
||||
if (X != 0.0f ||
|
||||
Y != 0.0f ||
|
||||
Z != 0.0f)
|
||||
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
bool CVector3D::operator== (const CVector3D &vector) const
|
||||
{
|
||||
return (X == vector.X && Y == vector.Y && Z == vector.Z);
|
||||
}
|
||||
|
||||
//vector addition
|
||||
CVector3D CVector3D::operator + (const CVector3D &vector) const
|
||||
{
|
||||
return CVector3D(X+vector.X, Y+vector.Y, Z+vector.Z);
|
||||
}
|
||||
|
||||
//vector addition/assignment
|
||||
CVector3D &CVector3D::operator += (const CVector3D &vector)
|
||||
{
|
||||
X += vector.X;
|
||||
Y += vector.Y;
|
||||
Z += vector.Z;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//vector subtraction
|
||||
CVector3D CVector3D::operator - (const CVector3D &vector) const
|
||||
{
|
||||
return CVector3D(X-vector.X, Y-vector.Y, Z-vector.Z);
|
||||
}
|
||||
|
||||
//vector negation
|
||||
CVector3D CVector3D::operator-() const
|
||||
{
|
||||
return CVector3D(-X, -Y, -Z);
|
||||
}
|
||||
//vector subtrcation/assignment
|
||||
CVector3D &CVector3D::operator -= (const CVector3D &vector)
|
||||
{
|
||||
X -= vector.X;
|
||||
Y -= vector.Y;
|
||||
Z -= vector.Z;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
//scalar multiplication
|
||||
CVector3D CVector3D::operator * (float value) const
|
||||
{
|
||||
return CVector3D(X*value, Y*value, Z*value);
|
||||
}
|
||||
|
||||
//scalar multiplication/assignment
|
||||
CVector3D& CVector3D::operator *= (float value)
|
||||
{
|
||||
X *= value;
|
||||
Y *= value;
|
||||
Z *= value;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void CVector3D::Set (float x, float y, float z)
|
||||
{
|
||||
X = x;
|
||||
Y = y;
|
||||
Z = z;
|
||||
}
|
||||
|
||||
void CVector3D::Clear ()
|
||||
{
|
||||
X = Y = Z = 0.0f;
|
||||
}
|
||||
|
||||
//Dot product
|
||||
float CVector3D::Dot (const CVector3D &vector) const
|
||||
{
|
||||
return ( X * vector.X +
|
||||
Y * vector.Y +
|
||||
Z * vector.Z );
|
||||
}
|
||||
|
||||
//Cross product
|
||||
CVector3D CVector3D::Cross (const CVector3D &vector) const
|
||||
{
|
||||
CVector3D Temp;
|
||||
|
||||
Temp.X = (Y * vector.Z) - (Z * vector.Y);
|
||||
Temp.Y = (Z * vector.X) - (X * vector.Z);
|
||||
Temp.Z = (X * vector.Y) - (Y * vector.X);
|
||||
|
||||
return Temp;
|
||||
}
|
||||
|
||||
|
||||
float CVector3D::LengthSquared () const
|
||||
{
|
||||
return ( SQR(X) + SQR(Y) + SQR(Z) );
|
||||
}
|
||||
|
||||
float CVector3D::GetLength () const
|
||||
{
|
||||
return sqrtf ( LengthSquared() );
|
||||
}
|
||||
|
||||
void CVector3D::Normalize ()
|
||||
{
|
||||
float scale = 1.0f/GetLength ();
|
||||
|
||||
X *= scale;
|
||||
Y *= scale;
|
||||
Z *= scale;
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
//***********************************************************
|
||||
// Name: Vector3D.H
|
||||
// Description: Provides an interface for a vector in R3 and
|
||||
// allows vector and scalar operations on it
|
||||
//
|
||||
//***********************************************************
|
||||
|
||||
#ifndef VECTOR3D_H
|
||||
#define VECTOR3D_H
|
||||
|
||||
class CVector3D
|
||||
{
|
||||
public:
|
||||
float X, Y, Z;
|
||||
|
||||
public:
|
||||
CVector3D () : X(0.0f), Y(0.0f), Z(0.0f) {}
|
||||
CVector3D (float x, float y, float z) : X(x), Y(y), Z(z) {}
|
||||
|
||||
int operator!() const;
|
||||
|
||||
float& operator[](int index) { return *((&X)+index); }
|
||||
const float& operator[](int index) const { return *((&X)+index); }
|
||||
|
||||
//vector equality (testing float equality, so please be careful if necessary)
|
||||
bool operator== (const CVector3D &vector) const;
|
||||
bool operator!= (const CVector3D &vector) const { return !operator==(vector); }
|
||||
|
||||
//vector addition
|
||||
CVector3D operator + (const CVector3D &vector) const ;
|
||||
//vector addition/assignment
|
||||
CVector3D &operator += (const CVector3D &vector);
|
||||
|
||||
//vector subtraction
|
||||
CVector3D operator - (const CVector3D &vector) const ;
|
||||
//vector subtraction/assignment
|
||||
CVector3D &operator -= (const CVector3D &vector);
|
||||
|
||||
//scalar multiplication
|
||||
CVector3D operator * (float value) const ;
|
||||
//scalar multiplication/assignment
|
||||
CVector3D& operator *= (float value);
|
||||
|
||||
// negation
|
||||
CVector3D operator-() const;
|
||||
|
||||
public:
|
||||
void Set (float x, float y, float z);
|
||||
void Clear ();
|
||||
|
||||
//Dot product
|
||||
float Dot (const CVector3D &vector) const;
|
||||
//Cross product
|
||||
CVector3D Cross (const CVector3D &vector) const;
|
||||
|
||||
//Returns length of the vector
|
||||
float GetLength () const;
|
||||
float LengthSquared () const;
|
||||
void Normalize ();
|
||||
|
||||
// Returns 3 element array of floats, e.g. for glVertex3fv
|
||||
const float* GetFloatArray() const { return &X; }
|
||||
};
|
||||
|
||||
#endif
|
@ -1,418 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "api.h"
|
||||
#include "rmgen.h"
|
||||
#include "random.h"
|
||||
#include "map.h"
|
||||
#include "object.h"
|
||||
#include "convert.h"
|
||||
#include "terrain.h"
|
||||
#include "simpleconstraints.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
// Function specs
|
||||
|
||||
JSFunctionSpec globalFunctions[] = {
|
||||
// {name, native, args}
|
||||
{"init", init, 3},
|
||||
{"initFromScenario", initFromScenario, 2},
|
||||
{"print", print, 1},
|
||||
{"error", error, 1},
|
||||
{"getTexture", getTexture, 2},
|
||||
{"setTexture", setTexture, 3},
|
||||
{"getHeight", getHeight, 2},
|
||||
{"setHeight", setHeight, 3},
|
||||
{"getMapSize", getMapSize, 0},
|
||||
{"randInt", randInt, 2},
|
||||
{"randFloat", randFloat, 1},
|
||||
{"placeTerrain", placeTerrain, 3},
|
||||
{"placeObject", placeObject, 4},
|
||||
{"createArea", createArea, 3},
|
||||
{"createObjectGroup", createObjectGroup, 3},
|
||||
{"createTileClass", createTileClass, 0},
|
||||
{"addToClass", addToClass, 0},
|
||||
{"removeFromClass", removeFromClass, 0},
|
||||
{0, 0, 0}
|
||||
};
|
||||
|
||||
// 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.
|
||||
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: requires %d arguments but got %d", function, num, argc);
|
||||
}
|
||||
JSObject* obj;
|
||||
for(int i=0; i<num; i++) {
|
||||
switch(types[i]) {
|
||||
case 'i':
|
||||
if(!JSVAL_IS_INT(argv[i])) {
|
||||
JS_ReportError(cx, "%s: argument %d must be an integer", function, i+1);
|
||||
}
|
||||
break;
|
||||
case 's':
|
||||
if(!JSVAL_IS_STRING(argv[i])) {
|
||||
JS_ReportError(cx, "%s: argument %d must be a string", function, i+1);
|
||||
}
|
||||
break;
|
||||
case 'n':
|
||||
if(!JSVAL_IS_NUMBER(argv[i])) {
|
||||
JS_ReportError(cx, "%s: argument %d must be an integer", function, i+1);
|
||||
}
|
||||
break;
|
||||
case 'a':
|
||||
if(!JSVAL_IS_OBJECT(argv[i])) {
|
||||
JS_ReportError(cx, "%s: argument %d must be an array", function, i+1);
|
||||
}
|
||||
obj = JSVAL_TO_OBJECT(argv[i]);
|
||||
if(!JS_IsArrayObject(cx, obj)) {
|
||||
JS_ReportError(cx, "%s: argument %d must be an array", function, i+1);
|
||||
}
|
||||
break;
|
||||
case '*':
|
||||
break;
|
||||
default:
|
||||
cerr << "Internal Error: Invalid type passed to ValidateArgs: " << types[i] << "." << endl;
|
||||
Shutdown(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Helper function to check whether map was initialized
|
||||
void CheckInit(bool shouldBeInitialized, JSContext* cx, const char* function) {
|
||||
if(shouldBeInitialized) {
|
||||
if(theMap == 0) {
|
||||
JS_ReportError(cx, "%s: cannot be called before map is initialized", function);
|
||||
}
|
||||
}
|
||||
else {
|
||||
if(theMap != 0) {
|
||||
JS_ReportError(cx, "%s: map was already initialized by an earlier call", function);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// JS API implementation
|
||||
|
||||
JSBool print(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
ValidateArgs("*", cx, argc, argv, __FUNCTION__);
|
||||
|
||||
cout << JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool error(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
ValidateArgs("*", cx, argc, argv, __FUNCTION__);
|
||||
|
||||
JS_ReportError(cx, JS_GetStringBytes(JS_ValueToString(cx, argv[0])));
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool init(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
CheckInit(false, cx, __FUNCTION__);
|
||||
ValidateArgs("i*n", cx, argc, argv, __FUNCTION__);
|
||||
|
||||
int size = JSVAL_TO_INT(argv[0]);
|
||||
Terrain* baseTerrain = ParseTerrain(cx, argv[1]);
|
||||
if(!baseTerrain) {
|
||||
JS_ReportError(cx, "init: argument 2 must be a terrain");
|
||||
}
|
||||
jsdouble baseHeight;
|
||||
JS_ValueToNumber(cx, argv[2], &baseHeight);
|
||||
|
||||
theMap = new Map(size, baseTerrain, (float) baseHeight);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool initFromScenario(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
CheckInit(false, cx, __FUNCTION__);
|
||||
ValidateArgs("si", cx, argc, argv, __FUNCTION__);
|
||||
|
||||
string fileName = JS_GetStringBytes(JSVAL_TO_STRING(argv[0]));
|
||||
int loadObjectLevel = JSVAL_TO_INT(argv[1]);
|
||||
|
||||
theMap = new Map(fileName, loadObjectLevel);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool getTexture(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
CheckInit(true, cx, __FUNCTION__);
|
||||
ValidateArgs("ii", cx, argc, argv, __FUNCTION__);
|
||||
|
||||
int x = JSVAL_TO_INT(argv[0]);
|
||||
int y = JSVAL_TO_INT(argv[1]);
|
||||
string texture = theMap->getTexture(x, y);
|
||||
*rval = NewJSString(texture);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool setTexture(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
CheckInit(true, cx, __FUNCTION__);
|
||||
ValidateArgs("iis", cx, argc, argv, __FUNCTION__);
|
||||
|
||||
int x = JSVAL_TO_INT(argv[0]);
|
||||
int y = JSVAL_TO_INT(argv[1]);
|
||||
char* texture = JS_GetStringBytes(JSVAL_TO_STRING(argv[2]));
|
||||
theMap->setTexture(x, y, texture);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool getHeight(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
CheckInit(true, cx, __FUNCTION__);
|
||||
ValidateArgs("ii", cx, argc, argv, __FUNCTION__);
|
||||
|
||||
int x = JSVAL_TO_INT(argv[0]);
|
||||
int y = JSVAL_TO_INT(argv[1]);
|
||||
jsdouble height = theMap->getHeight(x, y);
|
||||
JS_NewDoubleValue(cx, height, rval);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool setHeight(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
CheckInit(true, cx, __FUNCTION__);
|
||||
ValidateArgs("iin", cx, argc, argv, __FUNCTION__);
|
||||
|
||||
int x = JSVAL_TO_INT(argv[0]);
|
||||
int y = JSVAL_TO_INT(argv[1]);
|
||||
jsdouble height;
|
||||
JS_ValueToNumber(cx, argv[2], &height);
|
||||
theMap->setHeight(x, y, (float) height);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool randInt(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
if(argc!=1 && argc!=2) {
|
||||
JS_ReportError(cx, "randInt: requires 1 or 2 arguments but got %d", argc);
|
||||
}
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
JS_NewDoubleValue(cx, r, rval);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool placeObject(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
CheckInit(true, cx, __FUNCTION__);
|
||||
ValidateArgs("sinnn", cx, argc, argv, __FUNCTION__);
|
||||
|
||||
string type = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
|
||||
int player = JSVAL_TO_INT(argv[1]);
|
||||
jsdouble x, y, orientation;
|
||||
JS_ValueToNumber(cx, argv[2], &x);
|
||||
JS_ValueToNumber(cx, argv[3], &y);
|
||||
JS_ValueToNumber(cx, argv[4], &orientation);
|
||||
|
||||
theMap->addObject(new Object(type, player, x,y, orientation));
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool placeTerrain(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
CheckInit(true, cx, __FUNCTION__);
|
||||
ValidateArgs("ii*", cx, argc, argv, __FUNCTION__);
|
||||
|
||||
int x = JSVAL_TO_INT(argv[0]);
|
||||
int y = JSVAL_TO_INT(argv[1]);
|
||||
Terrain* terrain = ParseTerrain(cx, argv[2]);
|
||||
if(!terrain) {
|
||||
JS_ReportError(cx, "placeTerrain: invalid terrain argument");
|
||||
}
|
||||
theMap->placeTerrain(x, y, terrain);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool createArea(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
CheckInit(true, cx, __FUNCTION__);
|
||||
if(argc != 2 && argc != 3) {
|
||||
JS_ReportError(cx, "createArea: expected 2 or 3 arguments but got %d", argc);
|
||||
}
|
||||
|
||||
AreaPlacer* placer;
|
||||
AreaPainter* painter;
|
||||
Constraint* constr;
|
||||
|
||||
if(!(placer = ParseAreaPlacer(cx, argv[0]))) {
|
||||
JS_ReportError(cx, "createArea: argument 1 must be a valid area placer");
|
||||
}
|
||||
if(!(painter = ParseAreaPainter(cx, argv[1]))) {
|
||||
JS_ReportError(cx, "createArea: argument 2 must be a valid area painter");
|
||||
}
|
||||
if(argc == 3) {
|
||||
if(!(constr = ParseConstraint(cx, argv[2]))) {
|
||||
JS_ReportError(cx, "createArea: argument 3 must be a valid constraint");
|
||||
}
|
||||
}
|
||||
else {
|
||||
constr = new NullConstraint();
|
||||
}
|
||||
|
||||
Area* area = theMap->createArea(placer, painter, constr);
|
||||
|
||||
delete placer;
|
||||
delete painter;
|
||||
delete constr;
|
||||
|
||||
if(!area) {
|
||||
*rval = INT_TO_JSVAL(0);
|
||||
}
|
||||
else {
|
||||
*rval = INT_TO_JSVAL(theMap->areas.size());
|
||||
}
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool createObjectGroup(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
CheckInit(true, cx, __FUNCTION__);
|
||||
if(argc != 2 && argc != 3) {
|
||||
JS_ReportError(cx, "createObjectGroup: expected 1 or 2 arguments but got %d", argc);
|
||||
}
|
||||
|
||||
ObjectGroupPlacer* placer;
|
||||
Constraint* constr;
|
||||
|
||||
if(!(placer = ParseObjectGroupPlacer(cx, argv[0]))) {
|
||||
JS_ReportError(cx, "createObjectGroup: argument 1 must be a valid object group placer");
|
||||
}
|
||||
if(!JSVAL_IS_INT(argv[1])) {
|
||||
JS_ReportError(cx, "createObjectGroup: argument 2 must be a valid player number");
|
||||
}
|
||||
|
||||
if(argc == 3) {
|
||||
if(!(constr = ParseConstraint(cx, argv[2]))) {
|
||||
JS_ReportError(cx, "createObjectGroup: argument 3 must be a valid constraint");
|
||||
}
|
||||
}
|
||||
else {
|
||||
constr = new NullConstraint();
|
||||
}
|
||||
|
||||
int player = JSVAL_TO_INT(argv[1]);
|
||||
|
||||
bool ret = theMap->createObjectGroup(placer, player, constr);
|
||||
|
||||
delete placer;
|
||||
delete constr;
|
||||
|
||||
*rval = BOOLEAN_TO_JSVAL(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;
|
||||
}
|
||||
|
||||
JSBool addToClass(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
CheckInit(true, cx, __FUNCTION__);
|
||||
ValidateArgs("iii", cx, argc, argv, __FUNCTION__);
|
||||
|
||||
int x = JSVAL_TO_INT(argv[0]);
|
||||
int y = JSVAL_TO_INT(argv[1]);
|
||||
int classIndex = JSVAL_TO_INT(argv[2]) - 1;
|
||||
|
||||
if(!theMap->validClass(classIndex) || !theMap->validT(x, y)) {
|
||||
JS_ReportError(cx, "addToClass: Invalid arguments for addToClass(x, y, class)");
|
||||
}
|
||||
|
||||
theMap->tileClasses[classIndex]->add(x, y);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool removeFromClass(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
CheckInit(true, cx, __FUNCTION__);
|
||||
ValidateArgs("iii", cx, argc, argv, __FUNCTION__);
|
||||
|
||||
int x = JSVAL_TO_INT(argv[0]);
|
||||
int y = JSVAL_TO_INT(argv[1]);
|
||||
int classIndex = JSVAL_TO_INT(argv[2]) - 1;
|
||||
|
||||
if(!theMap->validClass(classIndex) || !theMap->validT(x, y)) {
|
||||
JS_ReportError(cx, "addToClass: Invalid arguments for removeFromClass(x, y, class)");
|
||||
}
|
||||
|
||||
theMap->tileClasses[classIndex]->remove(x, y);
|
||||
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
JSBool getMapSize(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
CheckInit(true, cx, __FUNCTION__);
|
||||
if(argc != 0) {
|
||||
JS_ReportError(cx, "getMapSize: expected 0 arguments but got %d", argc);
|
||||
}
|
||||
|
||||
*rval = INT_TO_JSVAL(theMap->size);
|
||||
return JS_TRUE;
|
||||
}
|
@ -1,39 +0,0 @@
|
||||
#ifndef __API_H__
|
||||
#define __API_H__
|
||||
|
||||
// Function specs (registered by rmgen.cpp)
|
||||
extern JSFunctionSpec globalFunctions[];
|
||||
|
||||
// JS API implementation
|
||||
|
||||
// Map creation functions
|
||||
JSBool init(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
JSBool initFromScenario(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
|
||||
// Utility functions
|
||||
JSBool error(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
JSBool print(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
JSBool randInt(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
JSBool randFloat(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
|
||||
// Low-level access to map data
|
||||
JSBool getTexture(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
JSBool setTexture(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
JSBool getHeight(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
JSBool setHeight(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
JSBool getMapSize(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
|
||||
// Low-level placement functions
|
||||
JSBool placeTerrain(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
JSBool placeObject(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
|
||||
// Medium-level placement functions (high level JS API sits on top of these)
|
||||
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);
|
||||
JSBool addToClass(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
JSBool removeFromClass(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
|
||||
|
||||
#endif
|
@ -1,14 +0,0 @@
|
||||
#include "StdAfx.h"
|
||||
#include ".\area.h"
|
||||
|
||||
Area::Area(void)
|
||||
{
|
||||
}
|
||||
|
||||
Area::Area(const std::vector<Point>& points) {
|
||||
this->points = points;
|
||||
}
|
||||
|
||||
Area::~Area(void)
|
||||
{
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "point.h"
|
||||
|
||||
class Area
|
||||
{
|
||||
public:
|
||||
std::vector<Point> points;
|
||||
|
||||
Area(void);
|
||||
Area(const std::vector<Point>& points);
|
||||
~Area(void);
|
||||
};
|
@ -1,10 +0,0 @@
|
||||
#include "StdAfx.h"
|
||||
#include ".\areapainter.h"
|
||||
|
||||
AreaPainter::AreaPainter(void)
|
||||
{
|
||||
}
|
||||
|
||||
AreaPainter::~AreaPainter(void)
|
||||
{
|
||||
}
|
@ -1,13 +0,0 @@
|
||||
#ifndef __AREAPAINTER_H__
|
||||
#define __AREAPAINTER_H__
|
||||
|
||||
class AreaPainter
|
||||
{
|
||||
public:
|
||||
virtual void paint(class Map* m, class Area* a) = 0;
|
||||
|
||||
AreaPainter(void);
|
||||
virtual ~AreaPainter(void);
|
||||
};
|
||||
|
||||
#endif
|
@ -1,10 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "areaplacer.h"
|
||||
|
||||
AreaPlacer::AreaPlacer(void)
|
||||
{
|
||||
}
|
||||
|
||||
AreaPlacer::~AreaPlacer(void)
|
||||
{
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
#ifndef __AREAPLACER_H__
|
||||
#define __AREAPLACER_H__
|
||||
|
||||
#include "point.h"
|
||||
#include "constraint.h"
|
||||
|
||||
class AreaPlacer
|
||||
{
|
||||
public:
|
||||
virtual bool place(class Map* m, Constraint* constr, std::vector<Point>& ret) = 0;
|
||||
|
||||
AreaPlacer(void);
|
||||
virtual ~AreaPlacer(void);
|
||||
};
|
||||
|
||||
#endif
|
@ -1,87 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "clumpplacer.h"
|
||||
#include "random.h"
|
||||
#include "pointmap.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
ClumpPlacer::ClumpPlacer(float size, float coherence, float smoothness, float failFraction, int x, int y)
|
||||
{
|
||||
this->size = size;
|
||||
this->coherence = coherence;
|
||||
this->smoothness = smoothness;
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
this->failFraction = failFraction;
|
||||
}
|
||||
|
||||
ClumpPlacer::~ClumpPlacer()
|
||||
{
|
||||
}
|
||||
|
||||
bool ClumpPlacer::place(class Map* m, Constraint* constr, std::vector<Point>& retVec) {
|
||||
if(!m->validT(x, y) || !constr->allows(m, x, y)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
PointMap<int> gotRet;
|
||||
|
||||
float radius = sqrt(size / PI);
|
||||
float perim = 4 * radius * 2 * PI;
|
||||
int intPerim = (int)(ceil(perim));
|
||||
vector<float> noise(intPerim);
|
||||
|
||||
int ctrlPts = 1 + (int)(1.0/max(smoothness,1.0f/intPerim));
|
||||
if(ctrlPts > radius * 2 * PI) ctrlPts = (int) (radius * 2 * PI) + 1;
|
||||
vector<float> ctrlCoords(ctrlPts+1);
|
||||
vector<float> ctrlVals(ctrlPts+1);
|
||||
for(int i=0; i<ctrlPts; i++) {
|
||||
ctrlCoords[i] = i * perim / ctrlPts;
|
||||
ctrlVals[i] = 2.0*RandFloat();
|
||||
}
|
||||
|
||||
int c = 0;
|
||||
int looped = 0;
|
||||
for(int i=0; i<intPerim; i++) {
|
||||
if(ctrlCoords[(c+1) % ctrlPts] < i && !looped) {
|
||||
c = (c+1) % ctrlPts;
|
||||
if(c==ctrlPts-1) looped = 1;
|
||||
}
|
||||
float t = (i - ctrlCoords[c]) / ((looped ? perim : ctrlCoords[(c+1)%ctrlPts]) - ctrlCoords[c]);
|
||||
float v0 = ctrlVals[(c+ctrlPts-1)%ctrlPts];
|
||||
float v1 = ctrlVals[c];
|
||||
float v2 = ctrlVals[(c+1)%ctrlPts];
|
||||
float v3 = ctrlVals[(c+2)%ctrlPts];
|
||||
float P = (v3 - v2) - (v0 - v1);
|
||||
float Q = (v0 - v1) - P;
|
||||
float R = v2 - v0;
|
||||
float S = v1;
|
||||
noise[i] = P*t*t*t + Q*t*t + R*t + S;
|
||||
}
|
||||
|
||||
int failed = 0;
|
||||
for(int p=0; p<intPerim; p++) {
|
||||
float th = 2 * PI * p / perim;
|
||||
float r = radius * (1 + (1-coherence)*noise[p]);
|
||||
float s = sin(th);
|
||||
float c = cos(th);
|
||||
float xx=x, yy=y;
|
||||
for(float k=0; k<r; k++) {
|
||||
int i = (int)xx, j = (int)yy;
|
||||
if(m->validT(i, j) && constr->allows(m, i, j)) {
|
||||
Point p(i,j);
|
||||
if(!gotRet[p]) {
|
||||
gotRet[p] = 1;
|
||||
retVec.push_back(p);
|
||||
}
|
||||
}
|
||||
else {
|
||||
failed++;
|
||||
}
|
||||
xx += s;
|
||||
yy += c;
|
||||
}
|
||||
}
|
||||
|
||||
return (failed > size*failFraction ? false : true);
|
||||
}
|
@ -1,22 +0,0 @@
|
||||
#ifndef __CLUMPPLACER_H__
|
||||
#define __CLUMPPLACER_H__
|
||||
|
||||
#include "areaplacer.h"
|
||||
#include "map.h"
|
||||
|
||||
class ClumpPlacer : public AreaPlacer
|
||||
{
|
||||
private:
|
||||
float size;
|
||||
float coherence;
|
||||
float smoothness;
|
||||
float failFraction;
|
||||
int x, y;
|
||||
public:
|
||||
virtual bool place(Map* m, Constraint* constr, std::vector<Point>& ret);
|
||||
|
||||
ClumpPlacer(float size, float coherence, float smoothness, float failFraction, int x, int y);
|
||||
virtual ~ClumpPlacer();
|
||||
};
|
||||
|
||||
#endif
|
@ -1,10 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "constraint.h"
|
||||
|
||||
Constraint::Constraint(void)
|
||||
{
|
||||
}
|
||||
|
||||
Constraint::~Constraint(void)
|
||||
{
|
||||
}
|
@ -1,12 +0,0 @@
|
||||
#ifndef __CONSTRAINT_H__
|
||||
#define __CONSTRAINT_H__
|
||||
|
||||
class Constraint
|
||||
{
|
||||
public:
|
||||
Constraint(void);
|
||||
virtual ~Constraint(void);
|
||||
virtual bool allows(class Map* m, int x, int y) = 0;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,306 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "convert.h"
|
||||
#include "rmgen.h"
|
||||
#include "simpleconstraints.h"
|
||||
#include "simplepainters.h"
|
||||
#include "rectplacer.h"
|
||||
#include "layeredpainter.h"
|
||||
#include "clumpplacer.h"
|
||||
#include "smoothelevationpainter.h"
|
||||
#include "simplegroup.h"
|
||||
|
||||
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;
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool GetIntField(JSContext* cx, jsval obj, const char* name, int& ret) {
|
||||
jsval val;
|
||||
if(!GetJsvalField(cx, obj, name, val)) return false;
|
||||
if(!JSVAL_IS_INT(val)) return false;
|
||||
ret = JSVAL_TO_INT(val);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetBoolField(JSContext* cx, jsval obj, const char* name, bool& ret) {
|
||||
jsval val;
|
||||
if(!GetJsvalField(cx, obj, name, val)) return false;
|
||||
if(!JSVAL_IS_BOOLEAN(val)) return false;
|
||||
ret = JSVAL_TO_BOOLEAN(val);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetFloatField(JSContext* cx, jsval obj, const char* name, float& ret) {
|
||||
jsval val;
|
||||
if(!GetJsvalField(cx, obj, name, val)) return false;
|
||||
if(!JSVAL_IS_NUMBER(val)) return false;
|
||||
jsdouble jsdbl;
|
||||
JS_ValueToNumber(cx, val, &jsdbl);
|
||||
ret = jsdbl;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetStringField(JSContext* cx, jsval obj, const char* name, std::string& ret) {
|
||||
jsval val;
|
||||
if(!GetJsvalField(cx, obj, name, val)) return false;
|
||||
if(!JSVAL_IS_STRING(val)) return false;
|
||||
ret = JS_GetStringBytes(JSVAL_TO_STRING(val));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetArrayField(JSContext* cx, jsval obj, const char* name, std::vector<jsval>& ret) {
|
||||
ret.clear();
|
||||
jsval val;
|
||||
if(!GetJsvalField(cx, obj, name, val)) return false;
|
||||
if(!ParseArray(cx, val, ret)) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool GetJsvalField(JSContext* cx, jsval obj, const char* name, jsval& ret) {
|
||||
if(!JSVAL_IS_OBJECT(obj)) return false;
|
||||
JSObject* fieldObj = JSVAL_TO_OBJECT(obj);
|
||||
return JS_GetProperty(cx, fieldObj, name, &ret);
|
||||
}
|
||||
|
||||
bool ParseArray(JSContext* cx, jsval val, vector<jsval>& ret) {
|
||||
ret.clear();
|
||||
if(!JSVAL_IS_OBJECT(val)) return false;
|
||||
JSObject* obj = JSVAL_TO_OBJECT(val);
|
||||
if(!JS_IsArrayObject(cx, obj)) return false;
|
||||
jsuint len;
|
||||
JS_GetArrayLength(cx, obj, &len);
|
||||
for(int i=0; i<len; i++) {
|
||||
jsval rval;
|
||||
JS_GetElement(cx, obj, i, &rval);
|
||||
ret.push_back(rval);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
AreaPainter* ParseAreaPainter(JSContext* cx, jsval val) {
|
||||
vector<jsval> array;
|
||||
jsval jsv, jsv2;
|
||||
Terrain* terrain = 0;
|
||||
float elevation;
|
||||
int type;
|
||||
int blendRadius;
|
||||
TileClass* tileClass;
|
||||
vector<Terrain*> terrains;
|
||||
vector<int> widths;
|
||||
|
||||
if(ParseArray(cx, val, array)) {
|
||||
// MultiPainter is encoded as an array of painters
|
||||
vector<AreaPainter*> painters(array.size());
|
||||
for(int i=0; i<array.size(); i++) {
|
||||
painters[i] = ParseAreaPainter(cx, array[i]);
|
||||
if(painters[i]==0) return 0;
|
||||
}
|
||||
return new MultiPainter(painters);
|
||||
}
|
||||
|
||||
switch(GetType(cx, val)) {
|
||||
case TYPE_TERRAIN_PAINTER:
|
||||
if(!GetJsvalField(cx, val, "terrain", jsv)) return 0;
|
||||
terrain = ParseTerrain(cx, jsv);
|
||||
if(terrain==0) return 0;
|
||||
return new TerrainPainter(terrain);
|
||||
|
||||
case TYPE_ELEVATION_PAINTER:
|
||||
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;
|
||||
if(!GetIntField(cx, val, "blendRadius", blendRadius)) return 0;
|
||||
return new SmoothElevationPainter(type, elevation, blendRadius);
|
||||
|
||||
case TYPE_LAYERED_PAINTER:
|
||||
if(!GetJsvalField(cx, val, "widths", jsv)) return 0;
|
||||
if(!GetJsvalField(cx, val, "terrains", jsv2)) return 0;
|
||||
if(!ParseArray(cx, jsv, array)) return 0;
|
||||
for(int i=0; i<array.size(); i++) {
|
||||
if(!JSVAL_IS_INT(array[i])) return 0;
|
||||
widths.push_back(JSVAL_TO_INT(array[i]));
|
||||
}
|
||||
if(!ParseArray(cx, jsv2, array)) return 0;
|
||||
for(int i=0; i<array.size(); i++) {
|
||||
terrain = ParseTerrain(cx, array[i]);
|
||||
if(terrain==0) return 0;
|
||||
terrains.push_back(terrain);
|
||||
}
|
||||
if(terrains.size() != 1+widths.size()) return 0;
|
||||
return new LayeredPainter(terrains, widths);
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
AreaPlacer* ParseAreaPlacer(JSContext* cx, jsval val) {
|
||||
int x, y, x1, y1, x2, y2, num, maxFail;
|
||||
float size, coherence, smoothness, failFraction;
|
||||
|
||||
switch(GetType(cx, val)) {
|
||||
case TYPE_RECT_PLACER:
|
||||
if(!GetIntField(cx, val, "x1", x1)) return 0;
|
||||
if(!GetIntField(cx, val, "y1", y1)) return 0;
|
||||
if(!GetIntField(cx, val, "x2", x2)) return 0;
|
||||
if(!GetIntField(cx, val, "y2", y2)) return 0;
|
||||
return new RectPlacer(x1, y1, x2, y2);
|
||||
|
||||
case TYPE_CLUMP_PLACER:
|
||||
if(!GetFloatField(cx, val, "size", size)) return 0;
|
||||
if(!GetFloatField(cx, val, "coherence", coherence)) return 0;
|
||||
if(!GetFloatField(cx, val, "smoothness", smoothness)) return 0;
|
||||
if(!GetFloatField(cx, val, "failFraction", failFraction)) return 0;
|
||||
if(!GetIntField(cx, val, "x", x)) return 0;
|
||||
if(!GetIntField(cx, val, "y", y)) return 0;
|
||||
return new ClumpPlacer(size, coherence, smoothness, failFraction, x, y);
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ObjectGroupPlacer* ParseObjectGroupPlacer(JSContext* cx, jsval val) {
|
||||
jsval jsv;
|
||||
vector<jsval> array;
|
||||
int x, y;
|
||||
bool avoidSelf;
|
||||
TileClass* tileClass;
|
||||
vector<SimpleGroup::Element*> elements;
|
||||
|
||||
switch(GetType(cx, val)) {
|
||||
case TYPE_SIMPLE_GROUP:
|
||||
// convert x and y
|
||||
if(!GetIntField(cx, val, "x", x)) return 0;
|
||||
if(!GetIntField(cx, val, "y", y)) return 0;
|
||||
if(!GetBoolField(cx, val, "avoidSelf", avoidSelf)) 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;
|
||||
elements.resize(array.size());
|
||||
for(int i=0; i<array.size(); i++) {
|
||||
string type;
|
||||
int minCount, maxCount;
|
||||
float minDistance, maxDistance, minAngle, maxAngle;
|
||||
if(!GetStringField(cx, array[i], "type", type)) return 0;
|
||||
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;
|
||||
if(!GetFloatField(cx, array[i], "minAngle", minAngle)) return 0;
|
||||
if(!GetFloatField(cx, array[i], "maxAngle", maxAngle)) return 0;
|
||||
elements[i] = new SimpleGroup::Element(type, minCount, maxCount,
|
||||
minDistance, maxDistance, minAngle, maxAngle);
|
||||
}
|
||||
return new SimpleGroup(elements, tileClass, avoidSelf, x, y);
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Constraint* ParseConstraint(JSContext* cx, jsval val) {
|
||||
vector<jsval> array;
|
||||
int areaId;
|
||||
TileClass* tileClass;
|
||||
float distance;
|
||||
float distance2;
|
||||
string texture;
|
||||
jsval jsv, jsv2;
|
||||
|
||||
if(JSVAL_IS_NULL(val)) {
|
||||
// convenience way of specifying a NullConstraint
|
||||
return new NullConstraint();
|
||||
}
|
||||
|
||||
if(ParseArray(cx, val, array)) {
|
||||
// AndConstraint is encoded as an array of constraints
|
||||
vector<Constraint*> constraints(array.size());
|
||||
for(int i=0; i<array.size(); i++) {
|
||||
constraints[i] = ParseConstraint(cx, array[i]);
|
||||
if(constraints[i]==0) return 0;
|
||||
}
|
||||
return new AndConstraint(constraints);
|
||||
}
|
||||
|
||||
switch(GetType(cx, val)) {
|
||||
case TYPE_NULL_CONSTRAINT:
|
||||
return new NullConstraint();
|
||||
|
||||
case TYPE_AVOID_AREA_CONSTRAINT:
|
||||
if(!GetIntField(cx, val, "area", areaId)) return 0;
|
||||
if(areaId <= 0 || areaId > theMap->areas.size()) return 0;
|
||||
return new AvoidAreaConstraint(theMap->areas[areaId-1]);
|
||||
|
||||
case TYPE_AVOID_TEXTURE_CONSTRAINT:
|
||||
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);
|
||||
|
||||
case TYPE_STAY_IN_TILE_CLASS_CONSTRAINT:
|
||||
if(!GetFloatField(cx, val, "distance", distance)) return 0;
|
||||
if(!GetTileClassField(cx, val, "tileClass", tileClass)) return 0;
|
||||
return new StayInTileClassConstraint(tileClass, distance);
|
||||
|
||||
case TYPE_BORDER_TILE_CLASS_CONSTRAINT:
|
||||
if(!GetFloatField(cx, val, "distanceInside", distance)) return 0;
|
||||
if(!GetFloatField(cx, val, "distanceOutside", distance2)) return 0;
|
||||
if(!GetTileClassField(cx, val, "tileClass", tileClass)) return 0;
|
||||
return new BorderTileClassConstraint(tileClass, distance, distance2);
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
Terrain* ParseTerrain(JSContext* cx, jsval val) {
|
||||
vector<jsval> array;
|
||||
|
||||
if(JSVAL_IS_STRING(val)) {
|
||||
// simple terrains are just encoded as strings
|
||||
string str = JS_GetStringBytes(JS_ValueToString(cx, val));
|
||||
return SimpleTerrain::parse(str);
|
||||
}
|
||||
|
||||
if(ParseArray(cx, val, array)) {
|
||||
// RandomTerrain is encoded as an array of terrains
|
||||
vector<Terrain*> terrains(array.size());
|
||||
for(int i=0; i<array.size(); i++) {
|
||||
terrains[i] = ParseTerrain(cx, array[i]);
|
||||
if(terrains[i]==0) return 0;
|
||||
}
|
||||
return new RandomTerrain(terrains);
|
||||
}
|
||||
|
||||
// so far these are the only ways of specifying a terrain
|
||||
return 0;
|
||||
}
|
@ -1,48 +0,0 @@
|
||||
#ifndef __CONVERT_H__
|
||||
#define __CONVERT_H__
|
||||
|
||||
#include "map.h"
|
||||
#include "object.h"
|
||||
#include "constraint.h"
|
||||
#include "areapainter.h"
|
||||
#include "areaplacer.h"
|
||||
#include "terrain.h"
|
||||
|
||||
// Object type constants
|
||||
|
||||
const int
|
||||
TYPE_RECT_PLACER = 1,
|
||||
TYPE_TERRAIN_PAINTER = 2,
|
||||
TYPE_NULL_CONSTRAINT = 3,
|
||||
TYPE_LAYERED_PAINTER = 4,
|
||||
TYPE_AVOID_AREA_CONSTRAINT = 5,
|
||||
TYPE_CLUMP_PLACER = 6,
|
||||
TYPE_AVOID_TEXTURE_CONSTRAINT = 7,
|
||||
TYPE_ELEVATION_PAINTER = 8,
|
||||
TYPE_SMOOTH_ELEVATION_PAINTER = 9,
|
||||
TYPE_SIMPLE_GROUP = 10,
|
||||
TYPE_AVOID_TILE_CLASS_CONSTRAINT = 11,
|
||||
TYPE_TILE_CLASS_PAINTER = 12,
|
||||
TYPE_STAY_IN_TILE_CLASS_CONSTRAINT = 13,
|
||||
TYPE_BORDER_TILE_CLASS_CONSTRAINT = 14;
|
||||
|
||||
// Helper functions to convert objects from JS versions
|
||||
|
||||
int GetType(JSContext* cx, jsval val);
|
||||
|
||||
bool GetIntField(JSContext* cx, jsval obj, const char* name, int& ret);
|
||||
bool GetBoolField(JSContext* cx, jsval obj, const char* name, int& ret);
|
||||
bool GetFloatField(JSContext* cx, jsval obj, const char* name, float& ret);
|
||||
bool GetStringField(JSContext* cx, jsval obj, const char* name, std::string& ret);
|
||||
bool GetArrayField(JSContext* cx, jsval obj, const char* name, std::vector<jsval>& ret);
|
||||
bool GetJsvalField(JSContext* cx, jsval obj, const char* name, jsval& ret);
|
||||
|
||||
bool ParseArray(JSContext* cx, jsval val, std::vector<jsval>& ret);
|
||||
|
||||
Terrain* ParseTerrain(JSContext* cx, jsval val);
|
||||
AreaPainter* ParseAreaPainter(JSContext* cx, jsval val);
|
||||
AreaPlacer* ParseAreaPlacer(JSContext* cx, jsval val);
|
||||
ObjectGroupPlacer* ParseObjectGroupPlacer(JSContext* cx, jsval val);
|
||||
Constraint* ParseConstraint(JSContext* cx, jsval val);
|
||||
|
||||
#endif
|
@ -1,75 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "layeredpainter.h"
|
||||
#include "area.h"
|
||||
#include "terrain.h"
|
||||
#include "map.h"
|
||||
#include "pointmap.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
LayeredPainter::LayeredPainter(const vector<Terrain*>& ts, const vector<int>& ws)
|
||||
{
|
||||
terrains = ts;
|
||||
widths = ws;
|
||||
}
|
||||
|
||||
LayeredPainter::~LayeredPainter(void)
|
||||
{
|
||||
}
|
||||
|
||||
void LayeredPainter::paint(Map* m, Area* a) {
|
||||
PointMap<int> saw;
|
||||
PointMap<int> dist;
|
||||
|
||||
queue<Point> q;
|
||||
|
||||
// push edge points
|
||||
vector<Point>& pts = a->points;
|
||||
for(int i=0; i<pts.size(); i++) {
|
||||
int x = pts[i].x, y = pts[i].y;
|
||||
for(int dx=-1; dx<=1; dx++) {
|
||||
for(int dy=-1; dy<=1; dy++) {
|
||||
int nx = x+dx, ny = y+dy;
|
||||
Point np(nx, ny);
|
||||
if(m->validT(nx, ny) && m->area[nx][ny]!=a && !saw[np]) {
|
||||
saw[np] = 1;
|
||||
dist[np] = 0;
|
||||
q.push(np);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// do BFS inwards to find distances to edge
|
||||
while(!q.empty()) {
|
||||
Point p = q.front();
|
||||
q.pop();
|
||||
|
||||
int d = dist[p];
|
||||
|
||||
// paint if in area
|
||||
if(m->area[p.x][p.y] == a) {
|
||||
int w=0, i=0;
|
||||
for(; i<widths.size(); i++) {
|
||||
w += widths[i];
|
||||
if(w>=d) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
terrains[i]->place(m, p.x, p.y);
|
||||
}
|
||||
|
||||
// enqueue neighbours
|
||||
for(int dx=-1; dx<=1; dx++) {
|
||||
for(int dy=-1; dy<=1; dy++) {
|
||||
int nx = p.x+dx, ny = p.y+dy;
|
||||
Point np(nx, ny);
|
||||
if(m->validT(nx, ny) && m->area[nx][ny]==a && !saw[np]) {
|
||||
saw[np] = 1;
|
||||
dist[np] = d+1;
|
||||
q.push(np);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
#ifndef __LAYEREDPAINTER_H__
|
||||
#define __LAYEREDPAINTER_H__
|
||||
|
||||
#include "areapainter.h"
|
||||
#include "terrain.h"
|
||||
|
||||
class LayeredPainter :
|
||||
public AreaPainter
|
||||
{
|
||||
private:
|
||||
std::vector<Terrain*> terrains;
|
||||
std::vector<int> widths;
|
||||
public:
|
||||
LayeredPainter(const std::vector<Terrain*>& terrains, const std::vector<int>& widths);
|
||||
~LayeredPainter(void);
|
||||
|
||||
virtual void paint(class Map* m, class Area* a);
|
||||
};
|
||||
|
||||
#endif
|
@ -1,297 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "rmgen.h"
|
||||
#include "map.h"
|
||||
#include "object.h"
|
||||
#include "pmp_file.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
Map::Map(int size, Terrain* baseTerrain, float baseHeight) {
|
||||
if(size<0 || size>1024) {
|
||||
JS_ReportError(cx, "init: map size out of range");
|
||||
}
|
||||
else if(size%16 != 0) {
|
||||
JS_ReportError(cx, "init: map size must be divisible by 16");
|
||||
}
|
||||
|
||||
this->size = size;
|
||||
|
||||
texture = new int*[size];
|
||||
for(int i=0; i<size; i++) {
|
||||
texture[i] = new int[size];
|
||||
}
|
||||
|
||||
terrainObjects = new vector<Object*>*[size];
|
||||
for(int i=0; i<size; i++) {
|
||||
terrainObjects[i] = new vector<Object*>[size];
|
||||
}
|
||||
|
||||
area = new Area**[size];
|
||||
for(int i=0; i<size; i++) {
|
||||
area[i] = new Area*[size];
|
||||
for(int j=0; j<size; j++) {
|
||||
area[i][j] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
height = new float*[size+1];
|
||||
for(int i=0; i<size+1; i++) {
|
||||
height[i] = new float[size+1];
|
||||
for(int j=0; j<size+1; j++) {
|
||||
height[i][j] = baseHeight;
|
||||
}
|
||||
}
|
||||
|
||||
for(int i=0; i<size; i++) {
|
||||
for(int j=0; j<size; j++) {
|
||||
baseTerrain->place(this, i, j);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Map::Map(string fileName, int loadLevel)
|
||||
{
|
||||
const int LOAD_NOTHING = 0;
|
||||
const int LOAD_TERRAIN = 1<<0;
|
||||
const int LOAD_INTERACTIVES = 1 << 1;
|
||||
const int LOAD_NONINTERACTIVES = 1 << 2;
|
||||
//const int SOMETHINGELSE = 1 << 3;
|
||||
|
||||
|
||||
// HACK, this should probably be in a struct and be shared with the code in output.cpp
|
||||
pmp_header hdr;
|
||||
u32 map_size;
|
||||
|
||||
//HACK, also in rmgen.cpp
|
||||
const string SCENARIO_PATH = "../data/mods/public/maps/scenarios/";
|
||||
|
||||
std::string pmpFile = SCENARIO_PATH + fileName + ".pmp";
|
||||
std::string xmlFile = SCENARIO_PATH + fileName + ".xml";
|
||||
|
||||
if (loadLevel & LOAD_TERRAIN)
|
||||
{
|
||||
|
||||
FILE* f = fopen(pmpFile.c_str(), "rb");
|
||||
|
||||
fread(&hdr, sizeof(pmp_header), 1, f);
|
||||
|
||||
/*TODO
|
||||
|
||||
if (hdr.marker !== "PSMP")
|
||||
JS_ReportError(cx, "");
|
||||
|
||||
if (hdr.version !== 4)
|
||||
JS_ReportError(cx, ""); */
|
||||
|
||||
|
||||
fread(&map_size, sizeof(int), 1, f);
|
||||
|
||||
size = map_size * 16;
|
||||
|
||||
// Load height data
|
||||
u16* heightmap = new u16[(size+1) * (size+1)];
|
||||
fread(heightmap, 2, ((size+1)*(size+1)), f);
|
||||
|
||||
height = new float*[(size+1)];
|
||||
for(int i=0; i<(size+1); i++)
|
||||
{
|
||||
height[i] = new float[(size+1)];
|
||||
for(int j=0; j<(size+1); j++)
|
||||
{
|
||||
height[i][j] = (float) (heightmap[(j*(size+1)) + i] / 256.0f) * 0.35f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Load the list of used textures
|
||||
|
||||
int numTextures;
|
||||
int strLength;
|
||||
|
||||
fread(&numTextures, sizeof(int), 1, f);
|
||||
|
||||
for (int i=0; i<numTextures; i++)
|
||||
{
|
||||
fread(&strLength, sizeof(int), 1, f);
|
||||
std::string name;
|
||||
|
||||
vector<char> buf(strLength+1);
|
||||
fread(&buf[0], 1, strLength, f);
|
||||
name = &buf[0];
|
||||
|
||||
// This will add the texture to the NameToId and idToName vectors if it
|
||||
// doesn't already exist. And in this case it shouldn't.
|
||||
getId( name.substr(0, name.length()-4));
|
||||
}
|
||||
|
||||
texture = new int*[size];
|
||||
for(int i=0; i<size; i++) {
|
||||
texture[i] = new int[size];
|
||||
}
|
||||
|
||||
Tile* tiles = new Tile[size*size];
|
||||
fread(tiles, sizeof(Tile), size*size, f);
|
||||
|
||||
for(int x=0; x<size; x++)
|
||||
{
|
||||
for(int y=0; y<size; y++)
|
||||
{
|
||||
int patchX = x/16, patchY = y/16;
|
||||
int offX = x%16, offY = y%16;
|
||||
Tile& t = tiles[ (patchY*size/16 + patchX)*16*16 + (offY*16 + offX) ];
|
||||
this->texture[x][y] = t.texture1;
|
||||
}
|
||||
}
|
||||
|
||||
terrainObjects = new vector<Object*>*[size];
|
||||
for(int i=0; i<size; i++) {
|
||||
terrainObjects[i] = new vector<Object*>[size];
|
||||
}
|
||||
|
||||
area = new Area**[size];
|
||||
for(int i=0; i<size; i++) {
|
||||
area[i] = new Area*[size];
|
||||
for(int j=0; j<size; j++) {
|
||||
area[i][j] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
|
||||
if ((loadLevel & (LOAD_INTERACTIVES | LOAD_NONINTERACTIVES)) != LOAD_NOTHING)
|
||||
{
|
||||
|
||||
//TODO: Load xml here
|
||||
|
||||
if (loadLevel & LOAD_INTERACTIVES)
|
||||
{
|
||||
//printf("Loading interactives..\n");
|
||||
}
|
||||
|
||||
|
||||
if (loadLevel & LOAD_NONINTERACTIVES)
|
||||
{
|
||||
//printf("Loading non-interactives..\n");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
Map::~Map() {
|
||||
for(int i=0; i<size; i++) {
|
||||
delete[] texture[i];
|
||||
}
|
||||
delete[] texture;
|
||||
|
||||
for(int i=0; i<size; i++) {
|
||||
delete[] terrainObjects[i];
|
||||
}
|
||||
delete[] terrainObjects;
|
||||
|
||||
for(int i=0; i<size+1; i++) {
|
||||
delete[] height[i];
|
||||
}
|
||||
delete[] height;
|
||||
|
||||
for(int i=0; i<size; i++) {
|
||||
delete[] area[i];
|
||||
}
|
||||
delete[] area;
|
||||
|
||||
for(int i=0; i<objects.size(); i++) {
|
||||
delete objects[i];
|
||||
}
|
||||
}
|
||||
|
||||
int Map::getId(string texture) {
|
||||
if(nameToId.find(texture) != nameToId.end()) {
|
||||
return nameToId[texture];
|
||||
}
|
||||
else {
|
||||
int newId = nameToId.size();
|
||||
nameToId[texture] = newId;
|
||||
idToName[newId] = texture;
|
||||
return newId;
|
||||
}
|
||||
}
|
||||
|
||||
string Map::getTexture(int x, int y) {
|
||||
if(!validT(x,y)) JS_ReportError(cx, "getTexture: invalid tile position");
|
||||
return idToName[texture[x][y]];
|
||||
}
|
||||
|
||||
void Map::setTexture(int x, int y, const string& t) {
|
||||
if(!validT(x,y)) JS_ReportError(cx, "setTexture: invalid tile position");
|
||||
texture[x][y] = getId(t);
|
||||
}
|
||||
|
||||
float Map::getHeight(int x, int y) {
|
||||
if(!validH(x,y)) JS_ReportError(cx, "getHeight: invalid vertex position");
|
||||
return height[x][y];
|
||||
}
|
||||
|
||||
void Map::setHeight(int x, int y, float h) {
|
||||
if(!validH(x,y)) JS_ReportError(cx, "setHeight: invalid vertex position");
|
||||
height[x][y] = h;
|
||||
}
|
||||
|
||||
vector<Object*> Map::getTerrainObjects(int x, int y) {
|
||||
if(!validT(x,y)) JS_ReportError(cx, "getTerrainObjects: invalid tile position");
|
||||
return terrainObjects[x][y];
|
||||
}
|
||||
|
||||
void Map::setTerrainObjects(int x, int y, vector<Object*> &objects) {
|
||||
if(!validT(x,y)) JS_ReportError(cx, "setTerrainObjects: invalid tile position");
|
||||
terrainObjects[x][y] = objects;
|
||||
}
|
||||
|
||||
void Map::placeTerrain(int x, int y, Terrain* t) {
|
||||
t->place(this, x, y);
|
||||
}
|
||||
|
||||
void Map::addObject(Object* ent) {
|
||||
objects.push_back(ent);
|
||||
}
|
||||
|
||||
Area* Map::createArea(AreaPlacer* placer, AreaPainter* painter, Constraint* constr) {
|
||||
vector<Point> points;
|
||||
if(!placer->place(this, constr, points)) {
|
||||
return 0;
|
||||
}
|
||||
Area* a = new Area(points);
|
||||
for(int i=0; i<points.size(); i++) {
|
||||
area[points[i].x][points[i].y] = a;
|
||||
}
|
||||
painter->paint(this, a);
|
||||
areas.push_back(a);
|
||||
return a;
|
||||
}
|
||||
|
||||
bool Map::createObjectGroup(ObjectGroupPlacer* placer, int player, Constraint* constr) {
|
||||
return placer->place(this, player, constr);
|
||||
}
|
||||
|
||||
int Map::createTileClass() {
|
||||
tileClasses.push_back(new TileClass(size));
|
||||
return tileClasses.size();
|
||||
}
|
||||
|
||||
float Map::getExactHeight(float x, float y) {
|
||||
// copied & modified from ScEd
|
||||
|
||||
int xi = min((int) floor(x), size);
|
||||
int yi = min((int) floor(y), size);
|
||||
float xf = x - xi;
|
||||
float yf = y - yi;
|
||||
|
||||
float h00 = height[xi][yi];
|
||||
float h01 = height[xi][yi+1];
|
||||
float h10 = height[xi+1][yi];
|
||||
float h11 = height[xi+1][yi+1];
|
||||
|
||||
return ( 1 - yf ) * ( ( 1 - xf ) * h00 + xf * h10 ) + yf * ( ( 1 - xf ) * h01 + xf * h11 ) ;
|
||||
}
|
@ -1,58 +0,0 @@
|
||||
#ifndef __MAP_H__
|
||||
#define __MAP_H__
|
||||
|
||||
#include "area.h"
|
||||
#include "areapainter.h"
|
||||
#include "areaplacer.h"
|
||||
#include "constraint.h"
|
||||
#include "object.h"
|
||||
#include "terrain.h"
|
||||
#include "objectgroupplacer.h"
|
||||
#include "tileclass.h"
|
||||
|
||||
class Map {
|
||||
public:
|
||||
int size;
|
||||
int** texture;
|
||||
std::vector<Object*>** terrainObjects;
|
||||
float** height;
|
||||
Area*** area;
|
||||
std::map<std::string, int> nameToId;
|
||||
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);
|
||||
~Map();
|
||||
|
||||
int getId(std::string texture);
|
||||
|
||||
bool validT(int x, int y) { return x>=0 && y>=0 && x<size && y<size; }
|
||||
bool validH(int x, int y) { return x>=0 && y>=0 && x<=size && y<=size; }
|
||||
|
||||
bool validClass(int c) { return c>=0 && c<(int)tileClasses.size(); }
|
||||
|
||||
std::string getTexture(int x, int y);
|
||||
void setTexture(int x, int y, const std::string& texture);
|
||||
|
||||
float getHeight(int x, int y);
|
||||
void setHeight(int x, int y, float height);
|
||||
|
||||
std::vector<Object*> getTerrainObjects(int x, int y);
|
||||
void setTerrainObjects(int x, int y, std::vector<Object*> &objects);
|
||||
|
||||
void placeTerrain(int x, int y, Terrain* t);
|
||||
|
||||
void addObject(class Object* ent);
|
||||
|
||||
Area* createArea(AreaPlacer* placer, AreaPainter* painter, Constraint* constr);
|
||||
bool createObjectGroup(ObjectGroupPlacer* placer, int player, Constraint* constr);
|
||||
|
||||
int createTileClass(); // returns ID of the new class
|
||||
|
||||
float getExactHeight(float x, float y); // get height taking into account terrain curvature
|
||||
};
|
||||
|
||||
#endif
|
@ -1,152 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "Noise.h"
|
||||
#include <cmath>
|
||||
#include "random.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace
|
||||
{
|
||||
/// Utility function used in both noises as an ease curve
|
||||
float easeCurve(float t)
|
||||
{
|
||||
return t*t*t*(t*(t*6-15)+10);
|
||||
}
|
||||
}
|
||||
|
||||
Noise2D::Noise2D(int f)
|
||||
{
|
||||
freq = f;
|
||||
grads = new CVector2D_Maths*[freq];
|
||||
for(int i=0; i<freq; i++)
|
||||
{
|
||||
grads[i] = new CVector2D_Maths[freq];
|
||||
for(int j=0; j<freq; j++)
|
||||
{
|
||||
float a = RandFloat() * 2 * PI;
|
||||
grads[i][j] = CVector2D_Maths(cos(a), sin(a));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Noise2D::~ Noise2D()
|
||||
{
|
||||
for(int i=0; i<freq; i++)
|
||||
{
|
||||
delete[] grads[i];
|
||||
}
|
||||
delete[] grads;
|
||||
}
|
||||
|
||||
float Noise2D::operator()(float x, float y)
|
||||
{
|
||||
x *= freq;
|
||||
y *= freq;
|
||||
|
||||
int ix = (int)floor(x);
|
||||
int iy = (int)floor(y);
|
||||
|
||||
float fx = x - ix;
|
||||
float fy = y - iy;
|
||||
|
||||
ix %= freq; if(ix<0) ix += freq;
|
||||
iy %= freq; if(iy<0) iy += freq;
|
||||
|
||||
int ix1 = (ix+1) % freq;
|
||||
int iy1 = (iy+1) % freq;
|
||||
|
||||
float s = grads[ix][iy].Dot(CVector2D_Maths(fx, fy));
|
||||
float t = grads[ix1][iy].Dot(CVector2D_Maths(fx-1, fy));
|
||||
float u = grads[ix][iy1].Dot(CVector2D_Maths(fx, fy-1));
|
||||
float v = grads[ix1][iy1].Dot(CVector2D_Maths(fx-1, fy-1));
|
||||
|
||||
float ex = easeCurve(fx);
|
||||
float ey = easeCurve(fy);
|
||||
float a = s + ex*(t-s);
|
||||
float b = u + ex*(v-u);
|
||||
return (a + ey*(b-a)) * .5 + .5;
|
||||
}
|
||||
|
||||
Noise3D::Noise3D(int f, int v) : freq(f), vfreq(v)
|
||||
{
|
||||
grads = new CVector3D**[freq];
|
||||
for(int i=0; i<freq; i++)
|
||||
{
|
||||
grads[i] = new CVector3D*[freq];
|
||||
for(int j=0; j<freq; j++)
|
||||
{
|
||||
grads[i][j] = new CVector3D[vfreq];
|
||||
for(int k=0; k<vfreq; k++)
|
||||
{
|
||||
CVector3D v;
|
||||
do {
|
||||
v = CVector3D(2*RandFloat()-1, 2*RandFloat()-1, 2*RandFloat()-1);
|
||||
}
|
||||
while(v.LengthSquared() > 1 || v.LengthSquared() < 0.1);
|
||||
v.Normalize();
|
||||
grads[i][j][k] = CVector3D(v.X, v.Y, v.Z);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Noise3D::~ Noise3D()
|
||||
{
|
||||
for(int i=0; i<freq; i++)
|
||||
{
|
||||
for(int j=0; j<freq; j++)
|
||||
{
|
||||
delete[] grads[i][j];
|
||||
}
|
||||
delete[] grads[i];
|
||||
}
|
||||
delete[] grads;
|
||||
}
|
||||
|
||||
float Noise3D::operator()(float x, float y, float z)
|
||||
{
|
||||
x *= freq;
|
||||
y *= freq;
|
||||
z *= vfreq;
|
||||
|
||||
int ix = (int)floor(x);
|
||||
int iy = (int)floor(y);
|
||||
int iz = (int)floor(z);
|
||||
|
||||
float fx = x - ix;
|
||||
float fy = y - iy;
|
||||
float fz = z - iz;
|
||||
|
||||
ix %= freq; if(ix<0) ix += freq;
|
||||
iy %= freq; if(iy<0) iy += freq;
|
||||
iz %= vfreq; if(iz<0) iz += vfreq;
|
||||
|
||||
int ix1 = (ix+1) % freq;
|
||||
int iy1 = (iy+1) % freq;
|
||||
int iz1 = (iz+1) % vfreq;
|
||||
|
||||
float s0 = grads[ix][iy][iz].Dot(CVector3D(fx, fy, fz));
|
||||
float t0 = grads[ix1][iy][iz].Dot(CVector3D(fx-1, fy, fz));
|
||||
float u0 = grads[ix][iy1][iz].Dot(CVector3D(fx, fy-1, fz));
|
||||
float v0 = grads[ix1][iy1][iz].Dot(CVector3D(fx-1, fy-1, fz));
|
||||
|
||||
float s1 = grads[ix][iy][iz1].Dot(CVector3D(fx, fy, fz-1));
|
||||
float t1 = grads[ix1][iy][iz1].Dot(CVector3D(fx-1, fy, fz-1));
|
||||
float u1 = grads[ix][iy1][iz1].Dot(CVector3D(fx, fy-1, fz-1));
|
||||
float v1 = grads[ix1][iy1][iz1].Dot(CVector3D(fx-1, fy-1, fz-1));
|
||||
|
||||
float ex = easeCurve(fx);
|
||||
float ey = easeCurve(fy);
|
||||
float ez = easeCurve(fz);
|
||||
|
||||
float a0 = s0 + ex*(t0-s0);
|
||||
float b0 = u0 + ex*(v0-u0);
|
||||
float c0 = a0 + ey*(b0-a0);
|
||||
|
||||
float a1 = s1 + ex*(t1-s1);
|
||||
float b1 = u1 + ex*(v1-u1);
|
||||
float c1 = a1 + ey*(b1-a1);
|
||||
|
||||
return (c0 + ez*(c1-c0)) * .5 + .5;
|
||||
}
|
||||
|
@ -1,51 +0,0 @@
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
// Name: Noise.h
|
||||
//
|
||||
// Description: 2D and 3D seamless Perlin noise classes. Not optimized for speed yet.
|
||||
//
|
||||
// Based on http://www.cs.cmu.edu/~mzucker/code/perlin-noise-math-faq.html
|
||||
// and http://mrl.nyu.edu/~perlin/paper445.pdf.
|
||||
//
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef NOISE_H
|
||||
#define NOISE_H
|
||||
|
||||
#include "Vector2D.h"
|
||||
#include "Vector3D.h"
|
||||
#include "MathUtil.h"
|
||||
|
||||
class Noise2D
|
||||
{
|
||||
/// Frequency in X and Y
|
||||
int freq;
|
||||
|
||||
/// freq*freq random gradient vectors in the unit cube
|
||||
CVector2D_Maths** grads;
|
||||
public:
|
||||
Noise2D(int freq);
|
||||
~Noise2D();
|
||||
|
||||
/// Evaluate the noise function at a given point
|
||||
float operator() (float x, float y);
|
||||
};
|
||||
|
||||
class Noise3D
|
||||
{
|
||||
/// Frequency in X and Y
|
||||
int freq;
|
||||
|
||||
/// Frequency in Z (vertical frequency)
|
||||
int vfreq;
|
||||
|
||||
/// freq*freq*vfreq random gradient vectors in the unit cube
|
||||
CVector3D*** grads;
|
||||
public:
|
||||
Noise3D(int freq, int vfreq);
|
||||
~Noise3D();
|
||||
|
||||
/// Evaluate the noise function at a given point
|
||||
float operator() (float x, float y, float z);
|
||||
};
|
||||
|
||||
#endif
|
@ -1,22 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "object.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
Object::Object() {
|
||||
}
|
||||
|
||||
Object::Object(const string& name, int player, float x, float y, float orientation) {
|
||||
this->name = name;
|
||||
this->player = player;
|
||||
this->x = x;
|
||||
this->y = y;
|
||||
this->orientation = orientation;
|
||||
}
|
||||
|
||||
bool Object::isEntity() {
|
||||
for(int i=0; i<name.size(); i++) {
|
||||
if(name[i]=='/') return false;
|
||||
}
|
||||
return true;
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
#ifndef __OBJECT_H__
|
||||
#define __OBJECT_H__
|
||||
|
||||
class Object {
|
||||
public:
|
||||
std::string name; // "template" field for objects, "actor" field for nonobjects
|
||||
int player; // -1 for nonobjects
|
||||
float x, y;
|
||||
float orientation;
|
||||
|
||||
Object();
|
||||
Object(const std::string& name, int player, float x, float y, float orientation);
|
||||
bool isEntity();
|
||||
};
|
||||
|
||||
#endif
|
@ -1,11 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "rmgen.h"
|
||||
#include "objectgroupplacer.h"
|
||||
|
||||
ObjectGroupPlacer::ObjectGroupPlacer() {
|
||||
}
|
||||
|
||||
ObjectGroupPlacer::~ObjectGroupPlacer() {
|
||||
}
|
||||
|
||||
using namespace std;
|
@ -1,16 +0,0 @@
|
||||
#ifndef __OBJECTGROUPPLACER_H__
|
||||
#define __OBJECTGROUPPLACER_H__
|
||||
|
||||
#include "constraint.h"
|
||||
#include "object.h"
|
||||
|
||||
class ObjectGroupPlacer
|
||||
{
|
||||
public:
|
||||
virtual bool place(class Map* m, int player, Constraint* constr) = 0;
|
||||
|
||||
ObjectGroupPlacer(void);
|
||||
virtual ~ObjectGroupPlacer(void);
|
||||
};
|
||||
|
||||
#endif
|
@ -1,193 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "rmgen.h"
|
||||
#include "output.h"
|
||||
#include "map.h"
|
||||
#include "object.h"
|
||||
#include "pmp_file.h"
|
||||
#include <iomanip>
|
||||
|
||||
using namespace std;
|
||||
|
||||
// Sea level elevation
|
||||
const float SEA_LEVEL = 20.0f;
|
||||
|
||||
void OutputObject(Map* m, Object* e, ostringstream& xml) {
|
||||
float height = m->getExactHeight(e->x, e->y) + SEA_LEVEL;
|
||||
|
||||
if(e->isEntity()) {
|
||||
xml << "\
|
||||
<Entity>\n\
|
||||
<Template>" << e->name << "</Template>\n\
|
||||
<Player>" << e->player << "</Player>\n\
|
||||
<Position x=\"" << 4*e->x << "\" y=\"" << height << "\" z=\"" << 4*e->y << "\" />\n\
|
||||
<Orientation angle=\"" << e->orientation << "\" />\n\
|
||||
</Entity>\n";
|
||||
}
|
||||
else {
|
||||
xml << "\
|
||||
<Nonentity>\n\
|
||||
<Actor>" << e->name << "</Actor>\n\
|
||||
<Position x=\"" << 4*e->x << "\" y=\"" << height << "\" z=\"" << 4*e->y << "\" />\n\
|
||||
<Orientation angle=\"" << e->orientation << "\" />\n\
|
||||
</Nonentity>\n";
|
||||
}
|
||||
}
|
||||
|
||||
void OutputObjects(ostringstream& xml, Map* m, bool entities) {
|
||||
for(int i=0; i<m->objects.size(); i++) {
|
||||
if(m->objects[i]->isEntity() == entities) {
|
||||
OutputObject(m, m->objects[i], xml);
|
||||
}
|
||||
}
|
||||
|
||||
for(int x=0; x<m->size; x++) {
|
||||
for(int y=0; y<m->size; y++) {
|
||||
vector<Object*>& vec = m->terrainObjects[x][y];
|
||||
for(int i=0; i<vec.size(); i++) {
|
||||
if(vec[i]->isEntity() == entities) {
|
||||
OutputObject(m, vec[i], xml);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void OutputXml(Map* m, FILE* f) {
|
||||
ostringstream xml;
|
||||
xml << "\
|
||||
<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>\n\
|
||||
<Scenario>\n\
|
||||
<Environment>\n\
|
||||
<SunColour r=\"1\" g=\"1\" b=\"1\" />\n\
|
||||
<SunElevation angle=\"0.72\" />\n\
|
||||
<SunRotation angle=\"0.5\" />\n\
|
||||
<TerrainAmbientColour r=\"0.5\" g=\"0.5\" b=\"0.5\" />\n\
|
||||
<UnitsAmbientColour r=\"0.52\" g=\"0.52\" b=\"0.52\" />\n\
|
||||
<Water><WaterBody><Height>" << SEA_LEVEL-0.1f << "</Height></WaterBody></Water>\n\
|
||||
</Environment>\n\
|
||||
<Entities>\n";
|
||||
OutputObjects(xml, m, true); // print entities
|
||||
xml << "\
|
||||
</Entities>\n\
|
||||
<Nonentities>\n";
|
||||
OutputObjects(xml, m, false); // print nonentities
|
||||
xml << "\
|
||||
</Nonentities>\n\
|
||||
</Scenario>\n";
|
||||
|
||||
fprintf(f, "%s", xml.str().c_str());
|
||||
}
|
||||
|
||||
|
||||
void OutputPmp(Map* m, FILE* f) {
|
||||
/*
|
||||
struct String {
|
||||
u32 length;
|
||||
char data[length]; // not NUL-terminated
|
||||
};
|
||||
struct PMP {
|
||||
char header[4]; // == "PSMP"
|
||||
u32 version; // == 4
|
||||
u32 data_size; // == filesize-12
|
||||
|
||||
|
||||
u32 map_size; // number of patches (16x16 tiles) per side
|
||||
|
||||
u16 heightmap[(mapsize*16 + 1)^2]; // (squared, not xor) - vertex heights
|
||||
|
||||
u32 num_texture_textures;
|
||||
String texture_textures[num_texture_textures]; // filenames (no path), e.g. "cliff1.dds"
|
||||
|
||||
Tile tiles[(mapsize*16)^2];
|
||||
};*/
|
||||
int size = m->size;
|
||||
int numTextures = m->idToName.size();
|
||||
|
||||
// header
|
||||
fwrite("PSMP", sizeof(char), 4, f);
|
||||
|
||||
// file format version
|
||||
u32 version = 4;
|
||||
fwrite(&version, sizeof(u32), 1, f);
|
||||
|
||||
// data size (write 0 for now, calculate it at the end)
|
||||
int temp = 0;
|
||||
fwrite(&temp, sizeof(u32), 1, f);
|
||||
|
||||
// map size in patches
|
||||
u32 sizeInPatches = size/16;
|
||||
fwrite(&sizeInPatches, sizeof(u32), 1, f);
|
||||
|
||||
// heightmap
|
||||
u16* heightmap = new u16[(size+1)*(size+1)];
|
||||
for(int x=0; x<size+1; x++) {
|
||||
for(int y=0; y<size+1; y++) {
|
||||
int intHeight = (int) ((m->height[x][y]+SEA_LEVEL) * 256.0f / 0.35f);
|
||||
if(intHeight > 0xFFFF) {
|
||||
intHeight = 0xFFFF;
|
||||
}
|
||||
else if(intHeight < 0) {
|
||||
intHeight = 0;
|
||||
}
|
||||
heightmap[y*(size+1)+x] = intHeight;
|
||||
}
|
||||
}
|
||||
fwrite(heightmap, sizeof(u16), (size+1)*(size+1), f);
|
||||
|
||||
// num texture textures
|
||||
fwrite(&numTextures, sizeof(u32), 1, f);
|
||||
|
||||
// texture names
|
||||
for(int i=0; i<numTextures; i++) {
|
||||
string fname = m->idToName[i] + ".dds";
|
||||
int len = fname.length();
|
||||
fwrite(&len, sizeof(u32), 1, f);
|
||||
fwrite(fname.c_str(), sizeof(char), fname.length(), f);
|
||||
}
|
||||
|
||||
|
||||
// texture; note that this is an array of 16x16 patches for some reason
|
||||
Tile* tiles = new Tile[size*size];
|
||||
for(int x=0; x<size; x++) {
|
||||
for(int y=0; y<size; y++) {
|
||||
int patchX = x/16, patchY = y/16;
|
||||
int offX = x%16, offY = y%16;
|
||||
Tile& t = tiles[ (patchY*size/16 + patchX)*16*16 + (offY*16 + offX) ];
|
||||
t.texture1 = m->texture[x][y];
|
||||
t.texture2 = 0xFFFF;
|
||||
t.priority = 0;
|
||||
}
|
||||
}
|
||||
fwrite(tiles, sizeof(Tile), size*size, f);
|
||||
|
||||
|
||||
|
||||
// data size (file size - 12)
|
||||
fseek(f, 0, SEEK_END);
|
||||
int fsize = ftell(f);
|
||||
u32 dataSize = fsize-12;
|
||||
fseek(f, 8, SEEK_SET);
|
||||
fwrite(&dataSize, sizeof(u32), 1, f);
|
||||
}
|
||||
|
||||
void OutputMap(Map* m, const string& outputName) {
|
||||
string xmlName = outputName + ".xml";
|
||||
FILE* xmlFile = fopen(xmlName.c_str(), "w");
|
||||
if(!xmlFile) {
|
||||
cerr << "Cannot open " << xmlName << endl;
|
||||
Shutdown(1);
|
||||
}
|
||||
OutputXml(m, xmlFile);
|
||||
fclose(xmlFile);
|
||||
|
||||
string pmpName = outputName + ".pmp";
|
||||
FILE* pmpFile = fopen(pmpName.c_str(), "wb");
|
||||
if(!pmpFile) {
|
||||
cerr << "Cannot open " << pmpName << endl;
|
||||
Shutdown(1);
|
||||
}
|
||||
OutputPmp(m, pmpFile);
|
||||
fclose(pmpFile);
|
||||
|
||||
cout << "Map outputted to " << outputName << ".*" << endl;
|
||||
}
|
@ -1,8 +0,0 @@
|
||||
#ifndef __OUTPUT_H__
|
||||
#define __OUTPUT_H__
|
||||
|
||||
#include "map.h"
|
||||
|
||||
void OutputMap(Map* map, const std::string& path);
|
||||
|
||||
#endif
|
@ -1,21 +0,0 @@
|
||||
#ifndef __PMP_FILE_H__
|
||||
#define __PMP_FILE_H__
|
||||
|
||||
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned int u32;
|
||||
|
||||
struct Tile {
|
||||
u16 texture1; // index into texture_textures[]
|
||||
u16 texture2; // index, or 0xFFFF for 'none'
|
||||
u32 priority; // ???
|
||||
};
|
||||
|
||||
struct pmp_header
|
||||
{
|
||||
char marker[4];
|
||||
u32 version;
|
||||
u32 data_size;
|
||||
};
|
||||
|
||||
#endif
|
@ -1,27 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "point.h"
|
||||
|
||||
Point::Point(void)
|
||||
{
|
||||
x = y = 0;
|
||||
}
|
||||
|
||||
Point::Point(int x_, int y_) : x(x_), y(y_)
|
||||
{
|
||||
}
|
||||
|
||||
Point::~Point(void)
|
||||
{
|
||||
}
|
||||
|
||||
bool Point::operator <(const Point& p) const {
|
||||
return x<p.x || (x==p.x && y<p.y);
|
||||
}
|
||||
|
||||
bool Point::operator ==(const Point& p) const {
|
||||
return x==p.x && y==p.y;
|
||||
}
|
||||
|
||||
Point::operator size_t() const {
|
||||
return (x<<10) ^ y;
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
#ifndef __POINT_H_
|
||||
#define __POINT_H_
|
||||
|
||||
class Point
|
||||
{
|
||||
public:
|
||||
int x, y;
|
||||
Point(void);
|
||||
Point(int x, int y);
|
||||
~Point(void);
|
||||
bool operator<(const Point& p) const;
|
||||
bool operator==(const Point& p) const;
|
||||
operator size_t() const; // cheap hack to provide a hash function
|
||||
};
|
||||
|
||||
#endif
|
@ -1,47 +0,0 @@
|
||||
#ifndef __POINTMAP_H__
|
||||
#define __POINTMAP_H__
|
||||
|
||||
#include "point.h"
|
||||
|
||||
// A 2D map class; should probably be optimized more, but beats STL map or hash_map
|
||||
template<typename E> class PointMap
|
||||
{
|
||||
static const int T = 5, P = 5;
|
||||
static const int T_VAL = (1<<T), P_VAL = (1<<P);
|
||||
static const int T_MASK = (1<<T)-1, P_MASK = (1<<P)-1;
|
||||
E** patches;
|
||||
public:
|
||||
PointMap(void)
|
||||
{
|
||||
patches = new E*[1<<(P+P)];
|
||||
memset(patches, 0, (1<<(P+P)) * sizeof(E*));
|
||||
}
|
||||
|
||||
~PointMap(void)
|
||||
{
|
||||
for(int i=0; i < (1<<(P+P)); i++)
|
||||
{
|
||||
if(patches[i] != 0)
|
||||
{
|
||||
delete[] patches[i];
|
||||
}
|
||||
}
|
||||
delete[] patches;
|
||||
}
|
||||
|
||||
E& operator[] (Point p)
|
||||
{
|
||||
int patchIndex = (p.x >> T) * P_VAL + (p.y >> T);
|
||||
int tileIndex = (p.x & T_MASK) * T_VAL + (p.y & T_MASK);
|
||||
|
||||
if(patches[patchIndex] == 0)
|
||||
{
|
||||
patches[patchIndex] = new E[1<<(T+T)];
|
||||
memset(patches[patchIndex], 0, (1<<(T+T)) * sizeof(E));
|
||||
}
|
||||
|
||||
return patches[patchIndex][tileIndex];
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
@ -1,28 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "random.h"
|
||||
|
||||
using namespace boost;
|
||||
|
||||
mt19937 rng;
|
||||
|
||||
void SeedRand(unsigned long s) {
|
||||
rng.seed(s);
|
||||
}
|
||||
|
||||
int RandInt(int maxVal) {
|
||||
return rng()%maxVal;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -1,5 +0,0 @@
|
||||
void SeedRand(unsigned long seed);
|
||||
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)
|
@ -1,49 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "rangeop.h"
|
||||
|
||||
RangeOp::RangeOp(int size) {
|
||||
nn = 1;
|
||||
while(nn < size) {
|
||||
nn *= 2;
|
||||
}
|
||||
vals = new int[2*nn];
|
||||
memset(vals, 0, 2*nn*sizeof(int));
|
||||
}
|
||||
|
||||
RangeOp::~RangeOp() {
|
||||
delete[] vals;
|
||||
}
|
||||
|
||||
int RangeOp::get(int pos) {
|
||||
return vals[nn + pos];
|
||||
}
|
||||
|
||||
void RangeOp::set(int pos, int amt) {
|
||||
add(pos, amt-get(pos));
|
||||
}
|
||||
|
||||
void RangeOp::add(int pos, int amt) {
|
||||
for(int s=nn; s>0; s/=2) {
|
||||
vals[s + pos] += amt;
|
||||
pos /= 2;
|
||||
}
|
||||
}
|
||||
|
||||
int RangeOp::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;
|
||||
}
|
@ -1,17 +0,0 @@
|
||||
#ifndef __RANGEOP_H__
|
||||
#define __RANGEOP_H__
|
||||
|
||||
class RangeOp {
|
||||
private:
|
||||
int* vals; // has size 2*nn
|
||||
int nn; // smallest power of 2 >= size
|
||||
public:
|
||||
RangeOp(int size);
|
||||
~RangeOp();
|
||||
void set(int pos, int amt);
|
||||
void add(int pos, int amt);
|
||||
int get(int pos);
|
||||
int get(int start, int end);
|
||||
};
|
||||
|
||||
#endif
|
@ -1,29 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "rectplacer.h"
|
||||
#include "map.h"
|
||||
|
||||
RectPlacer::RectPlacer(int x1, int y1, int x2, int y2)
|
||||
{
|
||||
this->x1 = x1;
|
||||
this->y1 = y1;
|
||||
this->x2 = x2;
|
||||
this->y2 = y2;
|
||||
}
|
||||
|
||||
RectPlacer::~RectPlacer(void)
|
||||
{
|
||||
}
|
||||
|
||||
bool RectPlacer::place(Map* m, Constraint* constr, std::vector<Point>& ret) {
|
||||
for(int x=x1; x<x2; x++) {
|
||||
for(int y=y1; y<y2; y++) {
|
||||
if(m->validT(x,y) && constr->allows(m,x,y)) {
|
||||
ret.push_back(Point(x,y));
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
#ifndef __RECTPLACER_H__
|
||||
#define __RECTPLACER_H__
|
||||
|
||||
#include "areaplacer.h"
|
||||
#include "map.h"
|
||||
|
||||
class RectPlacer :
|
||||
public AreaPlacer
|
||||
{
|
||||
public:
|
||||
int x1, y1, x2, y2;
|
||||
|
||||
bool place(Map* m, Constraint* constr, std::vector<Point>& ret);
|
||||
|
||||
RectPlacer(int x1, int y1, int x2, int y2);
|
||||
~RectPlacer(void);
|
||||
};
|
||||
|
||||
#endif
|
@ -1,160 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "rmgen.h"
|
||||
#include "map.h"
|
||||
#include "output.h"
|
||||
#include "api.h"
|
||||
#include "scripting.h"
|
||||
#include "random.h"
|
||||
#include "noise.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace js;
|
||||
|
||||
JSRuntime *rt = 0;
|
||||
JSContext *cx = 0;
|
||||
JSObject *global = 0;
|
||||
|
||||
Map* theMap = 0;
|
||||
|
||||
// JS support functions
|
||||
|
||||
template<typename T> JSClass Class<T>::jsClass = {
|
||||
"T", JSCLASS_HAS_PRIVATE,
|
||||
JS_PropertyStub, JS_PropertyStub, Class<T>::getProperty, Class<T>::setProperty,
|
||||
JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub
|
||||
// Note: the finalize stub should really be replaced by some function which
|
||||
// deletes the object if it must be deleted; this requires that we use some
|
||||
// kind of smart handles instead of just pointers though, so we don't delete
|
||||
// objects that we actually want C++ to use (which is most objects)
|
||||
};
|
||||
template<typename T> JSNative Class<T>::constructor;
|
||||
template<typename T> vector<JSFunctionSpec> Class<T>::methodSpecs;
|
||||
template<typename T> vector<JSPropertySpec> Class<T>::propertySpecs;
|
||||
template<typename T> vector<AbstractProperty*> Class<T>::properties;
|
||||
|
||||
void ErrorReporter(JSContext *cx, const char *message, JSErrorReport *report) {
|
||||
string path = string(report->filename);
|
||||
int lastSlash = -1;
|
||||
for(int i = ((int) path.size()) - 1; i >= 0; i--) {
|
||||
if(path[i]=='/' || path[i]=='\\') {
|
||||
lastSlash = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
string filename = path.substr(lastSlash+1);
|
||||
cerr << "Error at " << filename << ":" << report->lineno << ":\n\t"
|
||||
<< message << endl;
|
||||
Shutdown(1);
|
||||
}
|
||||
|
||||
void InitJS() {
|
||||
rt = JS_NewRuntime(8L * 1024L * 1024L);
|
||||
cx = JS_NewContext(rt, 8192);
|
||||
|
||||
JS_SetErrorReporter(cx, ErrorReporter);
|
||||
|
||||
static JSClass globalClass = {
|
||||
"global",0,
|
||||
JS_PropertyStub,JS_PropertyStub,JS_PropertyStub,JS_PropertyStub,
|
||||
JS_EnumerateStub,JS_ResolveStub,JS_ConvertStub,JS_FinalizeStub
|
||||
};
|
||||
global = JS_NewObject(cx, &globalClass, NULL, NULL);
|
||||
JS_InitStandardClasses(cx, global);
|
||||
|
||||
JS_DefineFunctions(cx, global, globalFunctions);
|
||||
|
||||
Class<Noise2D>::addMethod(Method<Noise2D, float, float, float, &Noise2D::operator()>, 2, "eval");
|
||||
Class<Noise2D>::init("Noise2D", Constructor<Noise2D, float>);
|
||||
}
|
||||
|
||||
void Shutdown(int status) {
|
||||
JS_DestroyContext(cx);
|
||||
JS_DestroyRuntime(rt);
|
||||
JS_ShutDown();
|
||||
system("pause");
|
||||
exit(status);
|
||||
}
|
||||
|
||||
char* ValToString(jsval val) {
|
||||
return JS_GetStringBytes(JS_ValueToString(cx, val));
|
||||
}
|
||||
|
||||
jsval NewJSString(const string& str) {
|
||||
char* buf = (char*) JS_malloc(cx, str.length());
|
||||
memcpy(buf, str.c_str(), str.length());
|
||||
return STRING_TO_JSVAL(JS_NewString(cx, buf, str.length()));
|
||||
}
|
||||
|
||||
void ExecuteFile(const string& fileName) {
|
||||
FILE* f = fopen(fileName.c_str(), "r");
|
||||
if(!f) {
|
||||
cerr << "Cannot open " << fileName << endl;
|
||||
Shutdown(1);
|
||||
}
|
||||
|
||||
string code;
|
||||
char buf[1025];
|
||||
while(fgets(buf, 1024, f)) {
|
||||
code += buf;
|
||||
}
|
||||
|
||||
jsval rval;
|
||||
JSBool ok = JS_EvaluateScript(cx, global, code.c_str(), code.length(), fileName.c_str(), 1, &rval);
|
||||
if(!ok) Shutdown(1);
|
||||
}
|
||||
|
||||
// Program entry point
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
const string LIBRARY_FILE = "../data/mods/public/maps/rmlibrary.js";
|
||||
const string RMS_PATH = "../data/mods/public/maps/random/";
|
||||
const string SCENARIO_PATH = "../data/mods/public/maps/scenarios/";
|
||||
|
||||
clock_t start = clock();
|
||||
|
||||
InitJS();
|
||||
|
||||
if(argc!=3 && argc!=4) {
|
||||
cerr << "Usage: rmgen <script> <output map> [<seed>] (no file extensions)" << endl;
|
||||
Shutdown(1);
|
||||
}
|
||||
|
||||
unsigned long seed;
|
||||
if(argc==4) {
|
||||
sscanf(argv[3], "%u", &seed);
|
||||
}
|
||||
else {
|
||||
seed = time(0);
|
||||
}
|
||||
SeedRand(seed);
|
||||
|
||||
// Load map settings (things like game type and player info)
|
||||
ostringstream out;
|
||||
out << "const SEED=" << seed << ";\n";
|
||||
string setts = out.str();
|
||||
jsval rval;
|
||||
JSBool ok = JS_EvaluateScript(cx, global, setts.c_str(), setts.length(),
|
||||
"map settings script", 1, &rval);
|
||||
if(!ok) Shutdown(1);
|
||||
|
||||
// Load library
|
||||
ExecuteFile(LIBRARY_FILE);
|
||||
|
||||
// Run the script
|
||||
ExecuteFile(RMS_PATH + argv[1] + ".js");
|
||||
|
||||
if(!theMap) {
|
||||
cerr << "Error:\n\tScript never called init!" << endl;
|
||||
Shutdown(1);
|
||||
}
|
||||
|
||||
string outputName = SCENARIO_PATH + argv[2];
|
||||
OutputMap(theMap, outputName);
|
||||
|
||||
clock_t end = clock();
|
||||
|
||||
printf("Took %0.3f seconds.\n", float(end-start) / CLOCKS_PER_SEC);
|
||||
|
||||
Shutdown(0);
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
#ifndef __RMGEN_H__
|
||||
#define __RMGEN_H__
|
||||
|
||||
extern JSRuntime *rt;
|
||||
extern JSContext *cx;
|
||||
extern JSObject *global;
|
||||
|
||||
extern class Map* theMap; // ugly
|
||||
|
||||
// Utility functions
|
||||
void Shutdown(int status);
|
||||
char* ValToString(jsval val);
|
||||
jsval NewJSString(const std::string& str);
|
||||
|
||||
#endif
|
@ -1,19 +0,0 @@
|
||||
Microsoft Visual Studio Solution File, Format Version 9.00
|
||||
# Visual Studio 2005
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "rmgen", "rmgen.vcproj", "{ED804376-98E9-4732-A1E9-717D5C6773FA}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Release|Win32 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{ED804376-98E9-4732-A1E9-717D5C6773FA}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{ED804376-98E9-4732-A1E9-717D5C6773FA}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{ED804376-98E9-4732-A1E9-717D5C6773FA}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{ED804376-98E9-4732-A1E9-717D5C6773FA}.Release|Win32.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
@ -1,474 +0,0 @@
|
||||
<?xml version="1.0" encoding="Windows-1252"?>
|
||||
<VisualStudioProject
|
||||
ProjectType="Visual C++"
|
||||
Version="8.00"
|
||||
Name="rmgen"
|
||||
ProjectGUID="{ED804376-98E9-4732-A1E9-717D5C6773FA}"
|
||||
Keyword="Win32Proj"
|
||||
>
|
||||
<Platforms>
|
||||
<Platform
|
||||
Name="Win32"
|
||||
/>
|
||||
</Platforms>
|
||||
<ToolFiles>
|
||||
</ToolFiles>
|
||||
<Configurations>
|
||||
<Configuration
|
||||
Name="Debug|Win32"
|
||||
OutputDirectory="../../../binaries/system"
|
||||
IntermediateDirectory="Debug"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="../../../libraries/boost/include;../../../libraries/spidermonkey/include"
|
||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||
MinimalRebuild="true"
|
||||
BasicRuntimeChecks="3"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="2"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="4"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)/rmgen_dbg.exe"
|
||||
LinkIncremental="2"
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(OutDir)/rmgen.pdb"
|
||||
SubSystem="1"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
<Configuration
|
||||
Name="Release|Win32"
|
||||
OutputDirectory="../../../binaries/system"
|
||||
IntermediateDirectory="Release"
|
||||
ConfigurationType="1"
|
||||
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
|
||||
CharacterSet="2"
|
||||
>
|
||||
<Tool
|
||||
Name="VCPreBuildEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCustomBuildTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXMLDataGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebServiceProxyGeneratorTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCMIDLTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
AdditionalIncludeDirectories="../../../libraries/boost/include;../../../libraries/spidermonkey/include"
|
||||
PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
|
||||
RuntimeLibrary="3"
|
||||
UsePrecompiledHeader="2"
|
||||
WarningLevel="3"
|
||||
Detect64BitPortabilityProblems="true"
|
||||
DebugInformationFormat="3"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManagedResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCResourceCompilerTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPreLinkEventTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
OutputFile="$(OutDir)/rmgen.exe"
|
||||
LinkIncremental="1"
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
EnableCOMDATFolding="2"
|
||||
TargetMachine="1"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCALinkTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCManifestTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCXDCMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCBscMakeTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCFxCopTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCAppVerifierTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCWebDeploymentTool"
|
||||
/>
|
||||
<Tool
|
||||
Name="VCPostBuildEventTool"
|
||||
/>
|
||||
</Configuration>
|
||||
</Configurations>
|
||||
<References>
|
||||
</References>
|
||||
<Files>
|
||||
<Filter
|
||||
Name="Source Files"
|
||||
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||
UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\api.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\area.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\areapainter.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\areaplacer.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\clumpplacer.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\constraint.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\convert.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\layeredpainter.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\map.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\MathUtil.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\noise.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\object.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\objectgroupplacer.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\output.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\point.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\random.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\rangeop.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\rectplacer.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\rmgen.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\simpleconstraints.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\simplegroup.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\simplepainters.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\smoothelevationpainter.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stdafx.cpp"
|
||||
>
|
||||
<FileConfiguration
|
||||
Name="Debug|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
<FileConfiguration
|
||||
Name="Release|Win32"
|
||||
>
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
UsePrecompiledHeader="1"
|
||||
/>
|
||||
</FileConfiguration>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\terrain.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\tileclass.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Vector2D.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Vector3D.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\Vector3D.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Header Files"
|
||||
Filter="h;hpp;hxx;hm;inl;inc;xsd"
|
||||
UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
|
||||
>
|
||||
<File
|
||||
RelativePath=".\api.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\area.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\areapainter.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\areaplacer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\clumpplacer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\constraint.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\convert.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\layeredpainter.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\map.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\noise.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\object.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\objectgroupplacer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\output.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pmp_file.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\point.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pointmap.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\random.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\rangeop.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\rectplacer.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\rmgen.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\scripting.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\simpleconstraints.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\simplegroup.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\simplepainters.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\smoothelevationpainter.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\stdafx.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\terrain.h"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\tileclass.h"
|
||||
>
|
||||
</File>
|
||||
</Filter>
|
||||
<Filter
|
||||
Name="Resource Files"
|
||||
Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx"
|
||||
UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
|
||||
>
|
||||
</Filter>
|
||||
<File
|
||||
RelativePath="..\..\..\binaries\data\mods\official\maps\random\andalucia.js"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\binaries\data\mods\official\maps\random\cantabrian_highlands.js"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\libraries\spidermonkey\lib\js32d.lib"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\binaries\data\mods\official\maps\random\neareastern_badlands.js"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\ReadMe.txt"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\binaries\data\mods\official\maps\rmlibrary.js"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\binaries\data\mods\official\maps\random\test.js"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath="..\..\..\binaries\data\mods\official\maps\random\test2.js"
|
||||
>
|
||||
</File>
|
||||
</Files>
|
||||
<Globals>
|
||||
</Globals>
|
||||
</VisualStudioProject>
|
@ -1,467 +0,0 @@
|
||||
#ifndef SCRIPTING_H
|
||||
#define SCRIPTING_H
|
||||
|
||||
#define XP_WIN
|
||||
#include <js/jsapi.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <cstdlib>
|
||||
|
||||
extern JSContext* cx;
|
||||
extern JSObject* global;
|
||||
|
||||
// Initialize scripting, declaring all our JS classes and functions
|
||||
void ScriptingInit();
|
||||
|
||||
// Run a script
|
||||
void RunScript(const std::string& filename);
|
||||
|
||||
// Shortcut for reporting a nice error to the user if an assertion fails
|
||||
#define jsASSERT(expr) if(!(expr)) { JS_ReportError(cx, \
|
||||
"Assertion failed in %s (%s:%d): " #expr, __FUNCTION__, __FILE__, __LINE__); return JS_FALSE; }
|
||||
|
||||
// A namespace containing utility functions used internally by the scripting API
|
||||
namespace js {
|
||||
// An interface to a property object (we'll have a subclass below once we have
|
||||
// the conversion functions, but this is needed for Class which is needed for
|
||||
// some of the conversion functions)
|
||||
|
||||
class AbstractProperty {
|
||||
public:
|
||||
virtual ~AbstractProperty() {};
|
||||
virtual JSBool set(JSObject *obj, jsval *val) = 0;
|
||||
virtual JSBool get(JSObject *obj, jsval *rval) = 0;
|
||||
};
|
||||
|
||||
// An easy way to wrap an entire class into JavaScript; just call add on
|
||||
// the methods and properties, then call Class<T>::init.
|
||||
|
||||
template<typename T> class Class
|
||||
{
|
||||
public:
|
||||
static JSClass jsClass;
|
||||
private:
|
||||
static JSNative constructor;
|
||||
static std::vector<JSFunctionSpec> methodSpecs;
|
||||
static std::vector<JSPropertySpec> propertySpecs;
|
||||
static std::vector<AbstractProperty*> properties;
|
||||
public:
|
||||
static void addMethod(JSNative func, int numArgs, const char* name) {
|
||||
JSFunctionSpec spec = { name, func, numArgs, 0, 0 };
|
||||
methodSpecs.push_back(spec);
|
||||
}
|
||||
|
||||
static void addProperty(AbstractProperty* (*propGen)(), const char* name) {
|
||||
AbstractProperty* prop = propGen();
|
||||
int index = properties.size();
|
||||
properties.push_back(prop);
|
||||
JSPropertySpec spec = { name, index, JSPROP_ENUMERATE };
|
||||
propertySpecs.push_back(spec);
|
||||
}
|
||||
private:
|
||||
static JSBool getProperty(JSContext*, JSObject *obj, jsval id, jsval *vp) {
|
||||
if(!JSVAL_IS_INT(id)) {
|
||||
if(strcmp(JS_GetStringBytes(JSVAL_TO_STRING(id)), "constructor")==0) {
|
||||
// For some reason this is called for the constructor
|
||||
*vp = JSVAL_NULL; return JS_TRUE;
|
||||
}
|
||||
else {
|
||||
return JS_TRUE;
|
||||
}
|
||||
};
|
||||
int index = JSVAL_TO_INT(id);
|
||||
properties[index]->get(obj, vp);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
static JSBool setProperty(JSContext*, JSObject *obj, jsval id, jsval *vp) {
|
||||
if(!JSVAL_IS_INT(id)) return JS_TRUE;
|
||||
int index = JSVAL_TO_INT(id);
|
||||
properties[index]->set(obj, vp);
|
||||
return JS_TRUE;
|
||||
}
|
||||
public:
|
||||
static void init(const char* name, JSNative cons) {
|
||||
constructor = cons;
|
||||
|
||||
JSFunctionSpec* methods = new JSFunctionSpec[methodSpecs.size() + 1];
|
||||
for(size_t i=0; i<methodSpecs.size(); i++) {
|
||||
methods[i] = methodSpecs[i];
|
||||
}
|
||||
JSFunctionSpec endMethod = { 0 };
|
||||
methods[methodSpecs.size()] = endMethod;
|
||||
|
||||
JSPropertySpec* props = new JSPropertySpec[propertySpecs.size() + 1];
|
||||
for(size_t i=0; i<propertySpecs.size(); i++) {
|
||||
props[i] = propertySpecs[i];
|
||||
}
|
||||
JSPropertySpec endProp = { 0 };
|
||||
props[propertySpecs.size()] = endProp;
|
||||
|
||||
jsClass.name = name;
|
||||
jsClass.construct = cons;
|
||||
|
||||
JS_InitClass(cx, global, 0, &jsClass, constructor, 0,
|
||||
props, methods, 0, 0);
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T> struct PointerClass {
|
||||
typedef int type;
|
||||
};
|
||||
|
||||
template<typename T> struct PointerClass<T*> {
|
||||
typedef Class<T> type;
|
||||
};
|
||||
|
||||
// Conversion functions from types to Javascript
|
||||
|
||||
template<typename T> jsval ToJsval(T v) { // T is really a pointer here (since we want to do ToJsval(pointer))
|
||||
if(v == 0) {
|
||||
return JSVAL_NULL;
|
||||
}
|
||||
else {
|
||||
JSObject* obj = JS_NewObject(cx, &(PointerClass<T>::type::jsClass), 0, 0);
|
||||
JS_SetPrivate(cx, obj, v);
|
||||
return OBJECT_TO_JSVAL(obj);
|
||||
}
|
||||
}
|
||||
|
||||
template<> inline jsval ToJsval<bool>(bool v) {
|
||||
return v ? JSVAL_TRUE : JSVAL_FALSE;
|
||||
}
|
||||
|
||||
template<> inline jsval ToJsval<int>(int v) {
|
||||
return INT_TO_JSVAL(v);
|
||||
}
|
||||
|
||||
template<> inline jsval ToJsval<double>(double v) {
|
||||
jsval ret;
|
||||
JS_NewDoubleValue(cx, v, &ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<> inline jsval ToJsval<float>(float v) {
|
||||
jsval ret;
|
||||
JS_NewDoubleValue(cx, v, &ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<> inline jsval ToJsval<const char*>(const char* v) {
|
||||
int length = strlen(v);
|
||||
char* buf = (char*) JS_malloc(cx, length+1);
|
||||
memcpy(buf, v, length+1);
|
||||
return STRING_TO_JSVAL(JS_NewString(cx, buf, length+1));
|
||||
}
|
||||
|
||||
template<> inline jsval ToJsval<const std::string&>(const std::string& v) {
|
||||
return ToJsval(v.c_str());
|
||||
}
|
||||
|
||||
template<> inline jsval ToJsval<JSFunction*>(JSFunction* v) {
|
||||
if(v == 0) return JSVAL_NULL;
|
||||
else return OBJECT_TO_JSVAL(JS_GetFunctionObject(v));
|
||||
}
|
||||
|
||||
// Conversion functions from Javascript to types
|
||||
|
||||
template<typename T> T To(jsval v) { // T is really a pointer here (since we want to do To<pointer>(jsval))
|
||||
if(v == JSVAL_NULL) {
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
JSObject* obj = JSVAL_TO_OBJECT(v);
|
||||
return (T) JS_GetPrivate(cx, obj);
|
||||
}
|
||||
}
|
||||
|
||||
template<> inline bool To<bool>(jsval v) {
|
||||
return (v==JSVAL_TRUE);
|
||||
}
|
||||
|
||||
template<> inline int To<int>(jsval v) {
|
||||
return JSVAL_TO_INT(v);
|
||||
}
|
||||
|
||||
template<> inline double To<double>(jsval v) {
|
||||
jsdouble d;
|
||||
JS_ValueToNumber(cx, v, &d);
|
||||
return d;
|
||||
}
|
||||
|
||||
template<> inline float To<float>(jsval v) {
|
||||
jsdouble d;
|
||||
JS_ValueToNumber(cx, v, &d);
|
||||
return (float) d;
|
||||
}
|
||||
|
||||
template<> inline std::string To<std::string>(jsval v) {
|
||||
return std::string(JS_GetStringBytes(JS_ValueToString(cx, v)));
|
||||
}
|
||||
|
||||
template<> inline JSFunction* To<JSFunction*>(jsval v) {
|
||||
if(v == JSVAL_NULL) return 0;
|
||||
return JS_ValueToFunction(cx, v);
|
||||
}
|
||||
|
||||
// A nice way of automatically creating a JS function for any
|
||||
// function or method; could be made shorter by using some kind of
|
||||
// preprocessor loop (boost), but that might get confusing.
|
||||
// Combining member function pointers and templates... fun.
|
||||
|
||||
// Functions with return type R and up to three arguments A, B, C
|
||||
|
||||
template<typename R, R (*func)()>
|
||||
JSBool Function
|
||||
(JSContext *cx, JSObject*, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsASSERT(argc==0);
|
||||
*rval = ToJsval(func());
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
template<typename R, typename A, R (*func)(A)>
|
||||
JSBool Function
|
||||
(JSContext *cx, JSObject*, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsASSERT(argc==1);
|
||||
*rval = ToJsval(func(To<A>(argv[0])));
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
template<typename R, typename A, typename B, R (*func)(A,B)>
|
||||
JSBool Function(JSContext *cx, JSObject*, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsASSERT(argc==2);
|
||||
*rval = ToJsval(func(To<A>(argv[0]), To<B>(argv[1])));
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
template<typename R, typename A, typename B, typename C, R (*func)(A,B,C)>
|
||||
JSBool Function(JSContext *cx, JSObject*, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsASSERT(argc==3);
|
||||
*rval = ToJsval(func(To<A>(argv[0]), To<B>(argv[1]), To<C>(argv[2])));
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
// Void functions with up to three arguments A, B, C
|
||||
|
||||
template<void (*func)()>
|
||||
JSBool VoidFunction
|
||||
(JSContext *cx, JSObject*, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsASSERT(argc==1);
|
||||
func();
|
||||
*rval = JSVAL_VOID;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
template<typename A, void (*func)(A)>
|
||||
JSBool VoidFunction
|
||||
(JSContext *cx, JSObject*, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsASSERT(argc==1);
|
||||
func(To<A>(argv[0]));
|
||||
*rval = JSVAL_VOID;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
template<typename A, typename B, void (*func)(A,B)>
|
||||
JSBool VoidFunction
|
||||
(JSContext *cx, JSObject*, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsASSERT(argc==2);
|
||||
func(To<A>(argv[0]), To<B>(argv[1]));
|
||||
*rval = JSVAL_VOID;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
template<typename A, typename B, typename C, void (*func)(A,B,C)>
|
||||
JSBool VoidFunction
|
||||
(JSContext *cx, JSObject*, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsASSERT(argc==3);
|
||||
func(To<A>(argv[0]), To<B>(argv[1]), To<C>(argv[2]));
|
||||
*rval = JSVAL_VOID;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
// Methods of O with return type R and up to three arguments A, B, C
|
||||
|
||||
template<typename O, typename R, R (O::*func)()>
|
||||
JSBool Method
|
||||
(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsASSERT(argc==0);
|
||||
O* o = (O*) JS_GetPrivate(cx, obj);
|
||||
*rval = ToJsval((o->*func)());
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
template<typename O, typename R, typename A, R (O::*func)(A)>
|
||||
JSBool Method
|
||||
(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsASSERT(argc==1);
|
||||
O* o = (O*) JS_GetPrivate(cx, obj);
|
||||
*rval = ToJsval((o->*func)(To<A>(argv[0])));
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
template<typename O, typename R, typename A, typename B, R (O::*func)(A,B)>
|
||||
JSBool Method
|
||||
(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsASSERT(argc==2);
|
||||
O* o = (O*) JS_GetPrivate(cx, obj);
|
||||
*rval = ToJsval((o->*func)(To<A>(argv[0]), To<B>(argv[1])));
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
template<typename O, typename R, typename A, typename B, typename C, R (O::*func)(A,B,C)>
|
||||
JSBool Method
|
||||
(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsASSERT(argc==3);
|
||||
O* o = (O*) JS_GetPrivate(cx, obj);
|
||||
*rval = ToJsval((o->*func)(To<A>(argv[0]), To<B>(argv[1]), To<C>(argv[2])));
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
// Void methods of O with up to three arguments A, B, C
|
||||
|
||||
template<typename O, void (O::*func)()>
|
||||
JSBool VoidMethod
|
||||
(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsASSERT(argc==0);
|
||||
O* o = (O*) JS_GetPrivate(cx, obj);
|
||||
(o->*func)();
|
||||
*rval = JSVAL_VOID;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
template<typename O, typename A, void (O::*func)(A)>
|
||||
JSBool VoidMethod
|
||||
(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsASSERT(argc==1);
|
||||
O* o = (O*) JS_GetPrivate(cx, obj);
|
||||
(o->*func)(To<A>(argv[0]));
|
||||
*rval = JSVAL_VOID;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
template<typename O, typename A, typename B, void (O::*func)(A,B)>
|
||||
JSBool VoidMethod
|
||||
(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsASSERT(argc==2);
|
||||
O* o = (O*) JS_GetPrivate(cx, obj);
|
||||
(o->*func)(To<A>(argv[0]), To<B>(argv[1]));
|
||||
*rval = JSVAL_VOID;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
template<typename O, typename A, typename B, typename C, void (O::*func)(A,B,C)>
|
||||
JSBool VoidMethod
|
||||
(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsASSERT(argc==3);
|
||||
O* o = (O*) JS_GetPrivate(cx, obj);
|
||||
(o->*func)(To<A>(argv[0]), To<B>(argv[1]), To<C>(argv[2]));
|
||||
*rval = JSVAL_VOID;
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
|
||||
// Constructors of O with up to three arguments A, B, C
|
||||
|
||||
template<typename O>
|
||||
JSBool Constructor
|
||||
(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
|
||||
{
|
||||
jsASSERT(argc==0);
|
||||
JS_SetPrivate(cx, obj, new O());
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
template<typename O, typename A>
|
||||
JSBool Constructor
|
||||
(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval*)
|
||||
{
|
||||
jsASSERT(argc==1);
|
||||
JS_SetPrivate(cx, obj, new O(To<A>(argv[0])));
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
template<typename O, typename A, typename B>
|
||||
JSBool Constructor
|
||||
(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval*)
|
||||
{
|
||||
jsASSERT(argc==2);
|
||||
JS_SetPrivate(cx, obj, new O(To<A>(argv[0]), To<B>(argv[1])));
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
template<typename O, typename A, typename B, typename C>
|
||||
JSBool Constructor
|
||||
(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval*)
|
||||
{
|
||||
jsASSERT(argc==3);
|
||||
JS_SetPrivate(cx, obj, new O(To<A>(argv[0]), To<B>(argv[1]), To<C>(argv[2])));
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
template<typename O, typename A, typename B, typename C, typename D>
|
||||
JSBool Constructor
|
||||
(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval*)
|
||||
{
|
||||
jsASSERT(argc==4);
|
||||
JS_SetPrivate(cx, obj, new O(
|
||||
To<A>(argv[0]), To<B>(argv[1]), To<C>(argv[2]), To<D>(argv[3])));
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
// Implementation of AbstractProperty for a given field of an object
|
||||
|
||||
template<typename O, typename T, T O::*field> class PropertyImpl: public AbstractProperty {
|
||||
public:
|
||||
virtual ~PropertyImpl() {}
|
||||
|
||||
virtual JSBool set(JSObject *obj, jsval *val) {
|
||||
O* o = (O*) JS_GetPrivate(cx, obj);
|
||||
(o->*field) = To<T>(*val);
|
||||
return JS_TRUE;
|
||||
}
|
||||
|
||||
virtual JSBool get(JSObject *obj, jsval *rval) {
|
||||
O* o = (O*) JS_GetPrivate(cx, obj);
|
||||
*rval = ToJsval(o->*field);
|
||||
return JS_TRUE;
|
||||
}
|
||||
};
|
||||
|
||||
// A nice function to pass to AddProperty so we don't have to type new PropertyImpl<blah>()
|
||||
|
||||
template<typename O, typename T, T O::*field> AbstractProperty* Property() {
|
||||
return new PropertyImpl<O, T, field>();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Call a void function with 1 argument
|
||||
template<typename T> void CallJSFunction(JSFunction* f, T arg) {
|
||||
if(f == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
jsval argv[1] = { js::ToJsval(arg) };
|
||||
jsval rval;
|
||||
JS_CallFunction(cx, global, f, 1, argv, &rval);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -1,107 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "simpleconstraints.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
// NullConstraint /////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool NullConstraint::allows(Map* m, int x, int y)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// AndConstraint /////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AndConstraint::AndConstraint(const vector<Constraint*>& constraints) {
|
||||
this->constraints = constraints;
|
||||
}
|
||||
|
||||
AndConstraint::~AndConstraint() {
|
||||
for(int i=0; i<constraints.size(); i++) {
|
||||
delete constraints[i];
|
||||
}
|
||||
}
|
||||
|
||||
bool AndConstraint::allows(Map* m, int x, int y)
|
||||
{
|
||||
for(int i=0; i<constraints.size(); i++) {
|
||||
if(!constraints[i]->allows(m, x, y)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
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->countMembersInRadius(x, y, distance) == 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// StayInTileClassConstraint /////////////////////////////////////////////////////////////
|
||||
|
||||
StayInTileClassConstraint::StayInTileClassConstraint(TileClass* tileClass, float distance) {
|
||||
this->tileClass = tileClass;
|
||||
this->distance = distance;
|
||||
}
|
||||
|
||||
bool StayInTileClassConstraint::allows(Map* m, int x, int y)
|
||||
{
|
||||
return tileClass->countNonMembersInRadius(x, y, distance) == 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// BorderTileClassConstraint /////////////////////////////////////////////////////////////
|
||||
|
||||
BorderTileClassConstraint::BorderTileClassConstraint(TileClass* tileClass, float distanceInside,
|
||||
float distanceOutside) {
|
||||
this->tileClass = tileClass;
|
||||
this->distanceInside = distanceInside;
|
||||
this->distanceOutside = distanceOutside;
|
||||
}
|
||||
|
||||
bool BorderTileClassConstraint::allows(Map* m, int x, int y)
|
||||
{
|
||||
return tileClass->countMembersInRadius(x, y, distanceOutside) > 0
|
||||
&& tileClass->countNonMembersInRadius(x, y, distanceInside) > 0;
|
||||
}
|
||||
|
@ -1,67 +0,0 @@
|
||||
#ifndef __SIMPLECONSTRAINTS_H__
|
||||
#define __SIMPLECONSTRAINTS_H__
|
||||
|
||||
#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;
|
||||
public:
|
||||
AvoidAreaConstraint(Area* area);
|
||||
virtual bool allows(Map* m, int x, int y);
|
||||
};
|
||||
|
||||
class AvoidTextureConstraint : public Constraint {
|
||||
private:
|
||||
int textureId;
|
||||
public:
|
||||
AvoidTextureConstraint(int textureId);
|
||||
virtual bool allows(Map* m, int x, int y);
|
||||
};
|
||||
|
||||
class AvoidTileClassConstraint : public Constraint {
|
||||
private:
|
||||
TileClass* tileClass;
|
||||
float distance;
|
||||
public:
|
||||
AvoidTileClassConstraint(TileClass* tileClass, float distance);
|
||||
virtual bool allows(Map* m, int x, int y);
|
||||
};
|
||||
|
||||
class StayInTileClassConstraint : public Constraint {
|
||||
private:
|
||||
TileClass* tileClass;
|
||||
float distance;
|
||||
public:
|
||||
StayInTileClassConstraint(TileClass* tileClass, float distance);
|
||||
virtual bool allows(Map* m, int x, int y);
|
||||
};
|
||||
|
||||
class BorderTileClassConstraint : public Constraint {
|
||||
private:
|
||||
TileClass* tileClass;
|
||||
float distanceInside;
|
||||
float distanceOutside;
|
||||
public:
|
||||
BorderTileClassConstraint(TileClass* tileClass, float distanceInside, float distanceOutside);
|
||||
virtual bool allows(Map* m, int x, int y);
|
||||
};
|
||||
|
||||
#endif
|
@ -1,101 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "simplegroup.h"
|
||||
#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 minC, int maxC,
|
||||
float minD, float maxD, float minA, float maxA):
|
||||
type(t), minCount(minC), maxCount(maxC), minDistance(minD), maxDistance(maxD),
|
||||
minAngle(minA), maxAngle(maxA)
|
||||
{
|
||||
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");
|
||||
}
|
||||
if(minAngle > maxAngle) {
|
||||
JS_ReportError(cx, "SimpleObject: minAngle must be less than or equal to maxAngle");
|
||||
}
|
||||
}
|
||||
|
||||
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 distance = RandFloat(minDistance, maxDistance);
|
||||
float direction = RandFloat(0, 2*PI);
|
||||
|
||||
float x = cx + 0.5f + distance*cos(direction);
|
||||
float y = cy + 0.5f + distance*sin(direction);
|
||||
|
||||
if(x<0 || y<0 || x>m->size || y>m->size) {
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if(avoidSelf) {
|
||||
for(int i=0; i<ret.size(); i++) {
|
||||
float dx = x - ret[i]->x;
|
||||
float dy = y - ret[i]->y;
|
||||
if(dx*dx + dy*dy < 1) {
|
||||
goto bad;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!constr->allows(m, (int)x, (int)y)) {
|
||||
goto bad;
|
||||
}
|
||||
|
||||
// if we got here, we're good
|
||||
float angle = RandFloat()*(maxAngle-minAngle) + minAngle;
|
||||
ret.push_back(new Object(type, player, x, y, angle));
|
||||
break;
|
||||
|
||||
bad: failCount++;
|
||||
if(failCount > 20) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SimpleGroup::place(Map* m, int player, Constraint* constr) {
|
||||
vector<Object*> ret;
|
||||
for(int i=0; i<elements.size(); i++) {
|
||||
if(!elements[i]->place(x, y, m, player, avoidSelf, 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, TileClass* tc, bool as, int _x, int _y):
|
||||
elements(e), x(_x), y(_y), tileClass(tc), avoidSelf(as)
|
||||
{
|
||||
}
|
||||
|
||||
SimpleGroup::~SimpleGroup(void) {
|
||||
for(int i=0; i<elements.size(); i++) {
|
||||
delete elements[i];
|
||||
}
|
||||
}
|
@ -1,37 +0,0 @@
|
||||
#ifndef __SIMPLEGROUP_H__
|
||||
#define __SIMPLEGROUP_H__
|
||||
|
||||
#include "objectgroupplacer.h"
|
||||
#include "tileclass.h"
|
||||
|
||||
class SimpleGroup : public ObjectGroupPlacer
|
||||
{
|
||||
public:
|
||||
class Element {
|
||||
public:
|
||||
std::string type;
|
||||
int minCount, maxCount;
|
||||
float minDistance, maxDistance;
|
||||
float minAngle, maxAngle;
|
||||
|
||||
Element::Element();
|
||||
Element::Element(const std::string& type, int minCount, int maxCount,
|
||||
float minDistance, float maxDistance, float minAngle, float maxAngle);
|
||||
Element::~Element();
|
||||
|
||||
bool place(int cx, int cy, class Map* m, int player, bool avoidSelf,
|
||||
Constraint* constr, std::vector<Object*>& ret);
|
||||
};
|
||||
|
||||
std::vector<Element*> elements;
|
||||
bool avoidSelf;
|
||||
int x, y;
|
||||
TileClass* tileClass;
|
||||
|
||||
virtual bool place(class Map* m, int player, Constraint* constr);
|
||||
|
||||
SimpleGroup(std::vector<Element*>& elements, TileClass* tileClass, bool avoidSelf, int x, int y);
|
||||
virtual ~SimpleGroup(void);
|
||||
};
|
||||
|
||||
#endif
|
@ -1,70 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "simplepainters.h"
|
||||
#include "random.h"
|
||||
#include "rmgen.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
// TerrainPainter
|
||||
|
||||
TerrainPainter::TerrainPainter(Terrain* terrain)
|
||||
{
|
||||
this->terrain = terrain;
|
||||
}
|
||||
|
||||
void TerrainPainter::paint(Map* m, Area* a)
|
||||
{
|
||||
for (int i=0; i<a->points.size(); i++) {
|
||||
Point p = a->points[i];
|
||||
terrain->place(m, p.x, p.y);
|
||||
}
|
||||
}
|
||||
|
||||
// ElevationPainter
|
||||
|
||||
ElevationPainter::ElevationPainter(float elevation)
|
||||
{
|
||||
this->elevation = elevation;
|
||||
}
|
||||
|
||||
void ElevationPainter::paint(Map* m, Area* a)
|
||||
{
|
||||
for (int i=0; i<a->points.size(); i++) {
|
||||
Point p = a->points[i];
|
||||
static const int DX[4] = {0,1,1,0};
|
||||
static const int DY[4] = {0,0,1,1};
|
||||
for(int j=0; j<4; j++) {
|
||||
m->height[p.x+DX[j]][p.y+DY[j]] = elevation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MultiPainter
|
||||
|
||||
MultiPainter::MultiPainter(const std::vector<AreaPainter*>& painters)
|
||||
{
|
||||
this->painters = painters;
|
||||
}
|
||||
|
||||
void MultiPainter::paint(Map* m, Area* a)
|
||||
{
|
||||
for (int i=0; i<painters.size(); i++) {
|
||||
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);
|
||||
}
|
||||
}
|
@ -1,38 +0,0 @@
|
||||
#ifndef __SIMPLEPAINTERS_H__
|
||||
#define __SIMPLEPAINTERS_H__
|
||||
|
||||
#include "areapainter.h"
|
||||
#include "map.h"
|
||||
#include "area.h"
|
||||
#include "terrain.h"
|
||||
#include "tileclass.h"
|
||||
|
||||
class TerrainPainter : public AreaPainter {
|
||||
Terrain* terrain;
|
||||
public:
|
||||
TerrainPainter(Terrain* terrain);
|
||||
virtual void paint(Map* m, Area* a);
|
||||
};
|
||||
|
||||
class ElevationPainter : public AreaPainter {
|
||||
float elevation;
|
||||
public:
|
||||
ElevationPainter(float elevation);
|
||||
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:
|
||||
MultiPainter(const std::vector<AreaPainter*>& painters);
|
||||
virtual void paint(Map* m, Area* a);
|
||||
};
|
||||
|
||||
#endif
|
@ -1,155 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "rmgen.h"
|
||||
#include "smoothelevationpainter.h"
|
||||
#include "pointmap.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
SmoothElevationPainter::SmoothElevationPainter(int t, float e, int b)
|
||||
{
|
||||
type = t;
|
||||
elevation = e;
|
||||
blendRadius = b;
|
||||
if(type!=SET && type!=MODIFY) {
|
||||
JS_ReportError(cx, "SmoothElevationPainter: type must be either SET or MODIFY");
|
||||
}
|
||||
}
|
||||
|
||||
SmoothElevationPainter::~SmoothElevationPainter(void)
|
||||
{
|
||||
}
|
||||
|
||||
bool SmoothElevationPainter::checkInArea(Map* m, Area* a, int x, int y) {
|
||||
if(m->validT(x, y)) {
|
||||
return m->area[x][y] == a;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void SmoothElevationPainter::paint(Map* m, Area* a) {
|
||||
// TODO: Use a 2D array instead of STL maps and sets for speed
|
||||
|
||||
PointMap<int> saw;
|
||||
PointMap<int> dist;
|
||||
queue<Point> q;
|
||||
vector<Point>& pts = a->points;
|
||||
vector<Point> heightPts;
|
||||
PointMap<int> gotHeightPt;
|
||||
PointMap<float> newHeight;
|
||||
|
||||
// get a list of all points
|
||||
for(int i=0; i<pts.size(); i++) {
|
||||
int x = pts[i].x, y = pts[i].y;
|
||||
for(int dx=-1; dx<=2; dx++) {
|
||||
for(int dy=-1; dy<=2; dy++) {
|
||||
int nx = x+dx, ny = y+dy;
|
||||
Point np(nx, ny);
|
||||
if(m->validH(nx, ny) && !gotHeightPt[np]) {
|
||||
gotHeightPt[np] = 1;
|
||||
heightPts.push_back(np);
|
||||
newHeight[np] = m->height[nx][ny];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// push edge points
|
||||
for(int i=0; i<pts.size(); i++) {
|
||||
int x = pts[i].x, y = pts[i].y;
|
||||
for(int dx=-1; dx<=2; dx++) {
|
||||
for(int dy=-1; dy<=2; dy++) {
|
||||
int nx = x+dx, ny = y+dy;
|
||||
Point np(nx, ny);
|
||||
if(m->validH(nx, ny)
|
||||
&& !checkInArea(m, a, nx, ny)
|
||||
&& !checkInArea(m, a, nx-1, ny)
|
||||
&& !checkInArea(m, a, nx, ny-1)
|
||||
&& !checkInArea(m, a, nx-1, ny-1)
|
||||
&& !saw[np]) {
|
||||
saw[np] = 1;
|
||||
dist[np] = 0;
|
||||
q.push(np);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// do BFS inwards to find distances to edge
|
||||
while(!q.empty()) {
|
||||
Point p = q.front();
|
||||
q.pop();
|
||||
|
||||
int d = dist[p];
|
||||
|
||||
// paint if in area
|
||||
if(m->validH(p.x, p.y)
|
||||
&& (checkInArea(m, a, p.x, p.y) || checkInArea(m, a, p.x-1, p.y)
|
||||
|| checkInArea(m, a, p.x, p.y-1) || checkInArea(m, a, p.x-1, p.y-1))) {
|
||||
if(d <= blendRadius) {
|
||||
float a = ((float)(d-1)) / blendRadius;
|
||||
if(type == SET) {
|
||||
newHeight[p] = a*elevation + (1-a)*m->height[p.x][p.y];
|
||||
}
|
||||
else { // type == MODIFY
|
||||
newHeight[p] += a*elevation;
|
||||
}
|
||||
}
|
||||
else { // also happens when blendRadius == 0
|
||||
if(type == SET) {
|
||||
newHeight[p] = elevation;
|
||||
}
|
||||
else { // type == MODIFY
|
||||
newHeight[p] += elevation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// enqueue neighbours
|
||||
for(int dx=-1; dx<=1; dx++) {
|
||||
for(int dy=-1; dy<=1; dy++) {
|
||||
int nx = p.x+dx, ny = p.y+dy;
|
||||
Point np(nx, ny);
|
||||
if(m->validH(nx, ny)
|
||||
&& (checkInArea(m, a, nx, ny) || checkInArea(m, a, nx-1, ny)
|
||||
|| checkInArea(m, a, nx, ny-1) || checkInArea(m, a, nx-1, ny-1))
|
||||
&& !saw[np]) {
|
||||
saw[np] = 1;
|
||||
dist[np] = d+1;
|
||||
q.push(np);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// smooth everything out
|
||||
for(vector<Point>::iterator it = heightPts.begin(); it != heightPts.end(); it++) {
|
||||
Point p = *it;
|
||||
int x = p.x, y = p.y;
|
||||
if((checkInArea(m, a, x, y) || checkInArea(m, a, x-1, y)
|
||||
|| checkInArea(m, a, x, y-1) || checkInArea(m, a, x-1, y-1))) {
|
||||
float sum = 8 * newHeight[p];
|
||||
int count = 8;
|
||||
for(int dx=-1; dx<=1; dx++) {
|
||||
for(int dy=-1; dy<=1; dy++) {
|
||||
int nx = x+dx, ny = y+dy;
|
||||
if(m->validH(nx, ny)) {
|
||||
sum += newHeight[Point(nx,ny)];//m->height[nx][ny];
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
m->height[x][y] = sum/count;
|
||||
}
|
||||
}
|
||||
// don't smooth
|
||||
/*
|
||||
for(int i=0; i<heightPts.size(); i++) {
|
||||
int x = heightPts[i].x, y = heightPts[i].y;
|
||||
if((checkInArea(m, a, x, y) || checkInArea(m, a, x-1, y)
|
||||
|| checkInArea(m, a, x, y-1) || checkInArea(m, a, x-1, y-1))) {
|
||||
m->height[x][y] = newHeight[p];
|
||||
}
|
||||
*/
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
#ifndef __SMOOTHELEVATIONPAINTER_H__
|
||||
#define __SMOOTHELEVATIONPAINTER_H__
|
||||
|
||||
#include "areapainter.h"
|
||||
#include "terrain.h"
|
||||
#include "map.h"
|
||||
#include "area.h"
|
||||
|
||||
class SmoothElevationPainter :
|
||||
public AreaPainter
|
||||
{
|
||||
public:
|
||||
static const int SET = 0, MODIFY = 1;
|
||||
|
||||
private:
|
||||
int type; // one of the constants above
|
||||
float elevation; // target or delta
|
||||
int blendRadius; // how many tiles to do blending for
|
||||
|
||||
bool checkInArea(Map* m, Area* a, int x, int y);
|
||||
|
||||
public:
|
||||
SmoothElevationPainter(int type, float elevation, int blendRadius);
|
||||
~SmoothElevationPainter(void);
|
||||
|
||||
virtual void paint(Map* m, Area* a);
|
||||
};
|
||||
|
||||
#endif
|
@ -1,8 +0,0 @@
|
||||
// stdafx.cpp : source file that includes just the standard includes
|
||||
// rmgen.pch will be the pre-compiled header
|
||||
// stdafx.obj will contain the pre-compiled type information
|
||||
|
||||
#include "stdafx.h"
|
||||
|
||||
// TODO: reference any additional headers you need in STDAFX.H
|
||||
// and not in this file
|
@ -1,39 +0,0 @@
|
||||
// stdafx.h : include file for standard system include files,
|
||||
// or project specific include files that are used frequently, but
|
||||
// are changed infrequently
|
||||
//
|
||||
|
||||
#ifndef __STDAFX_H__
|
||||
#define __STDAFX_H__
|
||||
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <cstdarg>
|
||||
#include <ctime>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <hash_set>
|
||||
#include <hash_map>
|
||||
|
||||
#include <boost/random.hpp>
|
||||
|
||||
#ifdef WIN32
|
||||
#define XP_WIN
|
||||
#else
|
||||
#define XP_UNIX // TODO: Someone should actually test this on Linux
|
||||
#endif
|
||||
#include <js/jsapi.h>
|
||||
|
||||
const float PI = acos(-1.0f);
|
||||
|
||||
#endif
|
@ -1,88 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "terrain.h"
|
||||
#include "map.h"
|
||||
#include "object.h"
|
||||
#include "random.h"
|
||||
#include "rmgen.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
// Terrain
|
||||
|
||||
Terrain::Terrain() {}
|
||||
|
||||
Terrain::~Terrain() {}
|
||||
|
||||
void Terrain::place(Map* m, int x, int y) {
|
||||
vector<Object*>& vec = m->terrainObjects[x][y];
|
||||
for(int i=0; i<vec.size(); i++) {
|
||||
delete vec[i];
|
||||
}
|
||||
vec.clear();
|
||||
placeNew(m, x, y);
|
||||
}
|
||||
|
||||
// SimpleTerrain
|
||||
|
||||
SimpleTerrain::SimpleTerrain(const std::string& texture)
|
||||
{
|
||||
this->texture = texture;
|
||||
this->treeType = "";
|
||||
}
|
||||
|
||||
SimpleTerrain::SimpleTerrain(const std::string& texture, const std::string& treeType)
|
||||
{
|
||||
this->texture = texture;
|
||||
this->treeType = treeType;
|
||||
}
|
||||
|
||||
void SimpleTerrain::placeNew(Map* m, int x, int y) {
|
||||
vector<Object*>& vec = m->terrainObjects[x][y];
|
||||
if(treeType != "") {
|
||||
vec.push_back(new Object(treeType, 0, x+0.5f, y+0.5f, RandFloat()*PI));
|
||||
}
|
||||
m->texture[x][y] = m->getId(texture);
|
||||
}
|
||||
|
||||
SimpleTerrain::~SimpleTerrain(void)
|
||||
{
|
||||
}
|
||||
|
||||
Terrain* SimpleTerrain::parse(const string& name) {
|
||||
static map<string, Terrain*> parsedTerrains;
|
||||
|
||||
if(parsedTerrains.find(name) != parsedTerrains.end()) {
|
||||
return parsedTerrains[name];
|
||||
}
|
||||
else {
|
||||
string texture, treeType;
|
||||
size_t pos = name.find('|');
|
||||
if(pos != name.npos) {
|
||||
texture = name.substr(0, pos);
|
||||
treeType = name.substr(pos+1, name.size()-pos-1);
|
||||
}
|
||||
else {
|
||||
texture = name;
|
||||
treeType = "";
|
||||
}
|
||||
return parsedTerrains[name] = new SimpleTerrain(texture, treeType);
|
||||
}
|
||||
}
|
||||
|
||||
// RandomTerrain
|
||||
|
||||
RandomTerrain::RandomTerrain(const vector<Terrain*>& terrains)
|
||||
{
|
||||
if(terrains.size()==0) {
|
||||
JS_ReportError(cx, "RandomTerrain: terrains array must not be empty");
|
||||
}
|
||||
this->terrains = terrains;
|
||||
}
|
||||
|
||||
void RandomTerrain::placeNew(Map* m, int x, int y) {
|
||||
terrains[RandInt(terrains.size())]->placeNew(m, x, y);
|
||||
}
|
||||
|
||||
RandomTerrain::~RandomTerrain(void)
|
||||
{
|
||||
}
|
@ -1,44 +0,0 @@
|
||||
#ifndef __TERRAIN_H__
|
||||
#define __TERRAIN_H__
|
||||
|
||||
class Terrain
|
||||
{
|
||||
public:
|
||||
Terrain();
|
||||
void place(class Map* m, int x, int y);
|
||||
virtual void placeNew(class Map* m, int x, int y) = 0; // template method
|
||||
virtual ~Terrain(void);
|
||||
};
|
||||
|
||||
class SimpleTerrain: public Terrain
|
||||
{
|
||||
private:
|
||||
std::string texture;
|
||||
std::string treeType;
|
||||
|
||||
public:
|
||||
SimpleTerrain(const std::string& texture);
|
||||
SimpleTerrain(const std::string& texture, const std::string& treeType);
|
||||
|
||||
static Terrain* parse(const std::string& name);
|
||||
|
||||
void placeNew(class Map* m, int x, int y);
|
||||
~SimpleTerrain(void);
|
||||
};
|
||||
|
||||
class RandomTerrain: public Terrain
|
||||
{
|
||||
private:
|
||||
std::vector<Terrain*> terrains;
|
||||
|
||||
public:
|
||||
RandomTerrain(const std::vector<Terrain*>& terrains);
|
||||
|
||||
void placeNew(class Map* m, int x, int y);
|
||||
~RandomTerrain(void);
|
||||
};
|
||||
|
||||
|
||||
extern std::map<std::string, Terrain*> parsedTerrains;
|
||||
|
||||
#endif
|
@ -1,71 +0,0 @@
|
||||
#include "stdafx.h"
|
||||
#include "tileclass.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
TileClass::TileClass(int mapSize) {
|
||||
this->mapSize = mapSize;
|
||||
inclusionCount = new int*[mapSize];
|
||||
for(int i=0; i<mapSize; i++) {
|
||||
inclusionCount[i] = new int[mapSize];
|
||||
memset(inclusionCount[i], 0, mapSize*sizeof(int));
|
||||
rc.push_back(new RangeOp(mapSize));
|
||||
}
|
||||
}
|
||||
|
||||
TileClass::~TileClass() {
|
||||
for(int i=0; i<mapSize; i++) {
|
||||
delete inclusionCount[i];
|
||||
delete rc[i];
|
||||
}
|
||||
delete inclusionCount;
|
||||
}
|
||||
|
||||
void TileClass::add(int x, int y) {
|
||||
if(!inclusionCount[x][y]) {
|
||||
rc[y]->add(x,1);
|
||||
}
|
||||
inclusionCount[x][y]++;
|
||||
}
|
||||
|
||||
void TileClass::remove(int x, int y) {
|
||||
inclusionCount[x][y]--;
|
||||
if(!inclusionCount[x][y]) {
|
||||
rc[y]->add(x, -1);
|
||||
}
|
||||
}
|
||||
|
||||
int TileClass::countMembersInRadius(float cx, float cy, float r) {
|
||||
int mem, nonMem;
|
||||
countInRadius(cx, cy, r, mem, nonMem);
|
||||
return mem;
|
||||
}
|
||||
|
||||
int TileClass::countNonMembersInRadius(float cx, float cy, float r) {
|
||||
int mem, nonMem;
|
||||
countInRadius(cx, cy, r, mem, nonMem);
|
||||
return nonMem;
|
||||
}
|
||||
|
||||
void TileClass::countInRadius(float cx, float cy, float r, int& members, int& nonMembers) {
|
||||
members = 0;
|
||||
nonMembers = 0;
|
||||
|
||||
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);
|
||||
int total = maxX - minX + 1;
|
||||
int mem = rc[iy]->get(minX, maxX+1);
|
||||
members += mem;
|
||||
nonMembers += total - mem;
|
||||
}
|
||||
}
|
@ -1,29 +0,0 @@
|
||||
#ifndef __TILECLASS_H__
|
||||
#define __TILECLASS_H__
|
||||
|
||||
#include "point.h"
|
||||
#include "rangeop.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<RangeOp*> rc; // range count on each row
|
||||
int** inclusionCount; // the inclusion count for each tile
|
||||
public:
|
||||
TileClass(int mapSize);
|
||||
~TileClass();
|
||||
|
||||
void add(int x, int y);
|
||||
void remove(int x, int y);
|
||||
|
||||
void countInRadius(float cx, float cy, float r, int& members, int& nonMembers);
|
||||
int countMembersInRadius(float cx, float cy, float r);
|
||||
int countNonMembersInRadius(float cx, float cy, float r);
|
||||
};
|
||||
|
||||
#endif
|
Loading…
Reference in New Issue
Block a user