Fixes to entity death and event handling, plus some updates to RmGen.
This was SVN commit r3226.
This commit is contained in:
parent
a5f9789940
commit
bc23379066
@ -153,6 +153,8 @@ void CEntity::kill()
|
||||
if( m_bounds ) delete( m_bounds );
|
||||
m_bounds = NULL;
|
||||
|
||||
m_extant = false;
|
||||
|
||||
m_destroyed = true;
|
||||
//Shutdown(); // PT: tentatively removed - this seems to be called by ~CJSComplex, and we don't want to do it twice
|
||||
|
||||
@ -519,9 +521,12 @@ void CEntity::clearOrders()
|
||||
}
|
||||
|
||||
void CEntity::pushOrder( CEntityOrder& order )
|
||||
{
|
||||
if( acceptsOrder( order.m_type, order.m_data[0].entity ) )
|
||||
{
|
||||
m_orderQueue.push_back( order );
|
||||
}
|
||||
}
|
||||
|
||||
bool CEntity::acceptsOrder( int orderType, CEntity* orderTarget )
|
||||
{
|
||||
@ -1065,6 +1070,11 @@ bool CEntity::Kill( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(arg
|
||||
// we don't fiddle with the actors or bounding information that we
|
||||
// usually do when changing templates.
|
||||
|
||||
if(m_corpse == L"null")
|
||||
{
|
||||
kill();
|
||||
}
|
||||
|
||||
CBaseEntity* corpse = g_EntityTemplateCollection.getTemplate( m_corpse );
|
||||
if( corpse )
|
||||
{
|
||||
@ -1072,12 +1082,14 @@ bool CEntity::Kill( JSContext* UNUSED(cx), uintN UNUSED(argc), jsval* UNUSED(arg
|
||||
SetBase( m_base );
|
||||
}
|
||||
|
||||
if( m_extant )
|
||||
{
|
||||
if( m_bounds )
|
||||
{
|
||||
delete( m_bounds );
|
||||
m_bounds = NULL;
|
||||
}
|
||||
|
||||
if( m_extant )
|
||||
{
|
||||
m_extant = false;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "stdafx.h"
|
||||
#include "clumpplacer.h"
|
||||
#include "random.h"
|
||||
#include "pointmap.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -19,13 +20,11 @@ ClumpPlacer::~ClumpPlacer()
|
||||
}
|
||||
|
||||
bool ClumpPlacer::place(class Map* m, Constraint* constr, std::vector<Point>& retVec) {
|
||||
// TODO: use a 2D array or hash set instead of a STL set for speed
|
||||
|
||||
if(!m->validT(x, y) || !constr->allows(m, x, y)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
map<Point, bool> gotRet;
|
||||
PointMap<int> gotRet;
|
||||
|
||||
float radius = sqrt(size / PI);
|
||||
float perim = 4 * radius * 2 * PI;
|
||||
@ -72,7 +71,7 @@ bool ClumpPlacer::place(class Map* m, Constraint* constr, std::vector<Point>& re
|
||||
if(m->validT(i, j) && constr->allows(m, i, j)) {
|
||||
Point p(i,j);
|
||||
if(!gotRet[p]) {
|
||||
gotRet[p] = true;
|
||||
gotRet[p] = 1;
|
||||
retVec.push_back(p);
|
||||
}
|
||||
}
|
||||
|
@ -206,14 +206,16 @@ ObjectGroupPlacer* ParseObjectGroupPlacer(JSContext* cx, jsval val) {
|
||||
for(int i=0; i<array.size(); i++) {
|
||||
string type;
|
||||
int minCount, maxCount;
|
||||
float minDistance, maxDistance;
|
||||
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);
|
||||
minDistance, maxDistance, minAngle, maxAngle);
|
||||
}
|
||||
return new SimpleGroup(elements, tileClass, avoidSelf, x, y);
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include "area.h"
|
||||
#include "terrain.h"
|
||||
#include "map.h"
|
||||
#include "pointmap.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -17,8 +18,8 @@ LayeredPainter::~LayeredPainter(void)
|
||||
}
|
||||
|
||||
void LayeredPainter::paint(Map* m, Area* a) {
|
||||
map<Point, int> saw;
|
||||
map<Point, int> dist;
|
||||
PointMap<int> saw;
|
||||
PointMap<int> dist;
|
||||
|
||||
queue<Point> q;
|
||||
|
||||
|
@ -17,3 +17,11 @@ 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;
|
||||
}
|
@ -9,6 +9,8 @@ public:
|
||||
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
|
47
source/tools/rmgen/pointmap.h
Normal file
47
source/tools/rmgen/pointmap.h
Normal file
@ -0,0 +1,47 @@
|
||||
#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,7 +1,7 @@
|
||||
#include "stdafx.h"
|
||||
#include "rangecount.h"
|
||||
#include "rangeop.h"
|
||||
|
||||
RangeCount::RangeCount(int size) {
|
||||
RangeOp::RangeOp(int size) {
|
||||
nn = 1;
|
||||
while(nn < size) {
|
||||
nn *= 2;
|
||||
@ -10,26 +10,26 @@ RangeCount::RangeCount(int size) {
|
||||
memset(vals, 0, 2*nn*sizeof(int));
|
||||
}
|
||||
|
||||
RangeCount::~RangeCount() {
|
||||
RangeOp::~RangeOp() {
|
||||
delete[] vals;
|
||||
}
|
||||
|
||||
int RangeCount::get(int pos) {
|
||||
int RangeOp::get(int pos) {
|
||||
return vals[nn + pos];
|
||||
}
|
||||
|
||||
void RangeCount::set(int pos, int amt) {
|
||||
void RangeOp::set(int pos, int amt) {
|
||||
add(pos, amt-get(pos));
|
||||
}
|
||||
|
||||
void RangeCount::add(int pos, int amt) {
|
||||
void RangeOp::add(int pos, int amt) {
|
||||
for(int s=nn; s>0; s/=2) {
|
||||
vals[s + pos] += amt;
|
||||
pos /= 2;
|
||||
}
|
||||
}
|
||||
|
||||
int RangeCount::get(int start, int end) {
|
||||
int RangeOp::get(int start, int end) {
|
||||
int ret = 0;
|
||||
int i;
|
||||
for(i=1; start+i<=end; i*=2) {
|
@ -1,13 +1,13 @@
|
||||
#ifndef __RANGECOUNT_H__
|
||||
#define __RANGECOUNT_H__
|
||||
#ifndef __RANGEOP_H__
|
||||
#define __RANGEOP_H__
|
||||
|
||||
class RangeCount {
|
||||
class RangeOp {
|
||||
private:
|
||||
int* vals; // has size 2*nn
|
||||
int nn; // smallest power of 2 >= size
|
||||
public:
|
||||
RangeCount(int size);
|
||||
~RangeCount();
|
||||
RangeOp(int size);
|
||||
~RangeOp();
|
||||
void set(int pos, int amt);
|
||||
void add(int pos, int amt);
|
||||
int get(int pos);
|
@ -157,7 +157,7 @@
|
||||
RelativePath=".\random.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\rangecount.cpp">
|
||||
RelativePath=".\rangeop.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\rectplacer.cpp">
|
||||
@ -245,11 +245,14 @@
|
||||
<File
|
||||
RelativePath=".\point.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\pointmap.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\random.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\rangecount.h">
|
||||
RelativePath=".\rangeop.h">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\rectplacer.h">
|
||||
|
@ -10,8 +10,10 @@ using namespace std;
|
||||
SimpleGroup::Element::Element(){
|
||||
}
|
||||
|
||||
SimpleGroup::Element::Element(const std::string& t, int minC, int maxC, float minD, float maxD):
|
||||
type(t), minCount(minC), maxCount(maxC), minDistance(minD), maxDistance(maxD)
|
||||
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");
|
||||
@ -19,6 +21,9 @@ SimpleGroup::Element::Element(const std::string& t, int minC, int maxC, float mi
|
||||
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() {
|
||||
@ -31,10 +36,10 @@ bool SimpleGroup::Element::place(int cx, int cy, Map* m, int player, bool avoidS
|
||||
for(int i=0; i<count; i++) {
|
||||
while(true) {
|
||||
float distance = RandFloat(minDistance, maxDistance);
|
||||
float angle = RandFloat(0, 2*PI);
|
||||
float direction = RandFloat(0, 2*PI);
|
||||
|
||||
float x = cx + 0.5f + distance*cos(angle);
|
||||
float y = cy + 0.5f + distance*sin(angle);
|
||||
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;
|
||||
@ -55,7 +60,8 @@ bool SimpleGroup::Element::place(int cx, int cy, Map* m, int player, bool avoidS
|
||||
}
|
||||
|
||||
// if we got here, we're good
|
||||
ret.push_back(new Object(type, player, x, y, RandFloat()*2*PI));
|
||||
float angle = RandFloat()*(maxAngle-minAngle) + minAngle;
|
||||
ret.push_back(new Object(type, player, x, y, angle));
|
||||
break;
|
||||
|
||||
bad: failCount++;
|
||||
|
@ -12,10 +12,11 @@ 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 minDistance, float maxDistance, float minAngle, float maxAngle);
|
||||
Element::~Element();
|
||||
|
||||
bool place(int cx, int cy, class Map* m, int player, bool avoidSelf,
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "stdafx.h"
|
||||
#include "rmgen.h"
|
||||
#include "smoothelevationpainter.h"
|
||||
#include "pointmap.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -30,15 +31,13 @@ bool SmoothElevationPainter::checkInArea(Map* m, Area* a, int x, int y) {
|
||||
void SmoothElevationPainter::paint(Map* m, Area* a) {
|
||||
// TODO: Use a 2D array instead of STL maps and sets for speed
|
||||
|
||||
map<Point, int> saw;
|
||||
map<Point, int> dist;
|
||||
|
||||
PointMap<int> saw;
|
||||
PointMap<int> dist;
|
||||
queue<Point> q;
|
||||
|
||||
vector<Point>& pts = a->points;
|
||||
|
||||
set<Point> heightPts;
|
||||
map<Point, float> newHeight;
|
||||
vector<Point> heightPts;
|
||||
PointMap<int> gotHeightPt;
|
||||
PointMap<float> newHeight;
|
||||
|
||||
// get a list of all points
|
||||
for(int i=0; i<pts.size(); i++) {
|
||||
@ -47,8 +46,9 @@ void SmoothElevationPainter::paint(Map* m, Area* a) {
|
||||
for(int dy=-1; dy<=2; dy++) {
|
||||
int nx = x+dx, ny = y+dy;
|
||||
Point np(nx, ny);
|
||||
if(m->validH(nx, ny)) {
|
||||
heightPts.insert(np);
|
||||
if(m->validH(nx, ny) && !gotHeightPt[np]) {
|
||||
gotHeightPt[np] = 1;
|
||||
heightPts.push_back(np);
|
||||
newHeight[np] = m->height[nx][ny];
|
||||
}
|
||||
}
|
||||
@ -124,7 +124,7 @@ void SmoothElevationPainter::paint(Map* m, Area* a) {
|
||||
}
|
||||
|
||||
// smooth everything out
|
||||
for(set<Point>::iterator it = heightPts.begin(); it != heightPts.end(); it++) {
|
||||
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)
|
||||
@ -135,7 +135,7 @@ void SmoothElevationPainter::paint(Map* m, Area* a) {
|
||||
for(int dy=-1; dy<=1; dy++) {
|
||||
int nx = x+dx, ny = y+dy;
|
||||
if(m->validH(nx, ny)) {
|
||||
sum += m->height[nx][ny];
|
||||
sum += newHeight[Point(nx,ny)];//m->height[nx][ny];
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,8 @@
|
||||
#include <set>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <hash_set>
|
||||
#include <hash_map>
|
||||
|
||||
#include <boost/random.hpp>
|
||||
|
||||
|
@ -9,7 +9,7 @@ TileClass::TileClass(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 RangeCount(mapSize));
|
||||
rc.push_back(new RangeOp(mapSize));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,7 @@
|
||||
#define __TILECLASS_H__
|
||||
|
||||
#include "point.h"
|
||||
#include "rangecount.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
|
||||
@ -12,7 +12,7 @@
|
||||
class TileClass {
|
||||
private:
|
||||
int mapSize;
|
||||
std::vector<RangeCount*> rc; // range count on each row
|
||||
std::vector<RangeOp*> rc; // range count on each row
|
||||
int** inclusionCount; // the inclusion count for each tile
|
||||
public:
|
||||
TileClass(int mapSize);
|
||||
|
Loading…
Reference in New Issue
Block a user