101 lines
2.4 KiB
C++
101 lines
2.4 KiB
C++
#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];
|
|
}
|
|
} |