Fixes to entity death and event handling, plus some updates to RmGen.

This was SVN commit r3226.
This commit is contained in:
Matei 2005-12-11 02:09:11 +00:00
parent a5f9789940
commit bc23379066
16 changed files with 131 additions and 48 deletions

View File

@ -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
@ -520,7 +522,10 @@ void CEntity::clearOrders()
void CEntity::pushOrder( CEntityOrder& order )
{
m_orderQueue.push_back( 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_bounds )
{
delete( m_bounds );
m_bounds = NULL;
}
if( m_extant )
{
if( m_bounds )
delete( m_bounds );
m_bounds = NULL;
m_extant = false;
}

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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;

View File

@ -16,4 +16,12 @@ 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;
}

View File

@ -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

View 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

View File

@ -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) {

View File

@ -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);

View File

@ -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">

View File

@ -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++;

View File

@ -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,

View File

@ -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++;
}
}

View File

@ -22,6 +22,8 @@
#include <set>
#include <string>
#include <vector>
#include <hash_set>
#include <hash_map>
#include <boost/random.hpp>

View File

@ -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));
}
}

View File

@ -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);