Ejemplo n.º 1
2
void draw_planet(HDC hDC, planetstruct *planet)
{
	HBRUSH hbrColor, hbrOld;
	gravstruct *gp = &gravs;
	double D;						// a DX variable to work with
	unsigned char cmpt;

	D = POS(X) * POS(X) + POS(Y) * POS(Y) + POS(Z) * POS(Z);
	if (D < COLLIDE)
		D = COLLIDE;
	D = sqrt(D);
	D = D * D * D;
	for (cmpt = X; cmpt < DIMENSIONS; cmpt++) {
		ACC(cmpt) = POS(cmpt) * GRAV / D;
		if (iDamping) {
			if (ACC(cmpt) > MaxA)
				ACC(cmpt) = MaxA;
			else if (ACC(cmpt) < -MaxA)
				ACC(cmpt) = -MaxA;
			VEL(cmpt) = VEL(cmpt) + ACC(cmpt);
			VEL(cmpt) *= DAMP;
		} else {
			// update velocity
			VEL(cmpt) = VEL(cmpt) + ACC(cmpt);
		}
		// update position
		POS(cmpt) = POS(cmpt) + VEL(cmpt);
	}

	gp->x = planet->xi;
	gp->y = planet->yi;

	if (POS(Z) > -ALMOST) {
		planet->xi = (unsigned int)
			((double) gp->width * (HALF + POS(X) / (POS(Z) + DIST)));
		planet->yi = (unsigned int)
			((double) gp->height * (HALF + POS(Y) / (POS(Z) + DIST)));
	}
	else
		planet->xi = planet->yi = -1;	

	// Mask
	hbrOld = (HBRUSH)SelectObject(hDC, (HBRUSH)GetStockObject(BLACK_BRUSH));
	Planet(gp->x, gp->y);

	if (iTrails)
		SetPixel(hDC, gp->x, gp->y, PALETTEINDEX(100));

	// Move
	gp->x = planet->xi;
	gp->y = planet->yi;
	planet->ri = RADIUS;

	if (iColorCycle) {
		if (planet->colors++ > (PALSIZE-21))
			planet->colors = 1;
	}

	// Redraw
	hbrColor = CreateSolidBrush(PALETTEINDEX(planet->colors));
	SelectObject(hDC, hbrColor);
	Planet(gp->x, gp->y);

	SelectObject(hDC, hbrOld);
	DeleteObject(hbrColor);
}
Ejemplo n.º 2
0
MainWindow::MainWindow() :
    m_update_pending(false),
    m_context(nullptr),
    m_program(nullptr),
    m_glBuffer(nullptr)
{
    setSurfaceType(QWindow::OpenGLSurface);

    planets.append(Planet(PointDouble2D(100, 100), PointDouble2D(0, 0), 100000));
    planets.append(Planet(PointDouble2D(150, 100), PointDouble2D(0, 50), 100));
    planets.append(Planet(PointDouble2D(50, 100), PointDouble2D(0, -50), 100));
    planets.append(Planet(PointDouble2D(100, 50), PointDouble2D(30, 0), 200));
    planets.append(Planet(PointDouble2D(100, 150), PointDouble2D(-30, 0), 200));

    root = QuadTree::createTree(planets, QRectF(0, 0, 200, 200));

    calc = new CalcThread(root);
    QThread* thread = new QThread();
    calc->moveToThread(thread);
    calc->setPlanets(planets);
    connect(this, SIGNAL(needCalc()), calc, SLOT(start()));
    connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
    connect(thread, SIGNAL(finished()), calc, SLOT(deleteLater()));
    thread->start();
}
Ejemplo n.º 3
0
static void
draw_planet(ModeInfo * mi, planetstruct * planet)
{
	Display    *display = MI_DISPLAY(mi);
	Window      window = MI_WINDOW(mi);
	GC          gc = MI_GC(mi);
	gravstruct *gp = &gravs[MI_SCREEN(mi)];
	double      D;		/* A distance variable to work with */
	register unsigned char cmpt;

	D = POS(X) * POS(X) + POS(Y) * POS(Y) + POS(Z) * POS(Z);
	if (D < COLLIDE)
		D = COLLIDE;
	D = sqrt(D);
	D = D * D * D;
	for (cmpt = X; cmpt < DIMENSIONS; cmpt++) {
		ACC(cmpt) = POS(cmpt) * GRAV / D;
		if (decay) {
			if (ACC(cmpt) > MaxA)
				ACC(cmpt) = MaxA;
			else if (ACC(cmpt) < -MaxA)
				ACC(cmpt) = -MaxA;
			VEL(cmpt) = VEL(cmpt) + ACC(cmpt);
			VEL(cmpt) *= DAMP;
		} else {
			/* update velocity */
			VEL(cmpt) = VEL(cmpt) + ACC(cmpt);
		}
		/* update position */
		POS(cmpt) = POS(cmpt) + VEL(cmpt);
	}

	gp->x = planet->xi;
	gp->y = planet->yi;

	if (POS(Z) > -ALMOST) {
		planet->xi = (int)
			((double) gp->width * (HALF + POS(X) / (POS(Z) + DIST)));
		planet->yi = (int)
			((double) gp->height * (HALF + POS(Y) / (POS(Z) + DIST)));
	} else
		planet->xi = planet->yi = -1;

	/* Mask */
	XSetForeground(display, gc, MI_BLACK_PIXEL(mi));
	Planet(gp->x, gp->y);
	if (trail) {
		XSetForeground(display, gc, planet->colors);
		XDrawPoint(display, MI_WINDOW(mi), gc, gp->x, gp->y);
	}
	/* Move */
	gp->x = planet->xi;
	gp->y = planet->yi;
	planet->ri = RADIUS;

	/* Redraw */
	XSetForeground(display, gc, planet->colors);
	Planet(gp->x, gp->y);
}
Ejemplo n.º 4
0
Coin::Coin(GLfloat x, GLfloat y, GLfloat z, GLfloat s) : planet(Planet(x, y, z, 0.5, texture)) {
    this->x = x;
    this->y = y;
    this->z = z;
    this->s = s;
    planet.light = true;
}
Ejemplo n.º 5
0
int Universe::splitString(std::string sSplitInp)
{
	char primaryLimiter = ';';
	char secondLimiter = ':';
	std::string sTemp;
	std::vector<int> vTemp;

	for (size_t p = 0, q = 0; p != sSplitInp.npos; p = q)
	{
		sTemp = sSplitInp.substr(p + (p != 0), (q = sSplitInp.find(primaryLimiter, p + 1)) - p - (p != 0));
		std::cout << sTemp << ' ';
		if (p == 0)
		{
			std::string sNew;
			size_t j = 0, k = 0;
			for (unsigned i = 0; i <= 2; i++)
			{
				sNew = sTemp.substr(j + (j != 0), (k = sTemp.find(secondLimiter, j + 1)) - j - (j != 0));
				vTemp.push_back(atoi(sNew.c_str()));
				j = k;
			}
		}
		else
		{
			vTemp.push_back(atoi(sTemp.c_str()));
		}
	}
	addPlanet(Planet(vTemp[0], vTemp[1], vTemp[2], vTemp[3], vTemp[4], vTemp[5], vTemp[6], vTemp[7], vTemp[8])); // ugly

	return 0;
}
Ejemplo n.º 6
0
static void
init_planet(ModeInfo * mi, planetstruct * planet)
{
	Display    *display = MI_DISPLAY(mi);
	Window      window = MI_WINDOW(mi);
	GC          gc = MI_GC(mi);
	gravstruct *gp = &gravs[MI_SCREEN(mi)];

	if (MI_NPIXELS(mi) > 2)
		planet->colors = MI_PIXEL(mi, NRAND(MI_NPIXELS(mi)));
	else
		planet->colors = MI_WHITE_PIXEL(mi);
	/* Initialize positions */
	POS(X) = FLOATRAND(-XR, XR);
	POS(Y) = FLOATRAND(-YR, YR);
	POS(Z) = FLOATRAND(-ZR, ZR);

	if (POS(Z) > -ALMOST) {
		planet->xi = (int)
			((double) gp->width * (HALF + POS(X) / (POS(Z) + DIST)));
		planet->yi = (int)
			((double) gp->height * (HALF + POS(Y) / (POS(Z) + DIST)));
	} else
		planet->xi = planet->yi = -1;
	planet->ri = RADIUS;

	/* Initialize velocities */
	VEL(X) = FLOATRAND(-VR, VR);
	VEL(Y) = FLOATRAND(-VR, VR);
	VEL(Z) = FLOATRAND(-VR, VR);

	/* Draw planets */
	Planet(planet->xi, planet->yi);
}
Ejemplo n.º 7
0
Planet * StarSystem::CreatePrimaryStar()
{
    if ( m_pPrimaryStar == NULL ) {
        BlockWorldFn->SelectMemory( TEXT("Planets") );
        m_pPrimaryStar = New Planet( this, STAR_ORBIT_PRIMARY, 0 );
        BlockWorldFn->UnSelectMemory();
    }
    return m_pPrimaryStar;
}
Ejemplo n.º 8
0
ENTRYPOINT void
draw_grav(ModeInfo * mi)
{
	Display    *display = MI_DISPLAY(mi);
	Window      window = MI_WINDOW(mi);
	GC          gc = MI_GC(mi);
	register unsigned char ball;
	gravstruct *gp;

	if (gravs == NULL)
			return;
	gp = &gravs[MI_SCREEN(mi)];
	if (gp->planets == NULL)
		return;

	if (!MI_IS_DRAWN(mi)) {
		for (ball = 0; ball < (unsigned char) gp->nplanets; ball++) {
			planetstruct *planet = &gp->planets[ball];

			/* Draw planets */
			Planet(planet->xi, planet->yi);
		}

		/* Draw centrepoint */
		XDrawArc(display, MI_WINDOW(mi), gc,
			 gp->width / 2 - gp->sr / 2, gp->height / 2 - gp->sr / 2, gp->sr, gp->sr,
			 0, 23040);
	}

	MI_IS_DRAWN(mi) = True;
	/* Mask centrepoint */
	XSetForeground(display, gc, MI_BLACK_PIXEL(mi));
	XDrawArc(display, window, gc,
		 gp->width / 2 - gp->sr / 2, gp->height / 2 - gp->sr / 2, gp->sr, gp->sr,
		 0, 23040);

	/* Resize centrepoint */
	switch (NRAND(4)) {
		case 0:
			if (gp->sr < (int) STARRADIUS)
				gp->sr++;
			break;
		case 1:
			if (gp->sr > 2)
				gp->sr--;
	}

	/* Draw centrepoint */
	XSetForeground(display, gc, gp->starcolor);
	XDrawArc(display, window, gc,
		 gp->width / 2 - gp->sr / 2, gp->height / 2 - gp->sr / 2, gp->sr, gp->sr,
		 0, 23040);

	for (ball = 0; ball < (unsigned char) gp->nplanets; ball++)
		draw_planet(mi, &gp->planets[ball]);
}
Ejemplo n.º 9
0
void setUpPlanet(PlanetPart& part , GLfloat radiusT , GLfloat rotateMod , GLfloat y  , GLfloat planetScale  ,char* path )
{
	part.planet = Planet(10 ,(y+ 4) ,0 , path);
	part.planet.scale = planetScale;
	part.upPole = Cylinder(10 , (y + 2.0f) ,0 , 0.1f , 4.0f , 15);
	part.outPole = OutPole(0 , y ,0 , 0.2f , radiusT + 0.2f , 15);
	part.outPole.setAngle(0,0,90);
	part.radius = radiusT;
	part.rotateModifier = rotateMod;
}
Ejemplo n.º 10
0
Planet * StarSystem::CreatePlanet( UInt iOrbit, UInt iMoonCount )
{
    Assert( iOrbit < m_iOrbitCount );
    if ( m_arrPlanets[iOrbit] != NULL )
        return m_arrPlanets[iOrbit];

    BlockWorldFn->SelectMemory( TEXT("Planets") );
    m_arrPlanets[iOrbit] = New Planet( this, iOrbit, iMoonCount );
    BlockWorldFn->UnSelectMemory();

    return m_arrPlanets[iOrbit];
}
Ejemplo n.º 11
0
void Star::generate(int seed)
{
    srand(seed);
    int q = rand() % 6 +3; //random int betweeen 3 and 6
    for(int i = 0; i < q; i++)
    {
        int r = rand() % 1 + 5;
        int pathrad = rand() % 100 + 100;
        int theta = rand() % 6;
        int ospeed = rand() % 45;
        Planet x = Planet(r,pathrad,theta,ospeed,*this,sf::Color(rand() % 255,rand() % 255,rand() % 255));
        addPlanet(x);
    }
}
Ejemplo n.º 12
0
void wipePlanets(Star stars[], Planet planets[]) {
    for (int i=0;i<NUM_PLANETS;++i) {
        int parent = planets[i].data[PARENT_STAR];
        if (parent!=-1) {
            if (!isHomeworld(stars[parent],planets)) {
                planets[i] = Planet();
            }
        }
    }
    int count=0;
    for (int i=0;i<NUM_PLANETS;++i) {
        if (planets[i].isEmpty()) count++;
    }
    printf("Empty Planet Slots %d/%d\n",count,NUM_PLANETS);
}
Ejemplo n.º 13
0
void World::init(Camera *camera, Player *player) {
	this->camera = camera;
	this->player = player;

	//LightManager::lights.push_back(new DirectionalLight(glm::vec3(1.2f, 1.0f, 4.0f), ResourceManager::materials["whiteLight"]));
	//LightManager::lights.push_back(new PointLight(glm::vec3(1.2f, 1.0f, 4.0f), ResourceManager::materials["whiteLight"], 0.2f, 0.09f, 0.032f));

	LightManager::lights.push_back(new DirectionalLight(glm::vec3(-10.0, -10.0, -10.0), ResourceManager::materials["whiteLight"]));
	LightManager::lights.push_back(new PointLight(glm::vec3(-9.0f, -9.0f, -10.0f), ResourceManager::materials["whiteLight"], 1.0f, 0.09f, 0.032f));

	planets.push_back(Planet(glm::vec3(-10.0f), ResourceManager::getModel("planet1"), ResourceManager::getShader("lightingModel")));
	c = new Cube(camera, ResourceManager::getShader("lighting"), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(2.0f, 2.0f, 2.0f), ResourceManager::materials["whiteLight"], 0.0f);

	player->currentPlanet = &planets[0];
	player->setPos(player->currentPlanet->model.getFirstVertexPos());
}
Ejemplo n.º 14
0
void wipeQuadrant(Star stars[],Planet planets[],double minx, double miny, double maxx, double maxy) {
    Star empty;//last star is our empty one?
    empty.x=0;
    empty.y=0;
    memset(empty.name,0,sizeof(empty.name));
    for (int i=0;i<NUM_STARS;++i) {
        if (!isHomeworld(stars[i],planets)) {
            if (stars[i].x>=minx&&stars[i].y>=miny&&
                stars[i].x<=maxx&&stars[i].y<=maxy) {
                stars[i]=empty;
                for (int i=0;i<NUM_PLANETS;++i){
                    if (planets[i].data[PARENT_STAR]==i) {
                        planets[i]=Planet();
                    }
                }
            }
        }
    }
}
Ejemplo n.º 15
0
/**
 * Helper function that will go through space objects and add them to appropriate list
 * of either planets, moons, or stars based on the objects type
 *
 */
void SolarSystem::assignObjects(){
	planets.clear();
	moons.clear();
	stars.clear();
	for(std::vector<SpaceObject>::iterator object = spaceObjects.begin(); object != spaceObjects.end(); ++object){

		if(object->_type == PLANET_TEXT)
			planets.insert( pair<string, Planet>(object->_planetName,Planet(*object)));

		if(object->_type == MOON_TEXT)
			moons.push_back(*object);

		if(object->_type == STAR_TEXT && object->_planetName == SUN_TEXT)
			sun = *object;

		if(object->_type == STAR_TEXT )
			stars.push_back(*object);


	}


}
Ejemplo n.º 16
0
int main (int argc, char**argv) {
    bool doHelp=false;
    if (argc<=1) {
        doHelp=true;
    }
    for (int i=1;i<argc;++i) {
        if (strcmp(argv[i],"-h")==0||
            strcmp(argv[i],"-help")==0||
            strcmp(argv[i],"--help")==0||
            strcmp(argv[i],"/help")==0||
            strcmp(argv[i],"/h")==0) {
            doHelp=true;
        }
    }
    if (doHelp) {
        printf("Usage Example:\n\n%s SAVE1.GAM SAVE2.GAM q0 SAVE3.GAM\nThe above example takes the planets from SAVE1.GAM applies it to the monsters and 4 player races and planet picks of SAVE2.GAM takes the 0th quadrant (numbered from 0 to 3) and saves the result into SAVE3.GAM\n\n",argv[0]);
        printf("Generic usage %s <planetInput> <raceInput> <quadrantSelection> <output>\n\n",argv[0]);
        printf("The general usage is that <planetInput> should be set to a Master of Orion II save game file, often the same file, that contains the planets and <raceInput> should be set to the save game that has the desired races. Then the quadrantSelection selects a portion of the map and rotates and mirrors it so that every player gets an even shake. <output> should be set to the final save file that may be reloaded for the fair game\n\n");
        printf("quadrant selection is limited to the following options:\n");
        printf("2 player options:\n");
        printf("h0 assume a 2 player game and take the left half and reflect it\n");
        printf("h1 assume a 2 player game and take the right half and reflect it\n");
        printf("v0 assume a 2 player game and take the top half and reflect it\n");
        printf("v1 assume a 2 player game and take the bottom half and reflect it\n");
        printf("4 player options:\n");
        printf("q0 assume a 4 player game and take the top left quarter and mirror it\n");
        printf("q1 assume a 4 player game and take the bottom left quarter and mirror it\n");
        printf("q2 assume a 4 player game and take the bottom right quarter and mirror it\n");
        printf("q3 assume a 4 player game and take the top right quarter and mirror it\n");
        printf("6 player options:\n");
        printf("x0 or x1 or x2 or x3 or x4 or x5 mirror the appropriate slice\n");

        return 0;
    }
    srand(0x31337);
    Star stars[MAX_NUM_STARS];
    Planet planets[MAX_NUM_PLANETS];
    Star newStars[MAX_NUM_STARS];
    Planet newPlanets[MAX_NUM_PLANETS];
    homeworlds.insert("Sol");
    homeworlds.insert("Nazin");
    homeworlds.insert("Meklon");
    homeworlds.insert("Altair");
    homeworlds.insert("Ursa");
    homeworlds.insert("Gnol");
    homeworlds.insert("Draconis");
    homeworlds.insert("Kholdan");
    homeworlds.insert("Sssla");
    homeworlds.insert("Mentar");
    homeworlds.insert("Fieras");
    homeworlds.insert("Cryslon");
    homeworlds.insert("Trilar");

    FILE * fp = fopen(argv[1],"rb");
    
    fseek(fp,0,SEEK_END);
    size_t fileSize = ftell(fp);
    fseek(fp,0,SEEK_SET);    
    byt * data = (byt*)malloc(fileSize);
    fread(data,1,fileSize,fp);
    fclose(fp);
    FILE * output;
    size_t writeFileSize=0;
    byt * writeData;
    if (argc>2) {
        output = fopen(argv[2],"rb");
        fseek(output,0,SEEK_END);
        writeFileSize = ftell(output);
        fseek(output,0,SEEK_SET);    
        writeData = (byt*)malloc(fileSize);
        fread(writeData,1,writeFileSize,output);
        fclose(output);
    }
    for (int doInput=(argc>2?0:1);doInput<2;++doInput) {
        for (int i=0;i<NUM_PLANETS;++i) {
            const byt * curData = (doInput?data:writeData)+(PLANET_OFFSET+i*PLANET_SIZE);
            Planet planetA;
            memcpy(&planetA,curData,PLANET_SIZE);
            Planet planetB;
            planetB.readPlanet(curData);
            //planetB.printPlanet(NULL);
            if (memcmp(&planetA,&planetB,PLANET_SIZE)) {
                printf("Endianness Mismatch: luckily we coded for that\n");
            }
            byt testIdempotency[PLANET_SIZE];
            planetB.writePlanet(testIdempotency);
            planetA.readPlanet(testIdempotency);
            if (memcmp(&planetA,&planetB,PLANET_SIZE)) {
                printf("Idempotency Mismatch: FAIL\n");
            }
            if (memcmp(testIdempotency,curData,PLANET_SIZE)) {
                printf("Idempotency Mismatch: FAIL Internal\n");
            }
            if (doInput) {
                planets[i]=planetB;
            }else {
                newPlanets[i]=planetB;
            }
        }
    }
    
    int maxx = -(1<<30);
    int minx = (1<<30);
    int maxy = -(1<<30);
    int miny = (1<<30);
    nerf(stars,planets);
    for (int doInput=(argc>2?0:1);doInput<2;++doInput) {
        for (int i=0;i<NUM_STARS;++i) {
            const byt * curData = (doInput?data:writeData)+(STAR_OFFSET+i*STAR_SIZE);
            Star starA;
            
            memcpy(&starA,curData,STAR_SIZE);
//        starA.printStar();
            Star starB;
            starB.readStar(curData);
            if (doInput) {
                if (starB.x!=0||starB.y!=0) {
                    if (starB.x<minx) {
                        minx = starB.x;
                    }
                    if (starB.x>maxx) {
                        maxx = starB.x;
                    }
                    if (starB.y<miny) {
                        miny = starB.y;
                    }
                    if (starB.y>maxy) {
                        maxy = starB.y;
                    }
                }else {
                    //invalid system
                }
                
                stars[i]=starB;
            }else {
                newStars[i]=starB;
            }
            if (memcmp(&starA,&starB,STAR_SIZE)) {
                printf("Endianness Mismatch: luckily we coded for that\n");
            }
            byt testIdempotency[STAR_SIZE];
            starB.writeStar(testIdempotency);
            starA.readStar(testIdempotency);
            if (memcmp(&starA,&starB,STAR_SIZE)) {
                starB.writeStar(testIdempotency);
                starA.readStar(testIdempotency);

                printf("Idempotency Mismatch: FAIL\n");
                if (!(starA==starB)) {
                    printf("Idempotency Mismatch: FAIL B\n");
                }
            }
            if (memcmp(testIdempotency,curData,STAR_SIZE)) {
                printf("Idempotency Mismatch: FAIL Internal\n");
            }
        }
    }
    for (int i=0;i<NUM_STARS;++i) {
        if (newStars[i].isEmpty()) {
            NUM_STARS=i;
            if (i==0) NUM_STARS=71;
            printf("Setting num stars to %d\n",NUM_STARS);
            break;
        }
    }
    if (argc==2) {
        for (int i=0;i<NUM_STARS;++i) {
            stars[i].recordHist();

            stars[i].printStar(planets,stars);
        }
        printf("Bounds: (%d,%d) - (%d,%d)\n",minx,miny,maxx,maxy);
        printHist();
        return 0;
    }
    printf("Bounds: (%d,%d) - (%d,%d)\n",minx,miny,maxx,maxy);
    if (false) {
        for (int i=0;i<NUM_STARS;++i) {
            isHomeworld(stars[i],planets);
        }
        for (int i=0;i<NUM_STARS;++i) {
            isHomeworld(newStars[i],newPlanets);
        }
        for (std::set<std::string>::iterator i=validNames.begin(),ie=validNames.end();i!=ie;++i) {
            starNames.push_back(*i);
        }
    }else {
        for (int i=0;i<sizeof(possibleNames)/sizeof(char*);++i) {
            starNames.push_back(possibleNames[i]);
        }
    }
    //wipePlanets(newStars,newPlanets);
    //wipeStars(newStars,newPlanets); no longer: we now work with what we have
    double percent_safe_zone=0;//.03125;
    double wid = maxx-minx;
    double hei = maxy-miny;
    char mode = argv[3][0];
    int slice=argv[3][1]-'0';//q2 is the 2nd quadrant  x5 is the 5th hex zone h0 is the 0th horizontal slice v0 is the 0th vertical slice
    double sourceminx;
    double sourcemaxx;
    double sourceminy;
    double sourcemaxy;
    
    bool flipX=true;
    bool flipY=true;
    int numX=2,numY=2;
    if (mode=='q') {
        NUM_PLAYERS=4;
        numX=2;
        numY=2;
        flipX=true;
        flipY=true;
    }
    if (mode=='h') {
        NUM_PLAYERS=2;
        numX=2;
        numY=1;
        flipX=true;
        flipY=false;

    }
    if (mode=='v') {
        NUM_PLAYERS=2;
        numX=1;
        numY=2;
        flipX=false;
        flipY=true;
    }
    if (mode=='x') {
        NUM_PLAYERS=6;
        numX=3;
        numY=2;
        flipX=false;
        flipY=true;
    }

    {
        std::set<int>homeworldlessQuadrant;
        std::vector<int> freePlanets;
        std::map<int,int> starMap;//destination star to source star (multiple desitnations may reference a single source)
        int freeStar=0;
        double homeX, homeY;
        for (int doPlace=0;doPlace<2;++doPlace) {
            int count=0;
            for (int x=0;x<numX;++x) {
                for (int y=0;y<numY;++y) {
                    double lenx = (maxx-minx)/(double)numX;
                    double leny = (maxy-miny)/(double)numY;

                    double localminx=minx+lenx*x;
                    double localminy=miny+leny*y;
                    double localmaxx=numX==1?lenx:lenx-percent_safe_zone;
                    double localmaxy=numY==1?leny:leny-percent_safe_zone;
                    localmaxx+=localminx;
                    localmaxy+=localminy;
                    if (numX>1) {//we shove things over so that we are flush with maxx by the end
                        double del = x*percent_safe_zone/(numX-1);
                        localminx+=del;
                        localmaxx+=del;
                        if (x+1==numX) {
                            localmaxx=maxx;//we don't want a float error here
                        }
                    }
                    if (numY>1) {//we shove things over so we are flush with maxx by the end
                        double del = y*percent_safe_zone/(numY-1);
                        localminy+=del;
                        localmaxy+=del;
                        if (y+1==numY) {
                            localmaxy=maxy;//we don't want a float error here cus we need every last star
                        }
                    }
                    if (!doPlace) {
                        //printf("Searching range (%f %f, %f %f)\n",localminx,localminy,localmaxx,localmaxy);
                        if (slice==count) {
                            sourceminx=localminx;
                            sourceminy=localminy;
                            sourcemaxx=localmaxx;
                            sourcemaxy=localmaxy;
                            int homeIndex = findHomeworld (stars,planets,localminx,localminy,localmaxx,localmaxy);
                            if (homeIndex==-1) {
                                printf("Cannot find homeworld in section %d...exiting\n",slice);
                                return -1;
                            }else {
                                Star homeSystem = stars[homeIndex];
                                homeX = ((flipX&&x)?localmaxx-homeSystem.x:homeSystem.x-localminx);
                                homeY = ((flipY&&y)?localmaxy-homeSystem.y:homeSystem.y-localminy);

                                printf("Homeworld located at %s %f %f (%d %d)\n",homeSystem.name,homeX,homeY,homeSystem.x,homeSystem.y);
                            }
                        }
                        //wipeQuadrant(newStars,newPlanets,localminx,localminy,localmaxx,localmaxy);
                    }else if (doPlace==1){
                        copyQuadrantStars(newStars,newPlanets, localminx,localminy,localmaxx,localmaxy,
                                          stars,planets,sourceminx,sourceminy,sourcemaxx,sourcemaxy,flipX,flipY,count,starMap,freePlanets, freeStar);//saves up some free planets for us
                        int newHomeX = (flipX&&x)?localmaxx-homeX:homeX+localminx;
                        int newHomeY = (flipY&&y)?localmaxy-homeY:homeY+localminy;
                        printf("Placing homeworld at %d %d (From %f %f)\n",newHomeX, newHomeY, homeX, homeY);
                        if (!fixupHomeworlds(newStars,newPlanets, localminx,localminy,localmaxx,localmaxy,
                                             newHomeX,newHomeY,count)) {
                            printf("Could not find %d th homeworld\n",count);
                        }

                    }
                    ++count;
                }
            }
        }
        {//go through and copy planets
            while ((freeStar=nextFreeStar(newStars,newPlanets,freeStar))!=-1) {
                //if (!isHomeworld(newStars[freeStar],newPlanets)) {freeStar should look for homeworlds
                //uSELESS STAR
                //strcpy(newStars[freeStar].name,"DANGER");
                printf("Found a free star\n");
                for (int p=0;p<5;++p) {
                    if (newStars[freeStar].planets[p]!=-1&&newStars[freeStar].planets[p]<NUM_PLANETS) {
                        if (newPlanets[newStars[freeStar].planets[p]].data[PARENT_STAR]==freeStar) {
                            freePlanets.push_back(newStars[freeStar].planets[p]);
                        }else {
                            if (newStars[freeStar].planets[p]!=0&&newStars[freeStar].planets[p]<NUM_PLANETS) {
                                printf("Odd syste in save file that's cross referenced\n");
                            }
                        }
                    }
                    newStars[freeStar].planets[p]=-1;
                }
                //}
                ++freeStar;
            } 
            printf("Orphan star size %d\n",(int)orphanStars.size());
            int orphanCount=orphanStars.size()==2?1:0;
            for (int index=0;index<NUM_STARS;++index) {
                Star &dst=newStars[index];
                if (starMap.find(index)!=starMap.end()) {
                    int destStarIndex = index;
                    
                    Star star = stars[starMap[index]];
                    for (int p=0;p<5;++p) {
                        if (dst.planets[p]!=-1&&dst.planets[p]<NUM_PLANETS) {
                            if (newPlanets[dst.planets[p]].data[PARENT_STAR]==destStarIndex) {
                                freePlanets.push_back(dst.planets[p]);//this will guarantee we pop these guys first to minimize change we can believe in
                            }else if (dst.planets[p]!=0&&dst.planets[p]<NUM_PLANETS) {
                                printf("Odder syste in save file that's cross referenced\n");
                            }
                            dst.planets[p]=-1;
                        }
                    }
                    bool didUltraRich=false;
                    bool isThisOrphan = orphanStars.find(destStarIndex)!=orphanStars.end();
                    if(isThisOrphan) {
                        dst.x=(minx+maxx)/2;
                        dst.y=(miny+maxy)/2;//put this in the middle of the map
                        if (orphanCount>0) {
                            double angle=0;
                            switch (orphanCount) {
                              case 1:
                                angle=0;
                                break;
                              case 2:
                                angle=M_PI;
                                break;
                              case 3:
                                angle=M_PI/2;
                                break;
                              case 4:
                                angle=3*M_PI/2;
                                break;
                              default:
                                angle = 3.1415926536*2*(.5+((orphanCount-5)/4.0));
                                break;
                            }
                            int del=(minx+maxx)/10;
                            int delx = (int)(del*cos(angle));
                            int dely = (int)(del*sin(angle));
                            dst.x+=delx;
                            dst.y+=dely;
                        }
                        ++orphanCount;
                    }
                    for (int p=0;p<5;++p) {
                            if (star.planets[p]!=-1&&star.planets[p]<NUM_PLANETS) {
                                if (freePlanets.size()) {
                                    int newPlanetIndex = freePlanets.back();
                                    freePlanets.pop_back();
                                    short originalOwner = newPlanets[newPlanetIndex].data[PARENT_STAR];
                                    if (originalOwner>=0&&originalOwner<NUM_STARS) {
                                        const Star &check = newStars[originalOwner];
                                        for (int pp=0;pp<5;++pp) {
                                            if (check.planets[pp]==newPlanetIndex&&check.planets[pp]!=-1) {
                                                printf("FATAL PLANETARY CROSS ALIGNMENT\n");
                                            }
                                        }
                                    }
                                    crossMapPlanetCopy(newPlanets[newPlanetIndex],planets[star.planets[p]]);
                                    
                                    if (isThisOrphan) {
                                        if (didUltraRich==false&&newPlanets[newPlanetIndex].data[TYPE]==0x3) {
                                            didUltraRich=true;
                                            if (NUM_STARS>50) {
                                                newPlanets[newPlanetIndex].data[MINERALS]=0x4;//set to ultra rich!!!!
                                                newPlanets[newPlanetIndex].data[G]=0x2;//set to heavy G!!!!
                                            }else {
                                                newPlanets[newPlanetIndex].data[MINERALS]=0x3;//set to rich!!!!
                                                newPlanets[newPlanetIndex].data[G]=0x1;//set to normal G!!!!
                                            }
                                            newPlanets[newPlanetIndex].data[PLANETSIZECLASS]=rand()%0x5;
                                            newPlanets[newPlanetIndex].data[ENVIRONMENT]=rand()%0xa;
                                        }else {
                                            newPlanets[newPlanetIndex].data[G]=0x1;//set to normal G!!!!
                                            
                                            if (NUM_STARS>50) {
                                                newPlanets[newPlanetIndex].data[MINERALS]=rand()%0x3+1;//not ultra rich
                                            }else {
                                                newPlanets[newPlanetIndex].data[MINERALS]=rand()%0x2+1;//not ultra poor
                                            }
                                            newPlanets[newPlanetIndex].data[PLANETSIZECLASS]=rand()%0x5;
                                            newPlanets[newPlanetIndex].data[ENVIRONMENT]=rand()%0xa;
                                        }
                                    }
                                    dst.planets[p]=newPlanetIndex;
                                    newPlanets[newPlanetIndex].data[PARENT_STAR]=destStarIndex;
                                }else {
                                    printf("Unable to allocate free planet for star %s\n",dst.name);
                                }
                            }
                        }
                }else {
                    printf("Could not locate source for %d\n",index);
                }
            }
            while (!freePlanets.empty()) {
                newPlanets[freePlanets.back()]=Planet();
                freePlanets.pop_back();
            }
            for (int index=0;index<NUM_STARS;++index) {
                bool error=false;
                for (int j=0;j<5;++j) {
                    int ind = newStars[index].planets[j];
                    if (ind!=-1&&ind<NUM_PLANETS) {
                        if (newPlanets[ind].data[PARENT_STAR]!=index) {
                            newStars[index].planets[j]=-1;
                            error=true;
                        }
                    }
                }
                if (error) {
                    if (starMap.find(index)!=starMap.end()) {
                        printf("MISMATCH ERROR in system %s index %d mapping to %s\n",newStars[index].name,index,stars[starMap[index]].name);
                    }else {
                        printf("MISMATCH ERROR in system %s index %d\n",newStars[index].name,index,stars[starMap[index]].name);
                    }
                }
            }
        }
        
    }
    free(data);
    if (argc>4) {//if we can write to a file
        output = fopen(argv[4],"w+b");//overwrite the output save file
        fwrite(writeData,1,writeFileSize,output);
        free(writeData);
        fseek(output,PLANET_OFFSET,SEEK_SET);
        for (int i=0;i<NUM_PLANETS;++i) {
            unsigned char planetData[PLANET_SIZE];
            newPlanets[i].writePlanet(planetData);
            fwrite(planetData,1,PLANET_SIZE,output);
        }
        fseek(output,STAR_OFFSET,SEEK_SET);
        for (int i=0;i<NUM_STARS;++i) {
            unsigned char starData[STAR_SIZE];
            newStars[i].writeStar(starData);
            fwrite(starData,1,STAR_SIZE,output);
        }
        fclose(output);
        return 0;
        char *args[2];
        args[0]=argv[0];
        args[1]=argv[4];
        return main(2,args);
    }else for (int i=0;i<NUM_STARS;++i) {
        newStars[i].printStar(newPlanets,newStars);
    }

}
void SolarSystem::addPlanet(float distanceFromSun, float revolutionTime, float rotationTime, float radiusOfPlanet, GLuint texture)
{
	planets.push_back(Planet(distanceFromSun, revolutionTime, rotationTime, radiusOfPlanet, texture));
}
Ejemplo n.º 18
0
MainWindow::MainWindow()
{
    widget = new QWidget;
    setCentralWidget(widget);
    widget->setFixedSize(1000, 800);

    planetView = new PlanetView();
    planetView->adjustSize();
    planetView->setFixedSize(widget->size());
    planetView->hide();
    planetName = new QLabel(tr("banana"));
    planetName->hide();

    satelliteView = new SatelliteView();
    satelliteView->adjustSize();
    satelliteView->setFixedSize(widget->size());
    satelliteView->hide();
    satelliteName = new QLabel(tr("banana"));
    satelliteName->hide();

    system = new SolarSystem(8);
    system->addPlanet(Planet("Меркурий", 3.302  * pow(10,23),   57909227000,     0.20563593,  0.3f,  0), 0);
    system->addPlanet(Planet("Венера",   4.8685 * pow(10,24),  108208930000,         0.0068,  0.4f,  0), 1);
    system->addPlanet(Planet("Земля",    5.973  * pow(10,24),  149598261000,     0.01671123,  0.5f,  0), 2);
    system->addPlanet(Planet("Марс",     6.4185 * pow(10,23),  227943820000,      0.0933941,  0.45f, 0), 3);
    system->addPlanet(Planet("Юпитер",   1.8986 * pow(10,27),  778547200000,       0.048775,  0.8f,  0), 4);
    system->addPlanet(Planet("Сатурн",   5.6846 * pow(10,26), 1433449370000,    0.055723219,  0.7f,  0), 5);
    system->addPlanet(Planet("Уран",     8.6832 * pow(10,25), 2876679082000,    0.044405586,  0.6f,  0), 6);
    system->addPlanet(Planet("Нептун",   1.0243 * pow(10,26), 4503443661000,    0.011214269,  0.6f,  0), 7);

    systemDrawer = new SystemDrawer(system);
    systemDrawer->adjustSize();
    systemDrawer->setFixedSize(widget->size());
    systemDrawer->hide();

    planetTimer = new QTimer(this);
    connect(planetTimer, SIGNAL(timeout()), SLOT(movePlanet()));

    juperos = new SolarSystem(16);
    juperos->addPlanet(Planet("Метида",     9.5    * pow(10,16),   127690000,       0.00002,     0.3f,  0), 0);
    juperos->addPlanet(Planet("Адрастея",   1.91   * pow(10,16),   128690000,       0.0015,      0.3f,  0), 1);
    juperos->addPlanet(Planet("Амальтея",   7.17   * pow(10,17),   181690000,       0.0032,      0.3f,  0), 2);
    juperos->addPlanet(Planet("Теба",       7.77   * pow(10,17),   222000000,       0.0038,      0.3f,  0), 3);
    juperos->addPlanet(Planet("Ио",         8.94   * pow(10,22),   422000000,       0.0041,      0.3f,  0), 4);
    juperos->addPlanet(Planet("Европа",     4.8    * pow(10,22),   617000000,       0.0094,      0.3f,  0), 5);
    juperos->addPlanet(Planet("Ганимед",    1.48   * pow(10,23),   1070000000,      0.0011,      0.3f,  0), 6);
    juperos->addPlanet(Planet("Каллисто",   1.08   * pow(10,23),   1883000000,      0.0074,      0.3f,  0), 7);
    juperos->addPlanet(Planet("Леда",       5.68   * pow(10,15),   11094000000,     0.1673,      0.3f,  0), 8);
    juperos->addPlanet(Planet("Гималия",    9.56   * pow(10,18),   11480000000,     0.1513,      0.3f,  0), 9);
    juperos->addPlanet(Planet("Лизистея",   7.77   * pow(10,16),   11720000000,     0.1322,      0.3f,  0), 10);
    juperos->addPlanet(Planet("Илара",      7.77   * pow(10,17),   11737000000,     0.1374,      0.3f,  0), 11);
    juperos->addPlanet(Planet("Ананке",     3.82   * pow(10,16),   21200000000,     0.3445,      0.3f,  0), 12);
    juperos->addPlanet(Planet("арме",       9.56   * pow(10,16),   22600000000,     0.2342,      0.3f,  0), 13);
    juperos->addPlanet(Planet("Писифе",     1.91   * pow(10,17),   23500000000,     0.3288,      0.3f,  0), 14);
    juperos->addPlanet(Planet("Синопе",     7.77   * pow(10,17),   23700000000,     0.2750,      0.3f,  0), 15);

    juperosDrawer = new JuperosDrawer(juperos);
    juperosDrawer->adjustSize();
    juperosDrawer->setFixedSize(widget->size());
    juperosDrawer->hide();

    satelliteTimer = new QTimer(this);
    connect(satelliteTimer, SIGNAL(timeout()), SLOT(moveSatellite()));

    QWidget *topFiller = new QWidget;
    topFiller->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    text = new QLabel;
    text->show();

    QPixmap background(":/1.jpg");
    QPalette pal;
    pal.setBrush(this->backgroundRole(), QBrush(background));
    this->setPalette(pal);

    infoLabel = new QLabel(tr("<font style=\"color:#fff; font-family:Times New Roman; font-size:40pt;\"><h1><center>Выберите пункт меню</center></h1></font>"));
    infoLabel->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
    infoLabel->setAlignment(Qt::AlignCenter);

    QWidget *bottomFiller = new QWidget;
    bottomFiller->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    step_delta = new QPushButton("Сдвиг на дельту", this);
    step_delta->resize(BUTTON_SIZE);
    step_delta->move(WINDOW_SIZE.width() - 150, WINDOW_SIZE.height() + 525);
    step_delta->hide();

    QVBoxLayout *layout = new QVBoxLayout;
    layout->setMargin(8);
    layout->addWidget(systemDrawer);
    layout->addWidget(juperosDrawer);
    layout->addWidget(planetName);
    layout->addWidget(planetView);
    layout->addWidget(satelliteName);
    layout->addWidget(satelliteView);
    layout->addWidget(topFiller);
    layout->addWidget(infoLabel);
    layout->addWidget(bottomFiller);
    widget->setLayout(layout);

    createActions();
    createMenus();

    QString message = tr("Контекстное меню доступно при помощи правой клавиши мыши");
    statusBar()->showMessage(message);

    setWindowTitle(tr("Симулятор звездной системы"));
    setMinimumSize(160, 160);
    resize(730, 525);
}
Ejemplo n.º 19
0
void MGADSMTrajectory::CalculateLegs()
{
   // Detect a valid node configuration
   if (m_nodes.size() <= 1)
   {
      OTL_ASSERT(false, "Invalid trajectory. Trajectory must consist of at least two nodes.");
   }
   if (m_nodes.front()->GetType() != TrajectoryNode::Type::Departure)
   {
      OTL_ASSERT(false, "Invalid trajectory. Trajectory must start with a Departure node.");
   }
   if (m_nodes.back()->GetType() != TrajectoryNode::Type::Flyby &&
       m_nodes.back()->GetType() != TrajectoryNode::Type::Rendezvous &&
       m_nodes.back()->GetType() != TrajectoryNode::Type::Insertion)
   {
      OTL_ASSERT(false, "Invalid trajectory. Trajectory must end with a Flyby, Rendezvous, or Insertion node.");
   }

   m_numStates = 0;

   m_legs.clear();
   TrajectoryLeg leg;

   for (int i = 0; i < m_numNodes; ++i)
   {
      // Departure
      if (m_nodes[i]->GetType() == TrajectoryNode::Type::Departure)
      {
         auto depNode = dynamic_cast<DepartureNode*>(m_nodes[i].get());
         OTL_ASSERT(depNode, "Failed to convert node to Departure node.");

         leg.departure = true;
         leg.initialPlanet = Planet(depNode->orbitalBody);

         AddState(depNode->epoch.GetMJD2000());

         // Only if followed by a DSM
         if (m_nodes[i+1]->GetType() == TrajectoryNode::Type::DSM)
         {
            AddState(depNode->deltaV.x());
            AddState(depNode->deltaV.y());
            AddState(depNode->deltaV.z());
         }
      }

      // DSM
      else if (m_nodes[i]->GetType() == TrajectoryNode::Type::DSM)
      {
         auto dsmNode = dynamic_cast<DSMNode*>(m_nodes[i].get());
         OTL_ASSERT(dsmNode, "Failed to convert node to DSM node.");

         leg.numDSM++;
         AddState(dsmNode->alpha);

         // Only for more than one DSM
         if (leg.numDSM > 1)
         {
            AddState(dsmNode->deltaV.x());
            AddState(dsmNode->deltaV.y());
            AddState(dsmNode->deltaV.z());
         }
      }

      // Flyby
      else if (m_nodes[i]->GetType() == TrajectoryNode::Type::Flyby)
      {
         auto flyNode = dynamic_cast<FlybyNode*>(m_nodes[i].get());
         OTL_ASSERT(flyNode, "Failed to convert node to Flyby node.");

         leg.flyby = true;
         leg.finalPlanet = Planet(flyNode->orbitalBody);
         leg.timeofFlightIndex = m_numStates;

         AddState(flyNode->timeOfFlight * MATH_DAY_TO_SEC);
         AddState(flyNode->altitude);
         AddState(flyNode->bInclinationAngle);
      }

      // Rendezvous
      else if (m_nodes[i]->GetType() == TrajectoryNode::Type::Rendezvous)
      {
         auto renNode = dynamic_cast<RendezvousNode*>(m_nodes[i].get());
         OTL_ASSERT(renNode, "Failed to convert node to Rendezvous node.");

         leg.rendezvous = true;
         leg.finalPlanet = Planet(renNode->orbitalBody);
         leg.timeofFlightIndex = m_numStates;

         AddState(renNode->timeOfFlight * MATH_DAY_TO_SEC);
      }

      // Insertion
      else if (m_nodes[i]->GetType() == TrajectoryNode::Type::Insertion)
      {
         auto insNode = dynamic_cast<InsertionNode*>(m_nodes[i].get());
         OTL_ASSERT(insNode, "Failed to convert node to Insertion node.");

         leg.insertion = true;
         leg.insertionOrbit = insNode->orbitalElements;
         leg.finalPlanet = Planet(insNode->orbitalBody);
         leg.timeofFlightIndex = m_numStates;

         AddState(insNode->timeOfFlight * MATH_DAY_TO_SEC);
         AddState(insNode->timeOfOrbit * MATH_DAY_TO_SEC);

         if (m_nodes[i+1]->GetType() == TrajectoryNode::Type::DSM)
         {
            AddState(insNode->deltaV.x());
            AddState(insNode->deltaV.y());
            AddState(insNode->deltaV.z());
         }
      }

      // Finished a leg, save it and start a new one
      if (m_nodes[i]->GetType() == TrajectoryNode::Type::Flyby ||
          m_nodes[i]->GetType() == TrajectoryNode::Type::Rendezvous || 
          m_nodes[i]->GetType() == TrajectoryNode::Type::Insertion)
      {
         m_legs.push_back(leg);
         leg = TrajectoryLeg();

         // Set the initial planet of the new leg to the final planet of the previous leg
         leg.initialPlanet = m_legs.back().finalPlanet;
      }
   }

   m_legsInitialized = true;
}
Ejemplo n.º 20
0
    double longitudeOfPerihelion; //meters (m)
    double perihelion; //meters (m)
    double velocity; //meters per second (m/s)
    double vx; //velocity in the x direction (m/s)
    double vy; //velocity in the y direction (m/s)
    double px; //position in the x direction (m)
    double py; //position in the y direction (m)
    bool reversed;*/
    
    //New Stuff
    unsigned short numMoons;
    Moon* moons;
    
};

//const Planet SUN =      Planet("Sun",       0,  1.98892 * pow(10, 30),  0, 0, 0, false);

const Planet MERCURY =  Planet("Mercury",   1,  0.33011 * pow(10, 24),  77.45645,   46.00e6 * pow(10, 3),    58.98 * pow(10, 3), false, 0);
const Planet VENUS =    Planet("Venus",     2,  4.8675 * pow(10, 24),   131.53298,  107.48e6 * pow(10, 3),   35.26 * pow(10, 3), true, 0);
const Planet EARTH =    Planet("Earth",     3,  5.9723 * pow(10, 24),   102.94719,  147.09e6 * pow(10, 3),   30.29 * pow(10, 3), false, 1);
const Planet MARS =     Planet("Mars",      4,  0.64171 * pow(10, 24),  336.04084,  206.62e6 * pow(10, 3),   26.50 * pow(10, 3), false, 2);
const Planet JUPITER =  Planet("Jupiter",   5,  1898.19 * pow(10, 24),  14.75385,   740.52e6 * pow(10, 3),   13.72 * pow(10, 3), false, 0);
const Planet SATURN =   Planet("Saturn",    6,  568.34 * pow(10, 24),   92.43194,   1352.55e6 * pow(10, 3),  10.18 * pow(10, 3), false, 0);
const Planet URANUS =   Planet("Uranus",    7,  86.813 * pow(10, 24),   170.96424,  2741.30e6 * pow(10, 3),  7.11 * pow(10, 3), false, 0);
const Planet NEPTUNE =  Planet("Neptune",   8,  102.413 * pow(10, 24),  44.97135,   4444.45e6 * pow(10, 3),  5.50 * pow(10, 3), false, 0);
const Planet PLUTO =    Planet("Pluto",     9,  0.01303 * pow(10, 24),  224.06676,  4436.82e6 * pow(10, 3),  6.10 * pow(10, 3), false, 1);
//http://cs.mcgill.ca/~rwest/wikispeedia/wpcd/wp/e/Eris_%2528dwarf_planet%2529.htm
const Planet ERIS =     Planet("Eris",      10, 1.66e22,                150.977,    5.723e9 * pow(10, 3),               4.126e3, false, 0);

#endif /* Planets_hpp */
Ejemplo n.º 21
0
//Main function
int main(int argc, char* argv[])
{
  /*
    -----
    // INITIALIZATION
    -----
  */

  //Seed RNG
  srand(time(NULL));
  
  //Initialize all SDL subsystems
  if (SDL_Init(SDL_INIT_EVERYTHING) == -1)
    {
      return 1;
    }

  //Initialize SDL_TTF
  TTF_Init();
  TTF_Font * planetFont = TTF_OpenFont("corbel.ttf", 20);

  //Set up the screen
  SDL_Surface* screen = SDL_SetVideoMode(SCREEN_WIDTH, SCREEN_HEIGHT, 32, SDL_SWSURFACE);

  //Make sure screen set up
  if (screen == NULL)
    {
      return false;
    }

  //Set the window caption
  SDL_WM_SetCaption("GAEM", NULL);

  //Create an event manager
  SDL_Event event;

  //Store keystates
  Uint8* keystates;

  //Set up camera
  SDL_Rect camera = {0, 0, SCREEN_WIDTH, SCREEN_HEIGHT};
  float camerax = 0;
  float cameray = 0;

  /*
    -----
    GAME SETUP
    -----
  */

  //Set up ship stats
  std::vector<ShipStats> shipstats(10);
  for (int i = 0; i < 10; i++)
    {
      shipstats[i].attack = i+1;
      shipstats[i].defense = i+1;
      shipstats[i].speed = DEFAULT_FLEET_SPEED;
      shipstats[i].interceptRange = 200;
      shipstats[i].interceptDamage = 0.1;
      shipstats[i].interceptCD = 250;
    }

  //Set up ship type 1: Heavy ship
  shipstats[1].attack = 3;
  shipstats[1].defense = 2;
  shipstats[1].speed = DEFAULT_FLEET_SPEED/2;

  //Set up ship type 2: Fiery attack ship
  shipstats[2].attack = 2;
  shipstats[2].defense = 1;
  shipstats[2].speed = DEFAULT_FLEET_SPEED*1.25;

  //Set up buildings and building rules
  std::list<Building> buildings;
  std::vector<std::list<Building*> > buildRules;
  buildRules.resize(2);
  SDL_Surface* b01 = loadImage("b01.png");
  SDL_Surface* bc01 = loadImage("bc01.png");
  SDL_Surface* b02 = loadImage("b02.png");
  SDL_Surface* bc02 = loadImage("bc02.png");
  buildings.push_back(Building(b01, bc01, "build 0 2")); //0
  buildings.push_back(Building(b02, bc02, "fire damage 2 1")); //1
  buildings.push_back(Building(b01, bc01, "build 1 4")); //2
  buildings.push_back(Building(b01, bc01, "build 2 2")); //3
  buildings.push_back(Building(b02, bc02, "aura damage 1 total")); //4

  //0
  std::list<Building>::iterator bi = buildings.begin();
  buildRules[0].push_back(&(*bi));
  bi->setBuildTime(15000);
  bi++;

  //1
  buildRules[0].push_back(&(*bi));
  bi->setBuildTime(10000);
  bi->setRange(250);
  bi++;

  //2
  buildRules[0].push_back(&(*bi));
  bi->setBuildTime(15000);
  bi++;

  //3
  buildRules[1].push_back(&(*bi));
  bi->setBuildTime(15000);
  bi++;

  //4
  buildRules[1].push_back(&(*bi));
  bi->setBuildTime(10000);
  bi->setRange(200);
  bi->setCD(1000);

  //Building images are now in rotation caches
  SDL_FreeSurface(b01);
  SDL_FreeSurface(bc01);
  SDL_FreeSurface(b02);
  SDL_FreeSurface(bc02);

  //Create a list of planets
  std::list<Planet> planets;

  //The standard rate of production of basic ship 0
  float ship0rate = 1.0;

  //The array of indicators
  SDL_Surface* indicator[3];
  indicator[1] = loadImage("selectorb.png");
  indicator[2] = loadImage("selectorr.png");
  
  SDL_Surface* planet0img = loadImage("planet0.png");
  SDL_Surface* planet1img = loadImage("planet1.png");
  SDL_Surface* planet1_1img = loadImage("planet1-1.png");

  //Create the planets at random
  //First, create two home planets
  std::vector<int> homestart;
  homestart.resize(1,3);
  planets.push_back(Planet(planet0img, 1.0,
			   Vec2f(rand()%100, 100 + rand()%(LEVEL_HEIGHT-200)), 0));
  planets.back().setOwner(1, indicator);
  planets.back().setShipRate(0, ship0rate);
  planets.back().setRotSpeed(M_PI/20);
  planets.back().addShips(3, 0);
  planets.push_back(Planet(planet0img, 1.0,
			   Vec2f(LEVEL_WIDTH-(2*UNSCALED_PLANET_RADIUS)-(rand()%100),
				 100 + rand()%(LEVEL_HEIGHT-200)), 0));
  planets.back().setOwner(2, indicator);
  planets.back().setShipRate(0, ship0rate);
  planets.back().setRotSpeed(M_PI/20);
  planets.back().addShips(3, 0);

  //Now repeatedly create planets until either a target density is reached
  //or we go too many tries without finding a spot for a new planet.
  char tries = 0;
  char maxTries = 10;
  double density = 0.13;
  double totalSize = LEVEL_WIDTH*LEVEL_HEIGHT;
  double currentSize = M_PI*UNSCALED_PLANET_RADIUS*UNSCALED_PLANET_RADIUS*2;
  double spacing = 23;
  
  while (currentSize/totalSize < density && tries < maxTries)
    {
      //Create a new planet at a completely random location with a random size
      //For now, make half normal and half volcanic
      float psize = (double(rand())/double(RAND_MAX))*0.7 + 0.5;
      Planet p(planet0img, psize,
               Vec2f(rand()%(LEVEL_WIDTH-int(2*UNSCALED_PLANET_RADIUS*psize)),
                     rand()%(LEVEL_HEIGHT-int(2*UNSCALED_PLANET_RADIUS*psize))), 0);;
      if (rand()%2 == 0)
        {
          p.setType(0);
          p.setImage(planet0img);
        }
      else
        {
          p.setType(1);
          p.setImage(planet1img);
        }

      //Make sure it doesn't collide with any other planets
      bool skip = false;
      for (planetIter pi = planets.begin(); pi != planets.end(); pi++)
	{
	  Vec2f ppos = p.pos()+Vec2f(UNSCALED_PLANET_RADIUS*p.size(),UNSCALED_PLANET_RADIUS*p.size());
	  Vec2f pipos = pi->pos()+Vec2f(UNSCALED_PLANET_RADIUS*pi->size(),UNSCALED_PLANET_RADIUS*pi->size());
	  if ((pipos-ppos).length() <
	      p.size()*UNSCALED_PLANET_RADIUS +
	      pi->size()*UNSCALED_PLANET_RADIUS + spacing)
	    {
	      //There's a collision. Increment tries and try again
	      tries++;
	      skip = true;
	      break;
	    }
	}
      if (skip) continue;

      //At this point, we know there's no collision. Reset tries
      tries = 0;

      //Add a few more random attributes
      p.setOwner(0, indicator);
      p.setShipRate(0, ship0rate);
      p.setRotSpeed((fmod(rand(),M_PI)/5) - M_PI/10);
      p.setDifficulty(p.size()*20 + rand()%15 - 9);

      //Add this planet to the current size
      currentSize += M_PI*(UNSCALED_PLANET_RADIUS*p.size())*(UNSCALED_PLANET_RADIUS*p.size());

      //Add it to the list
      planets.push_back(p);
    }
  
  //Set up fleet list
  std::list<Fleet> fleets;

  //Set up projectile list
  std::list<Projectile> projectiles;

  //Filler to act as NULL
  planetIter planNull;

  //The currently selected planet
  planetIter selectPlanet = planNull;

  //Set up AI
  std::list<GalconAI> ai;

  //For now, AI controls player 2
  GalconAISettings aiSet;
  aiSet.attackFraction = .8;
  aiSet.surplusDefecitThreshold = .25;
  aiSet.attackExtraNeutral = .2;
  aiSet.attackExtraEnemy = .7;
  aiSet.perPlanetAttackStrength = .5;
  aiSet.delay = 200;
  aiSet.maximumBuildingFraction = .8;
  aiSet.minimumDefenseForBuilding = 10;
  aiSet.distancePower = 1.15;
  ai.push_back(GalconAI(2, aiSet));
  ai.begin()->init(planets, shipstats);
  ai.begin()->activate();

  //The number of the locally playing player
  char localPlayer = 1;

  //The type of ship that will currently be sent
  int shipSendType = 0;

  //A line drawer for the main surface
  LineDrawer linedraw(screen);
  
  /*
    -----
    MAIN LOOP
    -----
  */

  int time = SDL_GetTicks();
  uint8_t quit = 0;
  while (quit == 0)
    {
      //Update time and dt
      //Cap FPS
      int dt = SDL_GetTicks() - time;
      float minms = 1000.0/float(FPS_CAP);
      if (dt < minms) SDL_Delay(minms-dt);
      time = SDL_GetTicks();

      //Update keystates
      keystates = SDL_GetKeyState(NULL);

      //Check for arrow keys/wasd
      if (keystates[SDLK_UP] || keystates[SDLK_w])
	{
	  cameray -= CAMERA_SPEED * (dt/1000.0);
	  if (cameray < 0) cameray = 0;
	}
      
      if (keystates[SDLK_RIGHT] || keystates[SDLK_d])
	{
	  camerax += CAMERA_SPEED * (dt/1000.0);
	  if (camerax > LEVEL_WIDTH - SCREEN_WIDTH) camerax = LEVEL_WIDTH - SCREEN_WIDTH;
	}
      
      if (keystates[SDLK_DOWN] || keystates[SDLK_s])
	{
	  cameray += CAMERA_SPEED * (dt/1000.0);
	  if (cameray > LEVEL_HEIGHT - SCREEN_HEIGHT) cameray = LEVEL_HEIGHT - SCREEN_HEIGHT;
	}
      
      if (keystates[SDLK_LEFT] || keystates[SDLK_a])
	{
	  camerax -= CAMERA_SPEED * (dt/1000.0);
	  if (camerax < 0) camerax = 0;
	}

      //Update camera from camerax and cameray to struct
      camera.x = camerax;
      camera.y = cameray;
      
      //Handle events
      while (SDL_PollEvent(&event))
	{
	  //Quit if requested
	  if (event.type == SDL_QUIT)
	    {
	      quit = 1;
	    }

	  //Check for escape key, QWERTY to construct buildings, or numbers to select
	  //ship type.
	  //BUILDING CONSTRUCTION AND TYPE SELECTION THIS WAY IS TEMPORARY
	  if (event.type == SDL_KEYDOWN)
	    {
	      switch (event.key.keysym.sym)
		{
		case SDLK_ESCAPE:
		  quit = 1;
		  break;
		case SDLK_q:
		  if (selectPlanet != planNull)
                    {
                      if (selectPlanet->owner() != localPlayer ||
                          buildRules[selectPlanet->type()].size() < 1) break;
                      
                      selectPlanet->build(*(buildRules[selectPlanet->type()].begin()),
                                          buildRules);
                    }
		  break;
		case SDLK_w:
		  if (selectPlanet != planNull)
                    {
                      if (selectPlanet->owner() != localPlayer ||
                          buildRules[selectPlanet->type()].size() < 2) break;
                      
                      selectPlanet->build(*(++buildRules[selectPlanet->type()].begin()),
                                          buildRules);
                    }
		  break;
		case SDLK_e:
		  if (selectPlanet != planNull)
                    {
                      if (selectPlanet->owner() != localPlayer ||
                          buildRules[selectPlanet->type()].size() < 3) break;
                      
                      std::list<Building*>::iterator i;
                      i = buildRules[selectPlanet->type()].begin();
                      i++; i++;
                      selectPlanet->build(*i, buildRules);
                    }
                  break;
		case SDLK_1:
		  shipSendType = 0;
		  break;
		case SDLK_2:
		  shipSendType = 1;
		  break;
		case SDLK_3:
		  shipSendType = 2;
		  break;
		case SDLK_4:
		  shipSendType = 3;
		  break;
		case SDLK_5:
		  shipSendType = 4;
		  break;
		default:
		  break;
		}
	    }

	  //Check for mouse clicks
	  if (event.type == SDL_MOUSEBUTTONDOWN)
	    {
	      //Left click
	      if (event.button.button == SDL_BUTTON_LEFT)
		{
		  //Used to select a planet
		  //Check if any are being clicked on
		  selectPlanet = planNull;

		  //Adjust mouse coordinates based on camera
		  Vec2f click(event.button.x + camera.x, event.button.y + camera.y);
		  
		  for (planetIter i = planets.begin(); i != planets.end(); i++)
		    {
		      //See if distance from center is less than planet radius
		      Vec2f center(i->x() + (UNSCALED_PLANET_RADIUS * i->size()),
				   i->y() + (UNSCALED_PLANET_RADIUS * i->size()));

		      if ((click-center).length() < UNSCALED_PLANET_RADIUS * i->size())
			{
			  //Ensure the planet belongs to this person
			  if ((*i).owner() == localPlayer)
			    {
			      selectPlanet = i;
			      break;
			    }
			}
		    }
		}

	      //Right click
	      if (event.button.button == SDL_BUTTON_RIGHT)
		{
		  //Used to choose the destination for a fleet
		  //See if we have a selected planet
		  if (selectPlanet != planNull)
		    {

		      //Adjust mouse coordinates based on camera
		      Vec2f click(event.button.x + camera.x, event.button.y + camera.y);
		      
		      //Check to see if any are being clicked on
		      for (planetIter i = planets.begin(); i != planets.end(); i++)
			{
			  Vec2f center(i->x() + (UNSCALED_PLANET_RADIUS * i->size()),
				       i->y() + (UNSCALED_PLANET_RADIUS * i->size()));
			  
			  //See if distance from center is less than planet radius
			  if ((click-center).length() < UNSCALED_PLANET_RADIUS * i->size())
			    {
			      //Split ships from the source planet
			      int transfer = (*selectPlanet).splitShips(0.5, shipSendType);
			      //Make sure we actually have a ship in the fleet
			      if (transfer > 0)
				{
				  //Add the new fleet
				  fleets.push_back(Fleet(transfer, shipSendType, shipstats[shipSendType], &(*selectPlanet), &(*i)));
				  break;
				}
			    }
			}
		    }
		}
	    }
	}

      //Draw a white background
      SDL_Rect back = {0, 0, SCREEN_WIDTH, SCREEN_HEIGHT};
      SDL_FillRect(screen, &back, 0xFFFFFF);

      //Update and display fleets
      for (fleetIter i = fleets.begin(); i != fleets.end(); i++)
	{
	  (*i).update();

	  //Check for arrival at destination
	  //See if distance from center is less than planet radius
	  Vec2f tar((*i).dest()->x() + (UNSCALED_PLANET_RADIUS*(*i).dest()->size()),
		    (*i).dest()->y() + (UNSCALED_PLANET_RADIUS*(*i).dest()->size()));
	  
	  if ((tar-i->pos()).length() < UNSCALED_PLANET_RADIUS * (i->dest())->size())
	    {
	      //Check if friendly or hostile
	      if ((*i).dest()->owner() == (*i).owner())
		{
		  //Add the fleet to the new planet
		  (*((*i).dest())).addShips(i->ships(), i->type());
		}
	      else //Hostile
		{
		  //Attack!
		  //Get ship counts before the attack
		  std::vector<int> ships1 = i->dest()->shipcount();
		  int oldowner = i->dest()->owner();

		  //Actually do the attack
		  (*((*i).dest())).takeAttack(i->ships(), i->type(), i->owner(), shipstats, indicator);

		  //If the attack changed ownership of the selected planet,
		  //deselect it
		  if (oldowner != i->dest()->owner() && i->dest() == &(*selectPlanet)) selectPlanet = planNull;

		  //Get ship counts after the attack
		  std::vector<int> ships2 = i->dest()->shipcount();

		  //Notify the defending AI about the losses
		  for (std::list<GalconAI>::iterator j = ai.begin(); j != ai.end(); j++)
		    {
		      if (oldowner != j->player()) continue;
		      float newdefense = 0;
		      for (unsigned int k = 0; k < ships1.size(); k++)
			{
			  int diff;
			  //If ownership has changed
			  if (oldowner != i->dest()->owner())
			    {
			      diff = ships1[k];
			      j->notifyPlanetLoss(i->dest());
			    }
			  else
			    {
			      diff = ships1[k] - ships2[k];
			    }
			  
			  newdefense += diff * shipstats[k].defense;
			}
		      j->notifyDefendLoss(newdefense);
		    }

		  //Notify the attacking AI about the losses
		  for (std::list<GalconAI>::iterator j = ai.begin(); j != ai.end(); j++)
		    {
		      if (i->owner() != j->player()) continue;
		      float lost;
		      
		      //If the attack failed
		      if (i->dest()->owner() != i->owner())
			{
			  //Lost everything
			  lost = i->ships();
			}
		      else //Successful attack
			{
			  //Lose the difference
			  lost = i->ships() - i->dest()->totalDefense(shipstats);
			  j->notifyPlanetGain(i->dest());
			}
		      
		      j->notifyAttackLoss(lost);
		    }
		}

	      //Delete all projectiles with this fleet as its target
	      for (projectileIter pi = projectiles.begin(); pi != projectiles.end(); pi++)
		{
		  if (pi->target() == &(*(i)))
		    {
		      pi = projectiles.erase(pi);
		      pi--;
		    }
		}

	      //Delete the fleet
	      i = fleets.erase(i);
	      i--;
	      continue;
	    }

	  //Check for interception
	  //Compare against every other fleet
	  for (fleetIter j = fleets.begin(); j != fleets.end(); j++)
	    {
	      //Atempt interception
	      char status = i->intercept(&(*j), shipstats);

	      //Greater than 0: Draw line
	      if (status <= 0) continue;
	      SDL_Color red = {255, 0, 0};
	      SDL_Color orange = {255, 255, 0};
	      linedraw.line(i->pos(), j->pos(), orange, red);

	      //Equal to 2: Dealt damage, but didn't notify
	      if (status == 2)
		{
		  //Notify the AI before we go around deleting things
		  for (std::list<GalconAI>::iterator k = ai.begin(); k != ai.end(); k++)
		    {
		      if (k->player() == j->owner())
			{
			  k->notifyFleetDamage(std::min(double(shipstats[i->type()].interceptDamage),
							double(j->totalDefense(shipstats))));
			}
		    }
		}

	      //Equal to 3: Destroy target
	      if (status != 3) break;

	      //We can have the projectile code handle the cleanup later
	      //Create a fake projectile right on top of it to deal the final blow
	      std::stringstream convertnum;
	      convertnum << "damage ";
	      convertnum << shipstats[i->type()].interceptDamage*i->ships()*2;
	      projectiles.push_back(Projectile(j->pos(), &(*j),
					       convertnum.str(),
					       shipstats[j->type()].speed*2));

	      //Don't attack more than one ship
	      break;
	    }
	  
	  (*i).display(screen, camera);
	}

      //Update and display planets
      for (planetIter i = planets.begin(); i != planets.end(); i++)
	{
	  //Get ship counts before the update
	  std::vector<int> ships1 = i->shipcount();

	  //Update the planet
	  (*i).update();

	  //Get ship counts after the update
	  std::vector<int> ships2 = i->shipcount();

	  //Notify a controlling AI about the construction
	  for (std::list<GalconAI>::iterator j = ai.begin(); j != ai.end(); j++)
	    {
	      if (i->owner() != j->player()) continue;
	      float newattack = 0;
	      float newdefense = 0;
	      for (unsigned int k = 0; k < ships1.size(); k++)
		{
		  int diff = ships2[k] - ships1[k];
		  newattack += diff * shipstats[k].attack;
		  newdefense += diff * shipstats[k].defense;
		}
	      j->notifyConstruction(newattack, newdefense);
	    }

	  //If this planet is selected, add an indicator
	  if (i == selectPlanet)
	    {
	      SDL_Rect temprect = {Sint16((*i).x()-10 - camera.x), Sint16((*i).y()-10 - camera.y), Uint16(UNSCALED_PLANET_RADIUS * (*i).size() * 2 + 20), Uint16(UNSCALED_PLANET_RADIUS * (*i).size() * 2 + 20)};
	      SDL_FillRect(screen, &temprect, SDL_MapRGB(screen->format, 100, 100, 100));
	    }

          //If this is a lava planet and it is depleted, replace the image
          if (i->typeInfo() < 0 && i->type() == 1)
            {
              i->setImage(planet1_1img);
              i->setTypeInfo(0);
              i->setRotSpeed(0);
              i->setShipRate(0, ship0rate * PLANET1_DEPLETION_PENALTY);
            }

	  //Iterate over all buildings to handle effects from buildings to other objects

	  for (unsigned int j = 0; j < i->buildcount(); j++)
	    {
	      //Get the building
	      BuildingInstance* b = i->building(j);
	      
	      //Skip over nonexistant and incomplete buildings
	      if (!(b->exists()) || j == Uint32(i->buildIndex())) continue;

	      //Try to make it fire, remember result
	      bool fire = b->fire();
	      
	      //Create a string stream and vector for tokens
	      std::stringstream ss(b->effect());
	      std::string item;
	      std::vector<std::string> tokens;
	      while (std::getline(ss, item, ' '))
		{
		  tokens.push_back(item);
		}
	      
	      //Ensure the size is at least two
	      if (tokens.size() < 3) continue;
	      
	      //Parse it and apply effects that involve multiple objects
	      //Fire projectile: fire <effect> <effectvars> <speed as multiplier>
	      if (tokens[0] == "fire")
		{
		  //Ensure size of four
		  if (tokens.size() != 4) continue;
		  
		  //Loop over all potential target fleets, find closest
		  Fleet* closest = NULL;
		  float closestDist = -1;
		  Vec2f coords = i->buildcoords(j);
		  for (fleetIter k = fleets.begin(); k != fleets.end(); k++)
		    {
		      //Only check further if it's an enemy fleet
		      if (k->owner() == i->owner()) continue;
		      //Compute the distance between them
		      double dist = (coords-k->pos()).length();
		      
		      //Continue if the fleet is out of range
		      if (dist > b->range()) continue;
		      
		      //Compare with previous best
		      if (dist < closestDist || closestDist < -0.5)
			{
			  closestDist = dist;
			  closest = &(*k);
			}
		    }
		  
		  //Fire a projectile from the building to the fleet
		  if (closest != NULL)
		    {
		      if (fire)
			{
			  //Create a proper string for the projectile
			  std::string projstr;
			  for (unsigned int word = 1; word < tokens.size()-1; word++)
			    { projstr += tokens[word] + " "; }
			  projectiles.push_back(Projectile(coords, closest, projstr, std::atof(tokens[tokens.size()-1].c_str())));
			}
		    }
		}

              //Aura: aura <effect> <effectvars>
              if (tokens[0] == "aura")
                {
                  //Find number of ships in range
                  int shipcount = 0;
                  for (fleetIter k = fleets.begin(); k != fleets.end(); k++)
		    {
		      //Only check further if it's an enemy fleet
		      if (k->owner() == i->owner()) continue;
		      //Compute the distance between them
		      double dist = (i->buildcoords(j)-k->pos()).length();
                      if (dist <= b->range()) shipcount += k->ships();
                    }

                  //Deal damage with a fake projectile
                  if (fire)
                    {
                      bool hit = false;
                      for (fleetIter k = fleets.begin(); k != fleets.end(); k++)
                        {
                          //Only check further if it's an enemy fleet
                          if (k->owner() == i->owner()) continue;
                          //Compute the distance between them
                          double dist = (i->buildcoords(j)-k->pos()).length();
                          if (dist > b->range()) continue;
                          hit = true;
                          
                          std::string projstr;
                          //Divide appropriately if needed
                          if (tokens[tokens.size()-1] == "total")
                            {
                              std::stringstream toa;
                              toa << atof(tokens[tokens.size()-2].c_str())*float(k->ships())/float(shipcount);
                              tokens[tokens.size()-1] = toa.str();
                            }
                          //Depleted volcanic planets don't do as much
                          if (i->type() == 1 && i->typeInfo() <= 0)
                            {
                              std::stringstream toa;
                              toa << atof(tokens[tokens.size()-2].c_str())*PLANET1_DEPLETION_PENALTY;
                              tokens[tokens.size()-1] = toa.str();
                            }
                          //Create the projectile
                          for (unsigned int word = 1; word < tokens.size()-1; word++)
                            {
                              projstr += tokens[word] + " ";
                            }
                          projectiles.push_back(Projectile(k->pos(), &(*k), projstr, 1));
                        }

                      //Volcanic planets will lost some fuel
                      if (i->type() == 1 && hit && i->typeInfo() != 0)
                        {
                          i->setTypeInfo(i->typeInfo()-PLANET1_DEPLETION_RATE);
                          if (i->typeInfo() == 0) i->setTypeInfo(-1);
                        }
                      
                    }
                }
                      
	    } //for each building

	  (*i).display(screen, planetFont, camera);
	}

      //Update and display projectiles
      for (projectileIter i = projectiles.begin(); i != projectiles.end(); i++)
	{
	  (*i).update();

	  //Check if the projectile has hit its target fleet
	  if ((i->pos() - i->target()->pos()).length() < 12.345) //MAGIC NUMBER >:(
	    {
	      //Tokenize string to determine effect
	      std::stringstream ss(i->effect());
	      std::string item;
	      std::vector<std::string> tokens;
	      while (std::getline(ss, item, ' '))
		{
		  tokens.push_back(item);
		}

	      //Damage: damage <amount>
	      if (tokens[0] == "damage")
		{
		  //Ensure size of two
		  if (tokens.size() != 2) continue;

		  //Deliver the damage

		  //Notify the AI before we go around deleting things
		  for (std::list<GalconAI>::iterator j = ai.begin(); j != ai.end(); j++)
		    {
		      if (j->player() == i->target()->owner())
			{
			  j->notifyFleetDamage(std::min(std::atof(tokens[1].c_str()), double(i->target()->totalDefense(shipstats))));
			}
		    }
		  
		  //Check to see if the fleet is destroyed by this
		  if (!(i->target()->takeHit(std::atof(tokens[1].c_str()), shipstats)))
		    {
		      //Delete the fleet
		      for (fleetIter fi = fleets.begin(); fi != fleets.end(); fi++)
			{
			  if (&(*fi) == &(*(i->target())))
			    {
			      fleets.erase(fi);
			      break;
			    }
			}

		      //Delete all projectiles with this fleet as the target
		      for (projectileIter pi = projectiles.begin(); pi != projectiles.end(); pi++)
			{
			  if (pi->target() == i->target())
			    {
			      if (pi == i) continue;
			      pi = projectiles.erase(pi);
			      pi--;
			    }
			}

		    }

		  //Either way, destroy this projectile
		  i = projectiles.erase(i);
		  i--;
		  continue;
		}
	    }

	  (*i).display(screen, camera);
	}

      //Perform AI calculations
      for (std::list<GalconAI>::iterator i = ai.begin(); i != ai.end(); i++)
	{
	  //Get the command list
	  commandList com = i->update(planets, fleets, shipstats, buildRules);

	  //Execute each command
	  for (commandList::iterator j = com.begin(); j != com.end(); j++)
	    {
	      //Extract the info from the command
	      Planet* source = j->first;
	      int amount = j->second.first;
	      Planet* dest = j->second.second;

	      //Handle building construction
	      if (source == dest)
		{
		  std::list<Building*>::iterator build = buildRules[source->type()].begin();
		  while (amount > 0)
		    {
		      amount--;
		      build++;
		    }

		  //Build it!
		  source->build((*build), buildRules);
		  continue;
		}

	      //Get the number of ships from the source
	      std::vector<int> ships = source->shipcount();

	      //Send out a fleet for each ship type used
	      std::vector<int> newfleet;
	      newfleet.resize(ships.size());
	      int total = 0;
	      for (unsigned int k = 0; k < ships.size(); k++)
		{
		  //Handle it differently for attack or defense
		  float typeTotal;
		  if (dest->owner() == source->owner())
		    {
		      //Check the total defense of this ship type
		      typeTotal = ships[k] * shipstats[k].defense;
		    }
		  else
		    {
		      //Check the total attack of this ship type
		      typeTotal = ships[k] * shipstats[k].attack;
		    }
		  
		  //If there's more ships requested than there are of this type
		  if (total + typeTotal <= amount)
		    {
		      //Add them all
		      newfleet[k] += ships[k];
		      total += typeTotal;
		    }
		  else //More ships than space in the requested fleet
		    {
		      //Find the proper amount
		      //# of ships to send = defense requested / def per ship
		      float properAmount = (amount - total) / (typeTotal / ships[k]);
		      newfleet[k] += properAmount;
		      break;
		    }
		}
	      
	      //Fleet is built, send each type that has some ships
	      for (unsigned int k = 0; k < newfleet.size(); k++)
		{
		  if (newfleet[k] == 0) continue;
		  fleets.push_back(Fleet(newfleet[k], k, shipstats[k], source, dest));

		  //Also subtract the fleet from the original planet
		  newfleet[k] *= -1;
		  source->addShips(newfleet[k], k);
		}
	    }
	}

      //Flipoo
      if (SDL_Flip(screen) == -1)
	{
	  return 1;
	}
    }

  //Free surfaces
  SDL_FreeSurface(indicator[1]);
  SDL_FreeSurface(indicator[2]);
  SDL_FreeSurface(planet0img);
  SDL_FreeSurface(planet1img);
  SDL_FreeSurface(planet1_1img);

  //Clean up TTF
  TTF_CloseFont(planetFont);
  TTF_Quit();

  SDL_Quit();
}
Ejemplo n.º 22
0
SolarSystem::SolarSystem(QString name) : data(new SolarSystemData)
{
    data->name = name;
    data->x = qrand() % 1000;
    data->y = qrand() % 1000;
    data->color = QColor(qrand() % 256, qrand() % 256, qrand() % 256, 96);

    QStringList planetNames;
    planetNames.append(QStringLiteral("6 Echo"));
    planetNames.append(QStringLiteral("Cybertron"));
    planetNames.append(QStringLiteral("Curie 3"));
    planetNames.append(QStringLiteral("Nzinga"));
    planetNames.append(QStringLiteral("Lithios"));
    planetNames.append(QStringLiteral("Reach"));
    planetNames.append(QStringLiteral("Halo"));
    planetNames.append(QStringLiteral("Reconciliation"));
    planetNames.append(QStringLiteral("New Mombasa"));
    planetNames.append(QStringLiteral("Draconis"));
    planetNames.append(QStringLiteral("Pegasus"));
    planetNames.append(QStringLiteral("Zeta"));
    planetNames.append(QStringLiteral("Hellespont"));
    planetNames.append(QStringLiteral("Jericho"));
    planetNames.append(QStringLiteral("Hydra"));
    planetNames.append(QStringLiteral("Alpha"));
    planetNames.append(QStringLiteral("Librae"));
    planetNames.append(QStringLiteral("Legit"));
    planetNames.append(QStringLiteral("Halcyon"));
    planetNames.append(QStringLiteral("Ceres"));
    planetNames.append(QStringLiteral("Gaia"));
    planetNames.append(QStringLiteral("Cronus"));
    planetNames.append(QStringLiteral("Metis"));
    planetNames.append(QStringLiteral("Pandora"));
    planetNames.append(QStringLiteral("Moonbase Alpha"));
    planetNames.append(QStringLiteral("Eris"));
    planetNames.append(QStringLiteral("Demetris"));
    planetNames.append(QStringLiteral("Threshold"));
    planetNames.append(QStringLiteral("Harvest"));
    planetNames.append(QStringLiteral("Arcadia"));
    planetNames.append(QStringLiteral("Installation 04"));
    planetNames.append(QStringLiteral("Onyx"));
    planetNames.append(QStringLiteral("Origin"));
    planetNames.append(QStringLiteral("Cryptum"));
    planetNames.append(QStringLiteral("Glasslands"));
    planetNames.append(QStringLiteral("Escalation"));
    planetNames.append(QStringLiteral("Cole Protocol"));
    planetNames.append(QStringLiteral("Midlothian"));
    planetNames.append(QStringLiteral("Valar"));
    planetNames.append(QStringLiteral("Arda"));
    planetNames.append(QStringLiteral("Castleguard"));
    planetNames.append(QStringLiteral("Midgard"));
    planetNames.append(QStringLiteral("Earendel"));
    planetNames.append(QStringLiteral("Middle Earth"));
    planetNames.append(QStringLiteral("Earth"));
    planetNames.append(QStringLiteral("Melkor"));
    planetNames.append(QStringLiteral("Eru"));
    planetNames.append(QStringLiteral("Silmarillion"));
    planetNames.append(QStringLiteral("Illuvatar"));
    planetNames.append(QStringLiteral("Valinor"));
    planetNames.append(QStringLiteral("Luthien"));
    planetNames.append(QStringLiteral("Arnor"));
    planetNames.append(QStringLiteral("Isildur"));
    planetNames.append(QStringLiteral("Pelennor"));
    planetNames.append(QStringLiteral("Arwen"));
    planetNames.append(QStringLiteral("Numenor"));
    planetNames.append(QStringLiteral("Narsil"));
    planetNames.append(QStringLiteral("Barahir"));
    planetNames.append(QStringLiteral("Denethor"));
    planetNames.append(QStringLiteral("Tinuviel"));
    planetNames.append(QStringLiteral("Thranduil"));
    planetNames.append(QStringLiteral("Harad"));
    planetNames.append(QStringLiteral("Caradhras"));
    planetNames.append(QStringLiteral("Anduin"));
    planetNames.append(QStringLiteral("Lothlorien"));
    planetNames.append(QStringLiteral("Rauros"));
    planetNames.append(QStringLiteral("Dunharrow"));
    planetNames.append(QStringLiteral("Telcontar"));
    planetNames.append(QStringLiteral("Haradrim"));
    planetNames.append(QStringLiteral("Eldarion"));
    planetNames.append(QStringLiteral("Easterlings"));
    planetNames.append(QStringLiteral("Ithilien"));
    planetNames.append(QStringLiteral("Orthanc"));
    planetNames.append(QStringLiteral("Dunadan"));
    planetNames.append(QStringLiteral("Evinyatar"));
    planetNames.append(QStringLiteral("Qatar"));
    planetNames.append(QStringLiteral("Estel"));
    planetNames.append(QStringLiteral("Cirdan"));
    planetNames.append(QStringLiteral("Narya"));
    planetNames.append(QStringLiteral("Aelia"));
    planetNames.append(QStringLiteral("Aquila"));
    planetNames.append(QStringLiteral("Atilius"));
    planetNames.append(QStringLiteral("Aulus"));
    planetNames.append(QStringLiteral("Avilius"));
    planetNames.append(QStringLiteral("Avitus"));
    planetNames.append(QStringLiteral("Cassia"));
    planetNames.append(QStringLiteral("Celsus"));
    planetNames.append(QStringLiteral("Drusa"));
    planetNames.append(QStringLiteral("Ennius"));
    planetNames.append(QStringLiteral("Felix"));
    planetNames.append(QStringLiteral("Gallus"));
    planetNames.append(QStringLiteral("Hadrianus"));
    planetNames.append(QStringLiteral("Horatia"));
    planetNames.append(QStringLiteral("Livia"));
    planetNames.append(QStringLiteral("Nerva"));
    planetNames.append(QStringLiteral("Nova"));
    planetNames.append(QStringLiteral("Quintus"));
    planetNames.append(QStringLiteral("Seneca"));
    planetNames.append(QStringLiteral("Sergius"));
    planetNames.append(QStringLiteral("Tacitus"));
    planetNames.append(QStringLiteral("Tiber"));
    planetNames.append(QStringLiteral("Valeria"));
    planetNames.append(QStringLiteral("Valhalla"));
    planetNames.append(QStringLiteral("Narnia"));
    planetNames.append(QStringLiteral("Constantine"));
    planetNames.append(QStringLiteral("Vita"));
    planetNames.append(QStringLiteral("Mithril"));
    planetNames.append(QStringLiteral("Istari"));
    planetNames.append(QStringLiteral("Ichitari"));
    planetNames.append(QStringLiteral("Erebor"));
    planetNames.append(QStringLiteral("Don Guldur"));
    planetNames.append(QStringLiteral("Thrain"));
    planetNames.append(QStringLiteral("Gladden"));
    planetNames.append(QStringLiteral("Bree"));
    planetNames.append(QStringLiteral("Glamdring"));
    planetNames.append(QStringLiteral("Beorn"));
    planetNames.append(QStringLiteral("Gwaihir"));
    planetNames.append(QStringLiteral("Mearas"));
    planetNames.append(QStringLiteral("Grima"));
    planetNames.append(QStringLiteral("Shadowfax"));
    planetNames.append(QStringLiteral("Tirith"));
    planetNames.append(QStringLiteral("Angmar"));
    planetNames.append(QStringLiteral("Imrahil"));
    planetNames.append(QStringLiteral("Rath"));
    planetNames.append(QStringLiteral("Dinen"));
    planetNames.append(QStringLiteral("Orodruin"));
    planetNames.append(QStringLiteral("Undying"));
    planetNames.append(QStringLiteral("Sotheby"));
    planetNames.append(QStringLiteral("Dolomite"));
    planetNames.append(QStringLiteral("Dale"));

    QStringList chosenPlanetNames;
    int numPlanets = qrand() % 3 + 1;
    while (chosenPlanetNames.length() < numPlanets) {
        QString planetName = planetNames.at(qrand() % planetNames.length());
        if (!chosenPlanetNames.contains(planetName)) {
            chosenPlanetNames.append(planetName);
        }
    }

    for (int i = 0; i < numPlanets; i++) {
        data->planets.insert(chosenPlanetNames.at(i), Planet(chosenPlanetNames.at(i)));
    }
}
Ejemplo n.º 23
0
// Add a planet with the given data
void SolarSystem::addPlanet(float distanceFromSun, float orbitTime, float rotationTime, float radius, GLuint textureHandle)
{
	planets.push_back(Planet(distanceFromSun, orbitTime, rotationTime, radius, textureHandle));
}
Ejemplo n.º 24
0
BOOL Initialize(GL_Window* window, Keys* keys)					// Any OpenGL Initialization Goes Here
{
	font = Font(window->hDC);
	standalonePointFont = Font(window->hDC);

	glShadeModel(GL_SMOOTH);
	glEnable(GL_TEXTURE_2D);

	app.SetLoggingFile("error.log");
	app.SetReferenceFrame(Frame::ECLIPJ2000);
	app.SetDefaultUnits(App::UT_DEFAULT);

	app.LoadKernel("data/meta.tm");
	//app.LoadChildren(SpaceObject("Solar system barycenter"), true, true);

	app.AddObject(SpaceBody("EARTH"));
	app.AddObject(SpaceBody("SUN"));
	app.AddObject(SpaceBody("MOON"));
	app.AddObject(SpaceObject("L2_OBJECT"));
	app.AddObject(SpaceObject("L2"));

	TGA* sunTexture = new TGA("Images\\SUN.tga");
	skyTexture = new TGA("Images\\STARS.tga");

	t = Date("Mar 29 2016 01:03:52.99996036291100000 (UTC+0)");

	size_t count = app.GetObjectsLength();
	for (int i = 0; i < count; i++)
	{
		const SpaceObject& obj = app.GetObjectByIndex(i);
		try
		{
			if (SpaceObject::IsPlanet(obj.GetSpiceId()) || obj.GetSpiceId() == SUN_SPICE_ID || obj.GetSpiceName() == "MOON")
			{
				std::string path = "Images\\" + obj.GetName() + ".tga";

				if (TGA* Texture = new TGA(path.c_str()))
				{
					const SpaceBody& body = dynamic_cast<const SpaceBody&>(obj);
					SolarSystem.addPlanet(Planet(body, Texture, obj, app.GetReferenceFrame(), window->hDC));
				}
				else
				{
					const SpaceBody& body = dynamic_cast<const SpaceBody&>(obj);
					SolarSystem.addPlanet(Planet(body, sunTexture, obj, app.GetReferenceFrame(), window->hDC));
				}
			}
			else if (obj.GetSpiceName() == "L2_OBJECT")
				SolarSystem.AddTrajectoryAsSpaceObject(obj, app.GetReferenceFrame(), t, app.RetrieveObject("L2"));
			else if (obj.GetSpiceName() == "L2")
				SolarSystem.AddStandaloneSpacePoint(obj, standalonePointFont);
		}
		catch (const std::bad_cast&)
		{
		}
	}

 	g_window = window;
	g_keys = keys;
	g_Camera.PositionCamera(Vector3(-5.5f, 28.44f, 0.2f), Vector3(-17.6f, 53.26f, -8.5f), Vector3(0, 0, 1));
	//g_Camera.FocusOnPlanet(SolarSystem.FindObjectWithID(0), t, app);
	RECT rect;
	GetClientRect(g_window->hWnd, &rect);

	centerX = (rect.right - rect.left) >> 1;
	centerY = (rect.bottom - rect.top) >> 1;

	SetCursorPos(centerX, centerY);

	//t = Date("Aug 17 2000 15:51:01 UTC-5");
	//Color setup
	glClearColor(0, 0, 0, 1);

	float g_LightPosition[4] = { 1, 1, 0, 1 };
	float ambience[4] = { 0.0f, 0.0f, 0.0f };
	float diffuse[4] = { 1.0f, 0.9f, 0.9f };

	glLightfv(GL_LIGHT0, GL_AMBIENT, ambience);
	glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);

	
	glLightfv(GL_LIGHT0, GL_POSITION, g_LightPosition);
	glEnable(GL_LIGHT0);
	glEnable(GL_LIGHTING);
	
	return TRUE;												// Return TRUE (Initialization Successful)
}