/*
** Aetheria.h contains all of the structs common
** to the game Aetheria and its related editors.
**
** Structures include all of the various forms of
** equipment, items and systems since the editors
** will need those too. Game state is not in here
** since that is handled by the client.
*/
#include <stdio.h>
#include <string>
#include <stdlib.h>
#include "..\..\include\hge.h"
#pragma comment(lib,"user32.lib")
#include "..\..\include\hgegui.h"
#include "..\..\include\hgefont.h"
#include "..\..\include\hgevector.h"
#include "..\..\include\hgesprite.h"
#include "..\..\include\hgeparticle.h"
#include "..\..\include\hgeresource.h"
int screenMode = 1;
#define MODE_FULLSCREEN 0
#define MODE_WINDOWED 1
#define TERRAN 1
#define VICTORIAN 2
#define ANCIENT 3
#define WILD 4
struct pointf;
struct pointi;
struct item;
struct thing;
struct npc;
struct celestial;
struct engine;
struct pwrplant;
struct shield;
struct weapon;
struct ship;
struct hive;
struct world;
struct pointf
{
float x,
y;
};
struct pointi
{
int x,
y;
};
struct item
{
static const int TYPE_SHIP = 1,
TYPE_POWER = 2,
TYPE_ENGINE= 3,
TYPE_SHIELD= 4,
TYPE_WEAPON= 5;
string name;
int cost,
type;
float mass,
size;
};
struct npc
{
char *name;
};
struct celestial
{
string name,
sprite,
portalto;
int orbits,
star,
portal;
pointf loc;
hgeVector orb;
float distance,
speed,
drot,
scale,
mass,
angle;
npc* npcs;
item* catalog;
hgeSprite* spt;
};
struct engine
{
static const int TYPE_ENERGY= 1,
TYPE_FUEL = 2,
TYPE_ZERO_P= 3;
string name,
sprite,
parsys;
int type,
stealth;
float thr;
float tur;
hgeParticleSystem* par;
};
struct pwrplant
{
string name;
int type,
stealth,
commod;
float max,
charge,
chgtime,
commoduse;
};
struct shield
{
static const int TYPE_DIRECT = 1, // Hits drain power (coeff)
TYPE_RESTORE = 2, // Power used on replenishing banks
TYPE_CONSTANT = 3, // Power always used, drain
TYPE_COMMOD = 4, // Hits drain resources (coeff)
TYPE_STATIC = 6; // Shield banks don't restore
string name,
sprite;
int type;
float max,
charge, // Charge per second
chgtime,
opacity, // Not all shields absorb 100% damage
drain,
coeff;
hgeSprite* spt;
};
struct weapon
{
static const int TYPE_PROJECTILE = 1,
TYPE_BEAM = 2,
TYPE_PARTICLES = 3;
string name,
sprite;
int type;
float dmg,
pwr,
cooldown,
range,
mass,
spread;
hgeSprite* spt;
};
struct ship
{
static const int TYPE_TERRAN = 1,
TYPE_VICTORIAN = 2,
TYPE_ANCIENT = 3,
TYPE_WILD = 4;
string name,
sprite;
float size,
armor,
capacity,
speed,
mass;
hgeVector *engines;
hgeVector *guns;
hgeVector center;
int type,
neng,
ngun;
hgeSprite* spt;
};
struct hive
{
ship *shp;
weapon *gun;
shield *shd;
pwrplant *pwr;
engine *eng;
celestial cel;
int number;
float range,
adrenaline,
cowardice,
aggressiveness;
bool feral;
};
struct world
{
string name;
celestial* celestials;
celestial** portals;
celestial** stars;
hive* hives;
int ncel,
nhiv,
nport,
nstars;
pointf pstart,
shift;
HTEXTURE bg1;
HTEXTURE bg2;
HTEXTURE bg3;
};
// Pointer to the HGE interface (helper classes require this to work)
HGE *hge=0;
//hgeResourceManager* shipres;
hgeResourceManager* wildres;
hgeResourceManager* shieldres;
hgeResourceManager* wepres;
hgeResourceManager* partres;
hgeResourceManager* planetres;
hgeResourceManager* bgres;
engine* engines;
pwrplant* pwrplants;
shield* shields;
weapon* weapons;
ship* ships;
#pragma warning(disable:4244) // Shuts the compiler up about those int to float conversions in hgeSprite(tex,f,f,f,f)
bool LoadEngineParticle(int i);
void cmdSavePreset(int n, hgeParticleSystemInfo info);
void cmdLoadPreset(int n, hgeParticleSystemInfo info);
ship LoadShip( int i )
{
if(ships[i].type)
return ships[i];
hge->System_SetState(HGE_INIFILE,"ships.ini");
char num [3]; // Creates a string buffer for the item index
_itoa_s(i,num,3,10); // And writes the index to the buffer
// These are intuitive, they copy the value from init file to data structure,
// issuing appropriate defaults if no value is found
ships[i].name = hge->Ini_GetString( num, "name", "Missing");
ships[i].sprite = hge->Ini_GetString( num, "sprite", num);
ships[i].type = hge->Ini_GetInt( num, "type", 1);
ships[i].size = hge->Ini_GetFloat( num, "size", 45.0);
ships[i].armor = hge->Ini_GetFloat( num, "armor", 100.0);
ships[i].capacity = hge->Ini_GetFloat( num, "capacity",100.0);
ships[i].speed = hge->Ini_GetFloat( num, "speed", 200.0);
ships[i].mass = hge->Ini_GetFloat( num, "mass", 75.0);
ships[i].neng = hge->Ini_GetInt( num, "engines", 1);
ships[i].ngun = hge->Ini_GetInt( num, "guns", 0);
ships[i].center.x = hge->Ini_GetFloat( num, "center x",0);
ships[i].center.y = hge->Ini_GetFloat( num, "center y",0);
ships[i].engines = new hgeVector[ships[i].neng];
for(int n = 0; n<ships[i].neng; n++)
{
char eng [20]; eng[0]=0;
sprintf_s(eng,20,"engine %d x",n+1);
ships[i].engines[n].x = hge->Ini_GetFloat( num, eng,0);
sprintf_s(eng,20,"engine %d y",n+1);
ships[i].engines[n].y = hge->Ini_GetFloat( num, eng,0);
}
ships[i].guns = new hgeVector[ships[i].ngun];
for(int n = 0; n<ships[i].neng; n++)
{
char gun [20]={0};
sprintf_s(gun,20,"weapon %d x",n+1);
ships[i].guns[n].x = hge->Ini_GetFloat( num, gun,0);
sprintf_s(gun,20,"weapon %d y",n+1);
ships[i].guns[n].y = hge->Ini_GetFloat( num, gun,0);
}
// Maps the item's sprite to a sprite cached by the respective resource manager
ships[i].spt = wildres->GetSprite(ships[i].sprite.c_str());
ships[i].spt->SetHotSpot(ships[i].spt->GetWidth()/2,ships[i].spt->GetHeight()/2);
return ships[i];
}
/*bool SaveShip( int i )
{
hge->System_SetState(HGE_INIFILE,"ships.ini");
char num [3];
_itoa_s(i,num,3,10);
hge->Ini_SetString( num, "name", ships[i].name);
hge->Ini_SetString( num, "sprite", ships[i].sprite);
hge->Ini_SetFloat( num, "size", ships[i].size);
hge->Ini_SetFloat( num, "armor", ships[i].armor);
hge->Ini_SetFloat( num, "capacity", ships[i].capacity);
hge->Ini_SetFloat( num, "speed", ships[i].speed);
hge->Ini_SetFloat( num, "mass", ships[i].mass);
hge->Ini_SetInt( num, "type", ships[i].type);
return true;
}*/
weapon LoadWeapon( int i )
{
if(weapons[i].type)
return weapons[i];
hge->System_SetState(HGE_INIFILE,"weapons.ini");
char num [3];
_itoa_s(i,num,3,10);
weapons[i].name = hge->Ini_GetString( num, "name", "Missing");
weapons[i].sprite = hge->Ini_GetString( num, "sprite", "Error.png");
weapons[i].type = hge->Ini_GetInt( num, "type", 1);
weapons[i].dmg = hge->Ini_GetFloat( num, "damage", 15.0);
weapons[i].mass = hge->Ini_GetFloat( num, "mass", 0);
weapons[i].pwr = hge->Ini_GetFloat( num, "power", 15.0);
weapons[i].cooldown = hge->Ini_GetFloat( num, "cooldown",0.5);
weapons[i].range = hge->Ini_GetFloat( num, "range", 500.0);
weapons[i].spread = hge->Ini_GetFloat( num, "spread", 5.0);
weapons[i].spt = wepres->GetSprite(weapons[i].sprite.c_str());
weapons[i].spt->SetHotSpot(weapons[i].spt->GetWidth()/2,weapons[i].spt->GetHeight()/2);
return weapons[i];
}/*
bool SaveWeapon( int i )
{
hge->System_SetState(HGE_INIFILE,"weapons.ini");
char num [3];
_itoa_s(i,num,3,10);
hge->Ini_SetString( num, "name", weapons[i].name);
hge->Ini_SetString( num, "sprite", weapons[i].sprite);
hge->Ini_SetFloat( num, "damage", weapons[i].dmg);
hge->Ini_SetFloat( num, "dmgtime", weapons[i].dmgtime);
hge->Ini_SetFloat( num, "power", weapons[i].pwr);
hge->Ini_SetFloat( num, "cooldown", weapons[i].cooldown);
hge->Ini_SetFloat( num, "range", weapons[i].range);
hge->Ini_SetFloat( num, "spread", weapons[i].spread);
return true;
}*/
shield LoadShield( int i )
{
if(shields[i].type)
return shields[i];
hge->System_SetState(HGE_INIFILE,"shields.ini");
char num [3];
_itoa_s(i,num,3,10);
shields[i].name = hge->Ini_GetString( num, "name", "Missing");
shields[i].sprite = hge->Ini_GetString( num, "sprite", "Bubble");
shields[i].type = hge->Ini_GetInt( num, "type", 1);
shields[i].max = hge->Ini_GetFloat( num, "max_shd", 200.0);
shields[i].charge = hge->Ini_GetFloat( num, "charge", 20.0);
shields[i].chgtime = hge->Ini_GetFloat( num, "chg_time",1000);
shields[i].spt = shieldres->GetSprite(shields[i].sprite.c_str());
shields[i].spt->SetHotSpot(shields[i].spt->GetWidth()/2,shields[i].spt->GetHeight()/2);
return shields[i];
}/*
bool SaveShield( int i )
{
hge->System_SetState(HGE_INIFILE,"shields.ini");
char num [3];
_itoa_s(i,num,3,10);
hge->Ini_SetString( num, "name", shields[i].name);
hge->Ini_SetString( num, "sprite", shields[i].sprite);
hge->Ini_SetFloat( num, "max_shd", shields[i].max);
hge->Ini_SetFloat( num, "charge", shields[i].charge);
hge->Ini_SetFloat( num, "chg_time", shields[i].chgtime);
return true;
}*/
pwrplant LoadPower( int i )
{
if(pwrplants[i].type)
return pwrplants[i];
hge->System_SetState(HGE_INIFILE,"pwrplants.ini");
char num [3];
_itoa_s(i,num,3,10);
pwrplants[i].name = hge->Ini_GetString( num, "name", "Missing");
pwrplants[i].type = hge->Ini_GetInt( num, "type", 1);
pwrplants[i].max = hge->Ini_GetFloat( num, "max_pwr", 100.0);
pwrplants[i].charge = hge->Ini_GetFloat( num, "charge", 10.0);
pwrplants[i].chgtime = hge->Ini_GetFloat( num, "chg_time",1000);
return pwrplants[i];
}/*
bool SavePower( int i )
{
hge->System_SetState(HGE_INIFILE,"pwrplants.ini");
char num [3];
_itoa_s(i,num,3,10);
hge->Ini_SetString( num, "name", pwrplants[i].name);
hge->Ini_SetFloat( num, "max_shd", pwrplants[i].max);
hge->Ini_SetFloat( num, "charge", pwrplants[i].charge);
hge->Ini_SetFloat( num, "chg_time", pwrplants[i].chgtime);
return true;
}*/
engine LoadEngine( int i )
{
if(engines[i].type)
return engines[i];
hge->System_SetState(HGE_INIFILE,"engines.ini");
char num[3];
//sprintf_s(num,4,"%d",i);
_itoa_s(i,num,3,10);
engines[i].name = hge->Ini_GetString( num, "name", "Missing");
engines[i].parsys = hge->Ini_GetString( num, "particle","Missing");
engines[i].sprite = hge->Ini_GetString( num, "sprite", "Error");
engines[i].type = hge->Ini_GetInt( num, "type", 1);
engines[i].thr = hge->Ini_GetFloat( num, "thrust", 100);
engines[i].tur = hge->Ini_GetFloat( num, "turning", 100);
//engines[i].spt = partres->GetSprite(engines[i].sprite.c_str());
//engines[i].spt->SetHotSpot(engines[i].spt->GetWidth()/2,engines[i].spt->GetHeight()/2);
LoadEngineParticle(i);
return engines[i];
}
bool SaveEngine( int i );
world LoadWorld(char *name)
{
// MessageBox(NULL, "World Components Configured", "Debug", MB_OK | MB_ICONERROR | MB_APPLMODAL);
hge->System_SetState(HGE_INIFILE,name);
world output;
output.bg1 = bgres->GetTexture(hge->Ini_GetString( "System", "Background 1", "clouds"));
output.bg2 = bgres->GetTexture(hge->Ini_GetString( "System", "Background 2", "smallstars"));
output.bg3 = bgres->GetTexture(hge->Ini_GetString( "System", "Background 3", "bigstars"));
output.name = hge->Ini_GetString( "System", "Name", "Missing");
output.ncel = hge->Ini_GetInt( "System", "Number of Bodies", 1);
output.celestials = new celestial[output.ncel];
output.nhiv = hge->Ini_GetInt( "System", "Number of Hives", 1);
output.hives = new hive[output.nhiv];
output.nstars = hge->Ini_GetInt( "System", "Number of Stars", 1);
output.stars = new celestial*[output.nstars];
output.nport = hge->Ini_GetInt( "System", "Number of Portals", 1);
output.portals = new celestial*[output.nport];
output.pstart.x = hge->Ini_GetFloat("System", "Origin X", 0.0);
output.pstart.y = hge->Ini_GetFloat("System", "Origin y", 0.0);
output.shift.x = hge->Ini_GetFloat( "System", "Background Shift X", 0.0);
output.shift.y = hge->Ini_GetFloat( "System", "Background Shift y", 0.0);
int stars=0; int portals=0;
char num [3];
for(int n = 1; n<=output.ncel; n++)
{
_itoa_s(n,num,3,10);
int i = n-1;
output.celestials[i].name = hge->Ini_GetString( num, "Name", "Noname");
output.celestials[i].sprite = hge->Ini_GetString( num, "Sprite", "Error.png");
output.celestials[i].orb.x = hge->Ini_GetFloat( num, "Location X", 0.0);
output.celestials[i].orb.y = hge->Ini_GetFloat( num, "Location Y", 0.0);
output.celestials[i].speed = hge->Ini_GetFloat( num, "Orbital Speed", 0);
output.celestials[i].scale = hge->Ini_GetFloat( num, "Scale", 1.0);
output.celestials[i].mass = hge->Ini_GetFloat( num, "Mass", output.celestials[i].scale);
output.celestials[i].drot = hge->Ini_GetFloat( num, "Rotation Speed", 0);
output.celestials[i].star = hge->Ini_GetInt( num, "Star", 0);
output.celestials[i].portal = hge->Ini_GetInt( num, "Portal", 0);
if(output.celestials[i].star){
output.stars[stars]=&output.celestials[i]; ++stars; }
if(output.celestials[i].portal){
output.portals[portals]=&output.celestials[i]; ++portals;
output.celestials[i].portalto= hge->Ini_GetString( num, "Portal To", "Sol.ini");}
output.celestials[i].orbits = hge->Ini_GetInt( num, "Orbits", 0);
output.celestials[i].spt = planetres->GetSprite(output.celestials[i].sprite.c_str());
output.celestials[i].spt->SetHotSpot(output.celestials[i].spt->GetWidth()/2,output.celestials[i].spt->GetHeight()/2);
}
for(int n = output.ncel+1; n<=output.ncel+output.nhiv; n++)
{
_itoa_s(n,num,3,10);
int i = n-output.ncel-1;
output.hives[i].cel.name = hge->Ini_GetString( num, "Name", "Error");
output.hives[i].cel.sprite = hge->Ini_GetString( num, "Sprite", "byroid");
output.hives[i].cel.orb.x = hge->Ini_GetFloat( num, "Location X", 0.0);
output.hives[i].cel.orb.y = hge->Ini_GetFloat( num, "Location Y", 0.0);
output.hives[i].cel.orbits = hge->Ini_GetInt( num, "Orbits", 0);
output.hives[i].cel.speed = hge->Ini_GetFloat( num, "Orbital Speed", 0);
output.hives[i].cel.scale = hge->Ini_GetFloat( num, "Scale", 1.0);
output.hives[i].cel.drot = hge->Ini_GetFloat( num, "Rotation Speed", 0);
output.hives[i].adrenaline = hge->Ini_GetFloat( num, "Offensive Feedback", 1.05f);
output.hives[i].cowardice = hge->Ini_GetFloat( num, "Defensive Feedback", 1.1f);
output.hives[i].aggressiveness = hge->Ini_GetFloat( num, "Offensive Coefficient", 1.0);
output.hives[i].shp = &ships[ hge->Ini_GetInt( num, "Ship", 1)];
output.hives[i].gun = &weapons[ hge->Ini_GetInt( num, "Weapon", 1)];
output.hives[i].eng = &engines[ hge->Ini_GetInt( num, "Engine", 1)];
output.hives[i].pwr = &pwrplants[ hge->Ini_GetInt( num, "Power", 1)];
output.hives[i].shd = &shields[ hge->Ini_GetInt( num, "Shield", 1)];
output.hives[i].number = hge->Ini_GetInt( num, "Number", 3);
output.hives[i].cel.spt = wildres->GetSprite(output.hives[i].cel.sprite.c_str());
output.hives[i].cel.spt->SetHotSpot(output.hives[i].cel.spt->GetWidth()/2,output.hives[i].cel.spt->GetHeight()/2);
}
return output;
}
struct shipeng
{
hgeVector loc;
hgeParticleSystem* par;
};
struct thing
{
hgeSprite* spt;
float x,y,
scale;
hgeVector v,f;
};
struct entity
{
char *name;
thing loc;
entity *target;
ship shp;
weapon gun;
shield shd;
pwrplant pwr;
engine eng;
shipeng *engines;
float drot;
bool cw,ccw,
thrusting,
firing;
float cooldown;
};
struct missile
{
thing loc;
entity *parent,
*target;
float damage,
mass,
range;
};
struct roamai
{ // Fight-or-flight engages when AI becomes aware of player
entity ent; //
pointf target, // (hostility*aggressiveness*anger)
range; // Attacks if -------------------------- > 1.0, flees if < 1.0
hive* parent; // (fear*(playerLvl/AILevel))
vector<float> angers, //
fears; // Anger and fear both rise as the AI is attacked
float hostility, // at rates proportional to adrenaline and cowardice;
adrenaline, // both go down constantly, and AI enemies may attack
cowardice, // differently depending on anger level
aggressiveness; //
};
struct config
{
int resolutionx,
resolutiony;
bool fullscreen,
whackyrotation;
};
world sys;
config options;
vector<entity> players;
vector<missile> missiles;
vector<roamai> roamers;
void newRoamer(hive* daddy, pointf range, float agg, float host, float adr, float cow)
{
roamai ai;
ai.parent = daddy;
ai.range = range;
ai.hostility = host;
ai.aggressiveness = agg;
ai.adrenaline = adr;
ai.cowardice = cow;
roamers.push_back(ai);
}
void newMissile(entity* parent, hgeSprite* spt, float x, float y, float mass, float damage, float range)
{
missile mis = *(new missile);
mis.damage = damage;
mis.mass = mass;
mis.range = range;
mis.parent = parent;
mis.target = parent->target;
mis.loc = parent->loc;
mis.loc.x = x;
mis.loc.y = y;
mis.loc.spt = spt;
mis.loc.scale*=.5;
missiles.push_back(mis);
}
void newEntity(int shp, int eng, int shd, int pwr, int wep, float x, float y, float scale)
{
entity ent = *(new entity);
ent.shp = LoadShip(shp);
ent.eng = LoadEngine(eng);
ent.shd = LoadShield(shd);
ent.pwr = LoadPower(pwr);
ent.gun = LoadWeapon(wep);
ent.cooldown = 0;
ent.thrusting = false;
ent.firing = false;
ent.cw = false;
ent.ccw = false;
ent.loc.v = hgeVector(0,0);
ent.loc.f = hgeVector(ent.eng.thr*40/ent.shp.mass,0);
ent.loc.scale = scale;
ent.loc.x = x;
ent.loc.y = y;
ent.engines = new shipeng[ent.shp.neng];
for(int i = 0; i<ent.shp.neng; i++){
ent.engines[i].loc = ent.shp.engines[i];
ent.engines[i].par = new hgeParticleSystem(*ent.eng.par);
ent.engines[i].par->SetScale(scale*2/sqrt((float)ent.shp.neng));
}
players.push_back(ent);
}
bool LoadEngineParticle(int i)
{
engines[i].par = new hgeParticleSystem( engines[i].parsys.c_str(),partres->GetSprite(engines[i].sprite.c_str()) );
return true;
}
#include <cstring>
#include <float.h>
#include <iostream>
#include <vector>
#include <math.h>
using namespace std;
#include "Aetheria.h"
#include "AetheriaIO.h"
#include "Client.h"
hgeSprite *bgspr1,*bgspr2,*bgspr3;
//HTEXTURE ptex;
//HTARGET target;
//hgeSprite* tar;
hgeSprite* pshd;
hgeFont *fnt;
char loading[20];
/*bool GfxRestoreFunc()
{
if(tar && target) tar->SetTexture(hge->Target_GetTexture(target));
return false;
}*/
bool FrameFunc()
{
float dt=hge->Timer_GetDelta();
if(*loading)
{
//delete sys;
sys = LoadWorld(loading);
delete bgspr1; bgspr1 = new hgeSprite(sys.bg1,0,0,800,600);
delete bgspr2; bgspr2 = new hgeSprite(sys.bg2,0,0,800,600);
delete bgspr3; bgspr3 = new hgeSprite(sys.bg3,0,0,800,600);
bgspr1->SetBlendMode(BLEND_COLORMUL | BLEND_ALPHABLEND | BLEND_NOZWRITE);
bgspr2->SetBlendMode(BLEND_COLORMUL | BLEND_ALPHABLEND | BLEND_NOZWRITE);
bgspr3->SetBlendMode(BLEND_COLORMUL | BLEND_ALPHABLEND | BLEND_NOZWRITE);
players.clear();
newEntity(8,1,1,1,1,sys.pstart.x,sys.pstart.y,0.5f);
//delete loading;
*loading = 0;
}
if(hge->Input_GetKeyState(HGEK_ESCAPE)) return true;
if(players.size() == 0) return false;
/* Process Key Input
*/
if(hge->Input_GetKeyState(HGEK_SPACE)) players[0].firing = true;
else players[0].firing = false;
if(hge->Input_GetKeyState(HGEK_UP)) players[0].thrusting = true;
else players[0].thrusting = false;
if(hge->Input_GetKeyState(HGEK_LEFT)) players[0].ccw = true;
else players[0].ccw = false;
if(hge->Input_GetKeyState(HGEK_RIGHT)) players[0].cw = true;
else players[0].cw = false;
if(hge->Input_GetKeyState(HGEK_R)){
for(int i=0; i<sys.nport; i++){
float xdist = abs(players[0].loc.x)-abs(sys.portals[i]->loc.x);
float ydist = abs(players[0].loc.y)-abs(sys.portals[i]->loc.y);
float dist = sqrt(xdist*xdist+ydist*ydist)*2;
if(dist<100) strcpy(loading,sys.portals[i]->portalto.c_str());
}
}
/* Process all registered entities, including AI ships
*/
vector<entity>::iterator ent;
for( ent=players.begin(); ent<players.end(); ent++)
{
/* Rotate the ship and associated vectors
*/
float drot = ent->eng.tur/ent->shp.mass;
if(ent->cw && !ent->ccw){
ent->loc.f.Rotate(drot*dt*100);
for(int i=0; i<ent->shp.neng; i++)
ent->engines[i].loc.Rotate(drot*dt*100);
for(int i=0; i<ent->shp.ngun; i++)
ent->shp.guns[i].Rotate(drot*dt*100);
}
if(!ent->cw && ent->ccw){
ent->loc.f.Rotate(-drot*dt*100);
for(int i=0; i<ent->shp.neng; i++)
ent->engines[i].loc.Rotate(-drot*dt*100);
for(int i=0; i<ent->shp.ngun; i++)
ent->shp.guns[i].Rotate(-drot*dt*100);
}
/* Compute engine impulse and process associated particle systems
*/
for(int i=0; i<ent->shp.neng; i++)
{
if(ent->thrusting)
{
ent->loc.v+=ent->loc.f*dt*100;
ent->engines[i].par->Fire();
ent->loc.v.Clamp(ent->shp.speed);
}
else ent->engines[i].par->Stop();
ent->engines[i].par->Update(dt);
ent->engines[i].par->Transpose(ent->loc.x - players[0].loc.x + options.resolutionx/2,
ent->loc.y - players[0].loc.y + options.resolutiony/2);
ent->engines[i].par->MoveTo(ent->engines[i].loc.x, ent->engines[i].loc.y,true);
ent->engines[i].par->info.fDirection=ent->loc.f.Angle()+M_PI;
}
/* Universal gravitation is processed for every celestial in-system
*/
int j = 0;
for( ; j < sys.ncel; j++ )
{
float dist = hgeVector(ent->loc.x-sys.celestials[j].loc.x,ent->loc.y-sys.celestials[j].loc.y).Length();
dist+=sys.celestials[j].scale*200; // This cuts off the horrendous asymptote in the G formula at the body's outer bound
ent->loc.v+=hgeVector( sys.celestials[j].loc.x - ent->loc.x,
sys.celestials[j].loc.y - ent->loc.y)*(10*sys.celestials[j].mass/(dist*dist));
}
/* Process weapon systems; spawning missiles, particles or beams
*/
ent->cooldown -= dt;
if((ent->cooldown <= 0) && ent->firing)
{
ent->cooldown = ent->gun.cooldown;
for(int i=0; i<ent->shp.ngun; i++)
{
float xloc = ent->loc.x+ent->shp.guns[i].x*ent->loc.scale;
float yloc = ent->loc.y+ent->shp.guns[i].y*ent->loc.scale;
newMissile(&*ent,ent->gun.spt,xloc,yloc,ent->gun.mass,ent->gun.dmg,ent->gun.range);
}
}
/* Finally, move the entity
*/
ent->loc.x += ent->loc.v.x*dt;
ent->loc.y += ent->loc.v.y*dt;
}
vector<missile>::iterator kill; bool dead=0;
vector<missile>::iterator mis;
for( mis=missiles.begin(); mis<missiles.end(); mis++)
{
mis->loc.x += mis->loc.v.x*dt;
mis->loc.y += mis->loc.v.y*dt;
mis->range -= mis->loc.v.Length()*dt;
if(mis->range <= 0){ kill=mis; dead=1;}
}
if(dead) missiles.erase(kill);
/* Process all celestials in registered world structure
*/
for( int i = 0; i < sys.ncel; i++ )
{
celestial* cel = &sys.celestials[i];
cel->angle+=cel->drot*dt;
cel->orb.Rotate(cel->speed*dt);
if(cel->orbits){
cel->loc.x=cel->orb.x+sys.celestials[cel->orbits-1].loc.x;
cel->loc.y=cel->orb.y+sys.celestials[cel->orbits-1].loc.y;
}else{
cel->loc.x=cel->orb.x;
cel->loc.y=cel->orb.y;
}
}
/* Do the same for all hives, spawning new AI if necessary.
*/
for( int i = 0; i < sys.nhiv; i++ )
{
hive* hiv = &sys.hives[i];
hiv->cel.orb.Rotate(hiv->cel.speed*dt);
hiv->cel.loc.x=hiv->cel.orb.x+sys.celestials[hiv->cel.orbits-1].loc.x;
hiv->cel.loc.y=hiv->cel.orb.y+sys.celestials[hiv->cel.orbits-1].loc.y;
//MessageBox(NULL, "Updating Hive", hiv->cel.name, MB_OK | MB_ICONERROR | MB_APPLMODAL);
}
return false;
}
bool RenderFunc()
{
// Render the scene
hge->Gfx_BeginScene();
bgspr1->SetTextureRect( players[0].loc.x*.1f + sys.shift.x - options.resolutionx/2,
players[0].loc.y*.1f + sys.shift.y - options.resolutiony/2,options.resolutionx,options.resolutiony);
bgspr1->Render(0,0);
bgspr2->SetTextureRect(players[0].loc.x*.3f,players[0].loc.y*.5f,options.resolutionx,options.resolutiony);
bgspr2->Render(0,0);
bgspr3->SetTextureRect(players[0].loc.x*.6f,players[0].loc.y*.8f,options.resolutionx,options.resolutiony);
bgspr3->Render(0,0);
for( int i = 0; i < sys.ncel; i++ )
{
celestial cel=sys.celestials[i];
cel.spt->RenderEx(cel.loc.x-players[0].loc.x+options.resolutionx/2,
cel.loc.y-players[0].loc.y+options.resolutiony/2,
cel.angle,cel.scale);
hgeVector(sys.celestials[1].loc.x-cel.loc.x,sys.celestials[1].loc.y-cel.loc.y).Angle();
if(!cel.star)
pshd->RenderEx(cel.loc.x-players[0].loc.x+options.resolutionx/2,
cel.loc.y-players[0].loc.y+options.resolutiony/2,
hgeVector(-(sys.celestials[1].loc.x-cel.loc.x),-(sys.celestials[1].loc.y-cel.loc.y)).Angle(),cel.scale);
}
for( int i = 0; i < sys.nhiv; i++ )
{
hive hiv=sys.hives[i];
hiv.cel.spt->RenderEx(hiv.cel.loc.x-players[0].loc.x+options.resolutionx/2,
hiv.cel.loc.y-players[0].loc.y+options.resolutiony/2,
hiv.cel.angle,hiv.cel.scale);
}
vector<entity>::iterator ent;
for( ent=players.begin(); ent<players.end(); ent++)
{
for(int i = 0; i < ent->shp.neng; i++){
//ent->par->Transpose(ent->engines[i].x+ent->loc.x-players[0].loc.x+options.resolutionx/2,
// ent->engines[i].y+ent->loc.y-players[0].loc.y+options.resolutiony/2);
ent->engines[i].par->Render();
}
ent->shp.spt->RenderEx(ent->loc.x-players[0].loc.x+options.resolutionx/2,
ent->loc.y-players[0].loc.y+options.resolutiony/2,
ent->loc.f.Angle(), ent->loc.scale);
}
vector<missile>::iterator mis;
for( mis=missiles.begin(); mis<missiles.end(); mis++)
{
mis->loc.spt->RenderEx(mis->loc.x-players[0].loc.x+options.resolutionx/2,
mis->loc.y-players[0].loc.y+options.resolutiony/2,
mis->loc.v.Angle(), mis->loc.scale);
}
float dist = hgeVector(players[0].loc.x-sys.celestials[0].loc.x,players[0].loc.y-sys.celestials[0].loc.y).Length();
fnt->printf(7,100,HGETEXT_LEFT, "Portal Location = %.1f,%.1f\nDistance From Portal = %.1f",sys.celestials[0].loc.x,sys.celestials[0].loc.y,dist);
fnt->printf(7, 7, HGETEXT_LEFT, "Current Position: %.1f,%.1f\nCurrent Direction: %.1f\nCurrent Speed: %.1f\nFPS: %d", players[0].loc.x, players[0].loc.y, players[0].loc.f.Angle()*180/M_PI, players[0].loc.v.Length(), hge->Timer_GetFPS());
hge->Gfx_EndScene();
return false;
}
int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
{
//_control87(_MCW_RC, _RC_CHOP);
hge = hgeCreate(HGE_VERSION);
// Set desired system states and initialize HGE
hge->Resource_AttachPack("Aetheria.pak");
hge->System_SetState(HGE_INIFILE, "options.ini");
options.resolutionx = hge->Ini_GetInt("System","Resolution X",640);
options.resolutiony = hge->Ini_GetInt("System","Resolution Y",480);
options.fullscreen = hge->Ini_GetInt("System","Fullscreen",0);
hge->System_SetState(HGE_LOGFILE, "Aetheria.log");
hge->System_SetState(HGE_FRAMEFUNC, FrameFunc);
hge->System_SetState(HGE_RENDERFUNC, RenderFunc);
hge->System_SetState(HGE_FPS, HGEFPS_UNLIMITED );
hge->System_SetState(HGE_TITLE, "Aetheria");
hge->System_SetState(HGE_USESOUND, false);
hge->System_SetState(HGE_WINDOWED, !((bool)options.fullscreen));
hge->System_SetState(HGE_SCREENWIDTH, options.resolutionx);
hge->System_SetState(HGE_SCREENHEIGHT, options.resolutiony);
hge->System_SetState(HGE_SCREENBPP, 32);
//hge->System_SetState(HGE_SHOWSPLASH,false);
if(hge->System_Initiate())
{
//shipres = new hgeResourceManager("ships.res");
wildres = new hgeResourceManager("wildships.res");
shieldres = new hgeResourceManager("shields.res");
wepres = new hgeResourceManager("weapons.res");
partres = new hgeResourceManager("particles.res");
planetres = new hgeResourceManager("planets.res");
planetres->Precache();
bgres = new hgeResourceManager("backgrounds.res");
pshd = planetres->GetSprite("shader.png");
pshd->SetHotSpot(200,200);
ships = new ship[64];
weapons = new weapon[64];
shields = new shield[64];
pwrplants = new pwrplant[64];
engines = new engine[64];
for(int i = 0;i<64;i++)
{
ships[i].type=0;
weapons[i].type=0;
shields[i].type=0;
pwrplants[i].type=0;
engines[i].type=0;
}
strcpy(loading,"Sol.ini");
fnt=new hgeFont("font2.fnt");
//ptex=hge->Texture_Load("particles.png");
//missiles.resize(12);
hge->System_Start();
// Delete created objects and free loaded resources
wildres->Purge();
shieldres->Purge();
wepres->Purge();
partres->Purge();
planetres->Purge();
bgres->Purge();
delete [] engines;
delete [] pwrplants;
delete [] shields;
delete [] weapons;
delete [] ships;
}
// Clean up and shutdown
hge->System_Shutdown();
hge->Release();
return 0;
}