[Change] All tabs back to spaces.
This commit is contained in:
parent
b286205f56
commit
4ea444b9ae
288
src/ai.c
288
src/ai.c
@ -48,14 +48,14 @@
|
||||
// FUCK LUA!!!
|
||||
#define luaL_register(L,n,l) (luaL_openlib(L, (n),(l), 0))
|
||||
// Creates a new lua table.
|
||||
#define newtable(L) (lua_newtable(L), lua_gettop(L))
|
||||
#define newtable(L) (lua_newtable(L), lua_gettop(L))
|
||||
// Register a number constant n to name s (syntax is just like lua_regfunc).
|
||||
#define lua_regnumber(l,s,n) (lua_pushnumber(l,n), lua_setglobal(l,s))
|
||||
// Registers a C function.
|
||||
#define lua_regfunc(l,s,f) (lua_pushcfunction(l,f), lua_setglobal(L,s))
|
||||
// L state, void* buf, int n size, char* s identifier.
|
||||
#define luaL_dobuffer(L,b,n,s) \
|
||||
(luaL_loadbuffer(L,b,n,s) || lua_pcall(L, 0, LUA_MULTRET, 0))
|
||||
(luaL_loadbuffer(L,b,n,s) || lua_pcall(L, 0, LUA_MULTRET, 0))
|
||||
|
||||
// Don't run the function if (n) params aren't passed.
|
||||
#define MIN_ARGS(n) if(lua_gettop(L) < n) return 0
|
||||
@ -94,13 +94,13 @@ void ai_create(Pilot* pilot);
|
||||
|
||||
// Ai routines for Lua.
|
||||
// Tasks.
|
||||
static int ai_pushtask(lua_State* L); // pushtask(string, number/pointer, number)
|
||||
static int ai_pushtask(lua_State* L); // pushtask(string, number/pointer, number)
|
||||
static int ai_poptask(lua_State* L); // poptask()
|
||||
static int ai_taskname(lua_State* L); // Number taskname.
|
||||
// Consult values.
|
||||
static int ai_gettarget(lua_State* L); // Pointer gettarget()
|
||||
static int ai_gettargetid(lua_State* L); // Number gettargetis()
|
||||
static int ai_getrndpilot(lua_State* L); // Number getrndpilot()
|
||||
static int ai_getrndpilot(lua_State* L); // Number getrndpilot()
|
||||
static int ai_armour(lua_State* L); // armour()
|
||||
static int ai_shield(lua_State* L); // shield()
|
||||
static int ai_parmour(lua_State* L); // parmour()
|
||||
@ -108,7 +108,7 @@ static int ai_pshield(lua_State* L); // pshield()
|
||||
static int ai_getdistance(lua_State* L); // Number getdist(Vec2)
|
||||
static int ai_getpos(lua_State* L); // getpos(number)
|
||||
static int ai_minbrakedist(lua_State* L); // Number minbrakedist()
|
||||
static int ai_cargofree(lua_State* L); // Number cargofree().
|
||||
static int ai_cargofree(lua_State* L); // Number cargofree().
|
||||
// Boolean expressions.
|
||||
static int ai_exists(lua_State* L); // boolean exists
|
||||
static int ai_ismaxvel(lua_State* L); // Boolean ismaxvel()
|
||||
@ -124,12 +124,12 @@ static int ai_brake(lua_State* L); // Brake()
|
||||
static int ai_getnearestplanet(lua_State* L); // pointer getnearestplanet()
|
||||
static int ai_getrndplanet(lua_State* L); // pointer getrndplanet()
|
||||
static int ai_hyperspace(lua_State* L); // [number] hyperspace()
|
||||
static int ai_stop(lua_State* L); // stop()
|
||||
static int ai_stop(lua_State* L); // stop()
|
||||
// Combat.
|
||||
static int ai_combat(lua_State* L); // combat(number)
|
||||
static int ai_settarget(lua_State* L); // settarget(number)
|
||||
static int ai_secondary(lua_State* L); // string secondary()
|
||||
static int ai_hasturrets(lua_State* L); // bool hasturrets()
|
||||
static int ai_hasturrets(lua_State* L); // bool hasturrets()
|
||||
static int ai_shoot(lua_State* L); // shoot(number) number = 1,2,3.
|
||||
static int ai_getenemy(lua_State* L); // number getenemy().
|
||||
static int ai_hostile(lua_State* L); // hostile(number).
|
||||
@ -140,66 +140,66 @@ static int ai_timeup(lua_State* L); // boolean timeup(number)
|
||||
static int ai_comm(lua_State* L); // comm(string)
|
||||
static int ai_broadcast(lua_State* L); // broadcast(string)
|
||||
// Loot.
|
||||
static int ai_credits(lua_State* L); // credits(number).
|
||||
static int ai_cargo(lua_State* L); // cargo(name, quantity).
|
||||
static int ai_shipprice(lua_State* L); // shipprice().
|
||||
static int ai_credits(lua_State* L); // credits(number).
|
||||
static int ai_cargo(lua_State* L); // cargo(name, quantity).
|
||||
static int ai_shipprice(lua_State* L); // shipprice().
|
||||
// Random.
|
||||
static int ai_rng(lua_State* L); // rng(number, number)
|
||||
|
||||
static const luaL_Reg ai_methods[] = {
|
||||
// Tasks.
|
||||
{ "pushtask", ai_pushtask },
|
||||
{ "poptask", ai_poptask },
|
||||
{ "taskname", ai_taskname },
|
||||
// Sanity checks.
|
||||
{ "exists", ai_exists },
|
||||
{ "ismaxvel", ai_ismaxvel },
|
||||
{ "isstopped", ai_isstopped },
|
||||
{ "isenemy", ai_isenemy },
|
||||
{ "isally", ai_isally },
|
||||
// Get's.
|
||||
{ "incombat", ai_incombat },
|
||||
{ "target", ai_gettarget },
|
||||
{ "targetid", ai_gettargetid },
|
||||
{ "rndpilot", ai_getrndpilot },
|
||||
{ "armour", ai_armour },
|
||||
{ "shield", ai_shield },
|
||||
{ "parmour", ai_parmour },
|
||||
{ "pshield", ai_pshield },
|
||||
{ "dist", ai_getdistance },
|
||||
{ "pos", ai_getpos },
|
||||
{ "minbrakedist", ai_minbrakedist },
|
||||
{ "cargofree", ai_cargofree },
|
||||
{ "nearestplanet", ai_getnearestplanet },
|
||||
{ "rndplanet", ai_getrndplanet },
|
||||
// Movement.
|
||||
{ "accel", ai_accel },
|
||||
{ "turn", ai_turn },
|
||||
{ "face", ai_face },
|
||||
{ "brake", ai_brake },
|
||||
{ "stop", ai_stop },
|
||||
{ "hyperspace", ai_hyperspace },
|
||||
// Combat.
|
||||
{ "combat", ai_combat },
|
||||
{ "settarget", ai_settarget },
|
||||
{ "secondary", ai_secondary },
|
||||
{ "hasturrets", ai_hasturrets },
|
||||
{ "shoot", ai_shoot },
|
||||
{ "getenemy", ai_getenemy },
|
||||
{ "hostile", ai_hostile },
|
||||
// Timers.
|
||||
{ "settime", ai_settimer },
|
||||
{ "timeup", ai_timeup },
|
||||
// Messages.
|
||||
{ "comm", ai_comm },
|
||||
{ "broadcast", ai_broadcast },
|
||||
// Loot.
|
||||
{ "setcredits", ai_credits },
|
||||
{ "setcargo", ai_cargo },
|
||||
{ "shipprice", ai_shipprice },
|
||||
// Random.
|
||||
{ "rnd", ai_rng },
|
||||
{ 0, 0 } // End.
|
||||
// Tasks.
|
||||
{ "pushtask", ai_pushtask },
|
||||
{ "poptask", ai_poptask },
|
||||
{ "taskname", ai_taskname },
|
||||
// Sanity checks.
|
||||
{ "exists", ai_exists },
|
||||
{ "ismaxvel", ai_ismaxvel },
|
||||
{ "isstopped", ai_isstopped },
|
||||
{ "isenemy", ai_isenemy },
|
||||
{ "isally", ai_isally },
|
||||
// Get's.
|
||||
{ "incombat", ai_incombat },
|
||||
{ "target", ai_gettarget },
|
||||
{ "targetid", ai_gettargetid },
|
||||
{ "rndpilot", ai_getrndpilot },
|
||||
{ "armour", ai_armour },
|
||||
{ "shield", ai_shield },
|
||||
{ "parmour", ai_parmour },
|
||||
{ "pshield", ai_pshield },
|
||||
{ "dist", ai_getdistance },
|
||||
{ "pos", ai_getpos },
|
||||
{ "minbrakedist", ai_minbrakedist },
|
||||
{ "cargofree", ai_cargofree },
|
||||
{ "nearestplanet", ai_getnearestplanet },
|
||||
{ "rndplanet", ai_getrndplanet },
|
||||
// Movement.
|
||||
{ "accel", ai_accel },
|
||||
{ "turn", ai_turn },
|
||||
{ "face", ai_face },
|
||||
{ "brake", ai_brake },
|
||||
{ "stop", ai_stop },
|
||||
{ "hyperspace", ai_hyperspace },
|
||||
// Combat.
|
||||
{ "combat", ai_combat },
|
||||
{ "settarget", ai_settarget },
|
||||
{ "secondary", ai_secondary },
|
||||
{ "hasturrets", ai_hasturrets },
|
||||
{ "shoot", ai_shoot },
|
||||
{ "getenemy", ai_getenemy },
|
||||
{ "hostile", ai_hostile },
|
||||
// Timers.
|
||||
{ "settime", ai_settimer },
|
||||
{ "timeup", ai_timeup },
|
||||
// Messages.
|
||||
{ "comm", ai_comm },
|
||||
{ "broadcast", ai_broadcast },
|
||||
// Loot.
|
||||
{ "setcredits", ai_credits },
|
||||
{ "setcargo", ai_cargo },
|
||||
{ "shipprice", ai_shipprice },
|
||||
// Random.
|
||||
{ "rnd", ai_rng },
|
||||
{ 0, 0 } // End.
|
||||
};
|
||||
|
||||
// Current pilot "thinking" and assorted variables.
|
||||
@ -210,17 +210,17 @@ static int pilot_flags = 0;
|
||||
static int pilot_target = 0;
|
||||
|
||||
// Ai status: 'Create' functions that can't be used elsewhere.
|
||||
#define AI_STATUS_NORMAL 1
|
||||
#define AI_STATUS_CREATE 2
|
||||
#define AI_STATUS_NORMAL 1
|
||||
#define AI_STATUS_CREATE 2
|
||||
static int ai_status = AI_STATUS_NORMAL;
|
||||
|
||||
// Attempt to run a function.
|
||||
static void ai_run(const char* funcname) {
|
||||
lua_getglobal(L, funcname);
|
||||
if(lua_pcall(L, 0, 0, 0))
|
||||
// Errors accured.
|
||||
WARN("Pilot '%s' ai -> '%s' : %s",
|
||||
cur_pilot->name, funcname, lua_tostring(L,-1));
|
||||
lua_getglobal(L, funcname);
|
||||
if(lua_pcall(L, 0, 0, 0))
|
||||
// Errors accured.
|
||||
WARN("Pilot '%s' ai -> '%s' : %s",
|
||||
cur_pilot->name, funcname, lua_tostring(L,-1));
|
||||
}
|
||||
|
||||
// Destroy the AI part of the pilot.
|
||||
@ -263,12 +263,12 @@ static int ai_loadProfile(char* filename) {
|
||||
profiles = realloc(profiles, sizeof(AI_Profile)*(++nprofiles));
|
||||
|
||||
profiles[nprofiles-1].name =
|
||||
malloc(sizeof(char)*
|
||||
(strlen(filename)-strlen(AI_PREFIX)-strlen(AI_SUFFIX))+1);
|
||||
malloc(sizeof(char)*
|
||||
(strlen(filename)-strlen(AI_PREFIX)-strlen(AI_SUFFIX))+1);
|
||||
|
||||
snprintf(profiles[nprofiles-1].name,
|
||||
strlen(filename)-strlen(AI_PREFIX)-strlen(AI_SUFFIX)+1,
|
||||
"%s", filename+strlen(AI_PREFIX));
|
||||
snprintf(profiles[nprofiles-1].name,
|
||||
strlen(filename)-strlen(AI_PREFIX)-strlen(AI_SUFFIX)+1,
|
||||
"%s", filename+strlen(AI_PREFIX));
|
||||
|
||||
profiles[nprofiles-1].L = luaL_newstate();
|
||||
|
||||
@ -286,7 +286,7 @@ static int ai_loadProfile(char* filename) {
|
||||
lua_regnumber(L, "player", PLAYER_ID); // Player id.
|
||||
|
||||
// Register C funstions in Lua.
|
||||
luaL_register(L, "ai", ai_methods);
|
||||
luaL_register(L, "ai", ai_methods);
|
||||
|
||||
// Now load the file, since all the functions have been previously loaded.
|
||||
buf = pack_readfile(DATA, filename, &bufsize);
|
||||
@ -354,7 +354,7 @@ void ai_think(Pilot* pilot) {
|
||||
if(pilot_turn) // Set the turning velocity.
|
||||
cur_pilot->solid->dir_vel -= cur_pilot->turn * pilot_turn;
|
||||
vect_pset(&cur_pilot->solid->force, cur_pilot->thrust * pilot_acc,
|
||||
cur_pilot->solid->dir);
|
||||
cur_pilot->solid->dir);
|
||||
|
||||
// Fire weapons if needs be.
|
||||
if(ai_isFlag(AI_PRIMARY)) pilot_shoot(pilot, pilot_target, 0); // Primary.
|
||||
@ -372,11 +372,11 @@ void ai_attacked(Pilot* attacked, const unsigned int attacker) {
|
||||
|
||||
// Pilot was just created.
|
||||
void ai_create(Pilot* pilot) {
|
||||
cur_pilot = pilot;
|
||||
L = cur_pilot->ai->L;
|
||||
ai_status = AI_STATUS_CREATE;
|
||||
ai_run("create");
|
||||
ai_status = AI_STATUS_NORMAL;
|
||||
cur_pilot = pilot;
|
||||
L = cur_pilot->ai->L;
|
||||
ai_status = AI_STATUS_CREATE;
|
||||
ai_run("create");
|
||||
ai_status = AI_STATUS_NORMAL;
|
||||
}
|
||||
|
||||
// =====================
|
||||
@ -416,11 +416,11 @@ static int ai_pushtask(lua_State* L) {
|
||||
// Only pointer valid is Vec2* in Lua.
|
||||
t->dtype = TYPE_PTR;
|
||||
t->dat.target = MALLOC_L(Vec2);
|
||||
// No idea why vectcpy doesn't work here..
|
||||
((Vec2*)t->dat.target)->x = ((Vec2*)lua_topointer(L,3))->x;
|
||||
((Vec2*)t->dat.target)->y = ((Vec2*)lua_topointer(L,3))->y;
|
||||
((Vec2*)t->dat.target)->mod = ((Vec2*)lua_topointer(L,3))->mod;
|
||||
((Vec2*)t->dat.target)->angle = ((Vec2*)lua_topointer(L,3))->angle;
|
||||
// No idea why vectcpy doesn't work here..
|
||||
((Vec2*)t->dat.target)->x = ((Vec2*)lua_topointer(L,3))->x;
|
||||
((Vec2*)t->dat.target)->y = ((Vec2*)lua_topointer(L,3))->y;
|
||||
((Vec2*)t->dat.target)->mod = ((Vec2*)lua_topointer(L,3))->mod;
|
||||
((Vec2*)t->dat.target)->angle = ((Vec2*)lua_topointer(L,3))->angle;
|
||||
} else
|
||||
t->dtype = TYPE_NULL;
|
||||
}
|
||||
@ -476,8 +476,8 @@ static int ai_gettargetid(lua_State* L) {
|
||||
}
|
||||
|
||||
static int ai_getrndpilot(lua_State* L) {
|
||||
lua_pushnumber(L, pilot_stack[RNG(0, pilots-1)]->id);
|
||||
return 1;
|
||||
lua_pushnumber(L, pilot_stack[RNG(0, pilots-1)]->id);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Get the pilots armour.
|
||||
@ -568,10 +568,10 @@ static int ai_getpos(lua_State* L) {
|
||||
// ========================================================
|
||||
static int ai_minbrakedist(lua_State* L) {
|
||||
double time, dist;
|
||||
time = VMOD(cur_pilot->solid->vel) /
|
||||
time = VMOD(cur_pilot->solid->vel) /
|
||||
(cur_pilot->thrust / cur_pilot->solid->mass);
|
||||
|
||||
dist = VMOD(cur_pilot->solid->vel)*0.9*(time+180./cur_pilot->turn) -
|
||||
dist = VMOD(cur_pilot->solid->vel)*0.9*(time+180./cur_pilot->turn) -
|
||||
0.5 * (cur_pilot->thrust / cur_pilot->solid->mass)*time*time;
|
||||
|
||||
lua_pushnumber(L, dist); // return
|
||||
@ -579,8 +579,8 @@ static int ai_minbrakedist(lua_State* L) {
|
||||
}
|
||||
|
||||
static int ai_cargofree(lua_State* L) {
|
||||
lua_pushnumber(L, cur_pilot->cargo_free);
|
||||
return 1;
|
||||
lua_pushnumber(L, cur_pilot->cargo_free);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ai_exists(lua_State* L) {
|
||||
@ -609,14 +609,14 @@ static int ai_isstopped(lua_State* L) {
|
||||
static int ai_isenemy(lua_State* L) {
|
||||
if(lua_isnumber(L,1))
|
||||
lua_pushboolean(L, areEnemies(cur_pilot->faction,
|
||||
pilot_get(lua_tonumber(L,1))->faction));
|
||||
pilot_get(lua_tonumber(L,1))->faction));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Check if the pilot is an ally.
|
||||
static int ai_isally(lua_State* L) {
|
||||
lua_pushboolean(L, areAllies(cur_pilot->faction,
|
||||
pilot_get(lua_tonumber(L,1))->faction));
|
||||
pilot_get(lua_tonumber(L,1))->faction));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -634,7 +634,7 @@ static int ai_incombat(lua_State* L) {
|
||||
// Accelerate the pilot based on a param.
|
||||
static int ai_accel(lua_State* L) {
|
||||
pilot_acc = (lua_gettop(L) > 1 && lua_isnumber(L, 1)) ?
|
||||
ABS((double)lua_tonumber(L, 1)) : 1.;
|
||||
ABS((double)lua_tonumber(L, 1)) : 1.;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -651,37 +651,37 @@ static int ai_face(lua_State* L) {
|
||||
Vec2* v, sv, tv; // Grab the position to face.
|
||||
Pilot* p;
|
||||
double mod, diff;
|
||||
int invert = 0;
|
||||
int n = -2;
|
||||
int invert = 0;
|
||||
int n = -2;
|
||||
|
||||
if(lua_isnumber(L, 1))
|
||||
n = (int)lua_tonumber(L, 1);
|
||||
if(lua_isnumber(L, 1))
|
||||
n = (int)lua_tonumber(L, 1);
|
||||
|
||||
if(n >= 0) {
|
||||
p = pilot_get(n);
|
||||
if(p == NULL) return 0; // Make sure pilot is valid.
|
||||
vect_cset(&tv, VX(p->solid->pos) + FACE_WVEL*VX(p->solid->vel),
|
||||
VY(p->solid->pos) + FACE_WVEL*VY(p->solid->vel));
|
||||
v = NULL;
|
||||
if(n >= 0) {
|
||||
p = pilot_get(n);
|
||||
if(p == NULL) return 0; // Make sure pilot is valid.
|
||||
vect_cset(&tv, VX(p->solid->pos) + FACE_WVEL*VX(p->solid->vel),
|
||||
VY(p->solid->pos) + FACE_WVEL*VY(p->solid->vel));
|
||||
v = NULL;
|
||||
}
|
||||
else if(lua_islightuserdata(L,1)) v = (Vec2*)lua_topointer(L,1);
|
||||
|
||||
mod = -10;
|
||||
if(lua_gettop(L) > 1 && lua_isnumber(L,2)) invert = (int)lua_tonumber(L,2);
|
||||
if(invert) mod *= -1;
|
||||
vect_cset(&sv, VX(cur_pilot->solid->pos) + FACE_WVEL*VX(cur_pilot->solid->vel),
|
||||
VY(cur_pilot->solid->pos) + FACE_WVEL*VY(cur_pilot->solid->vel));
|
||||
if(invert) mod *= -1;
|
||||
vect_cset(&sv, VX(cur_pilot->solid->pos) + FACE_WVEL*VX(cur_pilot->solid->vel),
|
||||
VY(cur_pilot->solid->pos) + FACE_WVEL*VY(cur_pilot->solid->vel));
|
||||
|
||||
if(v != NULL)
|
||||
// Target is static.
|
||||
diff = angle_diff(cur_pilot->solid->dir,
|
||||
(n==-1) ? VANGLE(cur_pilot->solid->pos) :
|
||||
vect_angle(&cur_pilot->solid->pos, v));
|
||||
else
|
||||
// Target is dynamic.
|
||||
diff = angle_diff(cur_pilot->solid->dir,
|
||||
(n==-1) ? VANGLE(sv) :
|
||||
vect_angle(&sv, &tv));
|
||||
if(v != NULL)
|
||||
// Target is static.
|
||||
diff = angle_diff(cur_pilot->solid->dir,
|
||||
(n==-1) ? VANGLE(cur_pilot->solid->pos) :
|
||||
vect_angle(&cur_pilot->solid->pos, v));
|
||||
else
|
||||
// Target is dynamic.
|
||||
diff = angle_diff(cur_pilot->solid->dir,
|
||||
(n==-1) ? VANGLE(sv) :
|
||||
vect_angle(&sv, &tv));
|
||||
|
||||
pilot_turn = mod*diff;
|
||||
|
||||
@ -737,12 +737,12 @@ static int ai_getrndplanet(lua_State* L) {
|
||||
|
||||
Planet** planets;
|
||||
int nplanets, i;
|
||||
Vec2 v;
|
||||
Vec2 v;
|
||||
planets = malloc(sizeof(Planet*) * cur_system->nplanets);
|
||||
|
||||
for(nplanets = 0, i = 0; i < cur_system->nplanets; i++)
|
||||
if(planet_hasService(&cur_system->planets[i], PLANET_SERVICE_BASIC) &&
|
||||
!areEnemies(cur_pilot->faction, cur_system->planets[i].faction))
|
||||
!areEnemies(cur_pilot->faction, cur_system->planets[i].faction))
|
||||
planets[nplanets++] = &cur_system->planets[i];
|
||||
|
||||
// No planet to land on found.
|
||||
@ -753,9 +753,9 @@ static int ai_getrndplanet(lua_State* L) {
|
||||
|
||||
// We can actually get a random planet now.
|
||||
i = RNG(0,nplanets-1);
|
||||
vectcpy(&v, &planets[i]->pos);
|
||||
vect_cadd(&v, RNG(0, planets[i]->gfx_space->sw)-planets[i]->gfx_space->sw/2.,
|
||||
RNG(0, planets[i]->gfx_space->sh)-planets[i]->gfx_space->sh/2.);
|
||||
vectcpy(&v, &planets[i]->pos);
|
||||
vect_cadd(&v, RNG(0, planets[i]->gfx_space->sw)-planets[i]->gfx_space->sw/2.,
|
||||
RNG(0, planets[i]->gfx_space->sh)-planets[i]->gfx_space->sh/2.);
|
||||
lua_pushlightuserdata(L, &v);
|
||||
free(planets);
|
||||
return 1;
|
||||
@ -774,12 +774,12 @@ static int ai_hyperspace(lua_State* L) {
|
||||
|
||||
// Completely stop the pilot if it is below minimum vel error. (No instant stops.)
|
||||
static int ai_stop(lua_State* L) {
|
||||
(void)L; // Just avoid a gcc warning.
|
||||
(void)L; // Just avoid a gcc warning.
|
||||
|
||||
if(VMOD(cur_pilot->solid->vel) < MIN_VEL_ERR)
|
||||
vect_pset(&cur_pilot->solid->vel, 0., 0.);
|
||||
if(VMOD(cur_pilot->solid->vel) < MIN_VEL_ERR)
|
||||
vect_pset(&cur_pilot->solid->vel, 0., 0.);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Toggle combat flag. Default is on.
|
||||
@ -831,8 +831,8 @@ static int ai_secondary(lua_State* L) {
|
||||
}
|
||||
|
||||
static int ai_hasturrets(lua_State* L) {
|
||||
lua_pushboolean(L, pilot_isFlag(cur_pilot, PILOT_HASTURRET));
|
||||
return 1;
|
||||
lua_pushboolean(L, pilot_isFlag(cur_pilot, PILOT_HASTURRET));
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Pew pew.. Says the pilot.
|
||||
@ -871,7 +871,7 @@ static int ai_settimer(lua_State* L) {
|
||||
if(lua_isnumber(L, 1)) n = lua_tonumber(L,1);
|
||||
|
||||
cur_pilot->timer[n] = (lua_isnumber(L,2)) ?
|
||||
lua_tonumber(L,2) + SDL_GetTicks() : 0;
|
||||
lua_tonumber(L,2) + SDL_GetTicks() : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -908,31 +908,31 @@ static int ai_broadcast(lua_State* L) {
|
||||
|
||||
// Set the pilots credits.
|
||||
static int ai_credits(lua_State* L) {
|
||||
MIN_ARGS(1);
|
||||
if(ai_status != AI_STATUS_CREATE) return 0;
|
||||
MIN_ARGS(1);
|
||||
if(ai_status != AI_STATUS_CREATE) return 0;
|
||||
|
||||
if(lua_isnumber(L,1))
|
||||
cur_pilot->credits = (int)lua_tonumber(L,1);
|
||||
if(lua_isnumber(L,1))
|
||||
cur_pilot->credits = (int)lua_tonumber(L,1);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Set the pilots cargo.
|
||||
static int ai_cargo(lua_State* L) {
|
||||
MIN_ARGS(2);
|
||||
if(ai_status != AI_STATUS_CREATE) return 0;
|
||||
MIN_ARGS(2);
|
||||
if(ai_status != AI_STATUS_CREATE) return 0;
|
||||
|
||||
if(lua_isstring(L,1) && lua_isnumber(L,2))
|
||||
pilot_addCargo(cur_pilot, commodity_get(lua_tostring(L,1)),
|
||||
(int)lua_tonumber(L,2));
|
||||
if(lua_isstring(L,1) && lua_isnumber(L,2))
|
||||
pilot_addCargo(cur_pilot, commodity_get(lua_tostring(L,1)),
|
||||
(int)lua_tonumber(L,2));
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Get the pilot's ship value.
|
||||
static int ai_shipprice(lua_State* L) {
|
||||
lua_pushnumber(L, cur_pilot->ship->price);
|
||||
return 1;
|
||||
lua_pushnumber(L, cur_pilot->ship->price);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Return a number between low and high.
|
||||
|
2
src/ai.h
2
src/ai.h
@ -5,7 +5,7 @@
|
||||
#define MAX_DIR_ERR 0.1*M_PI/180.
|
||||
#define MIN_VEL_ERR 1.0
|
||||
|
||||
#define FACE_WVEL 0.1 // Weight of velocity compared to position to face.
|
||||
#define FACE_WVEL 0.1 // Weight of velocity compared to position to face.
|
||||
|
||||
// Max number of AI timers.
|
||||
#define MAX_AI_TIMERS 2
|
||||
|
234
src/board.c
234
src/board.c
@ -8,8 +8,8 @@
|
||||
#include "economy.h"
|
||||
#include "board.h"
|
||||
|
||||
#define BOARDING_WIDTH 300
|
||||
#define BOARDING_HEIGHT 200
|
||||
#define BOARDING_WIDTH 300
|
||||
#define BOARDING_HEIGHT 200
|
||||
|
||||
extern unsigned int player_target;
|
||||
|
||||
@ -23,166 +23,166 @@ static void board_update(void);
|
||||
|
||||
// Attempt to board the players target.
|
||||
void player_board(void) {
|
||||
Pilot* p;
|
||||
Pilot* p;
|
||||
|
||||
if(player_target == PLAYER_ID) {
|
||||
player_message("You need a target to board first!");
|
||||
return;
|
||||
}
|
||||
if(player_target == PLAYER_ID) {
|
||||
player_message("You need a target to board first!");
|
||||
return;
|
||||
}
|
||||
|
||||
p = pilot_get(player_target);
|
||||
p = pilot_get(player_target);
|
||||
|
||||
if(!pilot_isDisabled(p)) {
|
||||
player_message("You cannot board a ship that is not disabled!");
|
||||
return;
|
||||
}
|
||||
else if(vect_dist(&player->solid->pos, &p->solid->pos) >
|
||||
p->ship->gfx_space->sw * PILOT_SIZE_APROX) {
|
||||
player_message("You are too far away to board your target");
|
||||
return;
|
||||
}
|
||||
else if((pow2(VX(player->solid->vel)-VX(p->solid->vel)) +
|
||||
pow2(VY(player->solid->vel)-VY(p->solid->vel))) >
|
||||
(double)pow2(MAX_HYPERSPACE_VEL)) {
|
||||
player_message("You are going too fast to board the ship");
|
||||
return;
|
||||
}
|
||||
else if(pilot_isFlag(p, PILOT_BOARDED)) {
|
||||
player_message("Your target cannot be boarded again");
|
||||
return;
|
||||
}
|
||||
if(!pilot_isDisabled(p)) {
|
||||
player_message("You cannot board a ship that is not disabled!");
|
||||
return;
|
||||
}
|
||||
else if(vect_dist(&player->solid->pos, &p->solid->pos) >
|
||||
p->ship->gfx_space->sw * PILOT_SIZE_APROX) {
|
||||
player_message("You are too far away to board your target");
|
||||
return;
|
||||
}
|
||||
else if((pow2(VX(player->solid->vel)-VX(p->solid->vel)) +
|
||||
pow2(VY(player->solid->vel)-VY(p->solid->vel))) >
|
||||
(double)pow2(MAX_HYPERSPACE_VEL)) {
|
||||
player_message("You are going too fast to board the ship");
|
||||
return;
|
||||
}
|
||||
else if(pilot_isFlag(p, PILOT_BOARDED)) {
|
||||
player_message("Your target cannot be boarded again");
|
||||
return;
|
||||
}
|
||||
|
||||
// Pilot will be boarded.
|
||||
pilot_setFlag(p, PILOT_BOARDED);
|
||||
player_message("Boarding ship %s", p->name);
|
||||
// Pilot will be boarded.
|
||||
pilot_setFlag(p, PILOT_BOARDED);
|
||||
player_message("Boarding ship %s", p->name);
|
||||
|
||||
// Create the boarding window.
|
||||
board_wid = window_create("Boarding", -1, -1, BOARDING_WIDTH, BOARDING_HEIGHT);
|
||||
// Create the boarding window.
|
||||
board_wid = window_create("Boarding", -1, -1, BOARDING_WIDTH, BOARDING_HEIGHT);
|
||||
|
||||
window_addText(board_wid, 20, -30, 120, 60,
|
||||
0, "txtCargo", &gl_smallFont, &cDConsole,
|
||||
"SCreds:\n"
|
||||
"Cargo:\n");
|
||||
window_addText(board_wid, 20, -30, 120, 60,
|
||||
0, "txtCargo", &gl_smallFont, &cDConsole,
|
||||
"SCreds:\n"
|
||||
"Cargo:\n");
|
||||
|
||||
window_addText(board_wid, 80, -30, 120, 60, 0, "txtData",
|
||||
&gl_smallFont, &cBlack, NULL);
|
||||
window_addText(board_wid, 80, -30, 120, 60, 0, "txtData",
|
||||
&gl_smallFont, &cBlack, NULL);
|
||||
|
||||
window_addButton(board_wid, 20, 20, 50, 30, "btnStealCredits",
|
||||
"Credits", board_stealCreds);
|
||||
window_addButton(board_wid, 20, 20, 50, 30, "btnStealCredits",
|
||||
"Credits", board_stealCreds);
|
||||
|
||||
window_addButton(board_wid, 90, 20, 50, 30, "btnStealCargo",
|
||||
"Cargo", board_stealCargo);
|
||||
window_addButton(board_wid, 90, 20, 50, 30, "btnStealCargo",
|
||||
"Cargo", board_stealCargo);
|
||||
|
||||
window_addButton(board_wid, -20, 20, 50, 30, "btnBoardingClose",
|
||||
"Leave", board_exit);
|
||||
window_addButton(board_wid, -20, 20, 50, 30, "btnBoardingClose",
|
||||
"Leave", board_exit);
|
||||
|
||||
board_update();
|
||||
board_update();
|
||||
}
|
||||
|
||||
static void board_exit(char* str) {
|
||||
(void)str;
|
||||
window_destroy(window_get("Boarding"));
|
||||
(void)str;
|
||||
window_destroy(window_get("Boarding"));
|
||||
}
|
||||
|
||||
static void board_stealCreds(char* str) {
|
||||
(void)str;
|
||||
Pilot* p;
|
||||
(void)str;
|
||||
Pilot* p;
|
||||
|
||||
p = pilot_get(player_target);
|
||||
p = pilot_get(player_target);
|
||||
|
||||
if(p->credits == 0) {
|
||||
// Can't steal from the poor. ;)
|
||||
player_message("The ship has no SCreds.");
|
||||
return;
|
||||
}
|
||||
if(p->credits == 0) {
|
||||
// Can't steal from the poor. ;)
|
||||
player_message("The ship has no SCreds.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(board_fail()) return;
|
||||
if(board_fail()) return;
|
||||
|
||||
player_credits += p->credits;
|
||||
p->credits = 0;
|
||||
board_update(); // Update the lack of credits.
|
||||
player_message("You manage to steal the ship's Scred.");
|
||||
player_credits += p->credits;
|
||||
p->credits = 0;
|
||||
board_update(); // Update the lack of credits.
|
||||
player_message("You manage to steal the ship's Scred.");
|
||||
}
|
||||
|
||||
static void board_stealCargo(char* str) {
|
||||
(void)str;
|
||||
int q;
|
||||
Pilot* p;
|
||||
(void)str;
|
||||
int q;
|
||||
Pilot* p;
|
||||
|
||||
p = pilot_get(player_target);
|
||||
p = pilot_get(player_target);
|
||||
|
||||
if(p->ncommodities==0) {
|
||||
// No cargo.
|
||||
player_message("The ship has no cargo.");
|
||||
return;
|
||||
}
|
||||
else if(player->cargo_free <= 0) {
|
||||
player_message("You have no room for cargo.");
|
||||
return;
|
||||
}
|
||||
if(p->ncommodities==0) {
|
||||
// No cargo.
|
||||
player_message("The ship has no cargo.");
|
||||
return;
|
||||
}
|
||||
else if(player->cargo_free <= 0) {
|
||||
player_message("You have no room for cargo.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(board_fail()) return;
|
||||
if(board_fail()) return;
|
||||
|
||||
// Steal as much as possible until full - TODO: Allow the player to choose.
|
||||
q = 1;
|
||||
while((p->ncommodities > 0) && (q != 0)) {
|
||||
q = pilot_addCargo(player, p->commodities[0].commodity,
|
||||
p->commodities[0].quantity);
|
||||
// Steal as much as possible until full - TODO: Allow the player to choose.
|
||||
q = 1;
|
||||
while((p->ncommodities > 0) && (q != 0)) {
|
||||
q = pilot_addCargo(player, p->commodities[0].commodity,
|
||||
p->commodities[0].quantity);
|
||||
|
||||
pilot_rmCargo(p, p->commodities[0].commodity, q);
|
||||
}
|
||||
pilot_rmCargo(p, p->commodities[0].commodity, q);
|
||||
}
|
||||
|
||||
board_update();
|
||||
player_message("You manage to steal the ship's cargo.");
|
||||
board_update();
|
||||
player_message("You manage to steal the ship's cargo.");
|
||||
}
|
||||
|
||||
// Failed to board.
|
||||
static int board_fail(void) {
|
||||
Pilot* p;
|
||||
Pilot* p;
|
||||
|
||||
p = pilot_get(player_target);
|
||||
p = pilot_get(player_target);
|
||||
|
||||
// Fail chance.
|
||||
if(RNG(0, 100) > (int)(50. *
|
||||
(10. + (double)p->ship->crew/10.+(double)player->ship->crew)))
|
||||
return 0;
|
||||
// Fail chance.
|
||||
if(RNG(0, 100) > (int)(50. *
|
||||
(10. + (double)p->ship->crew/10.+(double)player->ship->crew)))
|
||||
return 0;
|
||||
|
||||
if(RNG(0, 2)==0) {
|
||||
// 33% of instant death.
|
||||
p->armour = -1;
|
||||
player_message("You have tripped the ship's self destruct mechanism!");
|
||||
} else
|
||||
// You just got locked out!!
|
||||
player_message("The ship's security system locks you out!");
|
||||
if(RNG(0, 2)==0) {
|
||||
// 33% of instant death.
|
||||
p->armour = -1;
|
||||
player_message("You have tripped the ship's self destruct mechanism!");
|
||||
} else
|
||||
// You just got locked out!!
|
||||
player_message("The ship's security system locks you out!");
|
||||
|
||||
board_exit(NULL);
|
||||
return 1;
|
||||
board_exit(NULL);
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Update the cargo and credit fields.
|
||||
static void board_update(void) {
|
||||
int i;
|
||||
char str[128], buf[32];
|
||||
char cred[10];
|
||||
Pilot* p;
|
||||
int i;
|
||||
char str[128], buf[32];
|
||||
char cred[10];
|
||||
Pilot* p;
|
||||
|
||||
p = pilot_get(player_target);
|
||||
p = pilot_get(player_target);
|
||||
|
||||
credits2str(cred, p->credits, 2);
|
||||
credits2str(cred, p->credits, 2);
|
||||
|
||||
snprintf(str, 11,
|
||||
"%s\n", cred);
|
||||
if(p->ncommodities == 0)
|
||||
strncat(str, "none", 10);
|
||||
else {
|
||||
for(i = 0; i < p->ncommodities; i++) {
|
||||
snprintf(buf, 32,
|
||||
"%d %s\n",
|
||||
p->commodities[i].quantity, p->commodities[i].commodity->name);
|
||||
strncat(str, buf, 32);
|
||||
}
|
||||
}
|
||||
snprintf(str, 11,
|
||||
"%s\n", cred);
|
||||
if(p->ncommodities == 0)
|
||||
strncat(str, "none", 10);
|
||||
else {
|
||||
for(i = 0; i < p->ncommodities; i++) {
|
||||
snprintf(buf, 32,
|
||||
"%d %s\n",
|
||||
p->commodities[i].quantity, p->commodities[i].commodity->name);
|
||||
strncat(str, buf, 32);
|
||||
}
|
||||
}
|
||||
|
||||
window_modifyText(board_wid, "txtData", str);
|
||||
window_modifyText(board_wid, "txtData", str);
|
||||
}
|
||||
|
||||
|
@ -13,15 +13,15 @@
|
||||
// bsy - Position of y of sprite b.
|
||||
// bp - Position in space of sprite b.
|
||||
int CollideSprite(const glTexture* at, const int asx, const int asy,
|
||||
const Vec2* ap, const glTexture* bt,
|
||||
const int bsx, const int bsy, const Vec2* bp) {
|
||||
const Vec2* ap, const glTexture* bt,
|
||||
const int bsx, const int bsy, const Vec2* bp) {
|
||||
|
||||
int x,y;
|
||||
int ax1, ax2, ay1, ay2;
|
||||
int bx1, bx2, by1, by2;
|
||||
int inter_x0, inter_x1, inter_y0, inter_y1;
|
||||
int rasy, rbsy;
|
||||
int abx, aby, bbx, bby;
|
||||
int ax1, ax2, ay1, ay2;
|
||||
int bx1, bx2, by1, by2;
|
||||
int inter_x0, inter_x1, inter_y0, inter_y1;
|
||||
int rasy, rbsy;
|
||||
int abx, aby, bbx, bby;
|
||||
|
||||
// a - cube coords.
|
||||
ax1 = (int)VX(*ap) - (int)(at->sw)/2;
|
||||
|
@ -3,6 +3,6 @@
|
||||
#include "physics.h"
|
||||
|
||||
int CollideSprite(const glTexture* at, const int asx, const int asy,
|
||||
const Vec2* ap, const glTexture* bt,
|
||||
const int bsx, const int bsy, const Vec2* bp);
|
||||
const Vec2* ap, const glTexture* bt,
|
||||
const int bsx, const int bsy, const Vec2* bp);
|
||||
|
||||
|
32
src/colour.c
32
src/colour.c
@ -16,26 +16,26 @@ glColour cBlack = { .r = 0.00, .g = 0.00, .b = 0.00, .a = 1. };
|
||||
glColour cGreen = { .r = 0.20, .g = 0.80, .b = 0.20, .a = 1. };
|
||||
glColour cDarkRed = { .r = 0.60, .g = 0.10, .b = 0.10, .a = 1. };
|
||||
glColour cRed = { .r = 0.80, .g = 0.20, .b = 0.20, .a = 1. };
|
||||
glColour cYellow = { .r = 0.80, .g = 0.80, .b = 0.00, .a = 1. };
|
||||
glColour cDarkBlue = { .r = 0.10, .g = 0.20, .b = 0.80, .a = 1. };
|
||||
glColour cBlue = { .r = 0.20, .g = 0.20, .b = 0.80, .a = 1. };
|
||||
glColour cYellow = { .r = 0.80, .g = 0.80, .b = 0.00, .a = 1. };
|
||||
glColour cDarkBlue = { .r = 0.10, .g = 0.20, .b = 0.80, .a = 1. };
|
||||
glColour cBlue = { .r = 0.20, .g = 0.20, .b = 0.80, .a = 1. };
|
||||
|
||||
// Game specific.
|
||||
glColour cConsole = { .r = 0.1, .g = 0.9, .b = 0.1, .a = 1. };
|
||||
glColour cDConsole = { .r = 0.0, .g = 0.7, .b = 0.0, .a = 1. };
|
||||
glColour cConsole = { .r = 0.1, .g = 0.9, .b = 0.1, .a = 1. };
|
||||
glColour cDConsole = { .r = 0.0, .g = 0.7, .b = 0.0, .a = 1. };
|
||||
// Toolkit.
|
||||
glColour cHilight = { .r = 0.1, .g = 0.9, .b = 0.1, .a = 0.3 };
|
||||
glColour cHilight = { .r = 0.1, .g = 0.9, .b = 0.1, .a = 0.3 };
|
||||
// Objects
|
||||
glColour cInert = { .r = 0.6, .g = 0.6, .b = 0.6, .a = 1. };
|
||||
glColour cNeutral = { .r = 0.9, .g = 1.0, .b = 0.3, .a = 1. };
|
||||
glColour cFriend = { .r = 0.0, .g = 1.0, .b = 0.0, .a = 1. };
|
||||
glColour cHostile = { .r = 0.9, .g = 0.2, .b = 0.2, .a = 1. };
|
||||
glColour cInert = { .r = 0.6, .g = 0.6, .b = 0.6, .a = 1. };
|
||||
glColour cNeutral = { .r = 0.9, .g = 1.0, .b = 0.3, .a = 1. };
|
||||
glColour cFriend = { .r = 0.0, .g = 1.0, .b = 0.0, .a = 1. };
|
||||
glColour cHostile = { .r = 0.9, .g = 0.2, .b = 0.2, .a = 1. };
|
||||
// Radar
|
||||
glColour cRadar_player = { .r = 0.4, .g = 0.8, .b = 0.4, .a = 1. };
|
||||
glColour cRadar_targ = { .r = 0.0, .g = 0.7, .b = 1.0, .a = 1. };
|
||||
glColour cRadar_weap = { .r = 0.8, .g = 0.2, .b = 0.2, .a = 1. };
|
||||
glColour cRadar_player = { .r = 0.4, .g = 0.8, .b = 0.4, .a = 1. };
|
||||
glColour cRadar_targ = { .r = 0.0, .g = 0.7, .b = 1.0, .a = 1. };
|
||||
glColour cRadar_weap = { .r = 0.8, .g = 0.2, .b = 0.2, .a = 1. };
|
||||
// Bars.
|
||||
glColour cShield = { .r = 0.2, .g = 0.2, .b = 0.8, .a = 1. };
|
||||
glColour cArmour = { .r = 0.5, .g = 0.5, .b = 0.5, .a = 1. };
|
||||
glColour cEnergy = { .r = 0.2, .g = 0.8, .b = 0.2, .a = 1. };
|
||||
glColour cShield = { .r = 0.2, .g = 0.2, .b = 0.8, .a = 1. };
|
||||
glColour cArmour = { .r = 0.5, .g = 0.5, .b = 0.5, .a = 1. };
|
||||
glColour cEnergy = { .r = 0.2, .g = 0.8, .b = 0.2, .a = 1. };
|
||||
|
||||
|
@ -31,7 +31,7 @@ extern glColour cBlue;
|
||||
|
||||
// Game specific.
|
||||
extern glColour cConsole;
|
||||
extern glColour cDConsole;
|
||||
extern glColour cDConsole;
|
||||
// Toolkit.
|
||||
extern glColour cHilight;
|
||||
// Objects.
|
||||
|
66
src/conf.c
66
src/conf.c
@ -24,8 +24,8 @@ if(lua_isnumber(L, -1)) { \
|
||||
#define conf_loadFloat(n,f) \
|
||||
lua_getglobal(L,n); \
|
||||
if(lua_isnumber(L, -1)) { \
|
||||
f = (double)lua_tonumber(L, -1); \
|
||||
lua_remove(L,-1);\
|
||||
f = (double)lua_tonumber(L, -1); \
|
||||
lua_remove(L,-1);\
|
||||
}
|
||||
|
||||
#define conf_loadBool(n,b) \
|
||||
@ -65,8 +65,8 @@ static void print_usage(char** argv) {
|
||||
LOG("\t-d s, --data s - Set the data file to be s");
|
||||
LOG("\t-j n, --joystick n - Use joystick (n)");
|
||||
LOG("\t-J s, --joystick s - Use joystick whose name contains (s)");
|
||||
LOG("\t-m f, --music f - Set the music volume to f");
|
||||
LOG("\t-s f, --sound f - Set the sound volume to f");
|
||||
LOG("\t-m f, --music f - Set the music volume to f");
|
||||
LOG("\t-s f, --sound f - Set the sound volume to f");
|
||||
LOG("\t-h --help - Display this message and exit.");
|
||||
LOG("\t-v - Print the version and exit");
|
||||
}
|
||||
@ -89,7 +89,7 @@ void conf_setDefaults(void) {
|
||||
// Ok.. Parse a config file plox.
|
||||
int conf_loadConfig(const char* file) {
|
||||
int i = 0;
|
||||
double d = 0.;
|
||||
double d = 0.;
|
||||
|
||||
lua_State* L = luaL_newstate();
|
||||
if(luaL_dofile(L, file) == 0) {
|
||||
@ -104,9 +104,9 @@ int conf_loadConfig(const char* file) {
|
||||
if(i) { gl_screen.flags |= OPENGL_FULLSCREEN; i = 0; }
|
||||
conf_loadBool("aa", i);
|
||||
if(i) {
|
||||
gl_screen.flags |= OPENGL_AA_POINT | OPENGL_AA_LINE || OPENGL_AA_POLYGON;
|
||||
i = 0;
|
||||
}
|
||||
gl_screen.flags |= OPENGL_AA_POINT | OPENGL_AA_LINE || OPENGL_AA_POLYGON;
|
||||
i = 0;
|
||||
}
|
||||
conf_loadBool("aa_point", i);
|
||||
if(i) { gl_screen.flags |= OPENGL_AA_POINT; i = 0; }
|
||||
conf_loadBool("aa_line", i)
|
||||
@ -114,18 +114,18 @@ int conf_loadConfig(const char* file) {
|
||||
conf_loadBool("aa_polygon", i);
|
||||
if(i) { gl_screen.flags |= OPENGL_AA_POLYGON; i = 0; }
|
||||
|
||||
// FPS.
|
||||
conf_loadBool("showfps", show_fps);
|
||||
// FPS.
|
||||
conf_loadBool("showfps", show_fps);
|
||||
conf_loadInt("maxfps", max_fps);
|
||||
|
||||
// Input.
|
||||
conf_loadInt("afterburn", input_afterburnSensibility);
|
||||
// Input.
|
||||
conf_loadInt("afterburn", input_afterburnSensibility);
|
||||
|
||||
// Sound.
|
||||
conf_loadFloat("sound", d);
|
||||
if(d) { sound_volume(d); d = 0.; }
|
||||
conf_loadFloat("music", d);
|
||||
if(d) { music_volume(d); d = 0.; }
|
||||
// Sound.
|
||||
conf_loadFloat("sound", d);
|
||||
if(d) { sound_volume(d); d = 0.; }
|
||||
conf_loadFloat("music", d);
|
||||
if(d) { music_volume(d); d = 0.; }
|
||||
|
||||
// Joystick.
|
||||
lua_getglobal(L, "joystick");
|
||||
@ -200,22 +200,22 @@ int conf_loadConfig(const char* file) {
|
||||
// Parse some CLI options.
|
||||
void conf_parseCLI(int argc, char** argv) {
|
||||
static struct option long_options[] = {
|
||||
{ "fullscreen", no_argument, 0, 'f' },
|
||||
{ "fps", required_argument, 0, 'F' },
|
||||
{ "data", required_argument, 0, 'd' },
|
||||
{ "joystick", required_argument, 0, 'j' },
|
||||
{ "Joystick", required_argument, 0, 'J' },
|
||||
{ "music", required_argument, 0, 'm' },
|
||||
{ "sound", required_argument, 0, 's' },
|
||||
{ "help", no_argument, 0, 'h' },
|
||||
{ "version", no_argument, 0, 'v' },
|
||||
{ "fullscreen", no_argument, 0, 'f' },
|
||||
{ "fps", required_argument, 0, 'F' },
|
||||
{ "data", required_argument, 0, 'd' },
|
||||
{ "joystick", required_argument, 0, 'j' },
|
||||
{ "Joystick", required_argument, 0, 'J' },
|
||||
{ "music", required_argument, 0, 'm' },
|
||||
{ "sound", required_argument, 0, 's' },
|
||||
{ "help", no_argument, 0, 'h' },
|
||||
{ "version", no_argument, 0, 'v' },
|
||||
{ NULL, 0, 0, 0 }
|
||||
};
|
||||
int option_index = 0;
|
||||
int c = 0;
|
||||
|
||||
while((c = getopt_long(argc, argv, "fF:d:J:j:s:m:V:hv",
|
||||
long_options, &option_index)) != -1) {
|
||||
long_options, &option_index)) != -1) {
|
||||
switch(c) {
|
||||
case 'f':
|
||||
gl_screen.flags |= OPENGL_FULLSCREEN;
|
||||
@ -232,12 +232,12 @@ void conf_parseCLI(int argc, char** argv) {
|
||||
case 'J':
|
||||
namjoystick = strdup(optarg);
|
||||
break;
|
||||
case 'm':
|
||||
music_volume(atof(optarg));
|
||||
break;
|
||||
case 's':
|
||||
sound_volume(atof(optarg));
|
||||
break;
|
||||
case 'm':
|
||||
music_volume(atof(optarg));
|
||||
break;
|
||||
case 's':
|
||||
sound_volume(atof(optarg));
|
||||
break;
|
||||
case 'v':
|
||||
LOG(APPNAME": version %d.%d.%d", VMAJOR, VMINOR, VREV);
|
||||
case 'h':
|
||||
|
160
src/economy.c
160
src/economy.c
@ -8,9 +8,9 @@
|
||||
#include "log.h"
|
||||
#include "economy.h"
|
||||
|
||||
#define XML_COMMODITY_ID "Commodities" // XML section identifier.
|
||||
#define XML_COMMODITY_TAG "commodity"
|
||||
#define COMMODITY_DATA "../dat/commodity.xml"
|
||||
#define XML_COMMODITY_ID "Commodities" // XML section identifier.
|
||||
#define XML_COMMODITY_TAG "commodity"
|
||||
#define COMMODITY_DATA "../dat/commodity.xml"
|
||||
|
||||
// Commodity stack.
|
||||
static Commodity* commodity_stack = NULL;
|
||||
@ -22,115 +22,115 @@ static Commodity* commodity_parse(xmlNodePtr parent);
|
||||
// Convert credits to a usable string for displaying.
|
||||
// str must have 10 characters allocated.
|
||||
void credits2str(char* str, unsigned int credits, int decimals) {
|
||||
if(decimals < 0)
|
||||
snprintf(str, 32, "%d", credits);
|
||||
else if(credits >= 1000000000)
|
||||
snprintf(str, 16, "%.*fB", decimals, (double)credits / 1000000000.);
|
||||
else if(credits >= 1000000)
|
||||
snprintf(str, 16, "%*fM", decimals, (double)credits / 1000000.);
|
||||
else if(credits >= 1000)
|
||||
snprintf(str, 16, "%.*fK", decimals, (double)credits / 1000.);
|
||||
else snprintf(str, 16, "%d", credits);
|
||||
if(decimals < 0)
|
||||
snprintf(str, 32, "%d", credits);
|
||||
else if(credits >= 1000000000)
|
||||
snprintf(str, 16, "%.*fB", decimals, (double)credits / 1000000000.);
|
||||
else if(credits >= 1000000)
|
||||
snprintf(str, 16, "%*fM", decimals, (double)credits / 1000000.);
|
||||
else if(credits >= 1000)
|
||||
snprintf(str, 16, "%.*fK", decimals, (double)credits / 1000.);
|
||||
else snprintf(str, 16, "%d", credits);
|
||||
}
|
||||
|
||||
// Get a commodity.
|
||||
Commodity* commodity_get(const char* name) {
|
||||
int i;
|
||||
for(i = 0; i < commodity_nstack; i++)
|
||||
if(strcmp(commodity_stack[i].name, name)==0)
|
||||
return &commodity_stack[i];
|
||||
int i;
|
||||
for(i = 0; i < commodity_nstack; i++)
|
||||
if(strcmp(commodity_stack[i].name, name)==0)
|
||||
return &commodity_stack[i];
|
||||
|
||||
WARN("Commodity '%s' not found in stack", name);
|
||||
return NULL;
|
||||
WARN("Commodity '%s' not found in stack", name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Free a commodity.
|
||||
static void commodity_freeOne(Commodity* com) {
|
||||
if(com->name) free(com->name);
|
||||
if(com->description) free(com->description);
|
||||
if(com->name) free(com->name);
|
||||
if(com->description) free(com->description);
|
||||
}
|
||||
|
||||
static Commodity* commodity_parse(xmlNodePtr parent) {
|
||||
xmlNodePtr node;
|
||||
Commodity* tmp = CALLOC_L(Commodity);
|
||||
xmlNodePtr node;
|
||||
Commodity* tmp = CALLOC_L(Commodity);
|
||||
|
||||
tmp->name = (char*)xmlGetProp(parent, (xmlChar*)"name");
|
||||
if(tmp->name == NULL)
|
||||
WARN("Commodity from "COMMODITY_DATA" has invalid or noname");
|
||||
tmp->name = (char*)xmlGetProp(parent, (xmlChar*)"name");
|
||||
if(tmp->name == NULL)
|
||||
WARN("Commodity from "COMMODITY_DATA" has invalid or noname");
|
||||
|
||||
node = parent->xmlChildrenNode;
|
||||
node = parent->xmlChildrenNode;
|
||||
|
||||
do {
|
||||
if(xml_isNode(node, "description"))
|
||||
tmp->description = strdup(xml_get(node));
|
||||
else if(xml_isNode(node, "high"))
|
||||
tmp->high = xml_getInt(node);
|
||||
else if(xml_isNode(node, "medium"))
|
||||
tmp->medium = xml_getInt(node);
|
||||
else if(xml_isNode(node, "low"))
|
||||
tmp->low = xml_getInt(node);
|
||||
} while((node = node->next));
|
||||
do {
|
||||
if(xml_isNode(node, "description"))
|
||||
tmp->description = strdup(xml_get(node));
|
||||
else if(xml_isNode(node, "high"))
|
||||
tmp->high = xml_getInt(node);
|
||||
else if(xml_isNode(node, "medium"))
|
||||
tmp->medium = xml_getInt(node);
|
||||
else if(xml_isNode(node, "low"))
|
||||
tmp->low = xml_getInt(node);
|
||||
} while((node = node->next));
|
||||
|
||||
#define MELEMENT(o,s)if(o)WARN("Commodity '%s' missing '"s"' element",tmp->name)
|
||||
MELEMENT(tmp->high==0, "high");
|
||||
MELEMENT(tmp->description==NULL, "description");
|
||||
MELEMENT(tmp->medium==0, "medium");
|
||||
MELEMENT(tmp->low==0, "low");
|
||||
MELEMENT(tmp->high==0, "high");
|
||||
MELEMENT(tmp->description==NULL, "description");
|
||||
MELEMENT(tmp->medium==0, "medium");
|
||||
MELEMENT(tmp->low==0, "low");
|
||||
#undef MELEMENT
|
||||
|
||||
return tmp;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
int commodity_load(void) {
|
||||
uint32_t bufsize;
|
||||
char* buf = pack_readfile(DATA, COMMODITY_DATA, &bufsize);
|
||||
uint32_t bufsize;
|
||||
char* buf = pack_readfile(DATA, COMMODITY_DATA, &bufsize);
|
||||
|
||||
xmlNodePtr node;
|
||||
xmlDocPtr doc = xmlParseMemory(buf, bufsize);
|
||||
xmlNodePtr node;
|
||||
xmlDocPtr doc = xmlParseMemory(buf, bufsize);
|
||||
|
||||
Commodity* tmp = NULL;
|
||||
Commodity* tmp = NULL;
|
||||
|
||||
node = doc->xmlChildrenNode; // Commoditys node.
|
||||
if(strcmp((char*)node->name, XML_COMMODITY_ID)) {
|
||||
ERR("Malformed "COMMODITY_DATA
|
||||
" file: Missing root element '"XML_COMMODITY_ID"'");
|
||||
return -1;
|
||||
}
|
||||
node = doc->xmlChildrenNode; // Commoditys node.
|
||||
if(strcmp((char*)node->name, XML_COMMODITY_ID)) {
|
||||
ERR("Malformed "COMMODITY_DATA
|
||||
" file: Missing root element '"XML_COMMODITY_ID"'");
|
||||
return -1;
|
||||
}
|
||||
|
||||
node = node->xmlChildrenNode; // First faction node.
|
||||
if(node == NULL) {
|
||||
ERR("Malformed "COMMODITY_DATA" file: does not contain elements");
|
||||
return -1;
|
||||
}
|
||||
node = node->xmlChildrenNode; // First faction node.
|
||||
if(node == NULL) {
|
||||
ERR("Malformed "COMMODITY_DATA" file: does not contain elements");
|
||||
return -1;
|
||||
}
|
||||
|
||||
do {
|
||||
if(node->type == XML_NODE_START) {
|
||||
if(strcmp((char*)node->name, XML_COMMODITY_TAG)==0) {
|
||||
tmp = commodity_parse(node);
|
||||
commodity_stack = realloc(commodity_stack,
|
||||
sizeof(Commodity)*(++commodity_nstack));
|
||||
memcpy(commodity_stack+commodity_nstack-1, tmp, sizeof(Commodity));
|
||||
free(tmp);
|
||||
}
|
||||
}
|
||||
} while((node = node->next));
|
||||
do {
|
||||
if(node->type == XML_NODE_START) {
|
||||
if(strcmp((char*)node->name, XML_COMMODITY_TAG)==0) {
|
||||
tmp = commodity_parse(node);
|
||||
commodity_stack = realloc(commodity_stack,
|
||||
sizeof(Commodity)*(++commodity_nstack));
|
||||
memcpy(commodity_stack+commodity_nstack-1, tmp, sizeof(Commodity));
|
||||
free(tmp);
|
||||
}
|
||||
}
|
||||
} while((node = node->next));
|
||||
|
||||
xmlFreeDoc(doc);
|
||||
free(buf);
|
||||
xmlCleanupParser();
|
||||
xmlFreeDoc(doc);
|
||||
free(buf);
|
||||
xmlCleanupParser();
|
||||
|
||||
DEBUG("Loaded %d commodit%s",
|
||||
commodity_nstack, (commodity_nstack==1) ? "y" : "ies");
|
||||
DEBUG("Loaded %d commodit%s",
|
||||
commodity_nstack, (commodity_nstack==1) ? "y" : "ies");
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void commodity_free(void) {
|
||||
int i;
|
||||
for(i = 0; i < commodity_nstack; i++)
|
||||
commodity_freeOne(&commodity_stack[i]);
|
||||
free(commodity_stack);
|
||||
commodity_stack = NULL;
|
||||
commodity_nstack = 0;
|
||||
int i;
|
||||
for(i = 0; i < commodity_nstack; i++)
|
||||
commodity_freeOne(&commodity_stack[i]);
|
||||
free(commodity_stack);
|
||||
commodity_stack = NULL;
|
||||
commodity_nstack = 0;
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
typedef struct Commodity_ {
|
||||
char* name;
|
||||
char* description;
|
||||
int low, medium, high; // Prices.
|
||||
char* name;
|
||||
char* description;
|
||||
int low, medium, high; // Prices.
|
||||
} Commodity;
|
||||
|
||||
// Commidity stuff.
|
||||
|
@ -66,7 +66,7 @@ int areEnemies(Faction* a, Faction* b) {
|
||||
int i = 0;
|
||||
|
||||
if(a == b) return 0;
|
||||
else if((a == NULL) || (b == NULL)) return 0;
|
||||
else if((a == NULL) || (b == NULL)) return 0;
|
||||
|
||||
for(i = 0; i < a->nenemies; i++)
|
||||
if(a->enemies[i] == b)
|
||||
@ -83,7 +83,7 @@ int areAllies(Faction* a, Faction* b) {
|
||||
int i = 0;
|
||||
|
||||
if(a == b) return 0;
|
||||
else if((a == NULL) || (b == NULL)) return 0;
|
||||
else if((a == NULL) || (b == NULL)) return 0;
|
||||
|
||||
for(i = 0; i < a->nallies; i++)
|
||||
if(a->allies[i] == b)
|
||||
@ -101,7 +101,7 @@ static Faction* faction_parse(xmlNodePtr parent) {
|
||||
Faction* tmp = CALLOC_L(Faction);
|
||||
tmp->name = (char*)xmlGetProp(parent, (xmlChar*)"name");
|
||||
if(tmp->name == NULL)
|
||||
WARN("Faction from "FACTION_DATA" has invalid or no name");
|
||||
WARN("Faction from "FACTION_DATA" has invalid or no name");
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@ -115,7 +115,7 @@ static void alliance_parse(xmlNodePtr parent) {
|
||||
|
||||
do {
|
||||
if((node->type == XML_NODE_START) && (strcmp((char*)node->name,
|
||||
XML_ALLIANCE_TAG)==0)) {
|
||||
XML_ALLIANCE_TAG)==0)) {
|
||||
// Allocate a new alliance.
|
||||
alliances = realloc(alliances, sizeof(Alliance)*(++nalliances));
|
||||
alliances[nalliances-1].name = (char*)xmlGetProp(node,(xmlChar*)"name");
|
||||
@ -144,14 +144,14 @@ static void alliance_parse(xmlNodePtr parent) {
|
||||
// Set the crap needed by faction_stack.
|
||||
for(j = 0; j < (*i); j++) {
|
||||
a->factions[j]->nallies += (*i)-1;
|
||||
a->factions[j]->allies = realloc(a->factions[j]->allies,
|
||||
a->factions[j]->nallies*sizeof(Faction*));
|
||||
a->factions[j]->allies = realloc(a->factions[j]->allies,
|
||||
a->factions[j]->nallies*sizeof(Faction*));
|
||||
for(n = 0, m = 0; n < (*i); n++, m++) {
|
||||
// Add as ally for all factions exept self.
|
||||
if(n == j) m--;
|
||||
else if(n != j)
|
||||
a->factions[j]->allies[a->factions[j]->nallies-(*i)+1+m] =
|
||||
a->factions[n];
|
||||
a->factions[n];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -169,7 +169,7 @@ static void enemies_parse(xmlNodePtr parent) {
|
||||
|
||||
do {
|
||||
if((node->type == XML_NODE_START)
|
||||
&& (strcmp((char*)node->name, XML_ENEMIES_TAG)==0)) {
|
||||
&& (strcmp((char*)node->name, XML_ENEMIES_TAG)==0)) {
|
||||
i = 0;
|
||||
f = NULL;
|
||||
j = NULL;
|
||||
@ -188,7 +188,7 @@ static void enemies_parse(xmlNodePtr parent) {
|
||||
a = alliance_get((char*)cur->children->content);
|
||||
if(a == NULL)
|
||||
WARN("Alliance %s not found in stack",
|
||||
(char*)cur->children->content);
|
||||
(char*)cur->children->content);
|
||||
j[i-1] = a->nfactions;
|
||||
f[i-1] = a->factions;
|
||||
}
|
||||
@ -199,7 +199,7 @@ static void enemies_parse(xmlNodePtr parent) {
|
||||
f[i-1][0] = faction_get((char*)cur->children->content);
|
||||
if(f[i-1][0] == NULL)
|
||||
WARN("Faction %s not found in stack",
|
||||
(char*)cur->children->content);
|
||||
(char*)cur->children->content);
|
||||
}
|
||||
free(type);
|
||||
}
|
||||
@ -214,7 +214,7 @@ static void enemies_parse(xmlNodePtr parent) {
|
||||
// Now allocate the memory.
|
||||
f[n][m]->nenemies += e;
|
||||
f[n][m]->enemies = realloc(f[n][m]->enemies,
|
||||
sizeof(Faction*)*f[n][m]->nenemies);
|
||||
sizeof(Faction*)*f[n][m]->nenemies);
|
||||
|
||||
// Add the actualy enemies.
|
||||
for(x = 0, z = 0; x < i; x++)
|
||||
|
14
src/font.c
14
src/font.c
@ -76,7 +76,7 @@ void gl_print(const glFont* ft_font, const double x, const double y,
|
||||
// Acts just like gl_print, but prints to a max length of max.
|
||||
// Return the amount of characters we had to suppress.
|
||||
int gl_printMax(const glFont* ft_font, const int max,
|
||||
const double x, const double y, const glColour* c, const char* fmt, ...) {
|
||||
const double x, const double y, const glColour* c, const char* fmt, ...) {
|
||||
//float h = ft_font->h / .63; // Slightly increases font size.
|
||||
char txt[256];
|
||||
va_list ap;
|
||||
@ -231,7 +231,7 @@ int gl_printText(const glFont* ft_font, const int width, const int height,
|
||||
glPushMatrix(); // Translation matrix.
|
||||
glTranslated(x, y, 0);
|
||||
|
||||
// This is what we are displaying.
|
||||
// This is what we are displaying.
|
||||
glCallLists(lastspace-p-1, GL_UNSIGNED_BYTE, &buf);
|
||||
glPopMatrix(); // Translation matrix.
|
||||
|
||||
@ -273,13 +273,13 @@ int gl_printWidth(const glFont* ft_font, const char* fmt, ...) {
|
||||
// FONT!
|
||||
// ================
|
||||
static void glFontMakeDList(FT_Face face, char ch, GLuint list_base,
|
||||
GLuint* tex_base, int* width_base) {
|
||||
GLuint* tex_base, int* width_base) {
|
||||
FT_Glyph glyph;
|
||||
FT_Bitmap bitmap;
|
||||
GLubyte* expanded_data;
|
||||
int w, h;
|
||||
int i, j;
|
||||
double x, y;
|
||||
double x, y;
|
||||
|
||||
if(FT_Load_Glyph(face, FT_Get_Char_Index(face, ch), FT_LOAD_FORCE_AUTOHINT))
|
||||
WARN("FT_Load_Glyph failed");
|
||||
@ -304,7 +304,7 @@ static void glFontMakeDList(FT_Face face, char ch, GLuint list_base,
|
||||
for(i = 0; i < w; i++) {
|
||||
expanded_data[2*(i+j*w)] = expanded_data[2*(i+j*w)+1] =
|
||||
(i >= bitmap.width || j >= bitmap.rows) ?
|
||||
0 : bitmap.buffer[i + bitmap.width*j];
|
||||
0 : bitmap.buffer[i + bitmap.width*j];
|
||||
}
|
||||
}
|
||||
// Create the GL texture.
|
||||
@ -312,7 +312,7 @@ static void glFontMakeDList(FT_Face face, char ch, GLuint list_base,
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, w, h, 0, GL_LUMINANCE_ALPHA,
|
||||
GL_UNSIGNED_BYTE, expanded_data);
|
||||
GL_UNSIGNED_BYTE, expanded_data);
|
||||
|
||||
free(expanded_data); // No need for this now.
|
||||
|
||||
@ -343,7 +343,7 @@ static void glFontMakeDList(FT_Face face, char ch, GLuint list_base,
|
||||
|
||||
glPopMatrix();
|
||||
glTranslated(face->glyph->advance.x >> 6, 0,0);
|
||||
width_base[(int)ch] = (int)(face->glyph->advance.x >> 6);
|
||||
width_base[(int)ch] = (int)(face->glyph->advance.x >> 6);
|
||||
|
||||
// End of the display list.
|
||||
glEndList();
|
||||
|
@ -23,11 +23,11 @@ void gl_print(const glFont* ft_font, const double x, const double y,
|
||||
|
||||
// Print text to a max length.
|
||||
int gl_printMax(const glFont* ft_font, const int max,
|
||||
const double x, const double y, const glColour* c, const char* fmt, ...);
|
||||
const double x, const double y, const glColour* c, const char* fmt, ...);
|
||||
|
||||
// Print text centered in width at x.
|
||||
int gl_printMid(const glFont* ft_font, const int width,
|
||||
double x, const double y, const glColour* c, const char* fmt, ...);
|
||||
double x, const double y, const glColour* c, const char* fmt, ...);
|
||||
|
||||
// Respects \n -> bx, by is top left position.
|
||||
int gl_printText(const glFont* ft_font, const int width, const int height,
|
||||
|
86
src/input.c
86
src/input.c
@ -24,16 +24,16 @@ static Keybind** input_keybinds; // Contains the players keybindings.
|
||||
|
||||
// Name of each keybinding.
|
||||
const char* keybindNames[] = {
|
||||
"accel", "left", "right", "reverse", // Movement.
|
||||
"primary", "target", "target_nearest", "face", "board", // Combat.
|
||||
"accel", "left", "right", "reverse", // Movement.
|
||||
"primary", "target", "target_nearest", "face", "board", // Combat.
|
||||
"secondary", "secondary_next", // Secondary weapons.
|
||||
"target_planet", "land", "thyperspace","starmap", "jump", // Navigation.
|
||||
"mapzoomin", "mapzoomout", "screenshot", "pause", "menu", "info", // Misc.
|
||||
"mapzoomin", "mapzoomout", "screenshot", "pause", "menu", "info", // Misc.
|
||||
"end" }; // Must terminate at the end.
|
||||
|
||||
// Accel hacks.
|
||||
static unsigned int input_accelLast = 0; // Used to see if double tap.
|
||||
int input_afterburnSensibility = 500; // ms between taps to afterburn.
|
||||
static unsigned int input_accelLast = 0; // Used to see if double tap.
|
||||
int input_afterburnSensibility = 500; // ms between taps to afterburn.
|
||||
|
||||
// From player.c
|
||||
extern double player_turn;
|
||||
@ -57,22 +57,22 @@ void input_setDefault(void) {
|
||||
input_setKeybind("face", KEYBIND_KEYBOARD, SDLK_f, 0);
|
||||
input_setKeybind("board", KEYBIND_KEYBOARD, SDLK_b, 0);
|
||||
// Secondary weapon.
|
||||
input_setKeybind("secondary", KEYBIND_KEYBOARD, SDLK_LSHIFT, 0);
|
||||
input_setKeybind("secondary", KEYBIND_KEYBOARD, SDLK_LSHIFT, 0);
|
||||
input_setKeybind("secondary_next", KEYBIND_KEYBOARD, SDLK_e, 0);
|
||||
// Space
|
||||
input_setKeybind("target_planet", KEYBIND_KEYBOARD, SDLK_p, 0);
|
||||
input_setKeybind("land", KEYBIND_KEYBOARD, SDLK_l, 0);
|
||||
input_setKeybind("thyperspace", KEYBIND_KEYBOARD, SDLK_h, 0);
|
||||
input_setKeybind("starmap", KEYBIND_KEYBOARD, SDLK_m, 0);
|
||||
input_setKeybind("starmap", KEYBIND_KEYBOARD, SDLK_m, 0);
|
||||
input_setKeybind("jump", KEYBIND_KEYBOARD, SDLK_j, 0);
|
||||
|
||||
// Misc.
|
||||
input_setKeybind("mapzoomin", KEYBIND_KEYBOARD, SDLK_0, 0);
|
||||
input_setKeybind("mapzoomout", KEYBIND_KEYBOARD, SDLK_9, 0);
|
||||
input_setKeybind("mapzoomin", KEYBIND_KEYBOARD, SDLK_0, 0);
|
||||
input_setKeybind("mapzoomout", KEYBIND_KEYBOARD, SDLK_9, 0);
|
||||
input_setKeybind("screenshot", KEYBIND_KEYBOARD, SDLK_F12, 0);
|
||||
input_setKeybind("pause", KEYBIND_KEYBOARD, SDLK_F1, 0);
|
||||
input_setKeybind("menu", KEYBIND_KEYBOARD, SDLK_ESCAPE, 0);
|
||||
input_setKeybind("info", KEYBIND_KEYBOARD, SDLK_i, 0);
|
||||
input_setKeybind("info", KEYBIND_KEYBOARD, SDLK_i, 0);
|
||||
}
|
||||
|
||||
// Initialization/exit functions (does not assign keys).
|
||||
@ -118,31 +118,31 @@ void input_setKeybind(char* keybind, KeybindType type, int key, int reverse) {
|
||||
// value : Value of keypress (defined above).
|
||||
// abs : Whether or not it's an abs value (For those pesky joysticks.
|
||||
// =====================================================================
|
||||
#define KEY(s) (strcmp(input_keybinds[keynum]->name, s)==0)
|
||||
#define INGAME() (!toolkit)
|
||||
#define KEY(s) (strcmp(input_keybinds[keynum]->name, s)==0)
|
||||
#define INGAME() (!toolkit)
|
||||
// We won't be having any more funny stuff from VLack..
|
||||
#define NOHYP() \
|
||||
(!pilot_isFlag(player, PILOT_HYP_PREP) && \
|
||||
!pilot_isFlag(player, PILOT_HYP_BEGIN) && \
|
||||
!pilot_isFlag(player, PILOT_HYPERSPACE))
|
||||
(!pilot_isFlag(player, PILOT_HYP_PREP) && \
|
||||
!pilot_isFlag(player, PILOT_HYP_BEGIN) && \
|
||||
!pilot_isFlag(player, PILOT_HYPERSPACE))
|
||||
static void input_key(int keynum, double value, int abs) {
|
||||
unsigned int t;
|
||||
unsigned int t;
|
||||
|
||||
// Accelerating.
|
||||
if(KEY("accel")) {
|
||||
if(abs)player_acc = value;
|
||||
else player_acc += value;
|
||||
// Double tap accel = afterburn!
|
||||
t = SDL_GetTicks();
|
||||
if((value == KEY_PRESS) && (t-input_accelLast <= input_afterburnSensibility)) {
|
||||
player_afterburn();
|
||||
}
|
||||
else if((value == KEY_RELEASE) && player_isFlag(PLAYER_AFTERBURNER))
|
||||
player_afterburnOver();
|
||||
else
|
||||
player_acc = ABS(player_acc); // Make sure value is sane.
|
||||
// Double tap accel = afterburn!
|
||||
t = SDL_GetTicks();
|
||||
if((value == KEY_PRESS) && (t-input_accelLast <= input_afterburnSensibility)) {
|
||||
player_afterburn();
|
||||
}
|
||||
else if((value == KEY_RELEASE) && player_isFlag(PLAYER_AFTERBURNER))
|
||||
player_afterburnOver();
|
||||
else
|
||||
player_acc = ABS(player_acc); // Make sure value is sane.
|
||||
|
||||
if(value == KEY_PRESS) input_accelLast = t;
|
||||
if(value == KEY_PRESS) input_accelLast = t;
|
||||
}
|
||||
// Turning left.
|
||||
else if(KEY("left")) {
|
||||
@ -174,7 +174,7 @@ static void input_key(int keynum, double value, int abs) {
|
||||
if(player_isFlag(PLAYER_TURN_LEFT)) { player_turn -= 1; }
|
||||
if(player_isFlag(PLAYER_TURN_RIGHT)) { player_turn += 1; }
|
||||
}
|
||||
}
|
||||
}
|
||||
// Shoot primary weapon. BOOM BOOM.
|
||||
else if(KEY("primary")) {
|
||||
if(value == KEY_PRESS) { player_setFlag(PLAYER_PRIMARY); }
|
||||
@ -224,9 +224,9 @@ static void input_key(int keynum, double value, int abs) {
|
||||
else if(KEY("thyperspace") && INGAME() && NOHYP()) {
|
||||
if(value == KEY_PRESS) player_targetHyperspace();
|
||||
}
|
||||
else if(KEY("starmap") && NOHYP()) {
|
||||
if(value == KEY_PRESS) map_open();
|
||||
}
|
||||
else if(KEY("starmap") && NOHYP()) {
|
||||
if(value == KEY_PRESS) map_open();
|
||||
}
|
||||
else if(KEY("jump") && INGAME()) {
|
||||
if(value == KEY_PRESS) player_jump();
|
||||
}
|
||||
@ -254,10 +254,10 @@ static void input_key(int keynum, double value, int abs) {
|
||||
else if(KEY("menu")) {
|
||||
if(value == KEY_PRESS) menu_small();
|
||||
}
|
||||
// Show pilot information.
|
||||
else if(KEY("info") && NOHYP()) {
|
||||
if(value == KEY_PRESS) menu_info();
|
||||
}
|
||||
// Show pilot information.
|
||||
else if(KEY("info") && NOHYP()) {
|
||||
if(value == KEY_PRESS) menu_info();
|
||||
}
|
||||
}
|
||||
#undef KEY
|
||||
|
||||
@ -276,7 +276,7 @@ static void input_joyaxis(const unsigned int axis, const int value) {
|
||||
int i;
|
||||
for(i = 0; strcmp(keybindNames[i], "end"); i++)
|
||||
if(input_keybinds[i]->type == KEYBIND_JAXIS &&
|
||||
input_keybinds[i]->key == axis) {
|
||||
input_keybinds[i]->key == axis) {
|
||||
input_key(i, -(input_keybinds[i]->reverse) * (double)value / 32767., 1);
|
||||
return;
|
||||
}
|
||||
@ -287,7 +287,7 @@ static void input_joydown(const unsigned int button) {
|
||||
int i;
|
||||
for(i = 0; strcmp(keybindNames[i], "end");i++)
|
||||
if(input_keybinds[i]->type == KEYBIND_JBUTTON &&
|
||||
input_keybinds[i]->key == button) {
|
||||
input_keybinds[i]->key == button) {
|
||||
input_key(i, KEY_RELEASE, 0);
|
||||
return;
|
||||
}
|
||||
@ -298,7 +298,7 @@ static void input_joyup(const unsigned int button) {
|
||||
int i;
|
||||
for(i = 0; strcmp(keybindNames[i], "end"); i++)
|
||||
if(input_keybinds[i]->type == KEYBIND_JBUTTON &&
|
||||
input_keybinds[i]->key == button) {
|
||||
input_keybinds[i]->key == button) {
|
||||
input_key(i, KEY_RELEASE, 0);
|
||||
return;
|
||||
}
|
||||
@ -311,7 +311,7 @@ static void input_keydown(SDLKey key) {
|
||||
int i;
|
||||
for(i = 0; strcmp(keybindNames[i], "end"); i++)
|
||||
if(input_keybinds[i]->type == KEYBIND_KEYBOARD &&
|
||||
input_keybinds[i]->key == key) {
|
||||
input_keybinds[i]->key == key) {
|
||||
input_key(i, KEY_PRESS, 0);
|
||||
return;
|
||||
}
|
||||
@ -322,7 +322,7 @@ static void input_keyup(SDLKey key) {
|
||||
int i;
|
||||
for(i = 0; strcmp(keybindNames[i], "end"); i++)
|
||||
if(input_keybinds[i]->type == KEYBIND_KEYBOARD &&
|
||||
input_keybinds[i]->key == key) {
|
||||
input_keybinds[i]->key == key) {
|
||||
input_key(i, KEY_RELEASE, 0);
|
||||
return;
|
||||
}
|
||||
@ -332,10 +332,10 @@ static void input_keyup(SDLKey key) {
|
||||
|
||||
// Just seperates the event types.
|
||||
void input_handle(SDL_Event* event) {
|
||||
if(toolkit)
|
||||
// Toolkit is handled seperately.
|
||||
if(toolkit_input(event))
|
||||
return; // We don't process it if toolkit grabs it.
|
||||
if(toolkit)
|
||||
// Toolkit is handled seperately.
|
||||
if(toolkit_input(event))
|
||||
return; // We don't process it if toolkit grabs it.
|
||||
|
||||
switch(event->type) {
|
||||
case SDL_JOYAXISMOTION:
|
||||
|
@ -3,10 +3,10 @@
|
||||
|
||||
// Input types.
|
||||
typedef enum {
|
||||
KEYBIND_NULL,
|
||||
KEYBIND_KEYBOARD,
|
||||
KEYBIND_JAXIS,
|
||||
KEYBIND_JBUTTON
|
||||
KEYBIND_NULL,
|
||||
KEYBIND_KEYBOARD,
|
||||
KEYBIND_JAXIS,
|
||||
KEYBIND_JBUTTON
|
||||
} KeybindType;
|
||||
|
||||
// Set input.
|
||||
|
@ -20,7 +20,7 @@ int joystick_get(char* namjoystick) {
|
||||
int joystick_use(int indjoystick) {
|
||||
if(indjoystick < 0 || indjoystick >= SDL_NumJoysticks()) {
|
||||
WARN("Joystick of index number %d does not exist. Switching to default (0)",
|
||||
indjoystick);
|
||||
indjoystick);
|
||||
indjoystick = 0;
|
||||
}
|
||||
if(joystick)
|
||||
@ -31,7 +31,7 @@ int joystick_use(int indjoystick) {
|
||||
joystick = SDL_JoystickOpen(indjoystick);
|
||||
if(joystick == NULL) {
|
||||
WARN("Error opening joystick %d [%s]",
|
||||
indjoystick, SDL_JoystickName(indjoystick));
|
||||
indjoystick, SDL_JoystickName(indjoystick));
|
||||
return -1;
|
||||
}
|
||||
DEBUG("\t\tWith %d axes, %d buttons, %d balls, and %d hats",
|
||||
|
596
src/land.c
596
src/land.c
@ -18,12 +18,12 @@
|
||||
#define COMMODITY_HEIGHT 400
|
||||
|
||||
// Outfits.
|
||||
#define OUTFITS_WIDTH 700
|
||||
#define OUTFITS_HEIGHT 600
|
||||
#define OUTFITS_WIDTH 700
|
||||
#define OUTFITS_HEIGHT 600
|
||||
|
||||
// Shipyard.
|
||||
#define SHIPYARD_WIDTH 700
|
||||
#define SHIPYARD_HEIGHT 600
|
||||
#define SHIPYARD_WIDTH 700
|
||||
#define SHIPYARD_HEIGHT 600
|
||||
|
||||
// News window.
|
||||
#define NEWS_WIDTH 400
|
||||
@ -33,8 +33,8 @@
|
||||
#define BAR_WIDTH 460
|
||||
#define BAR_HEIGHT 300
|
||||
|
||||
#define MUSIC_TAKEOFF "liftoff"
|
||||
#define MUSIC_LAND "agriculture"
|
||||
#define MUSIC_TAKEOFF "liftoff"
|
||||
#define MUSIC_LAND "agriculture"
|
||||
|
||||
int landed = 0;
|
||||
|
||||
@ -55,7 +55,7 @@ static void outfits_close(char* str);
|
||||
static void outfits_update(char* str);
|
||||
static void outfits_buy(char* str);
|
||||
static void outfits_sell(char* str);
|
||||
static int outfits_getMod(void);
|
||||
static int outfits_getMod(void);
|
||||
static void outfits_renderMod(double bx, double by, double w, double h);
|
||||
// Shipyard.
|
||||
static void shipyard(void);
|
||||
@ -72,43 +72,43 @@ static void news_close(char* str);
|
||||
|
||||
// The local market.
|
||||
static void commodity_exchange(void) {
|
||||
int i;
|
||||
char** goods;
|
||||
int i;
|
||||
char** goods;
|
||||
secondary_wid = window_create("Commodity Exchange", -1, -1,
|
||||
COMMODITY_WIDTH, COMMODITY_HEIGHT);
|
||||
COMMODITY_WIDTH, COMMODITY_HEIGHT);
|
||||
|
||||
window_addButton(secondary_wid, -20, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnCommodityClose",
|
||||
"Close", commodity_exchange_close);
|
||||
|
||||
window_addButton(secondary_wid, -40-((BUTTON_WIDTH-20)/2), 20*2+BUTTON_HEIGHT,
|
||||
(BUTTON_WIDTH-20)/2, BUTTON_HEIGHT, "btnCommodityBuy",
|
||||
"Buy", commodity_buy);
|
||||
window_addButton(secondary_wid, -40-((BUTTON_WIDTH-20)/2), 20*2+BUTTON_HEIGHT,
|
||||
(BUTTON_WIDTH-20)/2, BUTTON_HEIGHT, "btnCommodityBuy",
|
||||
"Buy", commodity_buy);
|
||||
|
||||
window_addButton(secondary_wid, -20, 20*2+BUTTON_HEIGHT,
|
||||
(BUTTON_WIDTH-20)/2, BUTTON_HEIGHT, "btnCommoditySell",
|
||||
"Sell", commodity_sell);
|
||||
window_addButton(secondary_wid, -20, 20*2+BUTTON_HEIGHT,
|
||||
(BUTTON_WIDTH-20)/2, BUTTON_HEIGHT, "btnCommoditySell",
|
||||
"Sell", commodity_sell);
|
||||
|
||||
window_addText(secondary_wid, -20, -40, BUTTON_WIDTH, 20, 0,
|
||||
"txtSInfo", &gl_smallFont, &cDConsole,
|
||||
"You have:\n"
|
||||
"Market price:\n");
|
||||
window_addText(secondary_wid, -20, -40, BUTTON_WIDTH, 20, 0,
|
||||
"txtSInfo", &gl_smallFont, &cDConsole,
|
||||
"You have:\n"
|
||||
"Market price:\n");
|
||||
|
||||
window_addText(secondary_wid, -20, -40, BUTTON_WIDTH/2, 20, 0,
|
||||
"txtDInfo", &gl_smallFont, &cBlack, NULL);
|
||||
window_addText(secondary_wid, -20, -40, BUTTON_WIDTH/2, 20, 0,
|
||||
"txtDInfo", &gl_smallFont, &cBlack, NULL);
|
||||
|
||||
window_addText(secondary_wid, -40, -80, BUTTON_WIDTH-20,
|
||||
BUTTON_WIDTH, 0, "txtDesc", &gl_smallFont, &cBlack, NULL);
|
||||
window_addText(secondary_wid, -40, -80, BUTTON_WIDTH-20,
|
||||
BUTTON_WIDTH, 0, "txtDesc", &gl_smallFont, &cBlack, NULL);
|
||||
|
||||
goods = malloc(sizeof(char*)*planet->ncommodities);
|
||||
for(i = 0; i < planet->ncommodities; i++)
|
||||
goods[i] = strdup(planet->commodities[i]->name);
|
||||
goods = malloc(sizeof(char*)*planet->ncommodities);
|
||||
for(i = 0; i < planet->ncommodities; i++)
|
||||
goods[i] = strdup(planet->commodities[i]->name);
|
||||
|
||||
window_addList(secondary_wid, 20, -40,
|
||||
COMMODITY_WIDTH-BUTTON_WIDTH-60, COMMODITY_HEIGHT-80-BUTTON_HEIGHT,
|
||||
"lstGoods", goods, planet->ncommodities, 0, commodity_update);
|
||||
window_addList(secondary_wid, 20, -40,
|
||||
COMMODITY_WIDTH-BUTTON_WIDTH-60, COMMODITY_HEIGHT-80-BUTTON_HEIGHT,
|
||||
"lstGoods", goods, planet->ncommodities, 0, commodity_update);
|
||||
|
||||
commodity_update(NULL);
|
||||
commodity_update(NULL);
|
||||
}
|
||||
|
||||
static void commodity_exchange_close(char* str) {
|
||||
@ -117,356 +117,356 @@ static void commodity_exchange_close(char* str) {
|
||||
}
|
||||
|
||||
static void commodity_update(char* str) {
|
||||
(void)str;
|
||||
char buf[128];
|
||||
char* comname;
|
||||
Commodity* com;
|
||||
(void)str;
|
||||
char buf[128];
|
||||
char* comname;
|
||||
Commodity* com;
|
||||
|
||||
comname = toolkit_getList(secondary_wid, "lstGoods");
|
||||
com = commodity_get(comname);
|
||||
comname = toolkit_getList(secondary_wid, "lstGoods");
|
||||
com = commodity_get(comname);
|
||||
|
||||
snprintf(buf, 128,
|
||||
"%d\n"
|
||||
"%d Screds/ton\n",
|
||||
player_cargoOwned(comname),
|
||||
com->medium);
|
||||
snprintf(buf, 128,
|
||||
"%d\n"
|
||||
"%d Screds/ton\n",
|
||||
player_cargoOwned(comname),
|
||||
com->medium);
|
||||
|
||||
window_modifyText(secondary_wid, "txtDInfo", buf);
|
||||
window_modifyText(secondary_wid, "txtDesc", com->description);
|
||||
window_modifyText(secondary_wid, "txtDInfo", buf);
|
||||
window_modifyText(secondary_wid, "txtDesc", com->description);
|
||||
}
|
||||
|
||||
static void commodity_buy(char* str) {
|
||||
(void)str;
|
||||
char* comname;
|
||||
Commodity* com;
|
||||
int q;
|
||||
(void)str;
|
||||
char* comname;
|
||||
Commodity* com;
|
||||
int q;
|
||||
|
||||
q = 10;
|
||||
q = 10;
|
||||
|
||||
comname = toolkit_getList(secondary_wid, "lstGoods");
|
||||
com = commodity_get(comname);
|
||||
comname = toolkit_getList(secondary_wid, "lstGoods");
|
||||
com = commodity_get(comname);
|
||||
|
||||
if(player_credits <= q * com->medium) {
|
||||
toolkit_alert("Not enough Scred!");
|
||||
return;
|
||||
}
|
||||
else if(player->cargo_free <= 0) {
|
||||
toolkit_alert("not enough free space!");
|
||||
return;
|
||||
}
|
||||
if(player_credits <= q * com->medium) {
|
||||
toolkit_alert("Not enough Scred!");
|
||||
return;
|
||||
}
|
||||
else if(player->cargo_free <= 0) {
|
||||
toolkit_alert("not enough free space!");
|
||||
return;
|
||||
}
|
||||
|
||||
q = pilot_addCargo(player, com, q);
|
||||
player_credits -= q * com->medium;
|
||||
commodity_update(NULL);
|
||||
q = pilot_addCargo(player, com, q);
|
||||
player_credits -= q * com->medium;
|
||||
commodity_update(NULL);
|
||||
}
|
||||
|
||||
static void commodity_sell(char* str) {
|
||||
(void)str;
|
||||
char* comname;
|
||||
Commodity* com;
|
||||
int q;
|
||||
(void)str;
|
||||
char* comname;
|
||||
Commodity* com;
|
||||
int q;
|
||||
|
||||
q = 10;
|
||||
comname = toolkit_getList(secondary_wid, "lstGoods");
|
||||
com = commodity_get(comname);
|
||||
q = 10;
|
||||
comname = toolkit_getList(secondary_wid, "lstGoods");
|
||||
com = commodity_get(comname);
|
||||
|
||||
q = pilot_rmCargo(player, com, q);
|
||||
player_credits += q * com->medium;
|
||||
commodity_update(NULL);
|
||||
q = pilot_rmCargo(player, com, q);
|
||||
player_credits += q * com->medium;
|
||||
commodity_update(NULL);
|
||||
}
|
||||
|
||||
static void outfits(void) {
|
||||
char** outfits;
|
||||
int noutfits;
|
||||
char buf[128];
|
||||
char** outfits;
|
||||
int noutfits;
|
||||
char buf[128];
|
||||
|
||||
snprintf(buf, 128, "%s - Outfits", planet->name);
|
||||
secondary_wid = window_create(buf, -1, -1,
|
||||
OUTFITS_WIDTH, OUTFITS_HEIGHT);
|
||||
snprintf(buf, 128, "%s - Outfits", planet->name);
|
||||
secondary_wid = window_create(buf, -1, -1,
|
||||
OUTFITS_WIDTH, OUTFITS_HEIGHT);
|
||||
|
||||
window_addButton(secondary_wid, -20, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnCloseOutfits",
|
||||
"Close", outfits_close);
|
||||
window_addButton(secondary_wid, -20, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnCloseOutfits",
|
||||
"Close", outfits_close);
|
||||
|
||||
window_addButton(secondary_wid, -40-BUTTON_WIDTH, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnBuyOutfits",
|
||||
"Buy", outfits_buy);
|
||||
window_addButton(secondary_wid, -40-BUTTON_WIDTH, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnBuyOutfits",
|
||||
"Buy", outfits_buy);
|
||||
|
||||
window_addButton(secondary_wid, -40-BUTTON_WIDTH, 40+BUTTON_HEIGHT,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnSellOutfit",
|
||||
"Sell", outfits_sell);
|
||||
window_addButton(secondary_wid, -40-BUTTON_WIDTH, 40+BUTTON_HEIGHT,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnSellOutfit",
|
||||
"Sell", outfits_sell);
|
||||
|
||||
// Fancy 128x128 image.
|
||||
window_addRect(secondary_wid, -20, -50, 128, 128, "rctImage", &cBlack, 0);
|
||||
window_addImage(secondary_wid, -20-128, -50-128, "imgOutfit", NULL);
|
||||
// Fancy 128x128 image.
|
||||
window_addRect(secondary_wid, -20, -50, 128, 128, "rctImage", &cBlack, 0);
|
||||
window_addImage(secondary_wid, -20-128, -50-128, "imgOutfit", NULL);
|
||||
|
||||
window_addCust(secondary_wid, -40-BUTTON_WIDTH, 60+2*BUTTON_HEIGHT,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "cstMod", 0, outfits_renderMod, NULL);
|
||||
window_addCust(secondary_wid, -40-BUTTON_WIDTH, 60+2*BUTTON_HEIGHT,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "cstMod", 0, outfits_renderMod, NULL);
|
||||
|
||||
window_addText(secondary_wid, 40+200+20, -60,
|
||||
80, 96, 0, "txtSDesc", &gl_smallFont, &cDConsole,
|
||||
"Name:\n"
|
||||
"Type:\n"
|
||||
"Owned:\n"
|
||||
"\n"
|
||||
"Space taken:\n"
|
||||
"Free Space:\n"
|
||||
"\n"
|
||||
"Price:\n"
|
||||
"Money:\n");
|
||||
window_addText(secondary_wid, 40+200+20, -60,
|
||||
80, 96, 0, "txtSDesc", &gl_smallFont, &cDConsole,
|
||||
"Name:\n"
|
||||
"Type:\n"
|
||||
"Owned:\n"
|
||||
"\n"
|
||||
"Space taken:\n"
|
||||
"Free Space:\n"
|
||||
"\n"
|
||||
"Price:\n"
|
||||
"Money:\n");
|
||||
|
||||
window_addText(secondary_wid, 40+200+40+60, -60,
|
||||
250, 96, 0, "txtDDesc", &gl_smallFont, &cBlack, NULL);
|
||||
window_addText(secondary_wid, 40+200+40+60, -60,
|
||||
250, 96, 0, "txtDDesc", &gl_smallFont, &cBlack, NULL);
|
||||
|
||||
window_addText(secondary_wid, 20+200+40, -200,
|
||||
OUTFITS_WIDTH-300, 200, 0, "txtDescription",
|
||||
&gl_smallFont, NULL, NULL);
|
||||
window_addText(secondary_wid, 20+200+40, -200,
|
||||
OUTFITS_WIDTH-300, 200, 0, "txtDescription",
|
||||
&gl_smallFont, NULL, NULL);
|
||||
|
||||
// Set up the outfits to buy/sell.
|
||||
outfits = outfit_getTech(&noutfits, planet->tech, PLANET_TECH_MAX);
|
||||
window_addList(secondary_wid, 20, 40,
|
||||
200, OUTFITS_HEIGHT-80, "lstOutfits",
|
||||
outfits, noutfits, 0, outfits_update);
|
||||
// Set up the outfits to buy/sell.
|
||||
outfits = outfit_getTech(&noutfits, planet->tech, PLANET_TECH_MAX);
|
||||
window_addList(secondary_wid, 20, 40,
|
||||
200, OUTFITS_HEIGHT-80, "lstOutfits",
|
||||
outfits, noutfits, 0, outfits_update);
|
||||
|
||||
// Write the outfits stuff.
|
||||
outfits_update(NULL);
|
||||
// Write the outfits stuff.
|
||||
outfits_update(NULL);
|
||||
}
|
||||
|
||||
static void outfits_close(char* str) {
|
||||
if(strcmp(str, "btnCloseOutfits")==0)
|
||||
window_destroy(secondary_wid);
|
||||
if(strcmp(str, "btnCloseOutfits")==0)
|
||||
window_destroy(secondary_wid);
|
||||
}
|
||||
|
||||
static void outfits_update(char* str) {
|
||||
(void)str;
|
||||
char* outfitname;
|
||||
Outfit* outfit;
|
||||
char buf[80], buf2[16], buf3[16];
|
||||
(void)str;
|
||||
char* outfitname;
|
||||
Outfit* outfit;
|
||||
char buf[80], buf2[16], buf3[16];
|
||||
|
||||
outfitname = toolkit_getList(secondary_wid, "lstOutfits");
|
||||
outfit = outfit_get(outfitname);
|
||||
outfitname = toolkit_getList(secondary_wid, "lstOutfits");
|
||||
outfit = outfit_get(outfitname);
|
||||
|
||||
window_modifyImage(secondary_wid, "imgOutfit", outfit->gfx_store);
|
||||
window_modifyImage(secondary_wid, "imgOutfit", outfit->gfx_store);
|
||||
|
||||
window_modifyText(secondary_wid, "txtDescription", outfit->description);
|
||||
credits2str(buf2, outfit->price, 2);
|
||||
credits2str(buf3, player_credits, 2);
|
||||
snprintf(buf, 80,
|
||||
"%s\n"
|
||||
"%s\n"
|
||||
"%d\n"
|
||||
"\n"
|
||||
"%d\n"
|
||||
"%d\n"
|
||||
"\n"
|
||||
"%s SCred\n"
|
||||
"%s SCred\n",
|
||||
outfit->name,
|
||||
outfit_getType(outfit),
|
||||
player_outfitOwned(outfitname),
|
||||
outfit->mass,
|
||||
player_freeSpace(),
|
||||
buf2,
|
||||
buf3);
|
||||
window_modifyText(secondary_wid, "txtDescription", outfit->description);
|
||||
credits2str(buf2, outfit->price, 2);
|
||||
credits2str(buf3, player_credits, 2);
|
||||
snprintf(buf, 80,
|
||||
"%s\n"
|
||||
"%s\n"
|
||||
"%d\n"
|
||||
"\n"
|
||||
"%d\n"
|
||||
"%d\n"
|
||||
"\n"
|
||||
"%s SCred\n"
|
||||
"%s SCred\n",
|
||||
outfit->name,
|
||||
outfit_getType(outfit),
|
||||
player_outfitOwned(outfitname),
|
||||
outfit->mass,
|
||||
player_freeSpace(),
|
||||
buf2,
|
||||
buf3);
|
||||
|
||||
window_modifyText(secondary_wid, "txtDDesc", buf);
|
||||
window_modifyText(secondary_wid, "txtDDesc", buf);
|
||||
}
|
||||
|
||||
static void outfits_buy(char* str) {
|
||||
(void)str;
|
||||
char* outfitname;
|
||||
Outfit* outfit;
|
||||
int q;
|
||||
char buf[16];
|
||||
(void)str;
|
||||
char* outfitname;
|
||||
Outfit* outfit;
|
||||
int q;
|
||||
char buf[16];
|
||||
|
||||
outfitname = toolkit_getList(secondary_wid, "lstOutfits");
|
||||
outfit = outfit_get(outfitname);
|
||||
outfitname = toolkit_getList(secondary_wid, "lstOutfits");
|
||||
outfit = outfit_get(outfitname);
|
||||
|
||||
q = outfits_getMod();
|
||||
q = outfits_getMod();
|
||||
|
||||
// Can player actually fit the outfit?
|
||||
if((player_freeSpace() - outfit->mass) < 0) {
|
||||
toolkit_alert("No enough free space (you need %d more slots).",
|
||||
outfit->mass - player_freeSpace());
|
||||
return;
|
||||
}
|
||||
else if(player_outfitOwned(outfitname) >= outfit->max) {
|
||||
// Already has too many.
|
||||
toolkit_alert("You can only carry %d of this outfit.", outfit->max);
|
||||
return;
|
||||
}
|
||||
else if(outfit_isAfterburner(outfit) && (player->afterburner != NULL)) {
|
||||
toolkit_alert("You can only have one afterburner.");
|
||||
return;
|
||||
}
|
||||
// Not enough $$.
|
||||
else if(q*(int)outfit->price >= player_credits) {
|
||||
credits2str(buf, q*outfit->price - player_credits, 2);
|
||||
toolkit_alert("You need %s more SCred.", buf);
|
||||
return;
|
||||
}
|
||||
// Can player actually fit the outfit?
|
||||
if((player_freeSpace() - outfit->mass) < 0) {
|
||||
toolkit_alert("No enough free space (you need %d more slots).",
|
||||
outfit->mass - player_freeSpace());
|
||||
return;
|
||||
}
|
||||
else if(player_outfitOwned(outfitname) >= outfit->max) {
|
||||
// Already has too many.
|
||||
toolkit_alert("You can only carry %d of this outfit.", outfit->max);
|
||||
return;
|
||||
}
|
||||
else if(outfit_isAfterburner(outfit) && (player->afterburner != NULL)) {
|
||||
toolkit_alert("You can only have one afterburner.");
|
||||
return;
|
||||
}
|
||||
// Not enough $$.
|
||||
else if(q*(int)outfit->price >= player_credits) {
|
||||
credits2str(buf, q*outfit->price - player_credits, 2);
|
||||
toolkit_alert("You need %s more SCred.", buf);
|
||||
return;
|
||||
}
|
||||
|
||||
player_credits -= outfit->price * pilot_addOutfit(player, outfit,
|
||||
MIN(q, outfit->max));
|
||||
outfits_update(NULL);
|
||||
player_credits -= outfit->price * pilot_addOutfit(player, outfit,
|
||||
MIN(q, outfit->max));
|
||||
outfits_update(NULL);
|
||||
}
|
||||
|
||||
static void outfits_sell(char* str) {
|
||||
(void)str;
|
||||
char* outfitname;
|
||||
Outfit* outfit;
|
||||
int q;
|
||||
(void)str;
|
||||
char* outfitname;
|
||||
Outfit* outfit;
|
||||
int q;
|
||||
|
||||
outfitname = toolkit_getList(secondary_wid, "lstOutfits");
|
||||
outfit = outfit_get(outfitname);
|
||||
outfitname = toolkit_getList(secondary_wid, "lstOutfits");
|
||||
outfit = outfit_get(outfitname);
|
||||
|
||||
q = outfits_getMod();
|
||||
q = outfits_getMod();
|
||||
|
||||
if(player_outfitOwned(outfitname) <= 0) {
|
||||
// No outfits to sell.
|
||||
toolkit_alert("You can't sell something you don't have!");
|
||||
return;
|
||||
}
|
||||
if(player_outfitOwned(outfitname) <= 0) {
|
||||
// No outfits to sell.
|
||||
toolkit_alert("You can't sell something you don't have!");
|
||||
return;
|
||||
}
|
||||
|
||||
player_credits += outfit->price * pilot_rmOutfit(player, outfit, q);
|
||||
outfits_update(NULL);
|
||||
player_credits += outfit->price * pilot_rmOutfit(player, outfit, q);
|
||||
outfits_update(NULL);
|
||||
}
|
||||
|
||||
// Return the current modifier status.
|
||||
static int outfits_getMod(void) {
|
||||
SDLMod mods;
|
||||
int q;
|
||||
SDLMod mods;
|
||||
int q;
|
||||
|
||||
mods = SDL_GetModState();
|
||||
q = 1;
|
||||
if(mods & (KMOD_LCTRL | KMOD_RCTRL)) q *= 5;
|
||||
if(mods & (KMOD_LSHIFT | KMOD_RSHIFT)) q *= 10;
|
||||
mods = SDL_GetModState();
|
||||
q = 1;
|
||||
if(mods & (KMOD_LCTRL | KMOD_RCTRL)) q *= 5;
|
||||
if(mods & (KMOD_LSHIFT | KMOD_RSHIFT)) q *= 10;
|
||||
|
||||
return q;
|
||||
return q;
|
||||
}
|
||||
|
||||
static void outfits_renderMod(double bx, double by, double w, double h) {
|
||||
(void) h;
|
||||
int q;
|
||||
char buf[8];
|
||||
(void) h;
|
||||
int q;
|
||||
char buf[8];
|
||||
|
||||
q = outfits_getMod();
|
||||
if(q == 1) return;
|
||||
q = outfits_getMod();
|
||||
if(q == 1) return;
|
||||
|
||||
snprintf(buf, 8, "%dx", q);
|
||||
gl_printMid(&gl_smallFont, w,
|
||||
bx + (double)gl_screen.w/2.,
|
||||
by + (double)gl_screen.h/2.,
|
||||
&cBlack, buf);
|
||||
snprintf(buf, 8, "%dx", q);
|
||||
gl_printMid(&gl_smallFont, w,
|
||||
bx + (double)gl_screen.w/2.,
|
||||
by + (double)gl_screen.h/2.,
|
||||
&cBlack, buf);
|
||||
}
|
||||
|
||||
static void shipyard(void) {
|
||||
char** ships;
|
||||
int nships;
|
||||
char buf[128];
|
||||
char** ships;
|
||||
int nships;
|
||||
char buf[128];
|
||||
|
||||
snprintf(buf, 128, "%s - Shipyard", planet->name);
|
||||
secondary_wid = window_create(buf,
|
||||
-1, -1, SHIPYARD_WIDTH, SHIPYARD_HEIGHT);
|
||||
snprintf(buf, 128, "%s - Shipyard", planet->name);
|
||||
secondary_wid = window_create(buf,
|
||||
-1, -1, SHIPYARD_WIDTH, SHIPYARD_HEIGHT);
|
||||
|
||||
window_addButton(secondary_wid, -20, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnCloseShipyard",
|
||||
"Close", shipyard_close);
|
||||
window_addButton(secondary_wid, -20, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnCloseShipyard",
|
||||
"Close", shipyard_close);
|
||||
|
||||
window_addButton(secondary_wid, -40-BUTTON_WIDTH, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnBuyShip",
|
||||
"Buy", shipyard_buy);
|
||||
window_addButton(secondary_wid, -40-BUTTON_WIDTH, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnBuyShip",
|
||||
"Buy", shipyard_buy);
|
||||
|
||||
window_addButton(secondary_wid, -40-BUTTON_WIDTH, 40+BUTTON_HEIGHT,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnInfoShip",
|
||||
"Info", shipyard_info);
|
||||
window_addButton(secondary_wid, -40-BUTTON_WIDTH, 40+BUTTON_HEIGHT,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnInfoShip",
|
||||
"Info", shipyard_info);
|
||||
|
||||
window_addRect(secondary_wid, -40, -50,
|
||||
128, 96, "rctTarget", &cBlack, 0);
|
||||
window_addRect(secondary_wid, -40, -50,
|
||||
128, 96, "rctTarget", &cBlack, 0);
|
||||
|
||||
window_addImage(secondary_wid, -40-128, -50-96,
|
||||
"imgTarget", NULL);
|
||||
window_addImage(secondary_wid, -40-128, -50-96,
|
||||
"imgTarget", NULL);
|
||||
|
||||
window_addText(secondary_wid, 40+200+40, -55,
|
||||
80, 96, 0, "txtSDesc", &gl_smallFont, &cDConsole,
|
||||
"Name:\n"
|
||||
"Class:\n"
|
||||
"Fabricator:\n"
|
||||
"\n"
|
||||
"Price:\n"
|
||||
"Money:\n");
|
||||
window_addText(secondary_wid, 40+200+40, -55,
|
||||
80, 96, 0, "txtSDesc", &gl_smallFont, &cDConsole,
|
||||
"Name:\n"
|
||||
"Class:\n"
|
||||
"Fabricator:\n"
|
||||
"\n"
|
||||
"Price:\n"
|
||||
"Money:\n");
|
||||
|
||||
window_addText(secondary_wid, 40+200+40+80, -55,
|
||||
130, 96, 0, "txtDDesc", &gl_smallFont, &cBlack, NULL);
|
||||
window_addText(secondary_wid, 40+200+40+80, -55,
|
||||
130, 96, 0, "txtDDesc", &gl_smallFont, &cBlack, NULL);
|
||||
|
||||
|
||||
window_addText(secondary_wid, 20+200+40, -160,
|
||||
SHIPYARD_WIDTH-300, 200, 0, "txtDescription",
|
||||
&gl_smallFont, NULL, NULL);
|
||||
window_addText(secondary_wid, 20+200+40, -160,
|
||||
SHIPYARD_WIDTH-300, 200, 0, "txtDescription",
|
||||
&gl_smallFont, NULL, NULL);
|
||||
|
||||
// Setup the ships to buy/sell.
|
||||
ships = ship_getTech(&nships, planet->tech, PLANET_TECH_MAX);
|
||||
window_addList(secondary_wid, 20, 40,
|
||||
200, SHIPYARD_HEIGHT-80, "lstShipyard",
|
||||
ships, nships, 0, shipyard_update);
|
||||
// Setup the ships to buy/sell.
|
||||
ships = ship_getTech(&nships, planet->tech, PLANET_TECH_MAX);
|
||||
window_addList(secondary_wid, 20, 40,
|
||||
200, SHIPYARD_HEIGHT-80, "lstShipyard",
|
||||
ships, nships, 0, shipyard_update);
|
||||
|
||||
// Write the shipyard stuff.
|
||||
shipyard_update(NULL);
|
||||
// Write the shipyard stuff.
|
||||
shipyard_update(NULL);
|
||||
}
|
||||
|
||||
static void shipyard_close(char* str) {
|
||||
if(strcmp(str, "btnCloseShipyard")==0)
|
||||
window_destroy(secondary_wid);
|
||||
if(strcmp(str, "btnCloseShipyard")==0)
|
||||
window_destroy(secondary_wid);
|
||||
}
|
||||
|
||||
static void shipyard_update(char* str) {
|
||||
(void)str;
|
||||
char* shipname;
|
||||
Ship* ship;
|
||||
char buf[80], buf2[16], buf3[16];
|
||||
(void)str;
|
||||
char* shipname;
|
||||
Ship* ship;
|
||||
char buf[80], buf2[16], buf3[16];
|
||||
|
||||
shipname = toolkit_getList(secondary_wid, "lstShipyard");
|
||||
ship = ship_get(shipname);
|
||||
shipname = toolkit_getList(secondary_wid, "lstShipyard");
|
||||
ship = ship_get(shipname);
|
||||
|
||||
window_modifyText(secondary_wid, "txtDescription", ship->description);
|
||||
window_modifyImage(secondary_wid, "imgTarget", ship->gfx_target);
|
||||
window_modifyText(secondary_wid, "txtDescription", ship->description);
|
||||
window_modifyImage(secondary_wid, "imgTarget", ship->gfx_target);
|
||||
|
||||
credits2str(buf2, ship->price, 2);
|
||||
credits2str(buf3, player_credits, 2);
|
||||
snprintf(buf, 80,
|
||||
"%s\n"
|
||||
"%s\n"
|
||||
"%s\n"
|
||||
"\n"
|
||||
"%s SCred\n"
|
||||
"%s SCred\n",
|
||||
ship->name,
|
||||
ship_class(ship),
|
||||
ship->fabricator,
|
||||
buf2,
|
||||
buf3);
|
||||
credits2str(buf2, ship->price, 2);
|
||||
credits2str(buf3, player_credits, 2);
|
||||
snprintf(buf, 80,
|
||||
"%s\n"
|
||||
"%s\n"
|
||||
"%s\n"
|
||||
"\n"
|
||||
"%s SCred\n"
|
||||
"%s SCred\n",
|
||||
ship->name,
|
||||
ship_class(ship),
|
||||
ship->fabricator,
|
||||
buf2,
|
||||
buf3);
|
||||
|
||||
window_modifyText(secondary_wid, "txtDDesc", buf);
|
||||
window_modifyText(secondary_wid, "txtDDesc", buf);
|
||||
|
||||
}
|
||||
|
||||
static void shipyard_info(char* str) {
|
||||
(void)str;
|
||||
char* shipname;
|
||||
(void)str;
|
||||
char* shipname;
|
||||
|
||||
shipname = toolkit_getList(secondary_wid, "lstShipyard");
|
||||
ship_view(shipname);
|
||||
shipname = toolkit_getList(secondary_wid, "lstShipyard");
|
||||
ship_view(shipname);
|
||||
}
|
||||
|
||||
static void shipyard_buy(char* str) {
|
||||
(void)str;
|
||||
char* shipname;
|
||||
Ship* ship;
|
||||
(void)str;
|
||||
char* shipname;
|
||||
Ship* ship;
|
||||
|
||||
shipname = toolkit_getList(secondary_wid, "lstShipyard");
|
||||
ship = ship_get(shipname);
|
||||
shipname = toolkit_getList(secondary_wid, "lstShipyard");
|
||||
ship = ship_get(shipname);
|
||||
|
||||
player_newShip(ship);
|
||||
player_newShip(ship);
|
||||
}
|
||||
|
||||
// Spaceport bar.
|
||||
@ -480,9 +480,9 @@ static void spaceport_bar(void) {
|
||||
window_addButton(secondary_wid, -20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnCloseBar", "Close", spaceport_bar_close);
|
||||
|
||||
window_addButton(secondary_wid, 20, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnNews",
|
||||
"News", (void(*)(char*))news);
|
||||
window_addButton(secondary_wid, 20, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnNews",
|
||||
"News", (void(*)(char*))news);
|
||||
|
||||
}
|
||||
static void spaceport_bar_close(char* str) {
|
||||
@ -492,9 +492,9 @@ static void spaceport_bar_close(char* str) {
|
||||
|
||||
// Planet news reports.
|
||||
static void news(void) {
|
||||
unsigned int news_wid;
|
||||
news_wid = window_create("News Reports",
|
||||
-1, -1, NEWS_WIDTH, NEWS_HEIGHT);
|
||||
unsigned int news_wid;
|
||||
news_wid = window_create("News Reports",
|
||||
-1, -1, NEWS_WIDTH, NEWS_HEIGHT);
|
||||
|
||||
window_addText(news_wid, 20, 20 + BUTTON_HEIGHT + 20,
|
||||
NEWS_WIDTH-40, NEWS_HEIGHT - 20 - BUTTON_HEIGHT - 20 - 20 -20,
|
||||
@ -502,7 +502,7 @@ static void news(void) {
|
||||
"News reporters report that they are on strike right now! D:");
|
||||
|
||||
window_addButton(news_wid, -20, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnCloseNews", "Close", news_close);
|
||||
}
|
||||
|
||||
@ -515,9 +515,9 @@ static void news_close(char* str) {
|
||||
void land(Planet* p) {
|
||||
if(landed) return;
|
||||
|
||||
// Change music.
|
||||
music_load(MUSIC_LAND);
|
||||
music_play();
|
||||
// Change music.
|
||||
music_load(MUSIC_LAND);
|
||||
music_play();
|
||||
|
||||
planet = p;
|
||||
land_wid = window_create(p->name, -1, -1, LAND_WIDTH, LAND_HEIGHT);
|
||||
@ -552,7 +552,7 @@ void land(Planet* p) {
|
||||
window_addButton(land_wid, 20, 20 + BUTTON_HEIGHT + 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT, "btnBar",
|
||||
"Spaceport Bar", (void(*)(char*))spaceport_bar);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
landed = 1;
|
||||
@ -562,15 +562,15 @@ void land(Planet* p) {
|
||||
void takeoff(void) {
|
||||
if(!landed) return;
|
||||
|
||||
music_load(MUSIC_TAKEOFF);
|
||||
music_play();
|
||||
music_load(MUSIC_TAKEOFF);
|
||||
music_play();
|
||||
|
||||
int sw, sh;
|
||||
sw = planet->gfx_space->w;
|
||||
sh = planet->gfx_space->h;
|
||||
|
||||
// No longer authorized to land.
|
||||
player_rmFlag(PLAYER_LANDACK);
|
||||
// No longer authorized to land.
|
||||
player_rmFlag(PLAYER_LANDACK);
|
||||
|
||||
// Set player to another position with random facing direction and no velocity.
|
||||
player_warp(planet->pos.x + RNG(-sw/2, sw/2), planet->pos.y + RNG(-sh/2, sh/2));
|
||||
@ -580,7 +580,7 @@ void takeoff(void) {
|
||||
// Heal the player.
|
||||
player->armour = player->armour_max;
|
||||
player->shield = player->shield_max;
|
||||
player->energy = player->energy_max;
|
||||
player->energy = player->energy_max;
|
||||
|
||||
space_init(NULL);
|
||||
|
||||
|
@ -65,7 +65,7 @@ static void render_space(void);
|
||||
|
||||
#ifdef WIN32
|
||||
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine,
|
||||
int nCmdShow) {
|
||||
int nCmdShow) {
|
||||
int argc = 0;
|
||||
char *argv[] = { NULL };
|
||||
#else
|
||||
@ -113,14 +113,14 @@ int main(int argc, char** argv) {
|
||||
|
||||
window_caption();
|
||||
|
||||
// OpenAL sound.
|
||||
if(nosound)
|
||||
LOG("Sound is disabled!");
|
||||
else {
|
||||
if(sound_init()) WARN("Problem setting up sound!");
|
||||
music_load("Machina");
|
||||
music_play();
|
||||
}
|
||||
// OpenAL sound.
|
||||
if(nosound)
|
||||
LOG("Sound is disabled!");
|
||||
else {
|
||||
if(sound_init()) WARN("Problem setting up sound!");
|
||||
music_load("Machina");
|
||||
music_play();
|
||||
}
|
||||
|
||||
// Input.
|
||||
if((indjoystick >= 0) || (namjoystick != NULL)) {
|
||||
@ -153,15 +153,15 @@ int main(int argc, char** argv) {
|
||||
toolkit_init(); // Init the toolkit.
|
||||
|
||||
// Data loading.
|
||||
commodity_load();
|
||||
commodity_load();
|
||||
factions_load();
|
||||
spfx_load();
|
||||
spfx_load();
|
||||
outfit_load();
|
||||
ships_load();
|
||||
fleet_load();
|
||||
space_load();
|
||||
|
||||
menu_main();
|
||||
menu_main();
|
||||
|
||||
gtime = SDL_GetTicks(); // Init the time.
|
||||
|
||||
@ -187,17 +187,17 @@ int main(int argc, char** argv) {
|
||||
input_handle(&event); // handles all the events the player keybinds.
|
||||
}
|
||||
|
||||
sound_update(); // Do the sound stuff.
|
||||
sound_update(); // Do the sound stuff.
|
||||
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
|
||||
fps_control(); // Who doesn't love FPS control?
|
||||
toolkit_update(); // Simulate key repetition.
|
||||
toolkit_update(); // Simulate key repetition.
|
||||
|
||||
if(!menu_isOpen(MENU_MAIN)) {
|
||||
if(!paused && !toolkit) update_space(); // Update the game.
|
||||
render_space();
|
||||
}
|
||||
if(!menu_isOpen(MENU_MAIN)) {
|
||||
if(!paused && !toolkit) update_space(); // Update the game.
|
||||
render_space();
|
||||
}
|
||||
|
||||
if(toolkit) toolkit_render();
|
||||
|
||||
@ -212,11 +212,11 @@ int main(int argc, char** argv) {
|
||||
fleet_free();
|
||||
ships_free();
|
||||
outfit_free();
|
||||
spfx_free(); // Remove the special effects.
|
||||
spfx_free(); // Remove the special effects.
|
||||
factions_free();
|
||||
commodity_free();
|
||||
commodity_free();
|
||||
gl_freeFont(NULL);
|
||||
gl_freeFont(&gl_smallFont);
|
||||
gl_freeFont(&gl_smallFont);
|
||||
|
||||
// Exit subsystems.
|
||||
toolkit_exit(); // Kill the toolkit.
|
||||
@ -224,8 +224,8 @@ int main(int argc, char** argv) {
|
||||
joystick_exit(); // Release joystick.
|
||||
input_exit(); // Clean up keybindings.
|
||||
gl_exit(); // Kills video output.
|
||||
sound_exit(); // Kills the sound.
|
||||
SDL_Quit(); // Quits SDL.
|
||||
sound_exit(); // Kills the sound.
|
||||
SDL_Quit(); // Quits SDL.
|
||||
|
||||
// All is good.
|
||||
exit(EXIT_SUCCESS);
|
||||
@ -251,14 +251,14 @@ static void fps_control(void) {
|
||||
|
||||
// Update the game.
|
||||
static void update_space(void) {
|
||||
if(dt > 1./30.) {
|
||||
// Slow timers down and re-run calculations.
|
||||
pause_delay((unsigned int)dt*1000.);
|
||||
return;
|
||||
}
|
||||
space_update(dt);
|
||||
if(dt > 1./30.) {
|
||||
// Slow timers down and re-run calculations.
|
||||
pause_delay((unsigned int)dt*1000.);
|
||||
return;
|
||||
}
|
||||
space_update(dt);
|
||||
weapons_update(dt);
|
||||
spfx_update(dt);
|
||||
spfx_update(dt);
|
||||
pilots_update(dt);
|
||||
}
|
||||
|
||||
@ -287,10 +287,10 @@ static void render_space(void) {
|
||||
// N.
|
||||
pilots_render();
|
||||
weapons_render(WEAPON_LAYER_FG);
|
||||
spfx_render(SPFX_LAYER_BACK);
|
||||
spfx_render(SPFX_LAYER_BACK);
|
||||
// FG.
|
||||
player_render();
|
||||
spfx_render(SPFX_LAYER_FRONT);
|
||||
spfx_render(SPFX_LAYER_FRONT);
|
||||
display_fps(dt);
|
||||
}
|
||||
|
||||
|
@ -5,12 +5,12 @@
|
||||
#define MALLOC_L(type)(malloc(sizeof(type)))
|
||||
#define CALLOC_L(type)(calloc(1, sizeof(type)))
|
||||
|
||||
#define ABS(x) (((x)<0)?-(x):(x))
|
||||
#define ABS(x) (((x)<0)?-(x):(x))
|
||||
|
||||
#define MAX(x,y) (((x)>(y))?(x):(y))
|
||||
#define MIN(x,y) (((x)>(y))?(y):(x))
|
||||
|
||||
#define pow2(x) ((x)*(x))
|
||||
#define pow2(x) ((x)*(x))
|
||||
|
||||
#define DATA_DEF "data" // Default data packfile.
|
||||
extern char* data; // Modifiable datafile.
|
||||
|
@ -4,7 +4,7 @@
|
||||
#define LOG(str, args...)(fprintf(stdout, str"\n", ## args))
|
||||
#define WARN(str, args...)(fprintf(stderr, "Warning: "str"\n", ## args))
|
||||
#define ERR(str, args...) (fprintf(stderr, "ERROR %s:%d: "str"\n", \
|
||||
__FILE__, __LINE__, ## args))
|
||||
__FILE__, __LINE__, ## args))
|
||||
|
||||
#ifdef DEBUG
|
||||
# undef DEBUG
|
||||
|
388
src/map.c
388
src/map.c
@ -5,19 +5,19 @@
|
||||
#include "opengl.h"
|
||||
#include "map.h"
|
||||
|
||||
#define WINDOW_WIDTH 550
|
||||
#define WINDOW_HEIGHT 440
|
||||
#define WINDOW_WIDTH 550
|
||||
#define WINDOW_HEIGHT 440
|
||||
|
||||
#define MAP_WIDTH (WINDOW_WIDTH-150)
|
||||
#define MAP_HEIGHT (WINDOW_HEIGHT-100)
|
||||
#define MAP_WIDTH (WINDOW_WIDTH-150)
|
||||
#define MAP_HEIGHT (WINDOW_HEIGHT-100)
|
||||
|
||||
#define BUTTON_WIDTH 60
|
||||
#define BUTTON_HEIGHT 40
|
||||
#define BUTTON_WIDTH 60
|
||||
#define BUTTON_HEIGHT 40
|
||||
|
||||
static int map_wid = 0;
|
||||
static double map_zoom = 1.; // Zoom of the map.
|
||||
static double map_xpos = 0.; // Map position.
|
||||
static double map_ypos = 0.;
|
||||
static int map_wid = 0;
|
||||
static double map_zoom = 1.; // Zoom of the map.
|
||||
static double map_xpos = 0.; // Map position.
|
||||
static double map_ypos = 0.;
|
||||
static int map_selected = 0;
|
||||
|
||||
static int map_drag = 0; // Is the user dragging the map?
|
||||
@ -38,235 +38,235 @@ static void map_buttonZoom(char* str);
|
||||
|
||||
// Open the map window.
|
||||
void map_open(void) {
|
||||
if(map_wid) {
|
||||
map_close(NULL);
|
||||
return;
|
||||
}
|
||||
if(map_wid) {
|
||||
map_close(NULL);
|
||||
return;
|
||||
}
|
||||
|
||||
// Set the position to focus on current system.
|
||||
map_xpos = cur_system->pos.x;
|
||||
map_ypos = cur_system->pos.y;
|
||||
// Set the position to focus on current system.
|
||||
map_xpos = cur_system->pos.x;
|
||||
map_ypos = cur_system->pos.y;
|
||||
|
||||
map_wid = window_create("Star Map", -1, -1, WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||
map_wid = window_create("Star Map", -1, -1, WINDOW_WIDTH, WINDOW_HEIGHT);
|
||||
|
||||
window_addText(map_wid, -20, -20, 100, 20, 1, "txtSysname",
|
||||
&gl_defFont, &cDConsole, systems_stack[map_selected].name);
|
||||
window_addText(map_wid, -20, -20, 100, 20, 1, "txtSysname",
|
||||
&gl_defFont, &cDConsole, systems_stack[map_selected].name);
|
||||
|
||||
window_addText(map_wid, -20, -60, 90, 20, 0, "txtSFaction",
|
||||
&gl_smallFont, &cDConsole, "Faction:");
|
||||
window_addText(map_wid, -20, -60, 90, 20, 0, "txtSFaction",
|
||||
&gl_smallFont, &cDConsole, "Faction:");
|
||||
|
||||
window_addText(map_wid, -20, -60-gl_smallFont.h-5, 80, 100, 0, "txtFaction",
|
||||
&gl_smallFont, &cBlack, NULL);
|
||||
window_addText(map_wid, -20, -60-gl_smallFont.h-5, 80, 100, 0, "txtFaction",
|
||||
&gl_smallFont, &cBlack, NULL);
|
||||
|
||||
window_addText(map_wid, -20, -110, 90, 20, 0, "txtSPlanets",
|
||||
&gl_smallFont, &cDConsole, "Planets:");
|
||||
window_addText(map_wid, -20, -110, 90, 20, 0, "txtSPlanets",
|
||||
&gl_smallFont, &cDConsole, "Planets:");
|
||||
|
||||
window_addText(map_wid, -20, -110-gl_smallFont.h-5, 80, 100, 0, "txtPlanets",
|
||||
&gl_smallFont, &cBlack, NULL);
|
||||
window_addText(map_wid, -20, -110-gl_smallFont.h-5, 80, 100, 0, "txtPlanets",
|
||||
&gl_smallFont, &cBlack, NULL);
|
||||
|
||||
window_addCust(map_wid, 20, -40, MAP_WIDTH, MAP_HEIGHT,
|
||||
"cstMap", 1, map_render, map_mouse);
|
||||
window_addCust(map_wid, 20, -40, MAP_WIDTH, MAP_HEIGHT,
|
||||
"cstMap", 1, map_render, map_mouse);
|
||||
|
||||
window_addButton(map_wid, -20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnClose", "Close", map_close);
|
||||
window_addButton(map_wid, -20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnClose", "Close", map_close);
|
||||
|
||||
window_addButton(map_wid, 40, 20, 30, 30, "btnZoomIn", "+", map_buttonZoom);
|
||||
window_addButton(map_wid, 80, 20, 30, 30, "btnZoomOut", "-", map_buttonZoom);
|
||||
window_addButton(map_wid, 40, 20, 30, 30, "btnZoomIn", "+", map_buttonZoom);
|
||||
window_addButton(map_wid, 80, 20, 30, 30, "btnZoomOut", "-", map_buttonZoom);
|
||||
|
||||
map_update();
|
||||
map_update();
|
||||
}
|
||||
|
||||
static void map_close(char* str) {
|
||||
(void)str;
|
||||
if(map_wid) {
|
||||
window_destroy(map_wid);
|
||||
map_wid = 0;
|
||||
}
|
||||
(void)str;
|
||||
if(map_wid) {
|
||||
window_destroy(map_wid);
|
||||
map_wid = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void map_update(void) {
|
||||
int i;
|
||||
StarSystem* sys;
|
||||
Faction* f;
|
||||
char buf[100];
|
||||
int i;
|
||||
StarSystem* sys;
|
||||
Faction* f;
|
||||
char buf[100];
|
||||
|
||||
sys = &systems_stack[map_selected];
|
||||
sys = &systems_stack[map_selected];
|
||||
|
||||
window_modifyText(map_wid, "txtSysname", sys->name);
|
||||
window_modifyText(map_wid, "txtSysname", sys->name);
|
||||
|
||||
if(sys->nplanets == 0)
|
||||
// No planets -> no factions.
|
||||
snprintf(buf, 100, "NA");
|
||||
else {
|
||||
f = NULL;
|
||||
for(i = 0; i < sys->nplanets; i++) {
|
||||
if(f == NULL)
|
||||
f = sys->planets[i].faction;
|
||||
else if(f != sys->planets[i].faction) {
|
||||
// TODO: more verbosity.
|
||||
snprintf(buf, 100, "Multiple");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i == sys->nplanets)
|
||||
// Saw them all, and all the same.
|
||||
snprintf(buf, 100, "%s", f->name);
|
||||
}
|
||||
if(sys->nplanets == 0)
|
||||
// No planets -> no factions.
|
||||
snprintf(buf, 100, "NA");
|
||||
else {
|
||||
f = NULL;
|
||||
for(i = 0; i < sys->nplanets; i++) {
|
||||
if(f == NULL)
|
||||
f = sys->planets[i].faction;
|
||||
else if(f != sys->planets[i].faction) {
|
||||
// TODO: more verbosity.
|
||||
snprintf(buf, 100, "Multiple");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(i == sys->nplanets)
|
||||
// Saw them all, and all the same.
|
||||
snprintf(buf, 100, "%s", f->name);
|
||||
}
|
||||
|
||||
window_modifyText(map_wid, "txtFaction", buf);
|
||||
window_modifyText(map_wid, "txtFaction", buf);
|
||||
|
||||
buf[0] = '\0';
|
||||
if(sys->nplanets == 0)
|
||||
snprintf(buf, 100, "None");
|
||||
else {
|
||||
for(i = 0; i < sys->nplanets; i++) {
|
||||
strcat(buf, sys->planets[i].name);
|
||||
strcat(buf, "\n");
|
||||
}
|
||||
}
|
||||
window_modifyText(map_wid, "txtPlanets", buf);
|
||||
buf[0] = '\0';
|
||||
if(sys->nplanets == 0)
|
||||
snprintf(buf, 100, "None");
|
||||
else {
|
||||
for(i = 0; i < sys->nplanets; i++) {
|
||||
strcat(buf, sys->planets[i].name);
|
||||
strcat(buf, "\n");
|
||||
}
|
||||
}
|
||||
window_modifyText(map_wid, "txtPlanets", buf);
|
||||
}
|
||||
|
||||
// Render the map as a custom widget.
|
||||
static void map_render(double bx, double by, double w, double h) {
|
||||
int i, j;
|
||||
double x, y, r, tx, ty;
|
||||
StarSystem* sys;
|
||||
glColour* col;
|
||||
int i, j;
|
||||
double x, y, r, tx, ty;
|
||||
StarSystem* sys;
|
||||
glColour* col;
|
||||
|
||||
r = 5.;
|
||||
x = (bx - map_xpos + w/2) * 1.; // Map zoom.
|
||||
y = (by - map_ypos + h/2) * 1.; // Map zoom.
|
||||
// Background
|
||||
COLOUR(cBlack);
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2d(bx, by);
|
||||
glVertex2d(bx, by+h);
|
||||
glVertex2d(bx+w, by+h);
|
||||
glVertex2d(bx+w, by);
|
||||
glEnd();
|
||||
r = 5.;
|
||||
x = (bx - map_xpos + w/2) * 1.; // Map zoom.
|
||||
y = (by - map_ypos + h/2) * 1.; // Map zoom.
|
||||
// Background
|
||||
COLOUR(cBlack);
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2d(bx, by);
|
||||
glVertex2d(bx, by+h);
|
||||
glVertex2d(bx+w, by+h);
|
||||
glVertex2d(bx+w, by);
|
||||
glEnd();
|
||||
|
||||
// Render the star systems.
|
||||
for(i = 0; i < systems_nstack; i++) {
|
||||
sys = &systems_stack[i];
|
||||
// Render the star systems.
|
||||
for(i = 0; i < systems_nstack; i++) {
|
||||
sys = &systems_stack[i];
|
||||
|
||||
// Draw the system.
|
||||
if(sys == cur_system) COLOUR(cRadar_targ);
|
||||
else if(sys->nplanets==0) COLOUR(cInert); // TODO: dependant on planet type.
|
||||
else if(areEnemies(player->faction, sys->faction)) COLOUR(cRed);
|
||||
else COLOUR(cYellow);
|
||||
// Draw the system.
|
||||
if(sys == cur_system) COLOUR(cRadar_targ);
|
||||
else if(sys->nplanets==0) COLOUR(cInert); // TODO: dependant on planet type.
|
||||
else if(areEnemies(player->faction, sys->faction)) COLOUR(cRed);
|
||||
else COLOUR(cYellow);
|
||||
|
||||
gl_drawCircleInRect(x + sys->pos.x*map_zoom,
|
||||
y + sys->pos.y*map_zoom,
|
||||
r, bx, by, w, h);
|
||||
gl_drawCircleInRect(x + sys->pos.x*map_zoom,
|
||||
y + sys->pos.y*map_zoom,
|
||||
r, bx, by, w, h);
|
||||
|
||||
// Draw the system name.
|
||||
tx = x + 7. + sys->pos.x * map_zoom;
|
||||
ty = y - 5. + sys->pos.y * map_zoom;
|
||||
if((map_zoom >= 1.) && // Can't be tiny.
|
||||
((tx > bx) && (ty > by) && (ty < by+h-6.))) // Width checking.
|
||||
gl_printMax(&gl_smallFont, (bx+w)-(tx),
|
||||
tx + gl_screen.w/2., ty + gl_screen.h/2.,
|
||||
&cWhite, sys->name);
|
||||
// Draw the system name.
|
||||
tx = x + 7. + sys->pos.x * map_zoom;
|
||||
ty = y - 5. + sys->pos.y * map_zoom;
|
||||
if((map_zoom >= 1.) && // Can't be tiny.
|
||||
((tx > bx) && (ty > by) && (ty < by+h-6.))) // Width checking.
|
||||
gl_printMax(&gl_smallFont, (bx+w)-(tx),
|
||||
tx + gl_screen.w/2., ty + gl_screen.h/2.,
|
||||
&cWhite, sys->name);
|
||||
|
||||
// Draw the hyperspace paths.
|
||||
glShadeModel(GL_SMOOTH);
|
||||
// Cheaply use transparency instead of actually
|
||||
// calculating from x to y the line must go. :)
|
||||
for(j = 0; j < sys->njumps; j++) {
|
||||
// Set the colours, is the route the current one?
|
||||
if(((cur_system == sys) && (j == hyperspace_target)) ||
|
||||
((cur_system == &systems_stack[sys->jumps[j]]) &&
|
||||
(sys = &systems_stack[cur_system->jumps[hyperspace_target]])))
|
||||
col = &cRed;
|
||||
else col = &cDarkBlue;
|
||||
glBegin(GL_LINE_STRIP);
|
||||
ACOLOUR(*col, 0.);
|
||||
tx = x + sys->pos.x * map_zoom;
|
||||
ty = y + sys->pos.y * map_zoom;
|
||||
if(!((tx < bx) || (tx > bx + w) || (ty < by) || (ty > by+h)))
|
||||
glVertex2d(tx, ty);
|
||||
COLOUR(*col);
|
||||
tx += (systems_stack[sys->jumps[j]].pos.x - sys->pos.x)/2. * map_zoom;
|
||||
ty += (systems_stack[sys->jumps[j]].pos.y - sys->pos.y)/2. * map_zoom;
|
||||
if(!((tx < bx) || (tx > bx+w) || (ty < by) || (ty > by+h)))
|
||||
glVertex2d(tx, ty);
|
||||
ACOLOUR(*col, 0.);
|
||||
tx = x + systems_stack[sys->jumps[j]].pos.x * map_zoom;
|
||||
ty = y + systems_stack[sys->jumps[j]].pos.y * map_zoom;
|
||||
if(!((tx < bx) || (tx > bx+w) || (ty < by) || (ty > by+h)))
|
||||
glVertex2d(tx, ty);
|
||||
glEnd();
|
||||
}
|
||||
glShadeModel(GL_FLAT);
|
||||
}
|
||||
// Selected planet.
|
||||
sys = &systems_stack[map_selected];
|
||||
COLOUR(cRed);
|
||||
gl_drawCircleInRect(x + sys->pos.x*map_zoom, y + sys->pos.y*map_zoom,
|
||||
r+3., bx, by, w, h);
|
||||
// Draw the hyperspace paths.
|
||||
glShadeModel(GL_SMOOTH);
|
||||
// Cheaply use transparency instead of actually
|
||||
// calculating from x to y the line must go. :)
|
||||
for(j = 0; j < sys->njumps; j++) {
|
||||
// Set the colours, is the route the current one?
|
||||
if(((cur_system == sys) && (j == hyperspace_target)) ||
|
||||
((cur_system == &systems_stack[sys->jumps[j]]) &&
|
||||
(sys = &systems_stack[cur_system->jumps[hyperspace_target]])))
|
||||
col = &cRed;
|
||||
else col = &cDarkBlue;
|
||||
glBegin(GL_LINE_STRIP);
|
||||
ACOLOUR(*col, 0.);
|
||||
tx = x + sys->pos.x * map_zoom;
|
||||
ty = y + sys->pos.y * map_zoom;
|
||||
if(!((tx < bx) || (tx > bx + w) || (ty < by) || (ty > by+h)))
|
||||
glVertex2d(tx, ty);
|
||||
COLOUR(*col);
|
||||
tx += (systems_stack[sys->jumps[j]].pos.x - sys->pos.x)/2. * map_zoom;
|
||||
ty += (systems_stack[sys->jumps[j]].pos.y - sys->pos.y)/2. * map_zoom;
|
||||
if(!((tx < bx) || (tx > bx+w) || (ty < by) || (ty > by+h)))
|
||||
glVertex2d(tx, ty);
|
||||
ACOLOUR(*col, 0.);
|
||||
tx = x + systems_stack[sys->jumps[j]].pos.x * map_zoom;
|
||||
ty = y + systems_stack[sys->jumps[j]].pos.y * map_zoom;
|
||||
if(!((tx < bx) || (tx > bx+w) || (ty < by) || (ty > by+h)))
|
||||
glVertex2d(tx, ty);
|
||||
glEnd();
|
||||
}
|
||||
glShadeModel(GL_FLAT);
|
||||
}
|
||||
// Selected planet.
|
||||
sys = &systems_stack[map_selected];
|
||||
COLOUR(cRed);
|
||||
gl_drawCircleInRect(x + sys->pos.x*map_zoom, y + sys->pos.y*map_zoom,
|
||||
r+3., bx, by, w, h);
|
||||
}
|
||||
|
||||
// Map event handling.
|
||||
static void map_mouse(SDL_Event* event, double mx, double my) {
|
||||
int i, j;
|
||||
double x, y, t;
|
||||
int i, j;
|
||||
double x, y, t;
|
||||
|
||||
t = 13.*15.; // Threshold.
|
||||
t = 13.*15.; // Threshold.
|
||||
|
||||
mx -= MAP_WIDTH/2 - map_xpos;
|
||||
my -= MAP_HEIGHT/2 - map_ypos;
|
||||
mx -= MAP_WIDTH/2 - map_xpos;
|
||||
my -= MAP_HEIGHT/2 - map_ypos;
|
||||
|
||||
switch(event->type) {
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
// Selecting star system.
|
||||
if(event->button.button == SDL_BUTTON_LEFT) {
|
||||
for(i = 0; i < systems_nstack; i++) {
|
||||
x = systems_stack[i].pos.x * map_zoom;
|
||||
y = systems_stack[i].pos.y * map_zoom;
|
||||
switch(event->type) {
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
// Selecting star system.
|
||||
if(event->button.button == SDL_BUTTON_LEFT) {
|
||||
for(i = 0; i < systems_nstack; i++) {
|
||||
x = systems_stack[i].pos.x * map_zoom;
|
||||
y = systems_stack[i].pos.y * map_zoom;
|
||||
|
||||
if((pow2(mx-x)+pow2(my-y)) < t) {
|
||||
map_selected = i;
|
||||
for(j = 0; j < cur_system->njumps; j++)
|
||||
if(i == cur_system->jumps[j]) {
|
||||
planet_target = -1; // Override planet target.
|
||||
hyperspace_target = j;
|
||||
break;
|
||||
}
|
||||
map_update();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Start dragging.
|
||||
else if(event->button.button == SDL_BUTTON_RIGHT)
|
||||
map_drag = 1;
|
||||
break;
|
||||
if((pow2(mx-x)+pow2(my-y)) < t) {
|
||||
map_selected = i;
|
||||
for(j = 0; j < cur_system->njumps; j++)
|
||||
if(i == cur_system->jumps[j]) {
|
||||
planet_target = -1; // Override planet target.
|
||||
hyperspace_target = j;
|
||||
break;
|
||||
}
|
||||
map_update();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Start dragging.
|
||||
else if(event->button.button == SDL_BUTTON_RIGHT)
|
||||
map_drag = 1;
|
||||
break;
|
||||
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
if((event->button.button == SDL_BUTTON_RIGHT) && map_drag)
|
||||
map_drag = 0;
|
||||
break;
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
if((event->button.button == SDL_BUTTON_RIGHT) && map_drag)
|
||||
map_drag = 0;
|
||||
break;
|
||||
|
||||
case SDL_MOUSEMOTION:
|
||||
if(map_drag) {
|
||||
// Axis is inverted.
|
||||
map_xpos -= event->motion.xrel;
|
||||
map_ypos += event->motion.yrel;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SDL_MOUSEMOTION:
|
||||
if(map_drag) {
|
||||
// Axis is inverted.
|
||||
map_xpos -= event->motion.xrel;
|
||||
map_ypos += event->motion.yrel;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void map_buttonZoom(char* str) {
|
||||
if(strcmp(str, "btnZoomIn")==0) {
|
||||
map_zoom += (map_zoom >= 1.) ? 0.5 : 0.25;
|
||||
map_zoom = MIN(2.5, map_zoom);
|
||||
}
|
||||
if(strcmp(str, "btnZoomIn")==0) {
|
||||
map_zoom += (map_zoom >= 1.) ? 0.5 : 0.25;
|
||||
map_zoom = MIN(2.5, map_zoom);
|
||||
}
|
||||
|
||||
else if(strcmp(str, "btnZoomOut")==0) {
|
||||
map_zoom -= (map_zoom > 1.) ? 0.5 : 0.25;
|
||||
map_zoom = MAX(0.5, map_zoom);
|
||||
}
|
||||
else if(strcmp(str, "btnZoomOut")==0) {
|
||||
map_zoom -= (map_zoom > 1.) ? 0.5 : 0.25;
|
||||
map_zoom = MAX(0.5, map_zoom);
|
||||
}
|
||||
}
|
||||
|
||||
|
124
src/md5.c
124
src/md5.c
@ -27,7 +27,7 @@
|
||||
|
||||
This code implements the MD5 Algorithm defined in RFC 1321, whose
|
||||
text is available at
|
||||
http://www.ietf.org/rfc/rfc1321.txt
|
||||
http://www.ietf.org/rfc/rfc1321.txt
|
||||
The code is derived from the text of the RFC, including the test suite
|
||||
(section A.5) but excluding the rest of Appendix A. It does not include
|
||||
any code or documentation that is identified in the RFC as being
|
||||
@ -38,14 +38,14 @@
|
||||
that follows (in reverse chronological order):
|
||||
|
||||
2002-04-13 lpd Clarified derivation from RFC 1321; now handles byte order
|
||||
either statically or dynamically; added missing #include <string.h>
|
||||
in library.
|
||||
either statically or dynamically; added missing #include <string.h>
|
||||
in library.
|
||||
2002-03-11 lpd Corrected argument list for main(), and added int return
|
||||
type, in test program and T value program.
|
||||
type, in test program and T value program.
|
||||
2002-02-21 lpd Added missing #include <stdio.h> in test program.
|
||||
2000-07-03 lpd Patched to eliminate warnings about "constant is
|
||||
unsigned in ANSI C, signed in traditional"; made test program
|
||||
self-checking.
|
||||
unsigned in ANSI C, signed in traditional"; made test program
|
||||
self-checking.
|
||||
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
|
||||
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5).
|
||||
1999-05-03 lpd Original version.
|
||||
@ -54,7 +54,7 @@
|
||||
#include "md5.h"
|
||||
#include <string.h>
|
||||
|
||||
#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
|
||||
#undef BYTE_ORDER /* 1 = big-endian, -1 = little-endian, 0 = unknown */
|
||||
#ifdef ARCH_IS_BIG_ENDIAN
|
||||
# define BYTE_ORDER (ARCH_IS_BIG_ENDIAN ? 1 : -1)
|
||||
#else
|
||||
@ -132,8 +132,8 @@ static void
|
||||
md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
|
||||
{
|
||||
md5_word_t
|
||||
a = pms->abcd[0], b = pms->abcd[1],
|
||||
c = pms->abcd[2], d = pms->abcd[3];
|
||||
a = pms->abcd[0], b = pms->abcd[1],
|
||||
c = pms->abcd[2], d = pms->abcd[3];
|
||||
md5_word_t t;
|
||||
#if BYTE_ORDER > 0
|
||||
/* Define storage only for big-endian CPUs. */
|
||||
@ -146,51 +146,51 @@ md5_process(md5_state_t *pms, const md5_byte_t *data /*[64]*/)
|
||||
|
||||
{
|
||||
#if BYTE_ORDER == 0
|
||||
/*
|
||||
* Determine dynamically whether this is a big-endian or
|
||||
* little-endian machine, since we can use a more efficient
|
||||
* algorithm on the latter.
|
||||
*/
|
||||
static const int w = 1;
|
||||
/*
|
||||
* Determine dynamically whether this is a big-endian or
|
||||
* little-endian machine, since we can use a more efficient
|
||||
* algorithm on the latter.
|
||||
*/
|
||||
static const int w = 1;
|
||||
|
||||
if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
|
||||
if (*((const md5_byte_t *)&w)) /* dynamic little-endian */
|
||||
#endif
|
||||
#if BYTE_ORDER <= 0 /* little-endian */
|
||||
{
|
||||
/*
|
||||
* On little-endian machines, we can process properly aligned
|
||||
* data without copying it.
|
||||
*/
|
||||
if (!((data - (const md5_byte_t *)0) & 3)) {
|
||||
/* data are properly aligned */
|
||||
X = (const md5_word_t *)data;
|
||||
} else {
|
||||
/* not aligned */
|
||||
memcpy(xbuf, data, 64);
|
||||
X = xbuf;
|
||||
}
|
||||
}
|
||||
#if BYTE_ORDER <= 0 /* little-endian */
|
||||
{
|
||||
/*
|
||||
* On little-endian machines, we can process properly aligned
|
||||
* data without copying it.
|
||||
*/
|
||||
if (!((data - (const md5_byte_t *)0) & 3)) {
|
||||
/* data are properly aligned */
|
||||
X = (const md5_word_t *)data;
|
||||
} else {
|
||||
/* not aligned */
|
||||
memcpy(xbuf, data, 64);
|
||||
X = xbuf;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#if BYTE_ORDER == 0
|
||||
else /* dynamic big-endian */
|
||||
else /* dynamic big-endian */
|
||||
#endif
|
||||
#if BYTE_ORDER >= 0 /* big-endian */
|
||||
{
|
||||
/*
|
||||
* On big-endian machines, we must arrange the bytes in the
|
||||
* right order.
|
||||
*/
|
||||
const md5_byte_t *xp = data;
|
||||
int i;
|
||||
#if BYTE_ORDER >= 0 /* big-endian */
|
||||
{
|
||||
/*
|
||||
* On big-endian machines, we must arrange the bytes in the
|
||||
* right order.
|
||||
*/
|
||||
const md5_byte_t *xp = data;
|
||||
int i;
|
||||
|
||||
# if BYTE_ORDER == 0
|
||||
X = xbuf; /* (dynamic only) */
|
||||
X = xbuf; /* (dynamic only) */
|
||||
# else
|
||||
# define xbuf X /* (static only) */
|
||||
# define xbuf X /* (static only) */
|
||||
# endif
|
||||
for (i = 0; i < 16; ++i, xp += 4)
|
||||
xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
|
||||
}
|
||||
for (i = 0; i < 16; ++i, xp += 4)
|
||||
xbuf[i] = xp[0] + (xp[1] << 8) + (xp[2] << 16) + (xp[3] << 24);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -328,54 +328,54 @@ md5_append(md5_state_t *pms, const md5_byte_t *data, int nbytes)
|
||||
md5_word_t nbits = (md5_word_t)(nbytes << 3);
|
||||
|
||||
if (nbytes <= 0)
|
||||
return;
|
||||
return;
|
||||
|
||||
/* Update the message length. */
|
||||
pms->count[1] += nbytes >> 29;
|
||||
pms->count[0] += nbits;
|
||||
if (pms->count[0] < nbits)
|
||||
pms->count[1]++;
|
||||
pms->count[1]++;
|
||||
|
||||
/* Process an initial partial block. */
|
||||
if (offset) {
|
||||
int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
|
||||
int copy = (offset + nbytes > 64 ? 64 - offset : nbytes);
|
||||
|
||||
memcpy(pms->buf + offset, p, copy);
|
||||
if (offset + copy < 64)
|
||||
return;
|
||||
p += copy;
|
||||
left -= copy;
|
||||
md5_process(pms, pms->buf);
|
||||
memcpy(pms->buf + offset, p, copy);
|
||||
if (offset + copy < 64)
|
||||
return;
|
||||
p += copy;
|
||||
left -= copy;
|
||||
md5_process(pms, pms->buf);
|
||||
}
|
||||
|
||||
/* Process full blocks. */
|
||||
for (; left >= 64; p += 64, left -= 64)
|
||||
md5_process(pms, p);
|
||||
md5_process(pms, p);
|
||||
|
||||
/* Process a final partial block. */
|
||||
if (left)
|
||||
memcpy(pms->buf, p, left);
|
||||
memcpy(pms->buf, p, left);
|
||||
}
|
||||
|
||||
void
|
||||
md5_finish(md5_state_t *pms, md5_byte_t digest[16])
|
||||
{
|
||||
static const md5_byte_t pad[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
md5_byte_t data[8];
|
||||
int i;
|
||||
|
||||
/* Save the length before padding. */
|
||||
for (i = 0; i < 8; ++i)
|
||||
data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
|
||||
data[i] = (md5_byte_t)(pms->count[i >> 2] >> ((i & 3) << 3));
|
||||
/* Pad to 56 bytes mod 64. */
|
||||
md5_append(pms, pad, ((55 - (pms->count[0] >> 3)) & 63) + 1);
|
||||
/* Append the length. */
|
||||
md5_append(pms, data, 8);
|
||||
for (i = 0; i < 16; ++i)
|
||||
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
|
||||
digest[i] = (md5_byte_t)(pms->abcd[i >> 2] >> ((i & 3) << 3));
|
||||
}
|
||||
|
16
src/md5.h
16
src/md5.h
@ -27,7 +27,7 @@
|
||||
|
||||
This code implements the MD5 Algorithm defined in RFC 1321, whose
|
||||
text is available at
|
||||
http://www.ietf.org/rfc/rfc1321.txt
|
||||
http://www.ietf.org/rfc/rfc1321.txt
|
||||
The code is derived from the text of the RFC, including the test suite
|
||||
(section A.5) but excluding the rest of Appendix A. It does not include
|
||||
any code or documentation that is identified in the RFC as being
|
||||
@ -40,12 +40,12 @@
|
||||
2007-04-15 bobbens using uint8_t and uint32_t for compatibility.
|
||||
removed C++ conditionalization.
|
||||
2002-04-13 lpd Removed support for non-ANSI compilers; removed
|
||||
references to Ghostscript; clarified derivation from RFC 1321;
|
||||
now handles byte order either statically or dynamically.
|
||||
references to Ghostscript; clarified derivation from RFC 1321;
|
||||
now handles byte order either statically or dynamically.
|
||||
1999-11-04 lpd Edited comments slightly for automatic TOC extraction.
|
||||
1999-10-18 lpd Fixed typo in header comment (ansi2knr rather than md5);
|
||||
added conditionalization for C++ compilation from Martin
|
||||
Purschke <purschke@bnl.gov>.
|
||||
added conditionalization for C++ compilation from Martin
|
||||
Purschke <purschke@bnl.gov>.
|
||||
1999-05-03 lpd Original version.
|
||||
*/
|
||||
|
||||
@ -69,9 +69,9 @@ typedef uint32_t md5_word_t; /* 32-bit word */
|
||||
|
||||
/* Define the state of the MD5 Algorithm. */
|
||||
typedef struct md5_state_s {
|
||||
md5_word_t count[2]; /* message length in bits, lsw first */
|
||||
md5_word_t abcd[4]; /* digest buffer */
|
||||
md5_byte_t buf[64]; /* accumulate block */
|
||||
md5_word_t count[2]; /* message length in bits, lsw first */
|
||||
md5_word_t abcd[4]; /* digest buffer */
|
||||
md5_byte_t buf[64]; /* accumulate block */
|
||||
} md5_state_t;
|
||||
|
||||
|
||||
|
244
src/menu.c
244
src/menu.c
@ -10,26 +10,26 @@
|
||||
#include "player.h"
|
||||
#include "menu.h"
|
||||
|
||||
#define MAIN_WIDTH 130
|
||||
#define MAIN_HEIGHT 250
|
||||
#define MAIN_WIDTH 130
|
||||
#define MAIN_HEIGHT 250
|
||||
|
||||
#define MENU_WIDTH 130
|
||||
#define MENU_HEIGHT 200
|
||||
#define MENU_WIDTH 130
|
||||
#define MENU_HEIGHT 200
|
||||
|
||||
#define INFO_WIDTH 320
|
||||
#define INFO_HEIGHT 280
|
||||
#define INFO_WIDTH 320
|
||||
#define INFO_HEIGHT 280
|
||||
|
||||
#define OUTFITS_WIDTH 400
|
||||
#define OUTFITS_HEIGHT 200
|
||||
#define OUTFITS_WIDTH 400
|
||||
#define OUTFITS_HEIGHT 200
|
||||
|
||||
#define DEATH_WIDTH 130
|
||||
#define DEATH_HEIGHT 150
|
||||
#define DEATH_WIDTH 130
|
||||
#define DEATH_HEIGHT 150
|
||||
|
||||
#define BUTTON_WIDTH 90
|
||||
#define BUTTON_HEIGHT 30
|
||||
#define BUTTON_WIDTH 90
|
||||
#define BUTTON_HEIGHT 30
|
||||
|
||||
#define menu_Open(f) (menu_open |= (f))
|
||||
#define menu_Close(f) (menu_open ^= (f))
|
||||
#define menu_Open(f) (menu_open |= (f))
|
||||
#define menu_Close(f) (menu_open ^= (f))
|
||||
|
||||
int menu_open = 0;
|
||||
|
||||
@ -44,51 +44,51 @@ static void info_outfits_menu_close(char* str);
|
||||
static void menu_death_main(char* str);
|
||||
|
||||
void menu_main(void) {
|
||||
unsigned int bwid, wid;
|
||||
unsigned int bwid, wid;
|
||||
|
||||
// Create background image window.
|
||||
bwid = window_create("BG", -1, -1, gl_screen.w, gl_screen.h);
|
||||
window_addRect(bwid, 0, 0, gl_screen.w, gl_screen.h, "rctBG", &cBlack, 0);
|
||||
// Create background image window.
|
||||
bwid = window_create("BG", -1, -1, gl_screen.w, gl_screen.h);
|
||||
window_addRect(bwid, 0, 0, gl_screen.w, gl_screen.h, "rctBG", &cBlack, 0);
|
||||
|
||||
// Create menu window.
|
||||
wid = window_create("Main Menu", -1, -1, MAIN_WIDTH, MAIN_HEIGHT);
|
||||
window_addButton(wid, 20, 20 + (BUTTON_HEIGHT+20)*3,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnLoad", "Load Game", NULL);
|
||||
window_addButton(wid, 20, 20 + (BUTTON_HEIGHT+20)*2,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnNew", "New Game", menu_main_new);
|
||||
window_addButton(wid, 20, 20 + (BUTTON_HEIGHT+20),
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnOptions", "Options", (void(*)(char*)) edit_options);
|
||||
window_addButton(wid, 20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnExit", "Exit", (void(*)(char*)) exit_game);
|
||||
// Create menu window.
|
||||
wid = window_create("Main Menu", -1, -1, MAIN_WIDTH, MAIN_HEIGHT);
|
||||
window_addButton(wid, 20, 20 + (BUTTON_HEIGHT+20)*3,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnLoad", "Load Game", NULL);
|
||||
window_addButton(wid, 20, 20 + (BUTTON_HEIGHT+20)*2,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnNew", "New Game", menu_main_new);
|
||||
window_addButton(wid, 20, 20 + (BUTTON_HEIGHT+20),
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnOptions", "Options", (void(*)(char*)) edit_options);
|
||||
window_addButton(wid, 20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnExit", "Exit", (void(*)(char*)) exit_game);
|
||||
|
||||
menu_Open(MENU_MAIN);
|
||||
menu_Open(MENU_MAIN);
|
||||
}
|
||||
|
||||
static void menu_main_close(void) {
|
||||
window_destroy(window_get("Main Menu"));
|
||||
window_destroy(window_get("BG"));
|
||||
window_destroy(window_get("Main Menu"));
|
||||
window_destroy(window_get("BG"));
|
||||
|
||||
menu_Close(MENU_MAIN);
|
||||
menu_Close(MENU_MAIN);
|
||||
}
|
||||
|
||||
static void menu_main_new(char* str) {
|
||||
(void)str;
|
||||
(void)str;
|
||||
|
||||
menu_main_close();
|
||||
player_new();
|
||||
menu_main_close();
|
||||
player_new();
|
||||
}
|
||||
|
||||
// Ze ingame menu.
|
||||
// Small ingame menu.
|
||||
void menu_small(void) {
|
||||
if(menu_isOpen(MENU_MAIN) ||
|
||||
menu_isOpen(MENU_SMALL) ||
|
||||
menu_isOpen(MENU_DEATH))
|
||||
return; // It's already open..
|
||||
pause();
|
||||
menu_isOpen(MENU_SMALL) ||
|
||||
menu_isOpen(MENU_DEATH))
|
||||
return; // It's already open..
|
||||
pause();
|
||||
|
||||
unsigned int wid;
|
||||
|
||||
@ -98,14 +98,14 @@ void menu_small(void) {
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnResume", "Resume", menu_small_close);
|
||||
|
||||
window_addButton(wid, 20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
window_addButton(wid, 20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnExit", "Exit", (void(*)(char*))exit_game);
|
||||
|
||||
window_addButton(wid, 20, 20 + BUTTON_HEIGHT + 20,
|
||||
window_addButton(wid, 20, 20 + BUTTON_HEIGHT + 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnOptions", "Options", (void(*)(char*))edit_options);
|
||||
|
||||
menu_Open(MENU_SMALL);
|
||||
menu_Open(MENU_SMALL);
|
||||
}
|
||||
|
||||
static void menu_small_close(char* str) {
|
||||
@ -113,7 +113,7 @@ static void menu_small_close(char* str) {
|
||||
window_destroy(window_get("Menu"));
|
||||
|
||||
unpause();
|
||||
menu_Close(MENU_SMALL);
|
||||
menu_Close(MENU_SMALL);
|
||||
}
|
||||
|
||||
// Edit the options.
|
||||
@ -130,114 +130,114 @@ static void exit_game(void) {
|
||||
|
||||
// Info menu.
|
||||
void menu_info(void) {
|
||||
if(menu_isOpen(MENU_INFO)) return;
|
||||
pause();
|
||||
if(menu_isOpen(MENU_INFO)) return;
|
||||
pause();
|
||||
|
||||
char str[128];;
|
||||
unsigned int wid;
|
||||
wid = window_create("Info", -1, -1, INFO_WIDTH, INFO_HEIGHT);
|
||||
char str[128];;
|
||||
unsigned int wid;
|
||||
wid = window_create("Info", -1, -1, INFO_WIDTH, INFO_HEIGHT);
|
||||
|
||||
// Pilot generics.
|
||||
window_addText(wid, 20, 20, 120, INFO_HEIGHT-60,
|
||||
0, "txtDPilot", &gl_smallFont, &cDConsole,
|
||||
"Pilot:\n"
|
||||
"Combat Rating:\n");
|
||||
// Pilot generics.
|
||||
window_addText(wid, 20, 20, 120, INFO_HEIGHT-60,
|
||||
0, "txtDPilot", &gl_smallFont, &cDConsole,
|
||||
"Pilot:\n"
|
||||
"Combat Rating:\n");
|
||||
|
||||
snprintf(str, 128,
|
||||
"%s\n"
|
||||
"%s\n",
|
||||
player_name, player_rating());
|
||||
snprintf(str, 128,
|
||||
"%s\n"
|
||||
"%s\n",
|
||||
player_name, player_rating());
|
||||
|
||||
window_addText(wid, 120, 20,
|
||||
INFO_WIDTH-120-BUTTON_WIDTH, INFO_HEIGHT-60,
|
||||
0, "txtPilot", &gl_smallFont, &cBlack, str);
|
||||
window_addText(wid, 120, 20,
|
||||
INFO_WIDTH-120-BUTTON_WIDTH, INFO_HEIGHT-60,
|
||||
0, "txtPilot", &gl_smallFont, &cBlack, str);
|
||||
|
||||
// Menu.
|
||||
window_addButton(wid, -20, (20 + BUTTON_HEIGHT)*4 + 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
player->ship->name, "Ship", ship_view);
|
||||
window_addButton(wid, -20, (20 + BUTTON_HEIGHT)*3 + 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnOutfits", "Outfits", info_outfits_menu);
|
||||
window_addButton(wid, -20, (20 + BUTTON_HEIGHT)*2 + 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnCargo", "Cargo", NULL);
|
||||
window_addButton(wid, -20, 20 + BUTTON_HEIGHT + 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnMissions", "Missions", NULL);
|
||||
window_addButton(wid, -20, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnClose", "Close", menu_info_close);
|
||||
// Menu.
|
||||
window_addButton(wid, -20, (20 + BUTTON_HEIGHT)*4 + 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
player->ship->name, "Ship", ship_view);
|
||||
window_addButton(wid, -20, (20 + BUTTON_HEIGHT)*3 + 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnOutfits", "Outfits", info_outfits_menu);
|
||||
window_addButton(wid, -20, (20 + BUTTON_HEIGHT)*2 + 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnCargo", "Cargo", NULL);
|
||||
window_addButton(wid, -20, 20 + BUTTON_HEIGHT + 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnMissions", "Missions", NULL);
|
||||
window_addButton(wid, -20, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnClose", "Close", menu_info_close);
|
||||
|
||||
|
||||
menu_Open(MENU_INFO);
|
||||
menu_Open(MENU_INFO);
|
||||
}
|
||||
|
||||
static void menu_info_close(char* str) {
|
||||
if(strcmp(str, "btnClose")==0)
|
||||
window_destroy(window_get("Info"));
|
||||
if(strcmp(str, "btnClose")==0)
|
||||
window_destroy(window_get("Info"));
|
||||
|
||||
menu_Close(MENU_INFO);
|
||||
unpause();
|
||||
menu_Close(MENU_INFO);
|
||||
unpause();
|
||||
}
|
||||
|
||||
static void info_outfits_menu(char* str) {
|
||||
(void) str;
|
||||
int i;
|
||||
char buf[1024], buf2[64];
|
||||
unsigned int wid;
|
||||
wid = window_create("Outfits", -1, -1, OUTFITS_WIDTH, OUTFITS_HEIGHT);
|
||||
(void) str;
|
||||
int i;
|
||||
char buf[1024], buf2[64];
|
||||
unsigned int wid;
|
||||
wid = window_create("Outfits", -1, -1, OUTFITS_WIDTH, OUTFITS_HEIGHT);
|
||||
|
||||
window_addText(wid, 20, -40, 100, OUTFITS_HEIGHT-40,
|
||||
0, "txtLabel", &gl_smallFont, &cDConsole,
|
||||
"Ship Outfits:");
|
||||
window_addText(wid, 20, -40, 100, OUTFITS_HEIGHT-40,
|
||||
0, "txtLabel", &gl_smallFont, &cDConsole,
|
||||
"Ship Outfits:");
|
||||
|
||||
buf[0] = '\0';
|
||||
if(player->noutfits > 0)
|
||||
snprintf(buf, 1024, "%dx %s",
|
||||
player->outfits[0].quantity, player->outfits[0].outfit->name);
|
||||
buf[0] = '\0';
|
||||
if(player->noutfits > 0)
|
||||
snprintf(buf, 1024, "%dx %s",
|
||||
player->outfits[0].quantity, player->outfits[0].outfit->name);
|
||||
|
||||
for(i = 1; i < player->noutfits; i++) {
|
||||
snprintf(buf2, 64, ", %dx %s",
|
||||
player->outfits[i].quantity, player->outfits[i].outfit->name);
|
||||
strcat(buf, buf2);
|
||||
}
|
||||
for(i = 1; i < player->noutfits; i++) {
|
||||
snprintf(buf2, 64, ", %dx %s",
|
||||
player->outfits[i].quantity, player->outfits[i].outfit->name);
|
||||
strcat(buf, buf2);
|
||||
}
|
||||
|
||||
window_addText(wid, 20, -45-gl_smallFont.h,
|
||||
OUTFITS_WIDTH-40, OUTFITS_HEIGHT-60,
|
||||
0, "txtOutfits", &gl_smallFont, &cBlack, buf);
|
||||
window_addText(wid, 20, -45-gl_smallFont.h,
|
||||
OUTFITS_WIDTH-40, OUTFITS_HEIGHT-60,
|
||||
0, "txtOutfits", &gl_smallFont, &cBlack, buf);
|
||||
|
||||
window_addButton(wid, -20, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"closeOutfits", "Close", info_outfits_menu_close);
|
||||
window_addButton(wid, -20, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"closeOutfits", "Close", info_outfits_menu_close);
|
||||
}
|
||||
|
||||
static void info_outfits_menu_close(char* str) {
|
||||
window_destroy(window_get(str+5)); // closeFoo -> Foo.
|
||||
window_destroy(window_get(str+5)); // closeFoo -> Foo.
|
||||
}
|
||||
|
||||
// Pilot dead.
|
||||
void menu_death(void) {
|
||||
unsigned int wid;
|
||||
wid = window_create("Death", -1, -1, DEATH_WIDTH, DEATH_HEIGHT);
|
||||
unsigned int wid;
|
||||
wid = window_create("Death", -1, -1, DEATH_WIDTH, DEATH_HEIGHT);
|
||||
|
||||
window_addButton(wid, 20, 20 + (BUTTON_HEIGHT + 20),
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnMain", "MainMenu", menu_death_main);
|
||||
window_addButton(wid, 20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnExit", "Exit", (void(*)(char*)) exit_game);
|
||||
window_addButton(wid, 20, 20 + (BUTTON_HEIGHT + 20),
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnMain", "MainMenu", menu_death_main);
|
||||
window_addButton(wid, 20, 20, BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
"btnExit", "Exit", (void(*)(char*)) exit_game);
|
||||
|
||||
menu_Open(MENU_DEATH);
|
||||
menu_Open(MENU_DEATH);
|
||||
}
|
||||
|
||||
static void menu_death_main(char* str) {
|
||||
(void)str;
|
||||
unsigned int wid;
|
||||
(void)str;
|
||||
unsigned int wid;
|
||||
|
||||
wid = window_get("Death");
|
||||
window_destroy(wid);
|
||||
menu_Close(MENU_DEATH);
|
||||
wid = window_get("Death");
|
||||
window_destroy(wid);
|
||||
menu_Close(MENU_DEATH);
|
||||
|
||||
menu_main();
|
||||
menu_main();
|
||||
}
|
||||
|
||||
|
10
src/menu.h
10
src/menu.h
@ -1,10 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#define MENU_MAIN (1<<0)
|
||||
#define MENU_SMALL (1<<1)
|
||||
#define MENU_INFO (1<<2)
|
||||
#define MENU_DEATH (1<<3)
|
||||
#define menu_isOpen(f) (menu_open & (f))
|
||||
#define MENU_MAIN (1<<0)
|
||||
#define MENU_SMALL (1<<1)
|
||||
#define MENU_INFO (1<<2)
|
||||
#define MENU_DEATH (1<<3)
|
||||
#define menu_isOpen(f) (menu_open & (f))
|
||||
extern int menu_open;
|
||||
|
||||
void menu_main(void);
|
||||
|
374
src/music.c
374
src/music.c
@ -8,34 +8,34 @@
|
||||
#include "pack.h"
|
||||
#include "music.h"
|
||||
|
||||
#define MUSIC_STOPPED (1<<1)
|
||||
#define MUSIC_PLAYING (1<<2)
|
||||
#define MUSIC_KILL (1<<9)
|
||||
#define music_is(f) (music_state & f)
|
||||
#define music_set(f) (music_state |= f)
|
||||
#define music_rm(f) (music_state ^= f)
|
||||
#define MUSIC_STOPPED (1<<1)
|
||||
#define MUSIC_PLAYING (1<<2)
|
||||
#define MUSIC_KILL (1<<9)
|
||||
#define music_is(f) (music_state & f)
|
||||
#define music_set(f) (music_state |= f)
|
||||
#define music_rm(f) (music_state ^= f)
|
||||
|
||||
#define MUSIC_PREFIX "../snd/music/"
|
||||
#define MUSIC_SUFFIX ".ogg"
|
||||
#define MUSIC_PREFIX "../snd/music/"
|
||||
#define MUSIC_SUFFIX ".ogg"
|
||||
|
||||
#define BUFFER_SIZE (4096 * 8)
|
||||
#define BUFFER_SIZE (4096 * 8)
|
||||
|
||||
// Gobal sound mutex.
|
||||
extern SDL_mutex* sound_lock;
|
||||
|
||||
// Saves the music to ram in this structure.
|
||||
typedef struct alMusic_ {
|
||||
char name[32]; // Name.
|
||||
Packfile file;
|
||||
OggVorbis_File stream;
|
||||
vorbis_info* info;
|
||||
ALenum format;
|
||||
char name[32]; // Name.
|
||||
Packfile file;
|
||||
OggVorbis_File stream;
|
||||
vorbis_info* info;
|
||||
ALenum format;
|
||||
} alMusic;
|
||||
|
||||
// Song currently playing.
|
||||
static SDL_mutex* music_vorbis_lock;
|
||||
static alMusic music_vorbis;
|
||||
static ALuint music_buffer[2]; // Front and back buffer.
|
||||
static ALuint music_buffer[2]; // Front and back buffer.
|
||||
static ALuint music_source = 0;
|
||||
|
||||
// What is available?
|
||||
@ -47,17 +47,17 @@ static ALfloat mvolume = 1.;
|
||||
|
||||
// Vorbis suff.
|
||||
static size_t ovpack_read(void* ptr, size_t size,
|
||||
size_t nmemb, void* datasource) {
|
||||
return (ssize_t) pack_read(datasource, ptr, size*nmemb);
|
||||
size_t nmemb, void* datasource) {
|
||||
return (ssize_t) pack_read(datasource, ptr, size*nmemb);
|
||||
}
|
||||
|
||||
static int ovpack_retneg(void) { return -1; } // Must return -1.
|
||||
static int ovpack_retzero(void) { return 0; } // Must return 0.
|
||||
ov_callbacks ovcall = {
|
||||
.read_func = ovpack_read,
|
||||
.seek_func = (int(*)(void*, ogg_int64_t, int)) ovpack_retneg,
|
||||
.close_func = (int(*)(void*))ovpack_retzero,
|
||||
.tell_func = (long(*)(void*))ovpack_retneg
|
||||
.read_func = ovpack_read,
|
||||
.seek_func = (int(*)(void*, ogg_int64_t, int)) ovpack_retneg,
|
||||
.close_func = (int(*)(void*))ovpack_retzero,
|
||||
.tell_func = (long(*)(void*))ovpack_retneg
|
||||
};
|
||||
|
||||
static int stream_loadBuffer(ALuint buffer);
|
||||
@ -68,250 +68,250 @@ static void music_free(void);
|
||||
// The thread.
|
||||
static unsigned int music_state = 0;
|
||||
int music_thread(void* unused) {
|
||||
(void)unused;
|
||||
(void)unused;
|
||||
|
||||
int active; // Active buffer.
|
||||
ALint stat;
|
||||
int active; // Active buffer.
|
||||
ALint stat;
|
||||
|
||||
// Main loop.
|
||||
while(!music_is(MUSIC_KILL)) {
|
||||
if(music_is(MUSIC_PLAYING)) {
|
||||
if(music_vorbis.file.end == 0)
|
||||
music_rm(MUSIC_PLAYING);
|
||||
else {
|
||||
music_rm(MUSIC_STOPPED);
|
||||
// Main loop.
|
||||
while(!music_is(MUSIC_KILL)) {
|
||||
if(music_is(MUSIC_PLAYING)) {
|
||||
if(music_vorbis.file.end == 0)
|
||||
music_rm(MUSIC_PLAYING);
|
||||
else {
|
||||
music_rm(MUSIC_STOPPED);
|
||||
|
||||
SDL_mutexP(music_vorbis_lock); // Lock the mutex.
|
||||
SDL_mutexP(sound_lock);
|
||||
SDL_mutexP(music_vorbis_lock); // Lock the mutex.
|
||||
SDL_mutexP(sound_lock);
|
||||
|
||||
// Start playing current song.
|
||||
active = 0; // Load first buffer.
|
||||
if(stream_loadBuffer(music_buffer[active])) music_rm(MUSIC_PLAYING);
|
||||
alSourceQueueBuffers(music_source, 1, &music_buffer[active]);
|
||||
// Start playing current song.
|
||||
active = 0; // Load first buffer.
|
||||
if(stream_loadBuffer(music_buffer[active])) music_rm(MUSIC_PLAYING);
|
||||
alSourceQueueBuffers(music_source, 1, &music_buffer[active]);
|
||||
|
||||
// Start playing with buffer laoaded.
|
||||
alSourcePlay(music_source);
|
||||
// Start playing with buffer laoaded.
|
||||
alSourcePlay(music_source);
|
||||
|
||||
active = 1; // Load the second buffer.
|
||||
if(stream_loadBuffer(music_buffer[active])) music_rm(MUSIC_PLAYING);
|
||||
alSourceQueueBuffers(music_source, 1, &music_buffer[active]);
|
||||
active = 1; // Load the second buffer.
|
||||
if(stream_loadBuffer(music_buffer[active])) music_rm(MUSIC_PLAYING);
|
||||
alSourceQueueBuffers(music_source, 1, &music_buffer[active]);
|
||||
|
||||
SDL_mutexV(sound_lock);
|
||||
SDL_mutexV(sound_lock);
|
||||
|
||||
active = 0;
|
||||
}
|
||||
while(music_is(MUSIC_PLAYING)) {
|
||||
SDL_mutexP(sound_lock);
|
||||
active = 0;
|
||||
}
|
||||
while(music_is(MUSIC_PLAYING)) {
|
||||
SDL_mutexP(sound_lock);
|
||||
|
||||
alGetSourcei(music_source, AL_BUFFERS_PROCESSED, &stat);
|
||||
if(stat > 0) {
|
||||
// Refill active buffer.
|
||||
alSourceUnqueueBuffers(music_source, 1, &music_buffer[active]);
|
||||
if(stream_loadBuffer(music_buffer[active])) music_rm(MUSIC_PLAYING);
|
||||
alSourceQueueBuffers(music_source, 1, &music_buffer[active]);
|
||||
alGetSourcei(music_source, AL_BUFFERS_PROCESSED, &stat);
|
||||
if(stat > 0) {
|
||||
// Refill active buffer.
|
||||
alSourceUnqueueBuffers(music_source, 1, &music_buffer[active]);
|
||||
if(stream_loadBuffer(music_buffer[active])) music_rm(MUSIC_PLAYING);
|
||||
alSourceQueueBuffers(music_source, 1, &music_buffer[active]);
|
||||
|
||||
active = 1 - active;
|
||||
}
|
||||
SDL_mutexV(sound_lock);
|
||||
active = 1 - active;
|
||||
}
|
||||
SDL_mutexV(sound_lock);
|
||||
|
||||
SDL_Delay(0);
|
||||
}
|
||||
SDL_mutexP(sound_lock);
|
||||
SDL_Delay(0);
|
||||
}
|
||||
SDL_mutexP(sound_lock);
|
||||
|
||||
alSourceStop(music_source);
|
||||
alSourceUnqueueBuffers(music_source, 2, music_buffer);
|
||||
alSourceStop(music_source);
|
||||
alSourceUnqueueBuffers(music_source, 2, music_buffer);
|
||||
|
||||
SDL_mutexV(sound_lock);
|
||||
SDL_mutexV(music_vorbis_lock);
|
||||
}
|
||||
music_set(MUSIC_STOPPED);
|
||||
SDL_Delay(0); // We must not kill resources.
|
||||
}
|
||||
return 0;
|
||||
SDL_mutexV(sound_lock);
|
||||
SDL_mutexV(music_vorbis_lock);
|
||||
}
|
||||
music_set(MUSIC_STOPPED);
|
||||
SDL_Delay(0); // We must not kill resources.
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int stream_loadBuffer(ALuint buffer) {
|
||||
int size, section, result;
|
||||
char data[BUFFER_SIZE]; // Buffer to hold the data.
|
||||
int size, section, result;
|
||||
char data[BUFFER_SIZE]; // Buffer to hold the data.
|
||||
|
||||
size = 0;
|
||||
while(size < BUFFER_SIZE) {
|
||||
// Fill up the entire data buffer.
|
||||
result = ov_read(
|
||||
&music_vorbis.stream, // Stream.
|
||||
data + size, // Data.
|
||||
BUFFER_SIZE - size, // Amount to read.
|
||||
0, // Big endian?.
|
||||
2, // 16 bit.
|
||||
1, // Signed.
|
||||
§ion); // Current bitstream.
|
||||
size = 0;
|
||||
while(size < BUFFER_SIZE) {
|
||||
// Fill up the entire data buffer.
|
||||
result = ov_read(
|
||||
&music_vorbis.stream, // Stream.
|
||||
data + size, // Data.
|
||||
BUFFER_SIZE - size, // Amount to read.
|
||||
0, // Big endian?.
|
||||
2, // 16 bit.
|
||||
1, // Signed.
|
||||
§ion); // Current bitstream.
|
||||
|
||||
if(result == 0) return 1;
|
||||
else if(result == OV_HOLE) {
|
||||
WARN("OGG: Vorbis hole detected in music!");
|
||||
return 0;
|
||||
}
|
||||
else if(result == OV_EBADLINK) {
|
||||
WARN("OGG: Invalid stream section or corrupt link in music!");
|
||||
return -1;
|
||||
}
|
||||
if(result == 0) return 1;
|
||||
else if(result == OV_HOLE) {
|
||||
WARN("OGG: Vorbis hole detected in music!");
|
||||
return 0;
|
||||
}
|
||||
else if(result == OV_EBADLINK) {
|
||||
WARN("OGG: Invalid stream section or corrupt link in music!");
|
||||
return -1;
|
||||
}
|
||||
|
||||
size += result;
|
||||
if(size == BUFFER_SIZE) break; // Buffer is full.
|
||||
}
|
||||
// Load the buffer.
|
||||
alBufferData(buffer, music_vorbis.format, data, BUFFER_SIZE,
|
||||
music_vorbis.info->rate);
|
||||
size += result;
|
||||
if(size == BUFFER_SIZE) break; // Buffer is full.
|
||||
}
|
||||
// Load the buffer.
|
||||
alBufferData(buffer, music_vorbis.format, data, BUFFER_SIZE,
|
||||
music_vorbis.info->rate);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Init/Exit.
|
||||
int music_init(void) {
|
||||
music_vorbis_lock = SDL_CreateMutex();
|
||||
music_find();
|
||||
music_vorbis.file.end = 0; // Indication that it's not loaded..
|
||||
music_vorbis_lock = SDL_CreateMutex();
|
||||
music_find();
|
||||
music_vorbis.file.end = 0; // Indication that it's not loaded..
|
||||
|
||||
SDL_mutexP(sound_lock);
|
||||
SDL_mutexP(sound_lock);
|
||||
|
||||
alGenBuffers(2, music_buffer);
|
||||
alGenSources(1, &music_source);
|
||||
alSourcef(music_source, AL_GAIN, mvolume);
|
||||
alSourcef(music_source, AL_ROLLOFF_FACTOR, 0.);
|
||||
alSourcei(music_source, AL_SOURCE_RELATIVE, AL_TRUE);
|
||||
alGenBuffers(2, music_buffer);
|
||||
alGenSources(1, &music_source);
|
||||
alSourcef(music_source, AL_GAIN, mvolume);
|
||||
alSourcef(music_source, AL_ROLLOFF_FACTOR, 0.);
|
||||
alSourcei(music_source, AL_SOURCE_RELATIVE, AL_TRUE);
|
||||
|
||||
SDL_mutexV(sound_lock);
|
||||
SDL_mutexV(sound_lock);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void music_exit(void) {
|
||||
int i;
|
||||
int i;
|
||||
|
||||
// Free the music.
|
||||
alDeleteBuffers(2, music_buffer);
|
||||
alDeleteSources(1, &music_source);
|
||||
music_free();
|
||||
// Free the music.
|
||||
alDeleteBuffers(2, music_buffer);
|
||||
alDeleteSources(1, &music_source);
|
||||
music_free();
|
||||
|
||||
// Free selection
|
||||
for(i = 0; i < nmusic_selection; i++)
|
||||
free(music_selection[i]);
|
||||
free(music_selection);
|
||||
// Free selection
|
||||
for(i = 0; i < nmusic_selection; i++)
|
||||
free(music_selection[i]);
|
||||
free(music_selection);
|
||||
|
||||
SDL_DestroyMutex(music_vorbis_lock);
|
||||
SDL_DestroyMutex(music_vorbis_lock);
|
||||
}
|
||||
|
||||
// Internal music loading ruitines.
|
||||
static int music_loadOGG(const char* filename) {
|
||||
// Free currently loaded ogg.
|
||||
music_free();
|
||||
// Free currently loaded ogg.
|
||||
music_free();
|
||||
|
||||
SDL_mutexP(music_vorbis_lock);
|
||||
SDL_mutexP(music_vorbis_lock);
|
||||
|
||||
// Load the new ogg.
|
||||
pack_open(&music_vorbis.file, DATA, filename);
|
||||
ov_open_callbacks(&music_vorbis.file, &music_vorbis.stream, NULL, 0, ovcall);
|
||||
music_vorbis.info = ov_info(&music_vorbis.stream, -1);
|
||||
// Load the new ogg.
|
||||
pack_open(&music_vorbis.file, DATA, filename);
|
||||
ov_open_callbacks(&music_vorbis.file, &music_vorbis.stream, NULL, 0, ovcall);
|
||||
music_vorbis.info = ov_info(&music_vorbis.stream, -1);
|
||||
|
||||
if(music_vorbis.info->channels == 1) music_vorbis.format = AL_FORMAT_MONO16;
|
||||
else music_vorbis.format = AL_FORMAT_STEREO16;
|
||||
if(music_vorbis.info->channels == 1) music_vorbis.format = AL_FORMAT_MONO16;
|
||||
else music_vorbis.format = AL_FORMAT_STEREO16;
|
||||
|
||||
SDL_mutexV(music_vorbis_lock);
|
||||
return 0;
|
||||
SDL_mutexV(music_vorbis_lock);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int music_find(void) {
|
||||
char** files;
|
||||
uint32_t nfiles, i;
|
||||
char tmp[64];
|
||||
int len;
|
||||
char** files;
|
||||
uint32_t nfiles, i;
|
||||
char tmp[64];
|
||||
int len;
|
||||
|
||||
// Get the file list.
|
||||
files = pack_listfiles(data, &nfiles);
|
||||
// Get the file list.
|
||||
files = pack_listfiles(data, &nfiles);
|
||||
|
||||
// Load the profiles.
|
||||
for(i = 0; i < nfiles; i++)
|
||||
if((strncmp(files[i], MUSIC_PREFIX, strlen(MUSIC_PREFIX))==0) &&
|
||||
(strncmp(files[i] + strlen(files[i]) - strlen(MUSIC_SUFFIX),
|
||||
MUSIC_SUFFIX, strlen(MUSIC_SUFFIX))==0)) {
|
||||
// Load the profiles.
|
||||
for(i = 0; i < nfiles; i++)
|
||||
if((strncmp(files[i], MUSIC_PREFIX, strlen(MUSIC_PREFIX))==0) &&
|
||||
(strncmp(files[i] + strlen(files[i]) - strlen(MUSIC_SUFFIX),
|
||||
MUSIC_SUFFIX, strlen(MUSIC_SUFFIX))==0)) {
|
||||
|
||||
// Grow the selection size.
|
||||
music_selection = realloc(music_selection,++nmusic_selection*sizeof(char*));
|
||||
// Grow the selection size.
|
||||
music_selection = realloc(music_selection,++nmusic_selection*sizeof(char*));
|
||||
|
||||
// Remove the prefix and suffix.
|
||||
len = strlen(files[i]) - strlen(MUSIC_SUFFIX MUSIC_PREFIX);
|
||||
strncpy(tmp, files[i] + strlen(MUSIC_PREFIX), len);
|
||||
tmp[len] = '\0';
|
||||
// Remove the prefix and suffix.
|
||||
len = strlen(files[i]) - strlen(MUSIC_SUFFIX MUSIC_PREFIX);
|
||||
strncpy(tmp, files[i] + strlen(MUSIC_PREFIX), len);
|
||||
tmp[len] = '\0';
|
||||
|
||||
music_selection[nmusic_selection-1] = strdup(tmp);
|
||||
}
|
||||
// Free the char* allocated by pack.
|
||||
for(i = 0; i < nfiles; i++)
|
||||
free(files[i]);
|
||||
free(files);
|
||||
music_selection[nmusic_selection-1] = strdup(tmp);
|
||||
}
|
||||
// Free the char* allocated by pack.
|
||||
for(i = 0; i < nfiles; i++)
|
||||
free(files[i]);
|
||||
free(files);
|
||||
|
||||
DEBUG("Loaded %d song%c", nmusic_selection, (nmusic_selection==1)?' ':'s');
|
||||
DEBUG("Loaded %d song%c", nmusic_selection, (nmusic_selection==1)?' ':'s');
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void music_free(void) {
|
||||
SDL_mutexP(music_vorbis_lock);
|
||||
SDL_mutexP(music_vorbis_lock);
|
||||
|
||||
if(music_vorbis.file.end != 0) {
|
||||
ov_clear(&music_vorbis.stream);
|
||||
pack_close(&music_vorbis.file);
|
||||
music_vorbis.file.end = 0; // Somewhat ended.
|
||||
}
|
||||
if(music_vorbis.file.end != 0) {
|
||||
ov_clear(&music_vorbis.stream);
|
||||
pack_close(&music_vorbis.file);
|
||||
music_vorbis.file.end = 0; // Somewhat ended.
|
||||
}
|
||||
|
||||
SDL_mutexV(music_vorbis_lock);
|
||||
SDL_mutexV(music_vorbis_lock);
|
||||
}
|
||||
|
||||
void music_volume(const double vol) {
|
||||
if(sound_lock == NULL) return;
|
||||
if(sound_lock == NULL) return;
|
||||
|
||||
// Sanity check!
|
||||
ALfloat fvol = ABS(vol);
|
||||
if(fvol > 1.) fvol = 1.;
|
||||
// Sanity check!
|
||||
ALfloat fvol = ABS(vol);
|
||||
if(fvol > 1.) fvol = 1.;
|
||||
|
||||
mvolume = fvol;
|
||||
mvolume = fvol;
|
||||
|
||||
// Only needed if playing!
|
||||
if(music_set(MUSIC_PLAYING)) {
|
||||
SDL_mutexP(sound_lock);
|
||||
alSourcef(music_source, AL_GAIN, fvol);
|
||||
SDL_mutexV(sound_lock);
|
||||
}
|
||||
// Only needed if playing!
|
||||
if(music_set(MUSIC_PLAYING)) {
|
||||
SDL_mutexP(sound_lock);
|
||||
alSourcef(music_source, AL_GAIN, fvol);
|
||||
SDL_mutexV(sound_lock);
|
||||
}
|
||||
}
|
||||
|
||||
// Music control functions.
|
||||
void music_load(const char* name) {
|
||||
if(sound_lock == NULL) return;
|
||||
if(sound_lock == NULL) return;
|
||||
|
||||
int i;
|
||||
char tmp[64];
|
||||
int i;
|
||||
char tmp[64];
|
||||
|
||||
music_stop();
|
||||
while(!music_is(MUSIC_STOPPED)) SDL_Delay(0);
|
||||
music_stop();
|
||||
while(!music_is(MUSIC_STOPPED)) SDL_Delay(0);
|
||||
|
||||
for(i = 0; i < nmusic_selection; i++)
|
||||
if(strcmp(music_selection[i], name)==0) {
|
||||
snprintf(tmp, 64, MUSIC_PREFIX"%s"MUSIC_SUFFIX, name);
|
||||
music_loadOGG(tmp);
|
||||
return;
|
||||
}
|
||||
WARN("Requested load song '%s' but it can't be found in the music stack",name);
|
||||
for(i = 0; i < nmusic_selection; i++)
|
||||
if(strcmp(music_selection[i], name)==0) {
|
||||
snprintf(tmp, 64, MUSIC_PREFIX"%s"MUSIC_SUFFIX, name);
|
||||
music_loadOGG(tmp);
|
||||
return;
|
||||
}
|
||||
WARN("Requested load song '%s' but it can't be found in the music stack",name);
|
||||
}
|
||||
|
||||
void music_play(void) {
|
||||
if(!music_is(MUSIC_PLAYING)) music_set(MUSIC_PLAYING);
|
||||
if(!music_is(MUSIC_PLAYING)) music_set(MUSIC_PLAYING);
|
||||
}
|
||||
|
||||
void music_stop(void) {
|
||||
if(music_is(MUSIC_PLAYING)) music_rm(MUSIC_PLAYING);
|
||||
if(music_is(MUSIC_PLAYING)) music_rm(MUSIC_PLAYING);
|
||||
}
|
||||
|
||||
void music_kill(void) {
|
||||
if(!music_is(MUSIC_KILL)) music_set(MUSIC_KILL);
|
||||
if(!music_is(MUSIC_KILL)) music_set(MUSIC_KILL);
|
||||
}
|
||||
|
||||
|
198
src/opengl.c
198
src/opengl.c
@ -37,7 +37,7 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh);
|
||||
|
||||
// PNG.
|
||||
int write_png(const char* file_name, png_bytep* rows, int w, int h,
|
||||
int colourtype, int bitdepth);
|
||||
int colourtype, int bitdepth);
|
||||
|
||||
// ================
|
||||
// MISC!
|
||||
@ -181,7 +181,7 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh) {
|
||||
return 0;
|
||||
}
|
||||
if(SDL_FillRect(tmp, NULL, SDL_MapRGBA(surface->format, 0, 0, 0,
|
||||
SDL_ALPHA_TRANSPARENT))) {
|
||||
SDL_ALPHA_TRANSPARENT))) {
|
||||
WARN("Unable to fill rect: %s", SDL_GetError());
|
||||
return 0;
|
||||
}
|
||||
@ -203,7 +203,7 @@ static GLuint gl_loadSurface(SDL_Surface* surface, int* rw, int* rh) {
|
||||
return 0;
|
||||
}
|
||||
if(SDL_FillRect(tmp, NULL, SDL_MapRGBA(surface->format, 0, 0, 0,
|
||||
SDL_ALPHA_TRANSPARENT))) {
|
||||
SDL_ALPHA_TRANSPARENT))) {
|
||||
WARN("Unable to fill rect: %s", SDL_GetError());
|
||||
return 0;
|
||||
}
|
||||
@ -329,14 +329,14 @@ int gl_isTrans(const glTexture* t, const int x, const int y) {
|
||||
|
||||
// Set x and y to be the appropriate sprite for glTexture using dir.
|
||||
void gl_getSpriteFromDir(int* x, int* y, const glTexture* t, const double dir) {
|
||||
int s, sx, sy;
|
||||
int s, sx, sy;
|
||||
|
||||
s = (int)(dir / (2.0*M_PI / (t->sy*t->sx)));
|
||||
sx = t->sx;
|
||||
sy = t->sy;
|
||||
sx = t->sx;
|
||||
sy = t->sy;
|
||||
|
||||
// Make sure the sprite is "in range".
|
||||
if(s > (sy*sx-1)) s = s % (sy*sx);
|
||||
if(s > (sy*sx-1)) s = s % (sy*sx);
|
||||
|
||||
*x = s % sx;
|
||||
*y = s / sx;
|
||||
@ -389,7 +389,7 @@ void gl_blitSprite(const glTexture* sprite, const double bx, const double by,
|
||||
|
||||
// Just straight out blit the thing at position.
|
||||
void gl_blitStatic(const glTexture* texture, const double bx, const double by,
|
||||
const glColour* c) {
|
||||
const glColour* c) {
|
||||
double x, y;
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
@ -426,110 +426,110 @@ void gl_bindCamera(const Vec2* pos) {
|
||||
|
||||
// Draw circles.
|
||||
void gl_drawCircle(const double cx, const double cy, const double r) {
|
||||
double x, y, p;
|
||||
double x, y, p;
|
||||
|
||||
x = 0;
|
||||
y = r;
|
||||
p = (5. - (r*4.)) / 4.;
|
||||
x = 0;
|
||||
y = r;
|
||||
p = (5. - (r*4.)) / 4.;
|
||||
|
||||
glBegin(GL_POINTS);
|
||||
glVertex2d(cx, cy+y);
|
||||
glVertex2d(cx, cy-y);
|
||||
glVertex2d(cx+y, cy);
|
||||
glVertex2d(cx-y, cy);
|
||||
glBegin(GL_POINTS);
|
||||
glVertex2d(cx, cy+y);
|
||||
glVertex2d(cx, cy-y);
|
||||
glVertex2d(cx+y, cy);
|
||||
glVertex2d(cx-y, cy);
|
||||
|
||||
while(x < y) {
|
||||
x++;
|
||||
if(p < 0) p += 2*(double)(x)+1;
|
||||
else p += 2*(double)(x-(--y))+1;
|
||||
while(x < y) {
|
||||
x++;
|
||||
if(p < 0) p += 2*(double)(x)+1;
|
||||
else p += 2*(double)(x-(--y))+1;
|
||||
|
||||
if(x == 0) {
|
||||
glVertex2d(cx, cy+y);
|
||||
glVertex2d(cx, cy-y);
|
||||
glVertex2d(cx+y, cy);
|
||||
glVertex2d(cx-y, cy);
|
||||
}
|
||||
else if(x == y) {
|
||||
glVertex2d(cx+x, cy+y);
|
||||
glVertex2d(cx-x, cy+y);
|
||||
glVertex2d(cx+x, cy-y);
|
||||
glVertex2d(cx-x, cy-y);
|
||||
}
|
||||
else if(x < y) {
|
||||
glVertex2d(cx+x, cy+y);
|
||||
glVertex2d(cx-x, cy+y);
|
||||
glVertex2d(cx+x, cy-y);
|
||||
glVertex2d(cx-x, cy-y);
|
||||
glVertex2d(cx+y, cy+x);
|
||||
glVertex2d(cx-y, cy+x);
|
||||
glVertex2d(cx+y, cy-x);
|
||||
glVertex2d(cx-y, cy-x);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
if(x == 0) {
|
||||
glVertex2d(cx, cy+y);
|
||||
glVertex2d(cx, cy-y);
|
||||
glVertex2d(cx+y, cy);
|
||||
glVertex2d(cx-y, cy);
|
||||
}
|
||||
else if(x == y) {
|
||||
glVertex2d(cx+x, cy+y);
|
||||
glVertex2d(cx-x, cy+y);
|
||||
glVertex2d(cx+x, cy-y);
|
||||
glVertex2d(cx-x, cy-y);
|
||||
}
|
||||
else if(x < y) {
|
||||
glVertex2d(cx+x, cy+y);
|
||||
glVertex2d(cx-x, cy+y);
|
||||
glVertex2d(cx+x, cy-y);
|
||||
glVertex2d(cx-x, cy-y);
|
||||
glVertex2d(cx+y, cy+x);
|
||||
glVertex2d(cx-y, cy+x);
|
||||
glVertex2d(cx+y, cy-x);
|
||||
glVertex2d(cx-y, cy-x);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
// Draw a cirlce in a rect.
|
||||
#define PIXEL(x,y) \
|
||||
if((x>rx) && (y>ry) && (x<rxw) && (y<ryh)) \
|
||||
glVertex2d(x,y)
|
||||
glVertex2d(x,y)
|
||||
|
||||
void gl_drawCircleInRect(const double cx, const double cy, const double r,
|
||||
const double rx, const double ry, const double rw, const double rh) {
|
||||
const double rx, const double ry, const double rw, const double rh) {
|
||||
|
||||
double rxw, ryh, x, y, p;
|
||||
double rxw, ryh, x, y, p;
|
||||
|
||||
rxw = rx+rw;
|
||||
ryh = ry+rh;
|
||||
rxw = rx+rw;
|
||||
ryh = ry+rh;
|
||||
|
||||
// Are we offscreen?
|
||||
if((cx+r < rx) || (cy+r < ry) || (cx-r > rxw) || (cy-r > ryh))
|
||||
return;
|
||||
// Can be drawn normally.
|
||||
else if((cx-r > rx) && (cy-r > ry) && (cx+r < rxw) && (cy+r < ryh)) {
|
||||
gl_drawCircle(cx, cy, r);
|
||||
return;
|
||||
}
|
||||
// Are we offscreen?
|
||||
if((cx+r < rx) || (cy+r < ry) || (cx-r > rxw) || (cy-r > ryh))
|
||||
return;
|
||||
// Can be drawn normally.
|
||||
else if((cx-r > rx) && (cy-r > ry) && (cx+r < rxw) && (cy+r < ryh)) {
|
||||
gl_drawCircle(cx, cy, r);
|
||||
return;
|
||||
}
|
||||
|
||||
x = 0;
|
||||
y = r;
|
||||
p = (5. - (r*4.)) / 4.;
|
||||
x = 0;
|
||||
y = r;
|
||||
p = (5. - (r*4.)) / 4.;
|
||||
|
||||
glBegin(GL_POINTS);
|
||||
PIXEL(cx, cy+y);
|
||||
PIXEL(cx, cy-y);
|
||||
PIXEL(cx+y, cy);
|
||||
PIXEL(cx-y, cy);
|
||||
glBegin(GL_POINTS);
|
||||
PIXEL(cx, cy+y);
|
||||
PIXEL(cx, cy-y);
|
||||
PIXEL(cx+y, cy);
|
||||
PIXEL(cx-y, cy);
|
||||
|
||||
while(x < y) {
|
||||
x++;
|
||||
if(p < 0) p += 2*(double)(x)+1;
|
||||
else p += 2*(double)(x-(--y))+1;
|
||||
while(x < y) {
|
||||
x++;
|
||||
if(p < 0) p += 2*(double)(x)+1;
|
||||
else p += 2*(double)(x-(--y))+1;
|
||||
|
||||
if(x == 0) {
|
||||
PIXEL(cx, cy+y);
|
||||
PIXEL(cx, cy-y);
|
||||
PIXEL(cx+y, cy);
|
||||
PIXEL(cx-y, cy);
|
||||
}
|
||||
else if(x == y) {
|
||||
PIXEL(cx+x, cy+y);
|
||||
PIXEL(cx-x, cy+y);
|
||||
PIXEL(cx+x, cy-y);
|
||||
PIXEL(cx-x, cy-y);
|
||||
}
|
||||
else if(x < y) {
|
||||
PIXEL(cx+x, cy+y);
|
||||
PIXEL(cx-x, cy+y);
|
||||
PIXEL(cx+x, cy-y);
|
||||
PIXEL(cx-x, cy-y);
|
||||
PIXEL(cx+y, cy+x);
|
||||
PIXEL(cx-y, cy+x);
|
||||
PIXEL(cx+y, cy-x);
|
||||
PIXEL(cx-y, cy-x);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
if(x == 0) {
|
||||
PIXEL(cx, cy+y);
|
||||
PIXEL(cx, cy-y);
|
||||
PIXEL(cx+y, cy);
|
||||
PIXEL(cx-y, cy);
|
||||
}
|
||||
else if(x == y) {
|
||||
PIXEL(cx+x, cy+y);
|
||||
PIXEL(cx-x, cy+y);
|
||||
PIXEL(cx+x, cy-y);
|
||||
PIXEL(cx-x, cy-y);
|
||||
}
|
||||
else if(x < y) {
|
||||
PIXEL(cx+x, cy+y);
|
||||
PIXEL(cx-x, cy+y);
|
||||
PIXEL(cx+x, cy-y);
|
||||
PIXEL(cx-x, cy-y);
|
||||
PIXEL(cx+y, cy+x);
|
||||
PIXEL(cx-y, cy+x);
|
||||
PIXEL(cx+y, cy-x);
|
||||
PIXEL(cx-y, cy-x);
|
||||
}
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
|
||||
// ================
|
||||
@ -566,7 +566,7 @@ int gl_init(void) {
|
||||
for(i = 0; modes[i]; i++) {
|
||||
DEBUG("\t%dx%d", modes[i]->w, modes[i]->h);
|
||||
if((flags & SDL_FULLSCREEN) && (modes[i]->w == gl_screen.w) &&
|
||||
(modes[i]->h == gl_screen.h))
|
||||
(modes[i]->h == gl_screen.h))
|
||||
supported = 1; // Mode we asked for is supported.
|
||||
}
|
||||
}
|
||||
@ -621,10 +621,10 @@ int gl_init(void) {
|
||||
|
||||
// Debug heaven.
|
||||
DEBUG("OpenGL Window Created: %dx%d@%dbpp %s", gl_screen.w, gl_screen.h,
|
||||
gl_screen.depth, (gl_has(OPENGL_FULLSCREEN)) ? "fullscreen" : "window");
|
||||
gl_screen.depth, (gl_has(OPENGL_FULLSCREEN)) ? "fullscreen" : "window");
|
||||
|
||||
DEBUG("r: %d, g: %d, b: %d, a: %d, doublebuffer: %s",
|
||||
gl_screen.r, gl_screen.g, gl_screen.b, gl_screen.a,
|
||||
gl_screen.r, gl_screen.g, gl_screen.b, gl_screen.a,
|
||||
(gl_has(OPENGL_DOUBLEBUF)) ? "yes" : "no");
|
||||
|
||||
DEBUG("Renderer: %s", glGetString(GL_RENDERER));
|
||||
@ -658,7 +658,7 @@ void gl_exit(void) {
|
||||
|
||||
// Saves a png.
|
||||
int write_png(const char* file_name, png_bytep* rows, int w, int h,
|
||||
int colourtype, int bitdepth) {
|
||||
int colourtype, int bitdepth) {
|
||||
png_structp png_ptr;
|
||||
png_infop info_ptr;
|
||||
FILE* fp = NULL;
|
||||
@ -668,7 +668,7 @@ int write_png(const char* file_name, png_bytep* rows, int w, int h,
|
||||
|
||||
doing = "Create png write struct";
|
||||
if(!(png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
|
||||
NULL, NULL, NULL))) goto fail;
|
||||
NULL, NULL, NULL))) goto fail;
|
||||
|
||||
doing = "Create png info struct";
|
||||
if(!(info_ptr = png_create_info_struct(png_ptr))) goto fail;
|
||||
|
@ -33,8 +33,8 @@ typedef struct glInfo_ {
|
||||
} glInfo;
|
||||
extern glInfo gl_screen; // Local structure set with gl_init etc.
|
||||
|
||||
#define COLOUR(x) glColor4d((x).r, (x).g, (x).b, (x).a)
|
||||
#define ACOLOUR(x,a) glColor4d((x).r, (x).g, (x).b, a)
|
||||
#define COLOUR(x) glColor4d((x).r, (x).g, (x).b, (x).a)
|
||||
#define ACOLOUR(x,a) glColor4d((x).r, (x).g, (x).b, a)
|
||||
|
||||
// Spritesheet info.
|
||||
typedef struct glTexture_ {
|
||||
@ -67,7 +67,7 @@ void gl_bindCamera(const Vec2* pos);
|
||||
// Circle drawing.
|
||||
void gl_drawCircle(const double x, const double y, const double r);
|
||||
void gl_drawCircleInRect(const double x, const double y, const double r,
|
||||
const double rc, const double ry, const double rw, const double rh);
|
||||
const double rc, const double ry, const double rw, const double rh);
|
||||
|
||||
// Initialize/cleanup.
|
||||
int gl_init(void);
|
||||
|
330
src/outfit.c
330
src/outfit.c
@ -42,24 +42,24 @@ Outfit* outfit_get(const char* name) {
|
||||
|
||||
// Return all the outfits.
|
||||
char** outfit_getTech(int* n, const int* tech, const int techmax) {
|
||||
int i, j;
|
||||
char** outfitnames = malloc(sizeof(Outfit*) * outfits);
|
||||
int i, j;
|
||||
char** outfitnames = malloc(sizeof(Outfit*) * outfits);
|
||||
|
||||
*n = 0;
|
||||
for(i = 0; i < outfits; i++)
|
||||
if(outfit_stack[i].tech <= tech[0]) {
|
||||
outfitnames[*n] = strdup(outfit_stack[i].name);
|
||||
(*n)++;
|
||||
} else {
|
||||
for(j = 0; j < techmax; j++)
|
||||
if(tech[j] == outfit_stack[i].tech) {
|
||||
outfitnames[*n] = strdup(outfit_stack[i].name);
|
||||
(*n)++;
|
||||
}
|
||||
}
|
||||
*n = 0;
|
||||
for(i = 0; i < outfits; i++)
|
||||
if(outfit_stack[i].tech <= tech[0]) {
|
||||
outfitnames[*n] = strdup(outfit_stack[i].name);
|
||||
(*n)++;
|
||||
} else {
|
||||
for(j = 0; j < techmax; j++)
|
||||
if(tech[j] == outfit_stack[i].tech) {
|
||||
outfitnames[*n] = strdup(outfit_stack[i].name);
|
||||
(*n)++;
|
||||
}
|
||||
}
|
||||
|
||||
// Actual size is bigger, but it'll just get freed ;).
|
||||
return outfitnames;
|
||||
// Actual size is bigger, but it'll just get freed ;).
|
||||
return outfitnames;
|
||||
}
|
||||
|
||||
// Return 1 if outfit is a weapon (beam/bolt).
|
||||
@ -87,62 +87,62 @@ int outfit_isAmmo(const Outfit* o) {
|
||||
}
|
||||
|
||||
int outfit_isTurret(const Outfit* o) {
|
||||
return ((o->type == OUTFIT_TYPE_TURRET_BOLT) ||
|
||||
(o->type == OUTFIT_TYPE_TURRET_BEAM));
|
||||
return ((o->type == OUTFIT_TYPE_TURRET_BOLT) ||
|
||||
(o->type == OUTFIT_TYPE_TURRET_BEAM));
|
||||
}
|
||||
|
||||
// Return 1 if o is a modification.
|
||||
int outfit_isMod(const Outfit* o) {
|
||||
return (o->type == OUTFIT_TYPE_MODIFICATION);
|
||||
return (o->type == OUTFIT_TYPE_MODIFICATION);
|
||||
}
|
||||
|
||||
// Return 1 if o is an afterburner.
|
||||
int outfit_isAfterburner(const Outfit* o) {
|
||||
return (o->type == OUTFIT_TYPE_AFTERBURNER);
|
||||
return (o->type == OUTFIT_TYPE_AFTERBURNER);
|
||||
}
|
||||
|
||||
// Get the outfit graphics.
|
||||
glTexture* outfit_gfx(const Outfit* o) {
|
||||
if(outfit_isWeapon(o)) return o->u.blt.gfx_space;
|
||||
else if(outfit_isAmmo(o)) return o->u.amm.gfx_space;
|
||||
else if(outfit_isTurret(o)) return o->u.blt.gfx_space;
|
||||
return NULL;
|
||||
if(outfit_isWeapon(o)) return o->u.blt.gfx_space;
|
||||
else if(outfit_isAmmo(o)) return o->u.amm.gfx_space;
|
||||
else if(outfit_isTurret(o)) return o->u.blt.gfx_space;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Get the outfit spfx if applicable.
|
||||
int outfit_spfx(const Outfit* o) {
|
||||
if(outfit_isWeapon(o)) return o->u.blt.spfx;
|
||||
else if(outfit_isAmmo(o)) return o->u.amm.spfx;
|
||||
else if(outfit_isTurret(o)) return o->u.blt.spfx;
|
||||
return -1;
|
||||
if(outfit_isWeapon(o)) return o->u.blt.spfx;
|
||||
else if(outfit_isAmmo(o)) return o->u.amm.spfx;
|
||||
else if(outfit_isTurret(o)) return o->u.blt.spfx;
|
||||
return -1;
|
||||
}
|
||||
|
||||
double outfit_dmgShield(const Outfit* o) {
|
||||
if(outfit_isWeapon(o)) return o->u.blt.damage_armour;
|
||||
else if(outfit_isAmmo(o)) return o->u.amm.damage_armour;
|
||||
else if(outfit_isTurret(o)) return o->u.blt.damage_armour;
|
||||
return -1;
|
||||
if(outfit_isWeapon(o)) return o->u.blt.damage_armour;
|
||||
else if(outfit_isAmmo(o)) return o->u.amm.damage_armour;
|
||||
else if(outfit_isTurret(o)) return o->u.blt.damage_armour;
|
||||
return -1;
|
||||
}
|
||||
|
||||
double outfit_dmgArmour(const Outfit* o) {
|
||||
if(outfit_isWeapon(o)) return o->u.blt.damage_shield;
|
||||
else if(outfit_isAmmo(o)) return o->u.amm.damage_shield;
|
||||
else if(outfit_isTurret(o)) return o->u.blt.damage_shield;
|
||||
return -1;
|
||||
if(outfit_isWeapon(o)) return o->u.blt.damage_shield;
|
||||
else if(outfit_isAmmo(o)) return o->u.amm.damage_shield;
|
||||
else if(outfit_isTurret(o)) return o->u.blt.damage_shield;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int outfit_delay(const Outfit* o) {
|
||||
if(outfit_isWeapon(o)) return o->u.blt.delay;
|
||||
else if(outfit_isLauncher(o)) return o->u.lau.delay;
|
||||
else if(outfit_isTurret(o)) return o->u.blt.delay;
|
||||
return -1;
|
||||
if(outfit_isWeapon(o)) return o->u.blt.delay;
|
||||
else if(outfit_isLauncher(o)) return o->u.lau.delay;
|
||||
else if(outfit_isTurret(o)) return o->u.blt.delay;
|
||||
return -1;
|
||||
}
|
||||
|
||||
double outfit_energy(const Outfit* o) {
|
||||
if(outfit_isWeapon(o)) return o->u.blt.energy;
|
||||
else if(outfit_isAmmo(o)) return o->u.amm.energy;
|
||||
else if(outfit_isTurret(o)) return o->u.blt.energy;
|
||||
return -1.;
|
||||
if(outfit_isWeapon(o)) return o->u.blt.energy;
|
||||
else if(outfit_isAmmo(o)) return o->u.amm.energy;
|
||||
else if(outfit_isTurret(o)) return o->u.blt.energy;
|
||||
return -1.;
|
||||
}
|
||||
|
||||
const char* outfit_typename[] = {
|
||||
@ -159,10 +159,10 @@ const char* outfit_typename[] = {
|
||||
"Swarm Missile Ammunition Pack",
|
||||
"Smart Swarm Missile",
|
||||
"Smart Swarm Missile Ammunition Pack",
|
||||
"Bolt Turret",
|
||||
"Beam Turret",
|
||||
"Ship Modification",
|
||||
"Afterburner"
|
||||
"Bolt Turret",
|
||||
"Beam Turret",
|
||||
"Ship Modification",
|
||||
"Afterburner"
|
||||
};
|
||||
|
||||
const char* outfit_getType(const Outfit* o) {
|
||||
@ -171,23 +171,23 @@ const char* outfit_getType(const Outfit* o) {
|
||||
|
||||
// Return the broad outfit type.
|
||||
const char* outfit_typenamebroad[] = {
|
||||
"NULL",
|
||||
"Weapon",
|
||||
"Launcher",
|
||||
"Ammo",
|
||||
"Turret",
|
||||
"Modification",
|
||||
"Afterburner"
|
||||
"NULL",
|
||||
"Weapon",
|
||||
"Launcher",
|
||||
"Ammo",
|
||||
"Turret",
|
||||
"Modification",
|
||||
"Afterburner"
|
||||
};
|
||||
|
||||
const char* outfit_getTypeBroad(const Outfit* o) {
|
||||
int i = 0;
|
||||
if(outfit_isWeapon(o)) i = 1;
|
||||
else if(outfit_isLauncher(o)) i = 2;
|
||||
else if(outfit_isAmmo(o)) i = 3;
|
||||
else if(outfit_isTurret(o)) i = 4;
|
||||
else if(outfit_isMod(o)) i = 5;
|
||||
else if(outfit_isAfterburner(o)) i = 6;
|
||||
if(outfit_isWeapon(o)) i = 1;
|
||||
else if(outfit_isLauncher(o)) i = 2;
|
||||
else if(outfit_isAmmo(o)) i = 3;
|
||||
else if(outfit_isTurret(o)) i = 4;
|
||||
else if(outfit_isMod(o)) i = 5;
|
||||
else if(outfit_isAfterburner(o)) i = 6;
|
||||
|
||||
return outfit_typenamebroad[i];
|
||||
}
|
||||
@ -205,31 +205,31 @@ static void outfit_parseSWeapon(Outfit* tmp, const xmlNodePtr parent) {
|
||||
else if(xml_isNode(node, "delay")) tmp->u.blt.delay = xml_getInt(node);
|
||||
else if(xml_isNode(node, "range")) tmp->u.blt.range = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "accuracy")) tmp->u.blt.accuracy = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "energy")) tmp->u.blt.energy = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "energy")) tmp->u.blt.energy = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "gfx")) {
|
||||
snprintf(str, strlen(xml_get(node))+sizeof(OUTFIT_GFX)+10,
|
||||
OUTFIT_GFX"space/%s.png", xml_get(node));
|
||||
OUTFIT_GFX"space/%s.png", xml_get(node));
|
||||
tmp->u.blt.gfx_space = gl_newSprite(str, 6, 6);
|
||||
}
|
||||
else if(xml_isNode(node, "spfx"))
|
||||
tmp->u.blt.spfx = spfx_get(xml_get(node));
|
||||
else if(xml_isNode(node, "sound"))
|
||||
tmp->u.blt.sound = sound_get(xml_get(node));
|
||||
else if(xml_isNode(node, "spfx"))
|
||||
tmp->u.blt.spfx = spfx_get(xml_get(node));
|
||||
else if(xml_isNode(node, "sound"))
|
||||
tmp->u.blt.sound = sound_get(xml_get(node));
|
||||
else if(xml_isNode(node, "damage")) {
|
||||
cur = node->children;
|
||||
do {
|
||||
if(xml_isNode(cur, "armour"))
|
||||
tmp->u.blt.damage_armour = xml_getFloat(cur);
|
||||
tmp->u.blt.damage_armour = xml_getFloat(cur);
|
||||
else if(xml_isNode(cur, "shield"))
|
||||
tmp->u.blt.damage_shield = xml_getFloat(cur);
|
||||
tmp->u.blt.damage_shield = xml_getFloat(cur);
|
||||
} while((cur = cur->next));
|
||||
}
|
||||
} while((node = node->next));
|
||||
#define MELEMENT(o,s) if((o) == 0) \
|
||||
WARN("Outfit '%s' missing '"s"' element", tmp->name)
|
||||
WARN("Outfit '%s' missing '"s"' element", tmp->name)
|
||||
if(tmp->u.blt.gfx_space == NULL)
|
||||
WARN("Outfit '%s' missing 'gfx' element", tmp->name);
|
||||
MELEMENT(tmp->u.blt.sound, "sound");
|
||||
MELEMENT(tmp->u.blt.sound, "sound");
|
||||
MELEMENT(tmp->u.blt.delay, "delay");
|
||||
MELEMENT(tmp->u.blt.speed, "speed");
|
||||
MELEMENT(tmp->u.blt.range, "range");
|
||||
@ -251,8 +251,8 @@ static void outfit_parseSLauncher(Outfit* tmp, const xmlNodePtr parent) {
|
||||
} while((node = node->next));
|
||||
|
||||
#define MELEMENT(o,s) if(o) WARN("Outfit '%s' missing '"s"' element", tmp->name)
|
||||
MELEMENT(tmp->u.lau.ammo == NULL, "ammo");
|
||||
MELEMENT(tmp->u.lau.delay==0, "delay");
|
||||
MELEMENT(tmp->u.lau.ammo == NULL, "ammo");
|
||||
MELEMENT(tmp->u.lau.delay==0, "delay");
|
||||
#undef MELEMENT
|
||||
}
|
||||
|
||||
@ -267,20 +267,20 @@ static void outfit_parseSAmmo(Outfit* tmp, const xmlNodePtr parent) {
|
||||
if(xml_isNode(node, "thrust")) tmp->u.amm.thrust = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "turn")) tmp->u.amm.turn = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "speed")) tmp->u.amm.speed = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "energy")) tmp->u.amm.energy = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "energy")) tmp->u.amm.energy = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "duration"))
|
||||
tmp->u.amm.duration = (unsigned int)1000.*xml_getFloat(node);
|
||||
else if(xml_isNode(node, "lockon"))
|
||||
tmp->u.amm.lockon = (unsigned int)1000.*xml_getFloat(node);
|
||||
tmp->u.amm.duration = (unsigned int)1000.*xml_getFloat(node);
|
||||
else if(xml_isNode(node, "lockon"))
|
||||
tmp->u.amm.lockon = (unsigned int)1000.*xml_getFloat(node);
|
||||
else if(xml_isNode(node, "gfx")) {
|
||||
snprintf(str, strlen(xml_get(node))+sizeof(OUTFIT_GFX)+10,
|
||||
OUTFIT_GFX"space/%s.png", xml_get(node));
|
||||
tmp->u.amm.gfx_space = gl_newSprite(str, 6, 6);
|
||||
}
|
||||
else if(xml_isNode(node, "spfx"))
|
||||
tmp->u.amm.spfx = spfx_get(xml_get(node));
|
||||
else if(xml_isNode(node, "sound"))
|
||||
tmp->u.amm.sound = sound_get(xml_get(node));
|
||||
else if(xml_isNode(node, "spfx"))
|
||||
tmp->u.amm.spfx = spfx_get(xml_get(node));
|
||||
else if(xml_isNode(node, "sound"))
|
||||
tmp->u.amm.sound = sound_get(xml_get(node));
|
||||
else if(xml_isNode(node, "damage")) {
|
||||
cur = node->children;
|
||||
do {
|
||||
@ -290,70 +290,70 @@ static void outfit_parseSAmmo(Outfit* tmp, const xmlNodePtr parent) {
|
||||
}
|
||||
} while((node = node->next));
|
||||
#define MELEMENT(o,s) if(o) WARN("Outfit '%s' missing '"s"' element", tmp->name)
|
||||
MELEMENT(tmp->u.amm.gfx_space == NULL, "gfx");
|
||||
MELEMENT((sound_lock != NULL) && (tmp->u.amm.sound == 0), "sound");
|
||||
MELEMENT(tmp->u.amm.thrust==0, "thrust");
|
||||
MELEMENT(tmp->u.amm.turn==0, "turn");
|
||||
MELEMENT(tmp->u.amm.speed==0, "speed");
|
||||
MELEMENT(tmp->u.amm.duration==0, "duration");
|
||||
MELEMENT(tmp->u.amm.lockon==0, "lockon");
|
||||
MELEMENT(tmp->u.amm.damage_armour==0, "armour' from element 'damage");
|
||||
MELEMENT(tmp->u.amm.damage_shield==0, "shield' from element 'damage");
|
||||
MELEMENT(tmp->u.amm.gfx_space == NULL, "gfx");
|
||||
MELEMENT((sound_lock != NULL) && (tmp->u.amm.sound == 0), "sound");
|
||||
MELEMENT(tmp->u.amm.thrust==0, "thrust");
|
||||
MELEMENT(tmp->u.amm.turn==0, "turn");
|
||||
MELEMENT(tmp->u.amm.speed==0, "speed");
|
||||
MELEMENT(tmp->u.amm.duration==0, "duration");
|
||||
MELEMENT(tmp->u.amm.lockon==0, "lockon");
|
||||
MELEMENT(tmp->u.amm.damage_armour==0, "armour' from element 'damage");
|
||||
MELEMENT(tmp->u.amm.damage_shield==0, "shield' from element 'damage");
|
||||
#undef MELEMENT
|
||||
}
|
||||
|
||||
static void outfit_parseSMod(Outfit* tmp, const xmlNodePtr parent) {
|
||||
xmlNodePtr node;
|
||||
node = parent->children;
|
||||
xmlNodePtr node;
|
||||
node = parent->children;
|
||||
|
||||
// Load all the data.
|
||||
do {
|
||||
// Movement.
|
||||
if(xml_isNode(node, "thrust"))
|
||||
tmp->u.mod.thrust = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "turn"))
|
||||
tmp->u.mod.turn = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "speed"))
|
||||
tmp->u.mod.speed = xml_getFloat(node);
|
||||
// Load all the data.
|
||||
do {
|
||||
// Movement.
|
||||
if(xml_isNode(node, "thrust"))
|
||||
tmp->u.mod.thrust = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "turn"))
|
||||
tmp->u.mod.turn = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "speed"))
|
||||
tmp->u.mod.speed = xml_getFloat(node);
|
||||
|
||||
// Health.
|
||||
if(xml_isNode(node, "armour"))
|
||||
tmp->u.mod.armour = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "shield"))
|
||||
tmp->u.mod.shield = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "energy"))
|
||||
tmp->u.mod.energy = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "armour_regen"))
|
||||
tmp->u.mod.armour_regen = xml_getFloat(node)/60.0;
|
||||
else if(xml_isNode(node, "shield_regen"))
|
||||
tmp->u.mod.shield_regen = xml_getFloat(node)/60.0;
|
||||
else if(xml_isNode(node, "energy_regen"))
|
||||
tmp->u.mod.energy_regen = xml_getFloat(node)/60.0;
|
||||
// Health.
|
||||
if(xml_isNode(node, "armour"))
|
||||
tmp->u.mod.armour = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "shield"))
|
||||
tmp->u.mod.shield = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "energy"))
|
||||
tmp->u.mod.energy = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "armour_regen"))
|
||||
tmp->u.mod.armour_regen = xml_getFloat(node)/60.0;
|
||||
else if(xml_isNode(node, "shield_regen"))
|
||||
tmp->u.mod.shield_regen = xml_getFloat(node)/60.0;
|
||||
else if(xml_isNode(node, "energy_regen"))
|
||||
tmp->u.mod.energy_regen = xml_getFloat(node)/60.0;
|
||||
|
||||
} while((node = node->next));
|
||||
} while((node = node->next));
|
||||
}
|
||||
|
||||
// Parses the afterburner tidbits of the outfit.
|
||||
static void outfit_parseSAfterburner(Outfit* tmp, const xmlNodePtr parent) {
|
||||
xmlNodePtr node;
|
||||
node = parent->children;
|
||||
xmlNodePtr node;
|
||||
node = parent->children;
|
||||
|
||||
// Must be >= 1.
|
||||
tmp->u.afb.thrust_perc = 1.;
|
||||
tmp->u.afb.speed_perc = 1.;
|
||||
// Must be >= 1.
|
||||
tmp->u.afb.thrust_perc = 1.;
|
||||
tmp->u.afb.speed_perc = 1.;
|
||||
|
||||
do {
|
||||
if(xml_isNode(node, "thrust_perc"))
|
||||
tmp->u.afb.thrust_perc = 1. + xml_getFloat(node)/100.;
|
||||
else if(xml_isNode(node, "thrust_abs"))
|
||||
tmp->u.afb.thrust_abs = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "speed_perc"))
|
||||
tmp->u.afb.speed_perc = 1. + xml_getFloat(node)/100.;
|
||||
else if(xml_isNode(node, "speed_abs"))
|
||||
tmp->u.afb.speed_abs = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "energy"))
|
||||
tmp->u.afb.energy = xml_getFloat(node);
|
||||
} while((node = node->next));
|
||||
do {
|
||||
if(xml_isNode(node, "thrust_perc"))
|
||||
tmp->u.afb.thrust_perc = 1. + xml_getFloat(node)/100.;
|
||||
else if(xml_isNode(node, "thrust_abs"))
|
||||
tmp->u.afb.thrust_abs = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "speed_perc"))
|
||||
tmp->u.afb.speed_perc = 1. + xml_getFloat(node)/100.;
|
||||
else if(xml_isNode(node, "speed_abs"))
|
||||
tmp->u.afb.speed_abs = xml_getFloat(node);
|
||||
else if(xml_isNode(node, "energy"))
|
||||
tmp->u.afb.energy = xml_getFloat(node);
|
||||
} while((node = node->next));
|
||||
}
|
||||
|
||||
// Parse and return Outfits from parent node.
|
||||
@ -361,7 +361,7 @@ static Outfit* outfit_parse(const xmlNodePtr parent) {
|
||||
Outfit* tmp = CALLOC_L(Outfit);
|
||||
xmlNodePtr cur, node;
|
||||
char* prop;
|
||||
char str[PATH_MAX] = "\0";
|
||||
char str[PATH_MAX] = "\0";
|
||||
|
||||
tmp->name = xml_nodeProp(parent, "name"); // Already malloced.
|
||||
if(tmp->name == NULL) WARN("Outfit in "OUTFIT_DATA" has invalid or no name");
|
||||
@ -373,16 +373,16 @@ static Outfit* outfit_parse(const xmlNodePtr parent) {
|
||||
cur = node->children;
|
||||
do {
|
||||
if(xml_isNode(cur, "max")) tmp->max = xml_getInt(cur);
|
||||
else if(xml_isNode(cur, "tech")) tmp->tech = xml_getInt(cur);
|
||||
else if(xml_isNode(cur, "mass")) tmp->mass = xml_getInt(cur);
|
||||
else if(xml_isNode(cur, "price")) tmp->price = xml_getInt(cur);
|
||||
else if(xml_isNode(cur, "description"))
|
||||
tmp->description = strdup(xml_get(cur));
|
||||
else if(xml_isNode(cur, "gfx_store")) {
|
||||
snprintf(str, strlen(xml_get(cur))+sizeof(OUTFIT_GFX)+10,
|
||||
OUTFIT_GFX"store/%s.png", xml_get(cur));
|
||||
tmp->gfx_store = gl_newImage(str);
|
||||
}
|
||||
else if(xml_isNode(cur, "tech")) tmp->tech = xml_getInt(cur);
|
||||
else if(xml_isNode(cur, "mass")) tmp->mass = xml_getInt(cur);
|
||||
else if(xml_isNode(cur, "price")) tmp->price = xml_getInt(cur);
|
||||
else if(xml_isNode(cur, "description"))
|
||||
tmp->description = strdup(xml_get(cur));
|
||||
else if(xml_isNode(cur, "gfx_store")) {
|
||||
snprintf(str, strlen(xml_get(cur))+sizeof(OUTFIT_GFX)+10,
|
||||
OUTFIT_GFX"store/%s.png", xml_get(cur));
|
||||
tmp->gfx_store = gl_newImage(str);
|
||||
}
|
||||
} while((cur = cur->next));
|
||||
}
|
||||
else if(xml_isNode(node, "specific")) {
|
||||
@ -409,23 +409,23 @@ static Outfit* outfit_parse(const xmlNodePtr parent) {
|
||||
outfit_parseSLauncher(tmp, node);
|
||||
else if(outfit_isAmmo(tmp))
|
||||
outfit_parseSAmmo(tmp, node);
|
||||
else if(outfit_isTurret(tmp))
|
||||
outfit_parseSWeapon(tmp, node);
|
||||
else if(outfit_isMod(tmp))
|
||||
outfit_parseSMod(tmp, node);
|
||||
else if(outfit_isAfterburner(tmp))
|
||||
outfit_parseSAfterburner(tmp, node);
|
||||
else if(outfit_isTurret(tmp))
|
||||
outfit_parseSWeapon(tmp, node);
|
||||
else if(outfit_isMod(tmp))
|
||||
outfit_parseSMod(tmp, node);
|
||||
else if(outfit_isAfterburner(tmp))
|
||||
outfit_parseSAfterburner(tmp, node);
|
||||
}
|
||||
} while((node = node->next));
|
||||
#define MELEMENT(o,s) if(o) WARN("Outfit '%s' missing '"s"' element", tmp->name)
|
||||
MELEMENT(tmp->name==NULL, "name");
|
||||
MELEMENT(tmp->max==0, "max");
|
||||
MELEMENT(tmp->tech==0, "tech");
|
||||
MELEMENT(tmp->gfx_store==NULL, "gfx_store");
|
||||
//MELEMENT(tmp->mass==0, "mass");
|
||||
MELEMENT(tmp->type==0, "type");
|
||||
MELEMENT(tmp->price==0, "price");
|
||||
MELEMENT(tmp->description==NULL, "description");
|
||||
MELEMENT(tmp->name==NULL, "name");
|
||||
MELEMENT(tmp->max==0, "max");
|
||||
MELEMENT(tmp->tech==0, "tech");
|
||||
MELEMENT(tmp->gfx_store==NULL, "gfx_store");
|
||||
//MELEMENT(tmp->mass==0, "mass");
|
||||
MELEMENT(tmp->type==0, "type");
|
||||
MELEMENT(tmp->price==0, "price");
|
||||
MELEMENT(tmp->description==NULL, "description");
|
||||
#undef MELEMENT
|
||||
|
||||
return tmp;
|
||||
@ -466,7 +466,7 @@ int outfit_load(void) {
|
||||
free(buf);
|
||||
xmlCleanupParser();
|
||||
|
||||
DEBUG("Loaded %d outfit%s", outfits, (outfits==1) ? "" : "s");
|
||||
DEBUG("Loaded %d outfit%s", outfits, (outfits==1) ? "" : "s");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -476,18 +476,18 @@ void outfit_free(void) {
|
||||
int i;
|
||||
for(i = 0; i < outfits; i++) {
|
||||
// Free graphics.
|
||||
if(outfit_gfx(&outfit_stack[i]))
|
||||
gl_freeTexture(outfit_gfx(&outfit_stack[i]));
|
||||
if(outfit_gfx(&outfit_stack[i]))
|
||||
gl_freeTexture(outfit_gfx(&outfit_stack[i]));
|
||||
|
||||
// Strings.
|
||||
// Strings.
|
||||
if(outfit_isLauncher(&outfit_stack[i]) && outfit_stack[i].u.lau.ammo)
|
||||
free(outfit_stack[i].u.lau.ammo);
|
||||
|
||||
if(outfit_stack[i].description)
|
||||
free(outfit_stack[i].description);
|
||||
if(outfit_stack[i].description)
|
||||
free(outfit_stack[i].description);
|
||||
|
||||
if(outfit_stack[i].gfx_store)
|
||||
gl_freeTexture(outfit_stack[i].gfx_store);
|
||||
if(outfit_stack[i].gfx_store)
|
||||
gl_freeTexture(outfit_stack[i].gfx_store);
|
||||
|
||||
free(outfit_stack[i].name);
|
||||
}
|
||||
|
80
src/outfit.h
80
src/outfit.h
@ -21,10 +21,10 @@ typedef enum OutfitType_ {
|
||||
OUTFIT_TYPE_MISSILE_SWARM_AMMO = 10,
|
||||
OUTFIT_TYPE_MISSILE_SWARM_SMART = 11,
|
||||
OUTFIT_TYPE_MISSILE_SWARM_SMART_AMMO = 12,
|
||||
OUTFIT_TYPE_TURRET_BOLT = 13,
|
||||
OUTFIT_TYPE_TURRET_BEAM = 14,
|
||||
OUTFIT_TYPE_MODIFICATION = 15,
|
||||
OUTFIT_TYPE_AFTERBURNER = 16
|
||||
OUTFIT_TYPE_TURRET_BOLT = 13,
|
||||
OUTFIT_TYPE_TURRET_BEAM = 14,
|
||||
OUTFIT_TYPE_MODIFICATION = 15,
|
||||
OUTFIT_TYPE_AFTERBURNER = 16
|
||||
} OutfitType;
|
||||
|
||||
// An outfit depends a lot on the type.
|
||||
@ -36,9 +36,9 @@ typedef struct Outfit_ {
|
||||
int tech;
|
||||
int mass;
|
||||
|
||||
// Store stuff.
|
||||
unsigned int price;
|
||||
char* description;
|
||||
// Store stuff.
|
||||
unsigned int price;
|
||||
char* description;
|
||||
|
||||
glTexture* gfx_store; // Store graphic.
|
||||
|
||||
@ -49,53 +49,53 @@ typedef struct Outfit_ {
|
||||
union {
|
||||
struct { // Bolt.
|
||||
unsigned int delay; // Delay between shots.
|
||||
double speed; // Speed of shot. (not applicable to beam.
|
||||
double speed; // Speed of shot. (not applicable to beam.
|
||||
double range;
|
||||
double accuracy; // Desviation accuracy.
|
||||
double energy; // Energy usage.
|
||||
double accuracy; // Desviation accuracy.
|
||||
double energy; // Energy usage.
|
||||
double damage_armour, damage_shield; // Damage.
|
||||
|
||||
glTexture* gfx_space;
|
||||
ALuint sound; // Sound to play.
|
||||
int spfx; // Special effect on hit.
|
||||
ALuint sound; // Sound to play.
|
||||
int spfx; // Special effect on hit.
|
||||
} blt;
|
||||
struct { // Beam.
|
||||
double range; // Distance it travels.
|
||||
glColour colour; // Beam colour.
|
||||
double energy; // Energy drained.
|
||||
double damage_armour, damage_shield; // Damage.
|
||||
} bem;
|
||||
struct { // Beam.
|
||||
double range; // Distance it travels.
|
||||
glColour colour; // Beam colour.
|
||||
double energy; // Energy drained.
|
||||
double damage_armour, damage_shield; // Damage.
|
||||
} bem;
|
||||
struct { // Launcher.
|
||||
unsigned int delay; // Delay between shots.
|
||||
unsigned int delay; // Delay between shots.
|
||||
char* ammo;
|
||||
} lau;
|
||||
struct { // Ammo.
|
||||
unsigned int duration; // Duration.
|
||||
double speed; // Max speed.
|
||||
double turn; // Turn vel.
|
||||
double thrust; // Acceleration.
|
||||
double energy; // Energy usage.
|
||||
double speed; // Max speed.
|
||||
double turn; // Turn vel.
|
||||
double thrust; // Acceleration.
|
||||
double energy; // Energy usage.
|
||||
double damage_armour, damage_shield; // Damage.
|
||||
|
||||
glTexture* gfx_space;
|
||||
ALuint sound; // Sound to play.
|
||||
int spfx; // Special effect on hit.
|
||||
unsigned int lockon; // Time taken to lock on the target.
|
||||
glTexture* gfx_space;
|
||||
ALuint sound; // Sound to play.
|
||||
int spfx; // Special effect on hit.
|
||||
unsigned int lockon; // Time taken to lock on the target.
|
||||
} amm;
|
||||
struct { // Modification.
|
||||
// Movement.
|
||||
double thrust, turn, speed;
|
||||
struct { // Modification.
|
||||
// Movement.
|
||||
double thrust, turn, speed;
|
||||
|
||||
// Health.
|
||||
double armour, armour_regen;
|
||||
double shield, shield_regen;
|
||||
double energy, energy_regen;
|
||||
} mod;
|
||||
struct { // Afterburner.
|
||||
double thrust_perc, thrust_abs; // Percent and absolute thrust bonus.
|
||||
double speed_perc, speed_abs; // Percent and absolute speed bonus.
|
||||
double energy; // Energy used while active.
|
||||
} afb;
|
||||
// Health.
|
||||
double armour, armour_regen;
|
||||
double shield, shield_regen;
|
||||
double energy, energy_regen;
|
||||
} mod;
|
||||
struct { // Afterburner.
|
||||
double thrust_perc, thrust_abs; // Percent and absolute thrust bonus.
|
||||
double speed_perc, speed_abs; // Percent and absolute speed bonus.
|
||||
double energy; // Energy used while active.
|
||||
} afb;
|
||||
} u;
|
||||
} Outfit;
|
||||
|
||||
|
214
src/pack.c
214
src/pack.c
@ -52,25 +52,25 @@ static off_t getfilesize(const char* filename) {
|
||||
ERR("Unable to get filesize of %s", filename);
|
||||
return 0;
|
||||
#else
|
||||
long size;
|
||||
FILE* fp = fopen(filename, "rb");
|
||||
if(fp == NULL) return 0;
|
||||
long size;
|
||||
FILE* fp = fopen(filename, "rb");
|
||||
if(fp == NULL) return 0;
|
||||
|
||||
fseek(fp, 0, SEEK_END);
|
||||
size = ftell(fp);
|
||||
fseek(fp, 0, SEEK_END);
|
||||
size = ftell(fp);
|
||||
|
||||
fclose(fp);
|
||||
fclose(fp);
|
||||
|
||||
return size;
|
||||
return size;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Return true if filename is a Packfile.
|
||||
int pack_check(const char* filename) {
|
||||
int ret;
|
||||
char* buf;
|
||||
int ret;
|
||||
char* buf;
|
||||
|
||||
buf = malloc(sizeof(magic));
|
||||
buf = malloc(sizeof(magic));
|
||||
|
||||
#ifdef _POSIX_SOURCE
|
||||
int fd = open(filename, O_RDONLY);
|
||||
@ -84,24 +84,24 @@ int pack_check(const char* filename) {
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
ret = (memcmp(buf, &magic, sizeof(magic))==0) ? 0 : 1;
|
||||
close(fd);
|
||||
ret = (memcmp(buf, &magic, sizeof(magic))==0) ? 0 : 1;
|
||||
close(fd);
|
||||
#else
|
||||
FILE* file = fopen(filename, "rb");
|
||||
if(file == NULL) {
|
||||
ERR("Error opening '%s': %s", filename, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
FILE* file = fopen(filename, "rb");
|
||||
if(file == NULL) {
|
||||
ERR("Error opening '%s': %s", filename, strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
|
||||
buf = malloc(sizeof(magic));
|
||||
if(fread(buf, 1, sizeof(magic), file) != sizeof(magic)) {
|
||||
ERR("Error reading magic number: %s", strerror(errno));
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
buf = malloc(sizeof(magic));
|
||||
if(fread(buf, 1, sizeof(magic), file) != sizeof(magic)) {
|
||||
ERR("Error reading magic number: %s", strerror(errno));
|
||||
free(buf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = (memcmp(buf, &magic, sizeof(magic))==0) ? 0 : 1;
|
||||
fclose(file);
|
||||
ret = (memcmp(buf, &magic, sizeof(magic))==0) ? 0 : 1;
|
||||
fclose(file);
|
||||
#endif
|
||||
|
||||
free(buf);
|
||||
@ -110,9 +110,9 @@ int pack_check(const char* filename) {
|
||||
|
||||
// Pack nfiles, infiles into outfile.
|
||||
#ifdef _POSIX_SOURCE
|
||||
#define WRITE(b,n) if(write(outfd, b, n)==-1) { \
|
||||
ERR("Error writing to file: %s", strerror(errno)); \
|
||||
free(buf); return -1; }
|
||||
#define WRITE(b,n) if(write(outfd, b, n)==-1) { \
|
||||
ERR("Error writing to file: %s", strerror(errno)); \
|
||||
free(buf); return -1; }
|
||||
#else
|
||||
#define WRITE(b,n) if(fwrite(b, 1, n, outf)==0) { \
|
||||
ERR("Error writing to file: %s", strerror(errno)); \
|
||||
@ -122,9 +122,9 @@ int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles)
|
||||
void* buf;
|
||||
#ifdef _POSIX_SOURCE
|
||||
struct stat file;
|
||||
int outfd, infd;
|
||||
int outfd, infd;
|
||||
#else
|
||||
FILE* outf, *inf;
|
||||
FILE* outf, *inf;
|
||||
#endif
|
||||
uint32_t i;
|
||||
int namesize;
|
||||
@ -137,14 +137,14 @@ int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles)
|
||||
#ifdef _POSIX_SOURCE
|
||||
if(stat(infiles[i], &file)) {
|
||||
#else
|
||||
if(getfilesize(infiles[i]) == 0) {
|
||||
if(getfilesize(infiles[i]) == 0) {
|
||||
#endif
|
||||
ERR("File %s does not exist", infiles[i]);
|
||||
return -1;
|
||||
}
|
||||
if(strlen(infiles[i]) > MAX_FILENAME) {
|
||||
ERR("filename '%s' is too long, should be only %d characters", infiles[i],
|
||||
MAX_FILENAME);
|
||||
MAX_FILENAME);
|
||||
return -1;
|
||||
}
|
||||
namesize += strlen(infiles[i]);
|
||||
@ -160,8 +160,8 @@ int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles)
|
||||
outfd = creat(outfile, PERMS);
|
||||
if(outfd == -1) {
|
||||
#else
|
||||
outf = fopen(outfile, "wb");
|
||||
if(outf == NULL) {
|
||||
outf = fopen(outfile, "wb");
|
||||
if(outf == NULL) {
|
||||
#endif
|
||||
ERR("Unable to open %s for writing", outfile);
|
||||
return -1;
|
||||
@ -195,13 +195,13 @@ int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles)
|
||||
DEBUG("About to write '%s' of %d bytes", infiles[i], bytes);
|
||||
md5_init(&md5);
|
||||
#ifdef _POSIX_SOURCE
|
||||
infd = open(infiles[i], O_RDONLY);
|
||||
infd = open(infiles[i], O_RDONLY);
|
||||
while((bytes = read(infd, buf, BLOCKSIZE))) {
|
||||
#else
|
||||
inf = fopen(infiles[i], "rb");
|
||||
while((bytes = fread(buf, 1, BLOCKSIZE, inf))) {
|
||||
inf = fopen(infiles[i], "rb");
|
||||
while((bytes = fread(buf, 1, BLOCKSIZE, inf))) {
|
||||
#endif
|
||||
WRITE(buf, bytes); // Data.
|
||||
WRITE(buf, bytes); // Data.
|
||||
md5_append(&md5, buf, bytes);
|
||||
}
|
||||
md5_finish(&md5, md5val);
|
||||
@ -209,7 +209,7 @@ int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles)
|
||||
#ifdef _POSIX_SOURCE
|
||||
close(infd);
|
||||
#else
|
||||
fclose(inf);
|
||||
fclose(inf);
|
||||
#endif
|
||||
DEBUG("Wrote file '%s'", infiles[i]);
|
||||
}
|
||||
@ -218,25 +218,25 @@ int pack_files(const char* outfile, const char** infiles, const uint32_t nfiles)
|
||||
#ifdef _POSIX_SOURCE
|
||||
close(outfd);
|
||||
#else
|
||||
fclose(outf);
|
||||
fclose(outf);
|
||||
#endif
|
||||
free(buf);
|
||||
|
||||
DEBUG("Packfile success\n\t%d files\n\t%d bytes",
|
||||
nfiles, (int)getfilesize(outfile));
|
||||
nfiles, (int)getfilesize(outfile));
|
||||
return 0;
|
||||
}
|
||||
#undef WRITE
|
||||
|
||||
// Opens the filename in packfile for reading.
|
||||
#ifdef _POSIX_SOURCE
|
||||
#define READ(b,n) if(read(file->fd, (b), (n))!=(n)) { \
|
||||
#define READ(b,n) if(read(file->fd, (b), (n))!=(n)) { \
|
||||
ERR("Too few bytes read. Expected more."); \
|
||||
free(buf); return -1; }
|
||||
#else
|
||||
#define READ(b,n) if(fread((b), 1, (n), file->fp)!=(n)) { \
|
||||
ERR("Fewer bytes read then expected"); \
|
||||
free(buf); return -1; }
|
||||
#define READ(b,n) if(fread((b), 1, (n), file->fp)!=(n)) { \
|
||||
ERR("Fewer bytes read then expected"); \
|
||||
free(buf); return -1; }
|
||||
#endif
|
||||
int pack_open(Packfile* file, const char* packfile, const char* filename) {
|
||||
int j;
|
||||
@ -249,8 +249,8 @@ int pack_open(Packfile* file, const char* packfile, const char* filename) {
|
||||
file->fd = open(packfile, O_RDONLY);
|
||||
if(file->fd == -1) {
|
||||
#else
|
||||
file->fp = fopen(packfile, "rb");
|
||||
if(file->fp == NULL) {
|
||||
file->fp = fopen(packfile, "rb");
|
||||
if(file->fp == NULL) {
|
||||
#endif
|
||||
ERR("Error opening %s: %s", filename, strerror(errno));
|
||||
return -1;
|
||||
@ -279,7 +279,7 @@ int pack_open(Packfile* file, const char* packfile, const char* filename) {
|
||||
#ifdef _POSIX_SOURCE
|
||||
lseek(file->fd, 4, SEEK_CUR); // Ignore the file location.
|
||||
#else
|
||||
fseek(file->fp, 4, SEEK_CUR);
|
||||
fseek(file->fp, 4, SEEK_CUR);
|
||||
#endif
|
||||
}
|
||||
free(buf);
|
||||
@ -289,13 +289,13 @@ int pack_open(Packfile* file, const char* packfile, const char* filename) {
|
||||
#ifdef _POSIX_SOURCE
|
||||
if((uint32_t)lseek(file->fd, file->start, SEEK_SET) != file->start) {
|
||||
#else
|
||||
fseek(file->fp, file->start, SEEK_SET);
|
||||
if(errno) {
|
||||
fseek(file->fp, file->start, SEEK_SET);
|
||||
if(errno) {
|
||||
#endif
|
||||
ERR("Failure to seek to file start: %s", strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
READ(&file->end, 4);
|
||||
READ(&file->end, 4);
|
||||
DEBUG("\t%d bytes", file->end);
|
||||
file->pos = file->start;
|
||||
file->end += file->start;
|
||||
@ -310,7 +310,7 @@ int pack_open(Packfile* file, const char* packfile, const char* filename) {
|
||||
// Read count bytes from file and put them into buf.
|
||||
ssize_t pack_read(Packfile* file, void* buf, size_t count) {
|
||||
if(file->pos + count > file->end)
|
||||
count = file->end - file->pos; // Can't go past the end!
|
||||
count = file->end - file->pos; // Can't go past the end!
|
||||
if(count == 0) return 0;
|
||||
|
||||
int bytes;
|
||||
@ -318,7 +318,7 @@ ssize_t pack_read(Packfile* file, void* buf, size_t count) {
|
||||
#ifdef _POSIX_SOURCE
|
||||
if((bytes = read(file->fd, buf, count)) == -1) {
|
||||
#else
|
||||
if((bytes = fread(buf, 1, count, file->fp)) == -1) {
|
||||
if((bytes = fread(buf, 1, count, file->fp)) == -1) {
|
||||
#endif
|
||||
ERR("Error while reading file: %s", strerror(errno));
|
||||
return -1;
|
||||
@ -330,52 +330,52 @@ ssize_t pack_read(Packfile* file, void* buf, size_t count) {
|
||||
|
||||
// Seek in the packfile.
|
||||
off_t pack_seek(Packfile* file, off_t offset, int whence) {
|
||||
DEBUG("Attempting to seek offset: %d, whence: %d", offset, whence);
|
||||
off_t ret;
|
||||
switch(whence) {
|
||||
DEBUG("Attempting to seek offset: %d, whence: %d", offset, whence);
|
||||
off_t ret;
|
||||
switch(whence) {
|
||||
#ifdef _POSIX_SOURCE
|
||||
case SEEK_SET:
|
||||
if((file->start + offset) > file->end) return -1;
|
||||
ret = lseek(file->fd, file->start + offset, SEEK_SET);
|
||||
if(ret != ((off_t)file->start + offset)) return -1;
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
if((file->start + offset) > file->end) return -1;
|
||||
ret = lseek(file->fd, file->pos + offset, SEEK_SET);
|
||||
if(ret != ((off_t)file->pos + offset)) return -1;
|
||||
break;
|
||||
case SEEK_END:
|
||||
if((file->end - offset) < file->start) return -1;
|
||||
ret = lseek(file->fd, file->end - offset - 1, SEEK_SET);
|
||||
if(ret != ((off_t)file->end - offset)) return -1;
|
||||
break;
|
||||
case SEEK_SET:
|
||||
if((file->start + offset) > file->end) return -1;
|
||||
ret = lseek(file->fd, file->start + offset, SEEK_SET);
|
||||
if(ret != ((off_t)file->start + offset)) return -1;
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
if((file->start + offset) > file->end) return -1;
|
||||
ret = lseek(file->fd, file->pos + offset, SEEK_SET);
|
||||
if(ret != ((off_t)file->pos + offset)) return -1;
|
||||
break;
|
||||
case SEEK_END:
|
||||
if((file->end - offset) < file->start) return -1;
|
||||
ret = lseek(file->fd, file->end - offset - 1, SEEK_SET);
|
||||
if(ret != ((off_t)file->end - offset)) return -1;
|
||||
break;
|
||||
#else
|
||||
case SEEK_SET:
|
||||
if((file->start + offset) > file->end) return -1;
|
||||
ret = fseek(file->fd, file->start + offset, SEEK_SET);
|
||||
if(ret != (file->start + offset)) return -1;
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
if((file->start + offset) > file->end) return -1;
|
||||
ret = flseek(file->fd, file->pos + offset, SEEK_SET);
|
||||
if(ret != (file->pos + offset)) return -1;
|
||||
break;
|
||||
case SEEK_END:
|
||||
if((file->end - offset) < file->start) return -1;
|
||||
ret = flseek(file->fd, file->end - offset - 1, SEEK_SET);
|
||||
if(ret != (file->end - offset)) return -1;
|
||||
break;
|
||||
case SEEK_SET:
|
||||
if((file->start + offset) > file->end) return -1;
|
||||
ret = fseek(file->fd, file->start + offset, SEEK_SET);
|
||||
if(ret != (file->start + offset)) return -1;
|
||||
break;
|
||||
case SEEK_CUR:
|
||||
if((file->start + offset) > file->end) return -1;
|
||||
ret = flseek(file->fd, file->pos + offset, SEEK_SET);
|
||||
if(ret != (file->pos + offset)) return -1;
|
||||
break;
|
||||
case SEEK_END:
|
||||
if((file->end - offset) < file->start) return -1;
|
||||
ret = flseek(file->fd, file->end - offset - 1, SEEK_SET);
|
||||
if(ret != (file->end - offset)) return -1;
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ERR("Whence is not one of SEEK_SET, SEEK_CUR or SEEK_END");
|
||||
return -1;
|
||||
}
|
||||
return ret - file->start;
|
||||
default:
|
||||
ERR("Whence is not one of SEEK_SET, SEEK_CUR or SEEK_END");
|
||||
return -1;
|
||||
}
|
||||
return ret - file->start;
|
||||
}
|
||||
|
||||
// Return current pointer position.
|
||||
long pack_tell(Packfile* file) {
|
||||
return file->pos - file->start;
|
||||
return file->pos - file->start;
|
||||
}
|
||||
|
||||
// Loads an entire file into memory and returns a pointer to it.
|
||||
@ -398,7 +398,7 @@ void* pack_readfile(const char* packfile, const char* filename, uint32_t* filesi
|
||||
buf = malloc(size+1);
|
||||
if((bytes = pack_read(file, buf, size)) != size) {
|
||||
ERR("Reading '%s' from packfile '%s'. Expected %d bytes got %d bytes",
|
||||
filename, packfile, size, bytes);
|
||||
filename, packfile, size, bytes);
|
||||
free(buf);
|
||||
free(file);
|
||||
return NULL;
|
||||
@ -416,7 +416,7 @@ void* pack_readfile(const char* packfile, const char* filename, uint32_t* filesi
|
||||
#ifdef _POSIX_SOURCE
|
||||
if((bytes = read(file->fd, md5fd, 16)) == -1)
|
||||
#else
|
||||
if((bytes = fread(md5fd, 1, 16, file->fp)) == -1)
|
||||
if((bytes = fread(md5fd, 1, 16, file->fp)) == -1)
|
||||
#endif
|
||||
WARN("Failure to read MD5, continuing anyway..");
|
||||
else if(memcmp(md5val, md5fd, 16))
|
||||
@ -442,19 +442,19 @@ void* pack_readfile(const char* packfile, const char* filename, uint32_t* filesi
|
||||
// filenames should be freed after use
|
||||
// On error if filenames is (char**)-1.
|
||||
#ifdef _POSIX_SOURCE
|
||||
#define READ(b,n) if(read(fd, (b), (n))!=(n)) { \
|
||||
ERR("Too few bytes read"); \
|
||||
return NULL; }
|
||||
#define READ(b,n) if(read(fd, (b), (n))!=(n)) { \
|
||||
ERR("Too few bytes read"); \
|
||||
return NULL; }
|
||||
#else
|
||||
#define READ(b,n) if(fread((b), 1, (n), fp) != (n)) { \
|
||||
ERR("Too few bytes read"); \
|
||||
return NULL; }
|
||||
#define READ(b,n) if(fread((b), 1, (n), fp) != (n)) { \
|
||||
ERR("Too few bytes read"); \
|
||||
return NULL; }
|
||||
#endif
|
||||
char** pack_listfiles(const char* packfile, uint32_t* nfiles) {
|
||||
#ifdef _POSIX_SOURCE
|
||||
int fd;
|
||||
int fd;
|
||||
#else
|
||||
FILE* fp;
|
||||
FILE* fp;
|
||||
#endif
|
||||
int j;
|
||||
uint32_t i;
|
||||
@ -467,8 +467,8 @@ char** pack_listfiles(const char* packfile, uint32_t* nfiles) {
|
||||
fd = open(packfile, O_RDONLY);
|
||||
if(fd == -1) {
|
||||
#else
|
||||
fp = fopen(packfile, "rb");
|
||||
if(fp == NULL) {
|
||||
fp = fopen(packfile, "rb");
|
||||
if(fp == NULL) {
|
||||
#endif
|
||||
ERR("opening %s: %s", packfile, strerror(errno));
|
||||
return NULL;
|
||||
@ -495,7 +495,7 @@ char** pack_listfiles(const char* packfile, uint32_t* nfiles) {
|
||||
#ifdef _POSIX_SOURCE
|
||||
close(fd);
|
||||
#else
|
||||
fclose(fp);
|
||||
fclose(fp);
|
||||
#endif
|
||||
|
||||
return filenames;
|
||||
@ -504,11 +504,11 @@ char** pack_listfiles(const char* packfile, uint32_t* nfiles) {
|
||||
|
||||
// Close the packfile.
|
||||
int pack_close(Packfile* file) {
|
||||
int i;
|
||||
int i;
|
||||
#ifdef _POSIX_SOURCE
|
||||
i = close(file->fd);
|
||||
#else
|
||||
i = fclose(file->fp);
|
||||
i = fclose(file->fp);
|
||||
#endif
|
||||
return (i) ? -1 : 0;
|
||||
}
|
||||
|
@ -9,7 +9,7 @@ typedef struct Packfile_ {
|
||||
#ifdef _POSIX_SOURCE
|
||||
int fd; // File descriptor.
|
||||
#else
|
||||
FILE* fp;
|
||||
FILE* fp;
|
||||
#endif
|
||||
uint32_t pos; // position.
|
||||
uint32_t start, end; // file limits.
|
||||
|
28
src/pause.c
28
src/pause.c
@ -26,8 +26,8 @@ void pause(void) {
|
||||
|
||||
pilots_pause();
|
||||
weapons_pause();
|
||||
spfx_pause();
|
||||
spawn_timer -= SDL_GetTicks();
|
||||
spfx_pause();
|
||||
spawn_timer -= SDL_GetTicks();
|
||||
|
||||
paused = 1; // We should unpause it.
|
||||
}
|
||||
@ -37,17 +37,17 @@ void unpause(void) {
|
||||
|
||||
pilots_unpause();
|
||||
weapons_unpause();
|
||||
spfx_unpause();
|
||||
spawn_timer += SDL_GetTicks();
|
||||
spfx_unpause();
|
||||
spawn_timer += SDL_GetTicks();
|
||||
|
||||
paused = 0;
|
||||
}
|
||||
|
||||
// Set the timers back.
|
||||
void pause_delay(unsigned int delay) {
|
||||
pilots_delay(delay);
|
||||
weapons_delay(delay);
|
||||
spfx_delay(delay);
|
||||
pilots_delay(delay);
|
||||
weapons_delay(delay);
|
||||
spfx_delay(delay);
|
||||
}
|
||||
|
||||
static void pilots_pause(void) {
|
||||
@ -75,13 +75,13 @@ static void pilots_unpause(void) {
|
||||
}
|
||||
|
||||
static void pilots_delay(unsigned int delay) {
|
||||
int i, j;
|
||||
for(i = 0; i < pilots; i++) {
|
||||
pilot_stack[i]->ptimer += delay;
|
||||
int i, j;
|
||||
for(i = 0; i < pilots; i++) {
|
||||
pilot_stack[i]->ptimer += delay;
|
||||
|
||||
pilot_stack[i]->tcontrol += delay;
|
||||
for(j = 0; j < MAX_AI_TIMERS; j++)
|
||||
pilot_stack[i]->timer[j] += delay;
|
||||
}
|
||||
pilot_stack[i]->tcontrol += delay;
|
||||
for(j = 0; j < MAX_AI_TIMERS; j++)
|
||||
pilot_stack[i]->timer[j] += delay;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,9 +15,9 @@ double angle_diff(const double ref, double a) {
|
||||
}
|
||||
|
||||
void limit_speed(Vec2* vel, const double speed, const double dt) {
|
||||
double vmod = VMOD(*vel);
|
||||
if(vmod > speed) // Should not go faster.
|
||||
vect_pset(vel, (vmod-speed)*(1.-dt*3.) + speed, VANGLE(*vel));
|
||||
double vmod = VMOD(*vel);
|
||||
if(vmod > speed) // Should not go faster.
|
||||
vect_pset(vel, (vmod-speed)*(1.-dt*3.) + speed, VANGLE(*vel));
|
||||
}
|
||||
|
||||
// ================
|
||||
@ -190,7 +190,7 @@ static void rk4_update(Solid* obj, const double dt) {
|
||||
|
||||
// Initialize a new solid.
|
||||
void solid_init(Solid* dest, const double mass, const double dir,
|
||||
const Vec2* pos, const Vec2* vel) {
|
||||
const Vec2* pos, const Vec2* vel) {
|
||||
dest->mass = mass;
|
||||
|
||||
dest->dir_vel = 0.;
|
||||
@ -211,7 +211,7 @@ void solid_init(Solid* dest, const double mass, const double dir,
|
||||
|
||||
// Create a new solid.
|
||||
Solid* solid_create(const double mass, const double dir,
|
||||
const Vec2* pos, const Vec2* vel) {
|
||||
const Vec2* pos, const Vec2* vel) {
|
||||
Solid* dyn = MALLOC_L(Solid);
|
||||
if(dyn == NULL) ERR("Out of memory");
|
||||
solid_init(dyn, mass, dir, pos, vel);
|
||||
|
596
src/pilot.c
596
src/pilot.c
@ -140,8 +140,8 @@ double pilot_face(Pilot* p, const float dir) {
|
||||
|
||||
// Return quantity of a pilot outfit.
|
||||
static int pilot_oquantity(Pilot* p, PilotOutfit* w) {
|
||||
return (outfit_isAmmo(w->outfit) && p->secondary) ?
|
||||
p->secondary->quantity : w->quantity;
|
||||
return (outfit_isAmmo(w->outfit) && p->secondary) ?
|
||||
p->secondary->quantity : w->quantity;
|
||||
}
|
||||
|
||||
// Mkay, this is how we shoot. Listen up.
|
||||
@ -163,10 +163,10 @@ void pilot_shoot(Pilot* p, const unsigned int target, const int secondary) {
|
||||
}
|
||||
|
||||
static void pilot_shootWeapon(Pilot* p, PilotOutfit* w, const unsigned int t) {
|
||||
int quantity, delay;
|
||||
int quantity, delay;
|
||||
// WElll... Trying to shoot when you have no ammo?? FUUU
|
||||
quantity = pilot_oquantity(p,w);
|
||||
delay = outfit_delay(w->outfit);
|
||||
quantity = pilot_oquantity(p,w);
|
||||
delay = outfit_delay(w->outfit);
|
||||
|
||||
// Check to see if weapon is ready.
|
||||
if((SDL_GetTicks() - w->timer) < (unsigned int)(delay/quantity)) return;
|
||||
@ -174,14 +174,14 @@ static void pilot_shootWeapon(Pilot* p, PilotOutfit* w, const unsigned int t) {
|
||||
if(outfit_isWeapon(w->outfit) || (outfit_isTurret(w->outfit))) {
|
||||
// Different weapons.
|
||||
switch(w->outfit->type) {
|
||||
case OUTFIT_TYPE_TURRET_BOLT:
|
||||
case OUTFIT_TYPE_TURRET_BOLT:
|
||||
case OUTFIT_TYPE_BOLT:
|
||||
// Enough energy?
|
||||
if(outfit_energy(w->outfit) > p->energy) return;
|
||||
// Enough energy?
|
||||
if(outfit_energy(w->outfit) > p->energy) return;
|
||||
|
||||
p->energy -= outfit_energy(w->outfit);
|
||||
p->energy -= outfit_energy(w->outfit);
|
||||
weapon_add(w->outfit, p->solid->dir, &p->solid->pos,
|
||||
&p->solid->vel, p->id, t);
|
||||
&p->solid->vel, p->id, t);
|
||||
|
||||
// Can't shoot for a while.
|
||||
w->timer = SDL_GetTicks();
|
||||
@ -194,12 +194,12 @@ static void pilot_shootWeapon(Pilot* p, PilotOutfit* w, const unsigned int t) {
|
||||
// Must be secondary weapon, Shooter can't be the target.
|
||||
else if(outfit_isLauncher(w->outfit) && (w == p->secondary) && (p->id != t)) {
|
||||
if(p->ammo && (p->ammo->quantity > 0)) {
|
||||
// Enough energy?
|
||||
if(outfit_energy(w->outfit) > p->energy) return;
|
||||
// Enough energy?
|
||||
if(outfit_energy(w->outfit) > p->energy) return;
|
||||
|
||||
p->energy -= outfit_energy(w->outfit);
|
||||
p->energy -= outfit_energy(w->outfit);
|
||||
weapon_add(p->ammo->outfit, p->solid->dir, &p->solid->pos,
|
||||
&p->solid->vel, p->id, t);
|
||||
&p->solid->vel, p->id, t);
|
||||
|
||||
w->timer = SDL_GetTicks(); // Can't shoot for a while.
|
||||
p->ammo->quantity -= 1; // There's no getting this one back.
|
||||
@ -209,72 +209,72 @@ static void pilot_shootWeapon(Pilot* p, PilotOutfit* w, const unsigned int t) {
|
||||
|
||||
// Damage the pilot.
|
||||
void pilot_hit(Pilot* p, const Solid* w, const unsigned int shooter,
|
||||
const double damage_shield, const double damage_armour) {
|
||||
const double damage_shield, const double damage_armour) {
|
||||
|
||||
double dam_mod;
|
||||
double dam_mod;
|
||||
|
||||
if(p->shield - damage_shield > 0.) {
|
||||
p->shield -= damage_shield;
|
||||
dam_mod = damage_shield/p->shield_max;
|
||||
}
|
||||
dam_mod = damage_shield/p->shield_max;
|
||||
}
|
||||
else if(p->shield > 0.) {
|
||||
// Shields can take part of the blow.
|
||||
p->armour -= p->shield/damage_shield*damage_armour;
|
||||
p->shield = 0.;
|
||||
dam_mod = (damage_shield+damage_armour) / (p->shield_max + p->armour_max);
|
||||
dam_mod = (damage_shield+damage_armour) / (p->shield_max + p->armour_max);
|
||||
}
|
||||
else if(p->armour-damage_armour > 0.) {
|
||||
p->armour -= damage_armour;
|
||||
dam_mod = damage_armour/p->armour_max;
|
||||
}
|
||||
dam_mod = damage_armour/p->armour_max;
|
||||
}
|
||||
else {
|
||||
// We are officially dead.
|
||||
// We are officially dead.
|
||||
p->armour = 0.;
|
||||
dam_mod = 0.;
|
||||
dam_mod = 0.;
|
||||
|
||||
if(!pilot_isFlag(p, PILOT_DEAD)) {
|
||||
pilot_dead(p);
|
||||
// Adjust the combat rating based on pilot mass.
|
||||
if(shooter == PLAYER_ID) combat_crating += MAX(1, p->ship->mass/50);
|
||||
}
|
||||
}
|
||||
if(!pilot_isFlag(p, PILOT_DEAD)) {
|
||||
pilot_dead(p);
|
||||
// Adjust the combat rating based on pilot mass.
|
||||
if(shooter == PLAYER_ID) combat_crating += MAX(1, p->ship->mass/50);
|
||||
}
|
||||
}
|
||||
|
||||
// Knock back effect is dependent on both damage and mass of the weapon.
|
||||
// should probably turn it into a partial conservative collision..
|
||||
vect_cadd(&p->solid->vel,
|
||||
w->vel.x * (dam_mod/6. + w->mass/p->solid->mass/6.),
|
||||
w->vel.y * (dam_mod/6. + w->mass/p->solid->mass/6.));
|
||||
// Knock back effect is dependent on both damage and mass of the weapon.
|
||||
// should probably turn it into a partial conservative collision..
|
||||
vect_cadd(&p->solid->vel,
|
||||
w->vel.x * (dam_mod/6. + w->mass/p->solid->mass/6.),
|
||||
w->vel.y * (dam_mod/6. + w->mass/p->solid->mass/6.));
|
||||
}
|
||||
|
||||
void pilot_dead(Pilot* p) {
|
||||
// Basically just set the timers..
|
||||
if(p->id == PLAYER_ID) player_dead();
|
||||
p->timer[0] = SDL_GetTicks(); // No need for AI anymore.
|
||||
p->ptimer = p->timer[0] + 1000 + (unsigned int)sqrt(10*p->armour_max*p->shield_max);
|
||||
p->timer[1] = p->timer[0]; // Explosion timer.
|
||||
pilot_setFlag(p, PILOT_DEAD);
|
||||
// Basically just set the timers..
|
||||
if(p->id == PLAYER_ID) player_dead();
|
||||
p->timer[0] = SDL_GetTicks(); // No need for AI anymore.
|
||||
p->ptimer = p->timer[0] + 1000 + (unsigned int)sqrt(10*p->armour_max*p->shield_max);
|
||||
p->timer[1] = p->timer[0]; // Explosion timer.
|
||||
pilot_setFlag(p, PILOT_DEAD);
|
||||
}
|
||||
|
||||
void pilot_setSecondary(Pilot* p, const char* secondary) {
|
||||
int i;
|
||||
int i;
|
||||
|
||||
if(secondary == NULL) {
|
||||
p->secondary = NULL;
|
||||
p->ammo = NULL;
|
||||
return;
|
||||
}
|
||||
if(secondary == NULL) {
|
||||
p->secondary = NULL;
|
||||
p->ammo = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
for(i = 0; i < p->noutfits; i++) {
|
||||
if(strcmp(secondary, p->outfits[i].outfit->name)==0) {
|
||||
p->secondary = &p->outfits[i];;
|
||||
pilot_setAmmo(p);
|
||||
return;
|
||||
}
|
||||
}
|
||||
WARN("Attempted to set pilot '%s' secondary weapon to non-existing '%s'",
|
||||
p->name, secondary);
|
||||
p->secondary = NULL;
|
||||
p->ammo = NULL;
|
||||
for(i = 0; i < p->noutfits; i++) {
|
||||
if(strcmp(secondary, p->outfits[i].outfit->name)==0) {
|
||||
p->secondary = &p->outfits[i];;
|
||||
pilot_setAmmo(p);
|
||||
return;
|
||||
}
|
||||
}
|
||||
WARN("Attempted to set pilot '%s' secondary weapon to non-existing '%s'",
|
||||
p->name, secondary);
|
||||
p->secondary = NULL;
|
||||
p->ammo = NULL;
|
||||
}
|
||||
|
||||
// Set the pilot's ammo based on their secondary weapon.
|
||||
@ -301,102 +301,102 @@ void pilot_setAmmo(Pilot* p) {
|
||||
// Render the pilot.
|
||||
void pilot_render(Pilot* p) {
|
||||
gl_blitSprite(p->ship->gfx_space,
|
||||
p->solid->pos.x, p->solid->pos.y,
|
||||
p->tsx, p->tsy, NULL);
|
||||
p->solid->pos.x, p->solid->pos.y,
|
||||
p->tsx, p->tsy, NULL);
|
||||
}
|
||||
|
||||
// Update the pilot.
|
||||
static void pilot_update(Pilot* pilot, const double dt) {
|
||||
unsigned int t, l;
|
||||
double a, px, py, vx, vy;
|
||||
unsigned int t, l;
|
||||
double a, px, py, vx, vy;
|
||||
|
||||
if(pilot_isFlag(pilot, PILOT_DEAD)) {
|
||||
t = SDL_GetTicks();
|
||||
if(pilot_isFlag(pilot, PILOT_DEAD)) {
|
||||
t = SDL_GetTicks();
|
||||
|
||||
if(t > pilot->ptimer) {
|
||||
if(pilot->id == PLAYER_ID)
|
||||
player_destroyed();
|
||||
pilot_setFlag(pilot, PILOT_DELETE); // It'll get deleted next frame.
|
||||
return;
|
||||
}
|
||||
if(t > pilot->ptimer) {
|
||||
if(pilot->id == PLAYER_ID)
|
||||
player_destroyed();
|
||||
pilot_setFlag(pilot, PILOT_DELETE); // It'll get deleted next frame.
|
||||
return;
|
||||
}
|
||||
|
||||
if(!pilot_isFlag(pilot, PILOT_EXPLODED) && (t > pilot->ptimer - 200)) {
|
||||
spfx_add(spfx_get("ExpL"),
|
||||
VX(pilot->solid->pos), VY(pilot->solid->pos),
|
||||
VX(pilot->solid->vel), VY(pilot->solid->vel), SPFX_LAYER_BACK);
|
||||
pilot_setFlag(pilot, PILOT_EXPLODED);
|
||||
}
|
||||
else if(t > pilot->timer[1]) {
|
||||
pilot->timer[1] = t +
|
||||
(unsigned int)(100*(double)(pilot->ptimer - pilot->timer[1]) /
|
||||
(double)(pilot->ptimer - pilot->timer[0]));
|
||||
if(!pilot_isFlag(pilot, PILOT_EXPLODED) && (t > pilot->ptimer - 200)) {
|
||||
spfx_add(spfx_get("ExpL"),
|
||||
VX(pilot->solid->pos), VY(pilot->solid->pos),
|
||||
VX(pilot->solid->vel), VY(pilot->solid->vel), SPFX_LAYER_BACK);
|
||||
pilot_setFlag(pilot, PILOT_EXPLODED);
|
||||
}
|
||||
else if(t > pilot->timer[1]) {
|
||||
pilot->timer[1] = t +
|
||||
(unsigned int)(100*(double)(pilot->ptimer - pilot->timer[1]) /
|
||||
(double)(pilot->ptimer - pilot->timer[0]));
|
||||
|
||||
// Random position on ship.
|
||||
a = RNGF()*2.*M_PI;
|
||||
px = VX(pilot->solid->pos) + cos(a)*RNGF()*pilot->ship->gfx_space->sw/2.;
|
||||
py = VY(pilot->solid->pos) + sin(a)*RNGF()*pilot->ship->gfx_space->sh/2.;
|
||||
// Random position on ship.
|
||||
a = RNGF()*2.*M_PI;
|
||||
px = VX(pilot->solid->pos) + cos(a)*RNGF()*pilot->ship->gfx_space->sw/2.;
|
||||
py = VY(pilot->solid->pos) + sin(a)*RNGF()*pilot->ship->gfx_space->sh/2.;
|
||||
|
||||
vx = VX(pilot->solid->vel);
|
||||
vy = VY(pilot->solid->vel);
|
||||
vx = VX(pilot->solid->vel);
|
||||
vy = VY(pilot->solid->vel);
|
||||
|
||||
// Set explosions.
|
||||
l = (pilot->id == PLAYER_ID) ? SPFX_LAYER_FRONT : SPFX_LAYER_BACK;
|
||||
if(RNGF() > 0.8) spfx_add(spfx_get("ExpM"), px, py, vx, vy, l);
|
||||
else spfx_add(spfx_get("ExpS"), px, py, vx, vy, l);
|
||||
}
|
||||
}
|
||||
else if(pilot->armour <= 0.) // PWNED!
|
||||
pilot_dead(pilot);
|
||||
// Set explosions.
|
||||
l = (pilot->id == PLAYER_ID) ? SPFX_LAYER_FRONT : SPFX_LAYER_BACK;
|
||||
if(RNGF() > 0.8) spfx_add(spfx_get("ExpM"), px, py, vx, vy, l);
|
||||
else spfx_add(spfx_get("ExpS"), px, py, vx, vy, l);
|
||||
}
|
||||
}
|
||||
else if(pilot->armour <= 0.) // PWNED!
|
||||
pilot_dead(pilot);
|
||||
|
||||
// Pupose fallthrough to get the movement similar to disabled.
|
||||
// Pupose fallthrough to get the movement similar to disabled.
|
||||
if(pilot != player && pilot->armour < PILOT_DISABLED_ARMOUR * pilot->armour_max) {
|
||||
// We are disabled.
|
||||
pilot_setFlag(pilot, PILOT_DISABLED);
|
||||
// Come to a halt slowly.
|
||||
vect_pset(&pilot->solid->vel,
|
||||
VMOD(pilot->solid->vel) * (1. - dt*0.10), VANGLE(pilot->solid->vel));
|
||||
VMOD(pilot->solid->vel) * (1. - dt*0.10), VANGLE(pilot->solid->vel));
|
||||
vectnull(&pilot->solid->force);
|
||||
pilot->solid->dir_vel = 0.; // Stop it from turning.
|
||||
|
||||
// Update the solid.
|
||||
pilot->solid->update(pilot->solid, dt);
|
||||
gl_getSpriteFromDir(&pilot->tsx, &pilot->tsy,
|
||||
pilot->ship->gfx_space, pilot->solid->dir);
|
||||
gl_getSpriteFromDir(&pilot->tsx, &pilot->tsy,
|
||||
pilot->ship->gfx_space, pilot->solid->dir);
|
||||
return;
|
||||
}
|
||||
// We are still alive.
|
||||
else if(pilot->armour < pilot->armour_max) {
|
||||
pilot->armour += pilot->armour_regen*dt;
|
||||
pilot->energy += pilot->energy_regen*dt;
|
||||
} else {
|
||||
pilot->energy += pilot->energy_regen*dt;
|
||||
} else {
|
||||
pilot->shield += pilot->shield_regen*dt;
|
||||
pilot->energy += pilot->energy_regen*dt;
|
||||
}
|
||||
pilot->energy += pilot->energy_regen*dt;
|
||||
}
|
||||
|
||||
if(pilot->armour > pilot->armour_max) pilot->armour = pilot->armour_max;
|
||||
if(pilot->shield > pilot->shield_max) pilot->shield = pilot->shield_max;
|
||||
if(pilot->energy > pilot->energy_max) pilot->energy = pilot->energy_max;
|
||||
if(pilot->energy > pilot->energy_max) pilot->energy = pilot->energy_max;
|
||||
|
||||
// Update the solid.
|
||||
(*pilot->solid->update)(pilot->solid, dt);
|
||||
gl_getSpriteFromDir(&pilot->tsx, &pilot->tsy,
|
||||
pilot->ship->gfx_space, pilot->solid->dir);
|
||||
gl_getSpriteFromDir(&pilot->tsx, &pilot->tsy,
|
||||
pilot->ship->gfx_space, pilot->solid->dir);
|
||||
|
||||
if(!pilot_isFlag(pilot, PILOT_HYPERSPACE)) { // Limit the speed.
|
||||
if(pilot_isFlag(pilot, PILOT_AFTERBURNER) && // Must have enough energy.
|
||||
(player->energy > pilot->afterburner->outfit->u.afb.energy * dt)) {
|
||||
limit_speed(&pilot->solid->vel,
|
||||
pilot->speed * pilot->afterburner->outfit->u.afb.speed_perc +
|
||||
pilot->afterburner->outfit->u.afb.speed_abs, dt);
|
||||
pilot->energy -= pilot->afterburner->outfit->u.afb.energy * dt;
|
||||
} else
|
||||
limit_speed(&pilot->solid->vel, pilot->speed, dt);
|
||||
}
|
||||
if(!pilot_isFlag(pilot, PILOT_HYPERSPACE)) { // Limit the speed.
|
||||
if(pilot_isFlag(pilot, PILOT_AFTERBURNER) && // Must have enough energy.
|
||||
(player->energy > pilot->afterburner->outfit->u.afb.energy * dt)) {
|
||||
limit_speed(&pilot->solid->vel,
|
||||
pilot->speed * pilot->afterburner->outfit->u.afb.speed_perc +
|
||||
pilot->afterburner->outfit->u.afb.speed_abs, dt);
|
||||
pilot->energy -= pilot->afterburner->outfit->u.afb.energy * dt;
|
||||
} else
|
||||
limit_speed(&pilot->solid->vel, pilot->speed, dt);
|
||||
}
|
||||
}
|
||||
|
||||
// Pilot is getting ready or is in, hyperspace.
|
||||
static void pilot_hyperspace(Pilot* p) {
|
||||
double diff;
|
||||
double diff;
|
||||
|
||||
if(pilot_isFlag(p, PILOT_HYPERSPACE)) {
|
||||
// Pilot is actually in hyperspace.
|
||||
@ -421,14 +421,14 @@ static void pilot_hyperspace(Pilot* p) {
|
||||
if(VMOD(p->solid->vel) > MIN_VEL_ERR) {
|
||||
diff = pilot_face(p, VANGLE(p->solid->vel) + M_PI);
|
||||
|
||||
if(ABS(diff) < MAX_DIR_ERR) // Brake.
|
||||
vect_pset(&p->solid->force, p->thrust, p->solid->dir);
|
||||
if(ABS(diff) < MAX_DIR_ERR) // Brake.
|
||||
vect_pset(&p->solid->force, p->thrust, p->solid->dir);
|
||||
} else {
|
||||
vectnull(&p->solid->force); // Stop accelerating.
|
||||
|
||||
// Player should actually face the system she's headed to.
|
||||
if(p == player) diff = player_faceHyperspace();
|
||||
else diff = pilot_face(p, VANGLE(p->solid->pos));
|
||||
// Player should actually face the system she's headed to.
|
||||
if(p == player) diff = player_faceHyperspace();
|
||||
else diff = pilot_face(p, VANGLE(p->solid->pos));
|
||||
|
||||
if(ABS(diff) < MAX_DIR_ERR) {
|
||||
// We should prepare for the jump now.
|
||||
@ -441,188 +441,188 @@ static void pilot_hyperspace(Pilot* p) {
|
||||
}
|
||||
|
||||
int pilot_addOutfit(Pilot* pilot, Outfit* outfit, int quantity) {
|
||||
int i, q;
|
||||
char* s;
|
||||
int i, q;
|
||||
char* s;
|
||||
|
||||
q = quantity;
|
||||
q = quantity;
|
||||
|
||||
for(i = 0; i < pilot->noutfits; i++)
|
||||
if(strcmp(outfit->name, pilot->outfits[i].outfit->name)==0) {
|
||||
pilot->outfits[i].quantity += quantity;
|
||||
// Can't be over max.
|
||||
if(pilot->outfits[i].quantity > outfit->max) {
|
||||
q -= pilot->outfits[i].quantity - outfit->max;
|
||||
pilot->outfits[i].quantity = outfit->max;
|
||||
}
|
||||
pilot_calcStats(pilot);
|
||||
return q;
|
||||
}
|
||||
for(i = 0; i < pilot->noutfits; i++)
|
||||
if(strcmp(outfit->name, pilot->outfits[i].outfit->name)==0) {
|
||||
pilot->outfits[i].quantity += quantity;
|
||||
// Can't be over max.
|
||||
if(pilot->outfits[i].quantity > outfit->max) {
|
||||
q -= pilot->outfits[i].quantity - outfit->max;
|
||||
pilot->outfits[i].quantity = outfit->max;
|
||||
}
|
||||
pilot_calcStats(pilot);
|
||||
return q;
|
||||
}
|
||||
|
||||
s = (pilot->secondary) ? pilot->secondary->outfit->name : NULL;
|
||||
pilot->outfits = realloc(pilot->outfits, (pilot->noutfits+1)*sizeof(PilotOutfit));
|
||||
pilot->outfits[pilot->noutfits].outfit = outfit;
|
||||
pilot->outfits[pilot->noutfits].quantity = quantity;
|
||||
// Can't be over max.
|
||||
if(pilot->outfits[pilot->noutfits].quantity > outfit->max) {
|
||||
q -= pilot->outfits[pilot->noutfits].quantity - outfit->max;
|
||||
pilot->outfits[i].quantity = outfit->max;
|
||||
}
|
||||
pilot->outfits[pilot->noutfits].timer = 0;
|
||||
(pilot->noutfits)++;
|
||||
s = (pilot->secondary) ? pilot->secondary->outfit->name : NULL;
|
||||
pilot->outfits = realloc(pilot->outfits, (pilot->noutfits+1)*sizeof(PilotOutfit));
|
||||
pilot->outfits[pilot->noutfits].outfit = outfit;
|
||||
pilot->outfits[pilot->noutfits].quantity = quantity;
|
||||
// Can't be over max.
|
||||
if(pilot->outfits[pilot->noutfits].quantity > outfit->max) {
|
||||
q -= pilot->outfits[pilot->noutfits].quantity - outfit->max;
|
||||
pilot->outfits[i].quantity = outfit->max;
|
||||
}
|
||||
pilot->outfits[pilot->noutfits].timer = 0;
|
||||
(pilot->noutfits)++;
|
||||
|
||||
if(outfit_isTurret(outfit))
|
||||
// Used to speed up AI.
|
||||
pilot_setFlag(pilot, PILOT_HASTURRET);
|
||||
if(outfit_isTurret(outfit))
|
||||
// Used to speed up AI.
|
||||
pilot_setFlag(pilot, PILOT_HASTURRET);
|
||||
|
||||
// Hack due to realloc possibility.
|
||||
pilot_setSecondary(pilot, s);
|
||||
// Hack due to realloc possibility.
|
||||
pilot_setSecondary(pilot, s);
|
||||
|
||||
pilot_calcStats(pilot);
|
||||
return q;
|
||||
pilot_calcStats(pilot);
|
||||
return q;
|
||||
}
|
||||
|
||||
// Remove an outfit from the pilot.
|
||||
int pilot_rmOutfit(Pilot* pilot, Outfit* outfit, int quantity) {
|
||||
int i, q;
|
||||
char* s;
|
||||
int i, q;
|
||||
char* s;
|
||||
|
||||
q = quantity;
|
||||
q = quantity;
|
||||
|
||||
for(i = 0; i < pilot->noutfits; i++)
|
||||
if(strcmp(outfit->name, pilot->outfits[i].outfit->name)==0) {
|
||||
pilot->outfits[i].quantity -= quantity;
|
||||
if(pilot->outfits[i].quantity <= 0) {
|
||||
// We didn't actually remove the full amount.
|
||||
q += pilot->outfits[i].quantity;
|
||||
// Hack in case it reallocs - Can happen even when shrinking.
|
||||
s = (pilot->secondary) ? pilot->secondary->outfit->name : NULL;
|
||||
// Clear it if it's the afterburner.
|
||||
if(&pilot->outfits[i] == pilot->afterburner)
|
||||
pilot->afterburner = NULL;
|
||||
for(i = 0; i < pilot->noutfits; i++)
|
||||
if(strcmp(outfit->name, pilot->outfits[i].outfit->name)==0) {
|
||||
pilot->outfits[i].quantity -= quantity;
|
||||
if(pilot->outfits[i].quantity <= 0) {
|
||||
// We didn't actually remove the full amount.
|
||||
q += pilot->outfits[i].quantity;
|
||||
// Hack in case it reallocs - Can happen even when shrinking.
|
||||
s = (pilot->secondary) ? pilot->secondary->outfit->name : NULL;
|
||||
// Clear it if it's the afterburner.
|
||||
if(&pilot->outfits[i] == pilot->afterburner)
|
||||
pilot->afterburner = NULL;
|
||||
|
||||
// Remove the outfit.
|
||||
memmove(pilot->outfits+i, pilot->outfits+i+1,
|
||||
sizeof(PilotOutfit)*(pilot->noutfits-i));
|
||||
pilot->noutfits--;
|
||||
pilot->outfits = realloc(pilot->outfits,
|
||||
sizeof(PilotOutfit)*(pilot->noutfits));
|
||||
// Remove the outfit.
|
||||
memmove(pilot->outfits+i, pilot->outfits+i+1,
|
||||
sizeof(PilotOutfit)*(pilot->noutfits-i));
|
||||
pilot->noutfits--;
|
||||
pilot->outfits = realloc(pilot->outfits,
|
||||
sizeof(PilotOutfit)*(pilot->noutfits));
|
||||
|
||||
pilot_setSecondary(pilot, s);
|
||||
}
|
||||
return q;
|
||||
}
|
||||
WARN("Failure attempting to remove %d '%s' from pilot '%s'",
|
||||
quantity, outfit->name, pilot->name);
|
||||
pilot_setSecondary(pilot, s);
|
||||
}
|
||||
return q;
|
||||
}
|
||||
WARN("Failure attempting to remove %d '%s' from pilot '%s'",
|
||||
quantity, outfit->name, pilot->name);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Recalculate the pilot's stats based on her outfits.
|
||||
static void pilot_calcStats(Pilot* pilot) {
|
||||
int i;
|
||||
double q;
|
||||
Outfit* o;
|
||||
double ac, sc, ec; // Temp health coeficients to set.
|
||||
int i;
|
||||
double q;
|
||||
Outfit* o;
|
||||
double ac, sc, ec; // Temp health coeficients to set.
|
||||
|
||||
// -- Set up the basic stuff.
|
||||
// Movement.
|
||||
pilot->thrust = pilot->ship->thrust;
|
||||
pilot->turn = pilot->ship->turn;
|
||||
pilot->speed = pilot->ship->speed;
|
||||
// Health.
|
||||
ac = pilot->armour / pilot->armour_max;
|
||||
sc = pilot->shield / pilot->shield_max;
|
||||
ec = pilot->energy / pilot->energy_max;
|
||||
pilot->armour_max = pilot->ship->armour;
|
||||
pilot->shield_max = pilot->ship->shield;
|
||||
pilot->energy_max = pilot->ship->energy;
|
||||
pilot->armour_regen = pilot->ship->armour_regen;
|
||||
pilot->shield_regen = pilot->ship->shield_regen;
|
||||
pilot->energy_regen = pilot->ship->energy_regen;
|
||||
// -- Set up the basic stuff.
|
||||
// Movement.
|
||||
pilot->thrust = pilot->ship->thrust;
|
||||
pilot->turn = pilot->ship->turn;
|
||||
pilot->speed = pilot->ship->speed;
|
||||
// Health.
|
||||
ac = pilot->armour / pilot->armour_max;
|
||||
sc = pilot->shield / pilot->shield_max;
|
||||
ec = pilot->energy / pilot->energy_max;
|
||||
pilot->armour_max = pilot->ship->armour;
|
||||
pilot->shield_max = pilot->ship->shield;
|
||||
pilot->energy_max = pilot->ship->energy;
|
||||
pilot->armour_regen = pilot->ship->armour_regen;
|
||||
pilot->shield_regen = pilot->ship->shield_regen;
|
||||
pilot->energy_regen = pilot->ship->energy_regen;
|
||||
|
||||
// Now add outfit changes.
|
||||
for(i = 0; i < pilot->noutfits; i++) {
|
||||
if(outfit_isMod(pilot->outfits[i].outfit)) {
|
||||
q = (double) pilot->outfits[i].quantity;
|
||||
o = pilot->outfits[i].outfit;
|
||||
// Now add outfit changes.
|
||||
for(i = 0; i < pilot->noutfits; i++) {
|
||||
if(outfit_isMod(pilot->outfits[i].outfit)) {
|
||||
q = (double) pilot->outfits[i].quantity;
|
||||
o = pilot->outfits[i].outfit;
|
||||
|
||||
// Movement.
|
||||
pilot->thrust += o->u.mod.thrust * q;
|
||||
pilot->turn += o->u.mod.turn * q;
|
||||
pilot->speed += o->u.mod.speed * q;
|
||||
// Health.
|
||||
pilot->armour_max += o->u.mod.armour * q;
|
||||
pilot->armour_regen += o->u.mod.armour_regen * q;
|
||||
pilot->shield_max += o->u.mod.shield * q;
|
||||
pilot->shield_regen += o->u.mod.shield_regen * q;
|
||||
pilot->energy_max += o->u.mod.energy * q;
|
||||
pilot->energy_regen += o->u.mod.energy_regen * q;
|
||||
// Movement.
|
||||
pilot->thrust += o->u.mod.thrust * q;
|
||||
pilot->turn += o->u.mod.turn * q;
|
||||
pilot->speed += o->u.mod.speed * q;
|
||||
// Health.
|
||||
pilot->armour_max += o->u.mod.armour * q;
|
||||
pilot->armour_regen += o->u.mod.armour_regen * q;
|
||||
pilot->shield_max += o->u.mod.shield * q;
|
||||
pilot->shield_regen += o->u.mod.shield_regen * q;
|
||||
pilot->energy_max += o->u.mod.energy * q;
|
||||
pilot->energy_regen += o->u.mod.energy_regen * q;
|
||||
|
||||
}
|
||||
else if(outfit_isAfterburner(pilot->outfits[i].outfit)) {
|
||||
// Set the afterburner.
|
||||
pilot->afterburner = &pilot->outfits[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(outfit_isAfterburner(pilot->outfits[i].outfit)) {
|
||||
// Set the afterburner.
|
||||
pilot->afterburner = &pilot->outfits[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Give the pilot her health proportion back.
|
||||
pilot->armour = ac * pilot->armour_max;
|
||||
pilot->shield = sc * pilot->shield_max;
|
||||
pilot->energy = ec * pilot->energy_max;
|
||||
// Give the pilot her health proportion back.
|
||||
pilot->armour = ac * pilot->armour_max;
|
||||
pilot->shield = sc * pilot->shield_max;
|
||||
pilot->energy = ec * pilot->energy_max;
|
||||
}
|
||||
|
||||
// Try to add quantity of cargo to pilot, return quantity actually added.
|
||||
int pilot_addCargo(Pilot* pilot, Commodity* cargo, int quantity) {
|
||||
int i, q;
|
||||
int i, q;
|
||||
|
||||
q = quantity;
|
||||
for(i = 0; i < pilot->ncommodities; i++)
|
||||
if(pilot->commodities[i].commodity == cargo) {
|
||||
if(pilot->cargo_free < quantity)
|
||||
q = pilot->cargo_free;
|
||||
pilot->commodities[i].quantity += q;
|
||||
pilot->cargo_free -= q;
|
||||
return q;
|
||||
}
|
||||
q = quantity;
|
||||
for(i = 0; i < pilot->ncommodities; i++)
|
||||
if(pilot->commodities[i].commodity == cargo) {
|
||||
if(pilot->cargo_free < quantity)
|
||||
q = pilot->cargo_free;
|
||||
pilot->commodities[i].quantity += q;
|
||||
pilot->cargo_free -= q;
|
||||
return q;
|
||||
}
|
||||
|
||||
// Must add another one.
|
||||
pilot->commodities = realloc(pilot->commodities,
|
||||
sizeof(PilotCommodity) * (pilot->ncommodities+1));
|
||||
pilot->commodities[pilot->ncommodities].commodity = cargo;
|
||||
if(pilot->cargo_free < quantity)
|
||||
q = pilot->cargo_free;
|
||||
pilot->commodities[pilot->ncommodities].quantity = q;
|
||||
pilot->cargo_free -= q;
|
||||
pilot->ncommodities++;
|
||||
// Must add another one.
|
||||
pilot->commodities = realloc(pilot->commodities,
|
||||
sizeof(PilotCommodity) * (pilot->ncommodities+1));
|
||||
pilot->commodities[pilot->ncommodities].commodity = cargo;
|
||||
if(pilot->cargo_free < quantity)
|
||||
q = pilot->cargo_free;
|
||||
pilot->commodities[pilot->ncommodities].quantity = q;
|
||||
pilot->cargo_free -= q;
|
||||
pilot->ncommodities++;
|
||||
|
||||
return q;
|
||||
return q;
|
||||
}
|
||||
|
||||
// Try to get rid of quantity cargo from pilot,
|
||||
// return quantity actually removed.
|
||||
int pilot_rmCargo(Pilot* pilot, Commodity* cargo, int quantity) {
|
||||
int i, q;
|
||||
int i, q;
|
||||
|
||||
q = quantity;
|
||||
for(i = 0; i < pilot->ncommodities; i++)
|
||||
if(pilot->commodities[i].commodity == cargo) {
|
||||
if(quantity >= pilot->commodities[i].quantity) {
|
||||
q = pilot->commodities[i].quantity;
|
||||
q = quantity;
|
||||
for(i = 0; i < pilot->ncommodities; i++)
|
||||
if(pilot->commodities[i].commodity == cargo) {
|
||||
if(quantity >= pilot->commodities[i].quantity) {
|
||||
q = pilot->commodities[i].quantity;
|
||||
|
||||
// Remove cargo.
|
||||
memmove(pilot->commodities+i, pilot->commodities+i+1,
|
||||
sizeof(PilotCommodity)*(pilot->ncommodities-i));
|
||||
pilot->ncommodities--;
|
||||
pilot->commodities = realloc(pilot->commodities,
|
||||
sizeof(PilotCommodity)*pilot->ncommodities);
|
||||
} else
|
||||
pilot->commodities[i].quantity -= q;
|
||||
// Remove cargo.
|
||||
memmove(pilot->commodities+i, pilot->commodities+i+1,
|
||||
sizeof(PilotCommodity)*(pilot->ncommodities-i));
|
||||
pilot->ncommodities--;
|
||||
pilot->commodities = realloc(pilot->commodities,
|
||||
sizeof(PilotCommodity)*pilot->ncommodities);
|
||||
} else
|
||||
pilot->commodities[i].quantity -= q;
|
||||
|
||||
pilot->cargo_free += q;
|
||||
return q;
|
||||
}
|
||||
pilot->cargo_free += q;
|
||||
return q;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// ==Init pilot.===========================================
|
||||
@ -634,8 +634,8 @@ int pilot_rmCargo(Pilot* pilot, Commodity* cargo, int quantity) {
|
||||
// flags : Tweaking the pilot.
|
||||
// ========================================================
|
||||
void pilot_init(Pilot* pilot, Ship* ship, char* name, Faction* faction,
|
||||
AI_Profile* ai, const double dir, const Vec2* pos,
|
||||
const Vec2* vel, const int flags) {
|
||||
AI_Profile* ai, const double dir, const Vec2* pos,
|
||||
const Vec2* vel, const int flags) {
|
||||
|
||||
if(flags & PILOT_PLAYER) // Player is ID 0
|
||||
pilot->id = PLAYER_ID;
|
||||
@ -663,7 +663,7 @@ void pilot_init(Pilot* pilot, Ship* ship, char* name, Faction* faction,
|
||||
pilot->outfits = NULL;
|
||||
pilot->secondary = NULL;
|
||||
pilot->ammo = NULL;
|
||||
pilot->afterburner = NULL;
|
||||
pilot->afterburner = NULL;
|
||||
ShipOutfit* so;
|
||||
if(ship->outfit) {
|
||||
pilot->noutfits = 0;
|
||||
@ -673,25 +673,25 @@ void pilot_init(Pilot* pilot, Ship* ship, char* name, Faction* faction,
|
||||
pilot->outfits[pilot->noutfits].quantity = so->quantity;
|
||||
pilot->outfits[pilot->noutfits].timer = 0;
|
||||
(pilot->noutfits)++;
|
||||
if(outfit_isTurret(so->data)) // Used to speed up AI a bit.
|
||||
pilot_setFlag(pilot, PILOT_HASTURRET);
|
||||
if(outfit_isTurret(so->data)) // Used to speed up AI a bit.
|
||||
pilot_setFlag(pilot, PILOT_HASTURRET);
|
||||
}
|
||||
}
|
||||
|
||||
// Set the pilot stats based on her ship and outfits.
|
||||
// Hack to have full armour/shield/energy.
|
||||
pilot->armour = pilot->armour_max = 1.;
|
||||
pilot->shield = pilot->shield_max = 1.;
|
||||
pilot->energy = pilot->energy_max = 1.;
|
||||
pilot_calcStats(pilot);
|
||||
// Set the pilot stats based on her ship and outfits.
|
||||
// Hack to have full armour/shield/energy.
|
||||
pilot->armour = pilot->armour_max = 1.;
|
||||
pilot->shield = pilot->shield_max = 1.;
|
||||
pilot->energy = pilot->energy_max = 1.;
|
||||
pilot_calcStats(pilot);
|
||||
|
||||
// Cargo.
|
||||
pilot->credits = 0;
|
||||
pilot->commodities = NULL;
|
||||
pilot->ncommodities = 0;
|
||||
pilot->cargo_free = pilot->ship->cap_cargo;
|
||||
// Cargo.
|
||||
pilot->credits = 0;
|
||||
pilot->commodities = NULL;
|
||||
pilot->ncommodities = 0;
|
||||
pilot->cargo_free = pilot->ship->cap_cargo;
|
||||
|
||||
// Set flags and functions.
|
||||
// Set flags and functions.
|
||||
if(flags & PILOT_PLAYER) {
|
||||
pilot->think = player_think; // Players don't need to thing! :P
|
||||
pilot->render = NULL; // Render will be called from player_think
|
||||
@ -701,20 +701,20 @@ void pilot_init(Pilot* pilot, Ship* ship, char* name, Faction* faction,
|
||||
} else {
|
||||
pilot->think = ai_think;
|
||||
pilot->render = pilot_render;
|
||||
ai_create(pilot); // Will run the create function in ai.
|
||||
ai_create(pilot); // Will run the create function in ai.
|
||||
}
|
||||
// All update the same way.
|
||||
// All update the same way.
|
||||
pilot->update = pilot_update;
|
||||
}
|
||||
|
||||
// Create a new pilot - Params are same as pilot_init. Return pilot's id.
|
||||
unsigned int pilot_create(Ship* ship, char* name, Faction* faction,
|
||||
AI_Profile* ai, const double dir, const Vec2* pos,
|
||||
const Vec2* vel, const int flags) {
|
||||
AI_Profile* ai, const double dir, const Vec2* pos,
|
||||
const Vec2* vel, const int flags) {
|
||||
|
||||
Pilot** tp, *dyn;
|
||||
Pilot** tp, *dyn;
|
||||
|
||||
dyn = MALLOC_L(Pilot);
|
||||
dyn = MALLOC_L(Pilot);
|
||||
if(dyn == NULL) {
|
||||
WARN("Unable to allocate memory.");
|
||||
return 0;
|
||||
@ -733,15 +733,15 @@ unsigned int pilot_create(Ship* ship, char* name, Faction* faction,
|
||||
// Add to the stack.
|
||||
pilots++; // There is a new pilot.
|
||||
|
||||
if(pilots >= mpilots) {
|
||||
// Need to grow. About 20 at a time.
|
||||
mpilots += 20;
|
||||
tp = pilot_stack;
|
||||
pilot_stack = realloc(pilot_stack, mpilots*sizeof(Pilot*));
|
||||
if((pilot_stack != tp) && player)
|
||||
// Take into account possible mem move.
|
||||
player = pilot_stack[0];
|
||||
}
|
||||
if(pilots >= mpilots) {
|
||||
// Need to grow. About 20 at a time.
|
||||
mpilots += 20;
|
||||
tp = pilot_stack;
|
||||
pilot_stack = realloc(pilot_stack, mpilots*sizeof(Pilot*));
|
||||
if((pilot_stack != tp) && player)
|
||||
// Take into account possible mem move.
|
||||
player = pilot_stack[0];
|
||||
}
|
||||
|
||||
pilot_stack[pilots-1] = dyn;
|
||||
}
|
||||
@ -750,11 +750,11 @@ unsigned int pilot_create(Ship* ship, char* name, Faction* faction,
|
||||
|
||||
// Frees and cleans up a pilot.
|
||||
static void pilot_free(Pilot* p) {
|
||||
if(player == p) player = NULL;
|
||||
if(player == p) player = NULL;
|
||||
solid_free(p->solid);
|
||||
if(p->outfits) free(p->outfits);
|
||||
free(p->name);
|
||||
if(p->commodities) free(p->commodities);
|
||||
if(p->commodities) free(p->commodities);
|
||||
ai_destroy(p);
|
||||
free(p);
|
||||
}
|
||||
@ -766,7 +766,7 @@ void pilot_destroy(Pilot* p) {
|
||||
if(pilot_stack[i] == p)
|
||||
break;
|
||||
|
||||
pilots--;
|
||||
pilots--;
|
||||
|
||||
while(i < pilots) {
|
||||
pilot_stack[i] = pilot_stack[i+1];
|
||||
@ -869,7 +869,7 @@ static Fleet* fleet_parse(const xmlNodePtr parent) {
|
||||
pilot->chance = atoi(c);
|
||||
if(pilot->chance == 0)
|
||||
WARN("Pilot %s in Fleet %s has 0%% chance of appearing",
|
||||
pilot->name, tmp->name);
|
||||
pilot->name, tmp->name);
|
||||
if(c) free(c); // Free the external malloc.
|
||||
|
||||
tmp->pilots = realloc(tmp->pilots, sizeof(FleetPilot)*tmp->npilots);
|
||||
|
64
src/pilot.h
64
src/pilot.h
@ -10,11 +10,11 @@
|
||||
|
||||
#define PLAYER_ID 1
|
||||
|
||||
#define HYPERSPACE_ENGINE_DELAY 3000 // Warm up the engines.
|
||||
#define HYPERSPACE_FLY_DELAY 5000 // Time taken to hyperspace.
|
||||
#define HYPERSPACE_STARS_BLUR 2000 // Time stars blur.
|
||||
#define HYPERSPACE_STARS_LENGTH 1000 // Length the stars blur to at max.
|
||||
#define HYPERSPACE_FADEOUT 1000 // Time fadeout.
|
||||
#define HYPERSPACE_ENGINE_DELAY 3000 // Warm up the engines.
|
||||
#define HYPERSPACE_FLY_DELAY 5000 // Time taken to hyperspace.
|
||||
#define HYPERSPACE_STARS_BLUR 2000 // Time stars blur.
|
||||
#define HYPERSPACE_STARS_LENGTH 1000 // Length the stars blur to at max.
|
||||
#define HYPERSPACE_FADEOUT 1000 // Time fadeout.
|
||||
|
||||
// Aproximation for pilot size.
|
||||
#define PILOT_SIZE_APROX 0.8
|
||||
@ -26,18 +26,18 @@
|
||||
#define pilot_rmFlag(p,f) (p->flags ^= (f))
|
||||
// Creation.
|
||||
#define PILOT_PLAYER (1<<0) // Pilot is a player.
|
||||
#define PILOT_HASTURRET (1<<20) // Pilit has turrets.
|
||||
#define PILOT_HASTURRET (1<<20) // Pilit has turrets.
|
||||
// Dynamic.
|
||||
#define PILOT_HOSTILE (1<<1) // Pilot is hostile to the player.
|
||||
#define PILOT_COMBAT (1<<2) // Pilot is engaged in combat.
|
||||
#define PILOT_AFTERBURNER (1<<3) // Pilot has her afterburner activated.
|
||||
#define PILOT_AFTERBURNER (1<<3) // Pilot has her afterburner activated.
|
||||
#define PILOT_HYP_PREP (1<<5) // Pilot is getting ready for hyperspace.
|
||||
#define PILOT_HYP_BEGIN (1<<6) // Pilot is starting engines.
|
||||
#define PILOT_HYPERSPACE (1<<7) // Pilot is in hyperspace.
|
||||
#define PILOT_BOARDED (1<<8) // Pilot has been boarded already!
|
||||
#define PILOT_BOARDED (1<<8) // Pilot has been boarded already!
|
||||
#define PILOT_DISABLED (1<<9) // Pilot is disabled.
|
||||
#define PILOT_DEAD (1<<10) // Pilot is on it's death bed.
|
||||
#define PILOT_EXPLODED (1<<11) // Pilot did final death explosion.
|
||||
#define PILOT_DEAD (1<<10) // Pilot is on it's death bed.
|
||||
#define PILOT_EXPLODED (1<<11) // Pilot did final death explosion.
|
||||
#define PILOT_DELETE (1<<15) // Pilot will get delete asap.
|
||||
|
||||
// Just makes life simpler.
|
||||
@ -45,14 +45,14 @@
|
||||
#define pilot_isDisabled(p) ((p)->flags & PILOT_DISABLED)
|
||||
|
||||
typedef struct PilotOutfit_ {
|
||||
Outfit* outfit; // Associated outfit.
|
||||
int quantity; // Number of outfits of this type that the pilot has.
|
||||
Outfit* outfit; // Associated outfit.
|
||||
int quantity; // Number of outfits of this type that the pilot has.
|
||||
unsigned int timer; // Used to store last used weapon time.
|
||||
} PilotOutfit;
|
||||
|
||||
typedef struct PilotCommodity_ {
|
||||
Commodity* commodity;
|
||||
int quantity;
|
||||
Commodity* commodity;
|
||||
int quantity;
|
||||
} PilotCommodity;
|
||||
|
||||
// Primary pilot structure.
|
||||
@ -65,14 +65,14 @@ typedef struct Pilot_ {
|
||||
// Object characteristics.
|
||||
Ship* ship; // Pilots ship.
|
||||
Solid* solid; // Associated solid (physics).
|
||||
int tsx, tsy; // Current sprite, calculated on update.
|
||||
int tsx, tsy; // Current sprite, calculated on update.
|
||||
|
||||
double thrust, turn, speed;
|
||||
double thrust, turn, speed;
|
||||
|
||||
// Current health.
|
||||
double armour, shield, energy;
|
||||
double armour_max, shield_max, energy_max;
|
||||
double armour_regen, shield_regen, energy_regen;
|
||||
double armour_regen, shield_regen, energy_regen;
|
||||
double fuel; // Used only for jumps. TODO: make it do something.
|
||||
|
||||
void (*think)(struct Pilot_*); // AI thinking for the pilot.
|
||||
@ -82,18 +82,18 @@ typedef struct Pilot_ {
|
||||
// Outfit management.
|
||||
PilotOutfit* outfits;
|
||||
int noutfits;
|
||||
PilotOutfit* secondary; // Secondary weapon.
|
||||
PilotOutfit* ammo; // Secondary ammo (if needed).
|
||||
PilotOutfit* afterburner; // Ze afterburner.
|
||||
PilotOutfit* secondary; // Secondary weapon.
|
||||
PilotOutfit* ammo; // Secondary ammo (if needed).
|
||||
PilotOutfit* afterburner; // Ze afterburner.
|
||||
|
||||
// Cargo.
|
||||
int credits; // Moniez the pilot has.
|
||||
PilotCommodity* commodities; // Commodity and quantity.
|
||||
int ncommodities;
|
||||
int cargo_free;
|
||||
// Cargo.
|
||||
int credits; // Moniez the pilot has.
|
||||
PilotCommodity* commodities; // Commodity and quantity.
|
||||
int ncommodities;
|
||||
int cargo_free;
|
||||
|
||||
// Misc.
|
||||
uint32_t flags; // Used for AI etc.
|
||||
// Misc.
|
||||
uint32_t flags; // Used for AI etc.
|
||||
unsigned int ptimer; // Generic timer for internal pilot use.
|
||||
|
||||
// AI.
|
||||
@ -131,7 +131,7 @@ Fleet* fleet_get(const char* name);
|
||||
// MISC.
|
||||
void pilot_shoot(Pilot* p, const unsigned int target, const int secondary);
|
||||
void pilot_hit(Pilot* p, const Solid* w, const unsigned int shooter,
|
||||
const double damage_shield, const double damage_armour);
|
||||
const double damage_shield, const double damage_armour);
|
||||
void pilot_setSecondary(Pilot* p, const char* secondary);
|
||||
void pilot_setAmmo(Pilot* p);
|
||||
double pilot_face(Pilot* p, const float dir);
|
||||
@ -142,12 +142,12 @@ int pilot_rmCargo(Pilot* pilot, Commodity* cargo, int quantity);
|
||||
|
||||
// Creation.
|
||||
void pilot_init(Pilot* dest, Ship* ship, char* name, Faction* faction,
|
||||
AI_Profile* ai, const double dir, const Vec2* pos,
|
||||
const Vec2* vel, const int flags);
|
||||
AI_Profile* ai, const double dir, const Vec2* pos,
|
||||
const Vec2* vel, const int flags);
|
||||
|
||||
unsigned int pilot_create(Ship* ship, char* name, Faction* faction,
|
||||
AI_Profile* ai, const double dir, const Vec2* pos,
|
||||
const Vec2* vel, const int flags);
|
||||
AI_Profile* ai, const double dir, const Vec2* pos,
|
||||
const Vec2* vel, const int flags);
|
||||
|
||||
// Init/Cleanup.
|
||||
void pilot_destroy(Pilot* p);
|
||||
|
434
src/player.c
434
src/player.c
@ -30,16 +30,16 @@
|
||||
// Player stuff.
|
||||
Pilot* player = NULL; // extern in pilot.h
|
||||
// Player global properties.
|
||||
char* player_name = NULL; // Player name.
|
||||
int player_credits = 0; // Ze monies.
|
||||
int combat_crating = 0; // Ze rating.
|
||||
unsigned int player_flags = 0; // Player flags.
|
||||
char* player_name = NULL; // Player name.
|
||||
int player_credits = 0; // Ze monies.
|
||||
int combat_crating = 0; // Ze rating.
|
||||
unsigned int player_flags = 0; // Player flags.
|
||||
// Input.c
|
||||
double player_turn = 0.; // Turn velocity from input.
|
||||
double player_acc = 0.; // Accel velocity from input.
|
||||
double player_turn = 0.; // Turn velocity from input.
|
||||
double player_acc = 0.; // Accel velocity from input.
|
||||
unsigned int player_target = PLAYER_ID; // Targetted pilot.
|
||||
// Internal
|
||||
int planet_target = -1; // Targetted planet.
|
||||
int planet_target = -1; // Targetted planet.
|
||||
int hyperspace_target = -1; // Target hyperspace route.
|
||||
// For death etc.
|
||||
static unsigned int player_timer = 0;
|
||||
@ -90,9 +90,9 @@ typedef struct GUI_ {
|
||||
} GUI;
|
||||
|
||||
GUI gui = {
|
||||
.gfx_frame = NULL,
|
||||
.gfx_targetPilot = NULL,
|
||||
.gfx_targetPlanet = NULL
|
||||
.gfx_frame = NULL,
|
||||
.gfx_targetPilot = NULL,
|
||||
.gfx_targetPlanet = NULL
|
||||
};
|
||||
|
||||
double gui_xoff = 0.;
|
||||
@ -111,12 +111,12 @@ static Msg* msg_stack;
|
||||
// External.
|
||||
extern void pilot_render(const Pilot* pilot); // Extern is in Pilot.*
|
||||
extern void weapon_minimap(const double res,
|
||||
const double w, const double h, const RadarShape shape); // weapon.c
|
||||
const double w, const double h, const RadarShape shape); // weapon.c
|
||||
extern void planets_minimap(const double res,
|
||||
const double w, const double h, const RadarShape shape); // space.c
|
||||
const double w, const double h, const RadarShape shape); // space.c
|
||||
// Internal.
|
||||
static void rect_parse(const xmlNodePtr parent,
|
||||
double* x, double* y, double* w, double* h);
|
||||
double* x, double* y, double* w, double* h);
|
||||
static int gui_parse(const xmlNodePtr parent, const char* name);
|
||||
static void gui_renderPilot(const Pilot* p);
|
||||
static void gui_renderBar(const glColour* c, const Rect* r, const double w);
|
||||
@ -171,8 +171,8 @@ void player_new(void) {
|
||||
else if(xml_isNode(tmp, "y")) y = xml_getFloat(tmp);
|
||||
} while((tmp = tmp->next));
|
||||
}
|
||||
else if(xml_isNode(cur, "combat_crating"))
|
||||
combat_crating = xml_getInt(cur);
|
||||
else if(xml_isNode(cur, "combat_crating"))
|
||||
combat_crating = xml_getInt(cur);
|
||||
} while((cur = cur->next));
|
||||
}
|
||||
}while((node = node->next));
|
||||
@ -181,8 +181,8 @@ void player_new(void) {
|
||||
free(buf);
|
||||
xmlCleanupParser();
|
||||
|
||||
// In case we are respawning.
|
||||
player_rmFlag(PLAYER_DESTROYED);
|
||||
// In case we are respawning.
|
||||
player_rmFlag(PLAYER_DESTROYED);
|
||||
|
||||
// Money.
|
||||
player_credits = RNG(l, h);
|
||||
@ -191,24 +191,24 @@ void player_new(void) {
|
||||
player_message("Welcome to "APPNAME"!");
|
||||
player_message("v%d.%d.%d", VMAJOR, VMINOR, VREV);
|
||||
|
||||
// Create the player and start the game.
|
||||
player_newShip(ship);
|
||||
// Create the player and start the game.
|
||||
player_newShip(ship);
|
||||
space_init(system);
|
||||
|
||||
// Position and direction.
|
||||
player_warp(x, y);
|
||||
player->solid->dir = RNG(0, 359) / 180.*M_PI;
|
||||
// Position and direction.
|
||||
player_warp(x, y);
|
||||
player->solid->dir = RNG(0, 359) / 180.*M_PI;
|
||||
}
|
||||
|
||||
// Change the players ship.
|
||||
void player_newShip(Ship* ship) {
|
||||
if(player)
|
||||
pilot_destroy(player);
|
||||
if(player)
|
||||
pilot_destroy(player);
|
||||
|
||||
pilot_create(ship, "Player", faction_get("Player"), NULL,
|
||||
0., NULL, NULL, PILOT_PLAYER);
|
||||
pilot_create(ship, "Player", faction_get("Player"), NULL,
|
||||
0., NULL, NULL, PILOT_PLAYER);
|
||||
|
||||
gl_bindCamera(&player->solid->pos); // Set opengl camera.
|
||||
gl_bindCamera(&player->solid->pos); // Set opengl camera.
|
||||
}
|
||||
|
||||
void player_message(const char* fmt, ...) {
|
||||
@ -243,56 +243,56 @@ void player_clear(void) {
|
||||
}
|
||||
|
||||
static char* player_ratings[] = {
|
||||
"None",
|
||||
"Smallfry",
|
||||
"Minor",
|
||||
"Average",
|
||||
"Major",
|
||||
"Fearsome",
|
||||
"Godlike"
|
||||
"None",
|
||||
"Smallfry",
|
||||
"Minor",
|
||||
"Average",
|
||||
"Major",
|
||||
"Fearsome",
|
||||
"Godlike"
|
||||
};
|
||||
|
||||
const char* player_rating(void) {
|
||||
if(combat_crating == 0) return player_ratings[0];
|
||||
else if(combat_crating < 50) return player_ratings[1];
|
||||
else if(combat_crating < 200) return player_ratings[2];
|
||||
else if(combat_crating < 500) return player_ratings[3];
|
||||
else if(combat_crating < 1000) return player_ratings[4];
|
||||
else if(combat_crating < 2500) return player_ratings[5];
|
||||
else if(combat_crating < 10000) return player_ratings[6];
|
||||
else return player_ratings[7];
|
||||
if(combat_crating == 0) return player_ratings[0];
|
||||
else if(combat_crating < 50) return player_ratings[1];
|
||||
else if(combat_crating < 200) return player_ratings[2];
|
||||
else if(combat_crating < 500) return player_ratings[3];
|
||||
else if(combat_crating < 1000) return player_ratings[4];
|
||||
else if(combat_crating < 2500) return player_ratings[5];
|
||||
else if(combat_crating < 10000) return player_ratings[6];
|
||||
else return player_ratings[7];
|
||||
}
|
||||
|
||||
// Return how much weapon. space the player has remaining.
|
||||
int player_freeSpace(void) {
|
||||
int i, s;
|
||||
s = player->ship->cap_weapon;
|
||||
for(i = 0; i < player->noutfits; i++)
|
||||
s -= player->outfits[i].quantity * player->outfits[i].outfit->mass;
|
||||
int i, s;
|
||||
s = player->ship->cap_weapon;
|
||||
for(i = 0; i < player->noutfits; i++)
|
||||
s -= player->outfits[i].quantity * player->outfits[i].outfit->mass;
|
||||
|
||||
return s;
|
||||
return s;
|
||||
}
|
||||
|
||||
// Return amount of outfits the player owns.
|
||||
int player_outfitOwned(const char* outfitname) {
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < player->noutfits; i++)
|
||||
if(strcmp(outfitname, player->outfits[i].outfit->name)==0)
|
||||
return player->outfits[i].quantity;
|
||||
for(i = 0; i < player->noutfits; i++)
|
||||
if(strcmp(outfitname, player->outfits[i].outfit->name)==0)
|
||||
return player->outfits[i].quantity;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Return how many of the commodity the player has.
|
||||
int player_cargoOwned(const char* commodityname) {
|
||||
int i;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < player->ncommodities; i++)
|
||||
if(strcmp(commodityname, player->commodities[i].commodity->name)==0)
|
||||
return player->commodities[i].quantity;
|
||||
for(i = 0; i < player->ncommodities; i++)
|
||||
if(strcmp(commodityname, player->commodities[i].commodity->name)==0)
|
||||
return player->commodities[i].quantity;
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Render the background player stuff, namely planet target
|
||||
@ -301,8 +301,8 @@ void player_renderBG(void) {
|
||||
glColour* c;
|
||||
Planet* planet;
|
||||
|
||||
if(player_isFlag(PLAYER_DESTROYED) ||
|
||||
pilot_isFlag(player, PILOT_DEAD)) return;
|
||||
if(player_isFlag(PLAYER_DESTROYED) ||
|
||||
pilot_isFlag(player, PILOT_DEAD)) return;
|
||||
|
||||
if(planet_target >= 0) {
|
||||
planet = &cur_system->planets[planet_target];
|
||||
@ -334,41 +334,41 @@ void player_render(void) {
|
||||
glColour* c;
|
||||
glFont* f;
|
||||
|
||||
if(player_isFlag(PLAYER_DESTROYED) || pilot_isFlag(player, PILOT_DEAD)) {
|
||||
if(player_isFlag(PLAYER_DESTROYED)) {
|
||||
if(!toolkit && (SDL_GetTicks() > player_timer))
|
||||
menu_death();
|
||||
} else
|
||||
pilot_render(player);
|
||||
if(player_isFlag(PLAYER_DESTROYED) || pilot_isFlag(player, PILOT_DEAD)) {
|
||||
if(player_isFlag(PLAYER_DESTROYED)) {
|
||||
if(!toolkit && (SDL_GetTicks() > player_timer))
|
||||
menu_death();
|
||||
} else
|
||||
pilot_render(player);
|
||||
|
||||
// Fancy cinematic scene borders.
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix(); // Translation matrix.
|
||||
glTranslated(x-(double)gl_screen.w/2., y-(double)gl_screen.h/2., 0);
|
||||
// Fancy cinematic scene borders.
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix(); // Translation matrix.
|
||||
glTranslated(x-(double)gl_screen.w/2., y-(double)gl_screen.h/2., 0);
|
||||
|
||||
COLOUR(cBlack);
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2d(0., 0.);
|
||||
glVertex2d(0., gl_screen.h*0.2);
|
||||
glVertex2d(gl_screen.w, gl_screen.h*0.2);
|
||||
glVertex2d(gl_screen.w, 0.);
|
||||
glVertex2d(0., gl_screen.h);
|
||||
glVertex2d(gl_screen.w, gl_screen.h);
|
||||
glVertex2d(0., gl_screen.h*0.8);
|
||||
glEnd();
|
||||
COLOUR(cBlack);
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2d(0., 0.);
|
||||
glVertex2d(0., gl_screen.h*0.2);
|
||||
glVertex2d(gl_screen.w, gl_screen.h*0.2);
|
||||
glVertex2d(gl_screen.w, 0.);
|
||||
glVertex2d(0., gl_screen.h);
|
||||
glVertex2d(gl_screen.w, gl_screen.h);
|
||||
glVertex2d(0., gl_screen.h*0.8);
|
||||
glEnd();
|
||||
|
||||
glPopMatrix(); // Translation matrix.
|
||||
glPopMatrix(); // Translation matrix.
|
||||
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Render the player target graphics.
|
||||
if(player_target != PLAYER_ID) p = pilot_get(player_target);
|
||||
else p = NULL;
|
||||
if((p == NULL) || pilot_isFlag(p, PILOT_DEAD))
|
||||
player_target = PLAYER_ID; // No more pilot target.
|
||||
else {
|
||||
// There is still a pilot target.
|
||||
else p = NULL;
|
||||
if((p == NULL) || pilot_isFlag(p, PILOT_DEAD))
|
||||
player_target = PLAYER_ID; // No more pilot target.
|
||||
else {
|
||||
// There is still a pilot target.
|
||||
if(pilot_isDisabled(p)) c = &cInert;
|
||||
else if(pilot_isFlag(p, PILOT_HOSTILE)) c = &cHostile;
|
||||
else c = &cNeutral;
|
||||
@ -442,11 +442,11 @@ void player_render(void) {
|
||||
if(planet_target >= 0) {
|
||||
// Planet landing target.
|
||||
gl_printMid(NULL, (int)gui.nav.w,
|
||||
gui.nav.x, gui.nav.y - 5, &cConsole, "Land");
|
||||
gui.nav.x, gui.nav.y - 5, &cConsole, "Land");
|
||||
|
||||
gl_printMid(&gl_smallFont, (int)gui.nav.w, gui.nav.x,
|
||||
gui.nav.y - 10 - gl_smallFont.h, NULL, "%s",
|
||||
cur_system->planets[planet_target].name);
|
||||
gui.nav.y - 10 - gl_smallFont.h, NULL, "%s",
|
||||
cur_system->planets[planet_target].name);
|
||||
}
|
||||
else if(hyperspace_target >= 0) {
|
||||
// Hyperspace target.
|
||||
@ -455,8 +455,8 @@ void player_render(void) {
|
||||
c, "Hyperspace");
|
||||
|
||||
gl_printMid(&gl_smallFont, (int)gui.nav.w, gui.nav.x,
|
||||
gui.nav.y - 10 - gl_smallFont.h, NULL, "%s",
|
||||
systems_stack[cur_system->jumps[hyperspace_target]].name);
|
||||
gui.nav.y - 10 - gl_smallFont.h, NULL, "%s",
|
||||
systems_stack[cur_system->jumps[hyperspace_target]].name);
|
||||
}
|
||||
else {
|
||||
// No NAV target.
|
||||
@ -479,7 +479,7 @@ void player_render(void) {
|
||||
gui.weapon.y - 10 - gl_defFont.h, &cGrey, "None");
|
||||
} else {
|
||||
f = &gl_defFont;
|
||||
if(outfit_isLauncher(player->secondary->outfit)) {
|
||||
if(outfit_isLauncher(player->secondary->outfit)) {
|
||||
// Use the ammunitions name.
|
||||
i = gl_printWidth(f, "%s", player->secondary->outfit->u.lau.ammo);
|
||||
if(i > gui.weapon.w)
|
||||
@ -495,15 +495,15 @@ void player_render(void) {
|
||||
gui.weapon.y - 10 - gl_defFont.h,
|
||||
NULL, "%d", (player->ammo) ? player->ammo->quantity : 0);
|
||||
} else {
|
||||
// Just print the item name.
|
||||
i = gl_printWidth(f, "%s", player->secondary->outfit->name);
|
||||
if(i > (int)gui.weapon.w)
|
||||
// Font is too big.
|
||||
f = &gl_smallFont;
|
||||
gl_printMid(f, (int)gui.weapon.w,
|
||||
gui.weapon.x, gui.weapon.y - (gui.weapon.h - f->h)/2.,
|
||||
&cConsole, "%s", player->secondary->outfit->name);
|
||||
}
|
||||
// Just print the item name.
|
||||
i = gl_printWidth(f, "%s", player->secondary->outfit->name);
|
||||
if(i > (int)gui.weapon.w)
|
||||
// Font is too big.
|
||||
f = &gl_smallFont;
|
||||
gl_printMid(f, (int)gui.weapon.w,
|
||||
gui.weapon.x, gui.weapon.y - (gui.weapon.h - f->h)/2.,
|
||||
&cConsole, "%s", player->secondary->outfit->name);
|
||||
}
|
||||
}
|
||||
|
||||
// Target.
|
||||
@ -539,39 +539,39 @@ void player_render(void) {
|
||||
}
|
||||
|
||||
// Misc.
|
||||
j = gui.misc.y - 8 - gl_smallFont.h;
|
||||
j = gui.misc.y - 8 - gl_smallFont.h;
|
||||
gl_print(NULL, gui.misc.x + 8, j,
|
||||
&cConsole, "SCreds:");
|
||||
|
||||
credits2str(str, player_credits, 2);
|
||||
credits2str(str, player_credits, 2);
|
||||
|
||||
i = gl_printWidth(&gl_smallFont, str);
|
||||
gl_print(&gl_smallFont, gui.misc.x + gui.misc.w - 8 - i, j,
|
||||
NULL, str);
|
||||
NULL, str);
|
||||
|
||||
// Cargo and co.
|
||||
if(player->ncommodities > 0) {
|
||||
j -= gl_smallFont.h + 5;
|
||||
gl_print(&gl_smallFont,
|
||||
gui.misc.x + 8, j, &cConsole, "Cargo");
|
||||
// Cargo and co.
|
||||
if(player->ncommodities > 0) {
|
||||
j -= gl_smallFont.h + 5;
|
||||
gl_print(&gl_smallFont,
|
||||
gui.misc.x + 8, j, &cConsole, "Cargo");
|
||||
|
||||
for(i = 0; i < MIN(player->ncommodities,3); i++) {
|
||||
j -= gl_smallFont.h + 3;
|
||||
gl_print(&gl_smallFont,
|
||||
gui.misc.x + 13, j,
|
||||
NULL, "%d %s", player->commodities[i].quantity,
|
||||
player->commodities[i].commodity->name);
|
||||
}
|
||||
}
|
||||
for(i = 0; i < MIN(player->ncommodities,3); i++) {
|
||||
j -= gl_smallFont.h + 3;
|
||||
gl_print(&gl_smallFont,
|
||||
gui.misc.x + 13, j,
|
||||
NULL, "%d %s", player->commodities[i].quantity,
|
||||
player->commodities[i].commodity->name);
|
||||
}
|
||||
}
|
||||
|
||||
j -= gl_smallFont.h + 5;
|
||||
gl_print(&gl_smallFont,
|
||||
gui.misc.x + 8, j, &cConsole, "Free:");
|
||||
j -= gl_smallFont.h + 5;
|
||||
gl_print(&gl_smallFont,
|
||||
gui.misc.x + 8, j, &cConsole, "Free:");
|
||||
|
||||
i = gl_printWidth(&gl_smallFont, "%d", player->ship->cap_cargo);
|
||||
gl_print(&gl_smallFont,
|
||||
gui.misc.x + gui.misc.w - 8 - i, j,
|
||||
NULL, "%d", player->cargo_free);
|
||||
i = gl_printWidth(&gl_smallFont, "%d", player->ship->cap_cargo);
|
||||
gl_print(&gl_smallFont,
|
||||
gui.misc.x + gui.misc.w - 8 - i, j,
|
||||
NULL, "%d", player->cargo_free);
|
||||
|
||||
// Messages.
|
||||
x = gui.msg.x;
|
||||
@ -586,18 +586,18 @@ void player_render(void) {
|
||||
}
|
||||
// Hyperspace FLASH BANG!!!
|
||||
if(pilot_isFlag(player, PILOT_HYPERSPACE) && !paused) {
|
||||
i = (int)player->ptimer - HYPERSPACE_FADEOUT;
|
||||
j = (int)SDL_GetTicks();
|
||||
if(i < j) {
|
||||
x = (double)(j-i) / HYPERSPACE_FADEOUT;
|
||||
glColor4d(1.,1.,1., x); // We'll | I'll, make this more effiecent later.
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2d(-gl_screen.w/2., -gl_screen.h/2.);
|
||||
glVertex2d(-gl_screen.w/2., gl_screen.h/2.);
|
||||
glVertex2d( gl_screen.w/2., gl_screen.h/2.);
|
||||
glVertex2d( gl_screen.w/2., -gl_screen.h/2.);
|
||||
glEnd();
|
||||
}
|
||||
i = (int)player->ptimer - HYPERSPACE_FADEOUT;
|
||||
j = (int)SDL_GetTicks();
|
||||
if(i < j) {
|
||||
x = (double)(j-i) / HYPERSPACE_FADEOUT;
|
||||
glColor4d(1.,1.,1., x); // We'll | I'll, make this more effiecent later.
|
||||
glBegin(GL_QUADS);
|
||||
glVertex2d(-gl_screen.w/2., -gl_screen.h/2.);
|
||||
glVertex2d(-gl_screen.w/2., gl_screen.h/2.);
|
||||
glVertex2d( gl_screen.w/2., gl_screen.h/2.);
|
||||
glVertex2d( gl_screen.w/2., -gl_screen.h/2.);
|
||||
glEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -727,7 +727,7 @@ int gui_load(const char* name) {
|
||||
}
|
||||
|
||||
static void rect_parse(const xmlNodePtr parent, double* x, double* y,
|
||||
double* w, double* h) {
|
||||
double* w, double* h) {
|
||||
xmlNodePtr cur;
|
||||
int param;
|
||||
|
||||
@ -850,19 +850,19 @@ static int gui_parse(const xmlNodePtr parent, const char* name) {
|
||||
do {
|
||||
if(xml_isNode(cur, "shield")) {
|
||||
rect_parse(cur, &gui.shield.x, &gui.shield.y,
|
||||
&gui.shield.w, &gui.shield.h);
|
||||
&gui.shield.w, &gui.shield.h);
|
||||
RELATIVIZE(gui.shield);
|
||||
}
|
||||
|
||||
if(xml_isNode(cur, "armour")) {
|
||||
rect_parse(cur, &gui.armour.x, &gui.armour.y,
|
||||
&gui.armour.w, &gui.armour.h);
|
||||
&gui.armour.w, &gui.armour.h);
|
||||
RELATIVIZE(gui.armour);
|
||||
}
|
||||
|
||||
if(xml_isNode(cur, "energy")) {
|
||||
rect_parse(cur, &gui.energy.x, &gui.energy.y,
|
||||
&gui.energy.w, &gui.energy.h);
|
||||
&gui.energy.w, &gui.energy.h);
|
||||
RELATIVIZE(gui.energy);
|
||||
}
|
||||
} while((cur = cur->next));
|
||||
@ -870,7 +870,7 @@ static int gui_parse(const xmlNodePtr parent, const char* name) {
|
||||
// Secondary weapon.
|
||||
else if(xml_isNode(node, "weapon")) {
|
||||
rect_parse(node, &gui.weapon.x, &gui.weapon.y,
|
||||
&gui.weapon.w, &gui.weapon.h);
|
||||
&gui.weapon.w, &gui.weapon.h);
|
||||
RELATIVIZE(gui.weapon);
|
||||
gui.weapon.y -= gl_defFont.h;
|
||||
}
|
||||
@ -892,14 +892,14 @@ static int gui_parse(const xmlNodePtr parent, const char* name) {
|
||||
|
||||
if(xml_isNode(cur, "faction")) {
|
||||
rect_parse(cur, &gui.target_faction.x, &gui.target_faction.y,
|
||||
NULL, NULL);
|
||||
NULL, NULL);
|
||||
RELATIVIZE(gui.target_faction);
|
||||
gui.target_faction.y -= gl_smallFont.h;
|
||||
}
|
||||
|
||||
if(xml_isNode(cur, "health")) {
|
||||
rect_parse(cur, &gui.target_health.x, &gui.target_health.y,
|
||||
NULL, NULL);
|
||||
NULL, NULL);
|
||||
RELATIVIZE(gui.target_health);
|
||||
gui.target_health.y -= gl_smallFont.h;
|
||||
}
|
||||
@ -916,9 +916,9 @@ static int gui_parse(const xmlNodePtr parent, const char* name) {
|
||||
|
||||
// Free the GUI.
|
||||
void gui_free(void) {
|
||||
if(gui.gfx_frame) gl_freeTexture(gui.gfx_frame);
|
||||
if(gui.gfx_targetPilot) gl_freeTexture(gui.gfx_targetPilot);
|
||||
if(gui.gfx_targetPlanet) gl_freeTexture(gui.gfx_targetPlanet);
|
||||
if(gui.gfx_frame) gl_freeTexture(gui.gfx_frame);
|
||||
if(gui.gfx_targetPilot) gl_freeTexture(gui.gfx_targetPilot);
|
||||
if(gui.gfx_targetPlanet) gl_freeTexture(gui.gfx_targetPlanet);
|
||||
|
||||
free(msg_stack);
|
||||
}
|
||||
@ -926,20 +926,20 @@ void gui_free(void) {
|
||||
// Used in pilot.c
|
||||
// Basically uses keyboard input instead of AI input.
|
||||
void player_think(Pilot* player) {
|
||||
// Last I checked, the dead didn't think..
|
||||
if(pilot_isFlag(player, PILOT_DEAD)) return;
|
||||
// Last I checked, the dead didn't think..
|
||||
if(pilot_isFlag(player, PILOT_DEAD)) return;
|
||||
|
||||
// PLAYER_FACE will take over navigation.
|
||||
if(player_isFlag(PLAYER_FACE)) {
|
||||
if(player_target != PLAYER_ID)
|
||||
pilot_face(player,
|
||||
vect_angle(&player->solid->pos,
|
||||
&pilot_get(player_target)->solid->pos));
|
||||
else if(planet_target != -1)
|
||||
pilot_face(player,
|
||||
vect_angle(&player->solid->pos,
|
||||
&cur_system->planets[planet_target].pos));
|
||||
}
|
||||
if(player_isFlag(PLAYER_FACE)) {
|
||||
if(player_target != PLAYER_ID)
|
||||
pilot_face(player,
|
||||
vect_angle(&player->solid->pos,
|
||||
&pilot_get(player_target)->solid->pos));
|
||||
else if(planet_target != -1)
|
||||
pilot_face(player,
|
||||
vect_angle(&player->solid->pos,
|
||||
&cur_system->planets[planet_target].pos));
|
||||
}
|
||||
|
||||
// PLAYER_REVERSE will take over navigation.
|
||||
else if(player_isFlag(PLAYER_REVERSE) && (VMOD(player->solid->vel) > 0.))
|
||||
@ -956,18 +956,18 @@ void player_think(Pilot* player) {
|
||||
if(player_isFlag(PLAYER_SECONDARY)) // Needs a target.
|
||||
pilot_shoot(player, player_target, 1);
|
||||
|
||||
if(player_isFlag(PLAYER_AFTERBURNER))
|
||||
vect_pset(&player->solid->force,
|
||||
player->thrust * player->afterburner->outfit->u.afb.thrust_perc +
|
||||
player->afterburner->outfit->u.afb.thrust_abs, player->solid->dir);
|
||||
else
|
||||
vect_pset(&player->solid->force, player->thrust * player_acc,
|
||||
player->solid->dir);
|
||||
if(player_isFlag(PLAYER_AFTERBURNER))
|
||||
vect_pset(&player->solid->force,
|
||||
player->thrust * player->afterburner->outfit->u.afb.thrust_perc +
|
||||
player->afterburner->outfit->u.afb.thrust_abs, player->solid->dir);
|
||||
else
|
||||
vect_pset(&player->solid->force, player->thrust * player_acc,
|
||||
player->solid->dir);
|
||||
|
||||
// Set the listener stuff.
|
||||
sound_listener(player->solid->dir,
|
||||
player->solid->pos.x, player->solid->pos.y,
|
||||
player->solid->vel.x, player->solid->vel.y);
|
||||
// Set the listener stuff.
|
||||
sound_listener(player->solid->dir,
|
||||
player->solid->pos.x, player->solid->pos.y,
|
||||
player->solid->vel.x, player->solid->vel.y);
|
||||
}
|
||||
|
||||
// Modify the radar resolution.
|
||||
@ -976,7 +976,7 @@ void player_setRadarRel(int mod) {
|
||||
if(gui.radar.res > RADAR_RES_MAX) gui.radar.res = RADAR_RES_MAX;
|
||||
else if(gui.radar.res < RADAR_RES_MIN) gui.radar.res = RADAR_RES_MIN;
|
||||
|
||||
player_message("Radar set to %dx", (int)gui.radar.res);
|
||||
player_message("Radar set to %dx", (int)gui.radar.res);
|
||||
}
|
||||
|
||||
// Get the next secondary weapon.
|
||||
@ -1007,7 +1007,7 @@ void player_secondaryNext(void) {
|
||||
// Cycle through planet targets.
|
||||
void player_targetPlanet(void) {
|
||||
hyperspace_target = -1;
|
||||
player_rmFlag(PLAYER_LANDACK);
|
||||
player_rmFlag(PLAYER_LANDACK);
|
||||
|
||||
if((planet_target == -1) && (cur_system->nplanets > 0)) {
|
||||
// No target.
|
||||
@ -1031,26 +1031,26 @@ void player_land(void) {
|
||||
}
|
||||
Planet* planet = &cur_system->planets[planet_target];
|
||||
if(planet_target >= 0) {
|
||||
if(!planet_hasService(planet, PLANET_SERVICE_LAND)) {
|
||||
player_message("You can't land here.");
|
||||
return;
|
||||
}
|
||||
else if(!player_isFlag(PLAYER_LANDACK)) {
|
||||
// No landing authorization.
|
||||
if(!areEnemies(player->faction, planet->faction)) {
|
||||
player_message("%s> Permission to land cleared.", planet->name);
|
||||
player_setFlag(PLAYER_LANDACK);
|
||||
} else {
|
||||
player_message("%s> Land request denied.", planet->name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
if(!planet_hasService(planet, PLANET_SERVICE_LAND)) {
|
||||
player_message("You can't land here.");
|
||||
return;
|
||||
}
|
||||
else if(!player_isFlag(PLAYER_LANDACK)) {
|
||||
// No landing authorization.
|
||||
if(!areEnemies(player->faction, planet->faction)) {
|
||||
player_message("%s> Permission to land cleared.", planet->name);
|
||||
player_setFlag(PLAYER_LANDACK);
|
||||
} else {
|
||||
player_message("%s> Land request denied.", planet->name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
else if(vect_dist(&player->solid->pos, &planet->pos) > planet->gfx_space->sw) {
|
||||
player_message("You are too far away to land on %s", planet->name);
|
||||
return;
|
||||
}
|
||||
else if((pow2(VX(player->solid->vel)) + pow2(VY(player->solid->vel))) >
|
||||
(double)pow2(MAX_HYPERSPACE_VEL)) {
|
||||
(double)pow2(MAX_HYPERSPACE_VEL)) {
|
||||
player_message("You are going too fast to land on %s", planet->name);
|
||||
return;
|
||||
}
|
||||
@ -1066,20 +1066,20 @@ void player_land(void) {
|
||||
for(i = 0; i < cur_system->nplanets; i++) {
|
||||
d = vect_dist(&player->solid->pos, &cur_system->planets[i].pos);
|
||||
if(planet_hasService(&cur_system->planets[i], PLANET_SERVICE_LAND) &&
|
||||
((tp == -1) || ((td == -1) || (td > d)))) {
|
||||
((tp == -1) || ((td == -1) || (td > d)))) {
|
||||
tp = i;
|
||||
td = d;
|
||||
}
|
||||
}
|
||||
planet_target = tp;
|
||||
player_rmFlag(PLAYER_LANDACK);
|
||||
player_land(); // Re-run land protocol.
|
||||
player_rmFlag(PLAYER_LANDACK);
|
||||
player_land(); // Re-run land protocol.
|
||||
}
|
||||
}
|
||||
|
||||
void player_targetHyperspace(void) {
|
||||
planet_target = -1; // Remove planet target.
|
||||
player_rmFlag(PLAYER_LANDACK); // Get rid of landing permission.
|
||||
player_rmFlag(PLAYER_LANDACK); // Get rid of landing permission.
|
||||
hyperspace_target++;
|
||||
|
||||
if(hyperspace_target >= cur_system->njumps)
|
||||
@ -1089,10 +1089,10 @@ void player_targetHyperspace(void) {
|
||||
// Actually attempt to jump into hyperspace.
|
||||
void player_jump(void) {
|
||||
if((hyperspace_target == -1) ||
|
||||
pilot_isFlag(player, PILOT_HYP_PREP) ||
|
||||
pilot_isFlag(player, PILOT_HYP_BEGIN) ||
|
||||
pilot_isFlag(player, PILOT_HYPERSPACE))
|
||||
return;
|
||||
pilot_isFlag(player, PILOT_HYP_PREP) ||
|
||||
pilot_isFlag(player, PILOT_HYP_BEGIN) ||
|
||||
pilot_isFlag(player, PILOT_HYPERSPACE))
|
||||
return;
|
||||
|
||||
int i = space_hyperspace(player);
|
||||
|
||||
@ -1121,29 +1121,29 @@ void player_brokeHyperspace(void) {
|
||||
|
||||
// Make the player face her hyperspace target.
|
||||
double player_faceHyperspace(void) {
|
||||
double a;
|
||||
a = ANGLE(systems_stack[cur_system->jumps[hyperspace_target]].pos.x -
|
||||
cur_system->pos.x,
|
||||
systems_stack[cur_system->jumps[hyperspace_target]].pos.y -
|
||||
cur_system->pos.y);
|
||||
double a;
|
||||
a = ANGLE(systems_stack[cur_system->jumps[hyperspace_target]].pos.x -
|
||||
cur_system->pos.x,
|
||||
systems_stack[cur_system->jumps[hyperspace_target]].pos.y -
|
||||
cur_system->pos.y);
|
||||
|
||||
return pilot_face(player, a);
|
||||
return pilot_face(player, a);
|
||||
}
|
||||
|
||||
// Activate afterburner.
|
||||
void player_afterburn(void) {
|
||||
// TODO: Fancy effects.
|
||||
if(player->afterburner != NULL) {
|
||||
player_setFlag(PLAYER_AFTERBURNER);
|
||||
pilot_setFlag(player, PILOT_AFTERBURNER);
|
||||
}
|
||||
// TODO: Fancy effects.
|
||||
if(player->afterburner != NULL) {
|
||||
player_setFlag(PLAYER_AFTERBURNER);
|
||||
pilot_setFlag(player, PILOT_AFTERBURNER);
|
||||
}
|
||||
}
|
||||
|
||||
void player_afterburnOver(void) {
|
||||
if(player->afterburner != NULL) {
|
||||
player_rmFlag(PLAYER_AFTERBURNER);
|
||||
pilot_rmFlag(player, PILOT_AFTERBURNER);
|
||||
}
|
||||
if(player->afterburner != NULL) {
|
||||
player_rmFlag(PLAYER_AFTERBURNER);
|
||||
pilot_rmFlag(player, PILOT_AFTERBURNER);
|
||||
}
|
||||
}
|
||||
|
||||
// Take a screenshot.
|
||||
@ -1162,7 +1162,7 @@ void player_screenshot(void) {
|
||||
return;
|
||||
}
|
||||
snprintf(filename, PATH_MAX, "../screenshots/screenshot%03d.png",
|
||||
screenshot_cur);
|
||||
screenshot_cur);
|
||||
fp = fopen(filename, "r"); // Myeah, I know it's a horrible way to check.
|
||||
if(fp == NULL) done = 1;
|
||||
else {
|
||||
@ -1180,15 +1180,15 @@ void player_screenshot(void) {
|
||||
|
||||
// Player go pwned.
|
||||
void player_dead(void) {
|
||||
gui_xoff = 0.;
|
||||
gui_yoff = 0.;
|
||||
gui_xoff = 0.;
|
||||
gui_yoff = 0.;
|
||||
}
|
||||
|
||||
// Player blew up in a nice fireball.
|
||||
void player_destroyed(void) {
|
||||
vectcpy(&player_cam, &player->solid->pos);
|
||||
gl_bindCamera(&player_cam);
|
||||
player_setFlag(PLAYER_DESTROYED);
|
||||
player_timer = SDL_GetTicks() + 5000;
|
||||
vectcpy(&player_cam, &player->solid->pos);
|
||||
gl_bindCamera(&player_cam);
|
||||
player_setFlag(PLAYER_DESTROYED);
|
||||
player_timer = SDL_GetTicks() + 5000;
|
||||
}
|
||||
|
||||
|
20
src/player.h
20
src/player.h
@ -2,20 +2,20 @@
|
||||
#include "pilot.h"
|
||||
|
||||
// Flag definitions.
|
||||
#define PLAYER_TURN_LEFT (1<<0) // Player is turning left.
|
||||
#define PLAYER_TURN_RIGHT (1<<1) // Player is turning right.
|
||||
#define PLAYER_REVERSE (1<<2) // Player is facint opposite vel.
|
||||
#define PLAYER_AFTERBURNER (1<<3) // Player is burning it up.
|
||||
#define PLAYER_DESTROYED (1<<9) // Player goes BOOM!
|
||||
#define PLAYER_FACE (1<<10) // Player is facing target.
|
||||
#define PLAYER_PRIMARY (1<<11) // Player is shooting primary weapon.
|
||||
#define PLAYER_SECONDARY (1<<12) // Player is shooting secondary weapon.
|
||||
#define PLAYER_LANDACK (1<<13) // Player has permission to land.
|
||||
#define PLAYER_TURN_LEFT (1<<0) // Player is turning left.
|
||||
#define PLAYER_TURN_RIGHT (1<<1) // Player is turning right.
|
||||
#define PLAYER_REVERSE (1<<2) // Player is facint opposite vel.
|
||||
#define PLAYER_AFTERBURNER (1<<3) // Player is burning it up.
|
||||
#define PLAYER_DESTROYED (1<<9) // Player goes BOOM!
|
||||
#define PLAYER_FACE (1<<10) // Player is facing target.
|
||||
#define PLAYER_PRIMARY (1<<11) // Player is shooting primary weapon.
|
||||
#define PLAYER_SECONDARY (1<<12) // Player is shooting secondary weapon.
|
||||
#define PLAYER_LANDACK (1<<13) // Player has permission to land.
|
||||
|
||||
// Flag functions.
|
||||
#define player_isFlag(f) (player_flags & f)
|
||||
#define player_setFlag(f) if(!player_isFlag(f)) (player_flags |= f)
|
||||
#define player_rmFlag(f) if(player_isFlag(f)) (player_flags ^= f)
|
||||
#define player_rmFlag(f) if(player_isFlag(f)) (player_flags ^= f)
|
||||
|
||||
// The player.
|
||||
extern Pilot* pilot;
|
||||
|
@ -1,8 +1,8 @@
|
||||
#pragma once
|
||||
#include <stdlib.h>
|
||||
|
||||
#define RNG(L,H) ((int)L + (int)((double)(H-L+1) * (rand()/(RAND_MAX+1.))))
|
||||
#define RNGF() (rand()/(RAND_MAX+1.))
|
||||
#define RNG(L,H) ((int)L + (int)((double)(H-L+1) * (rand()/(RAND_MAX+1.))))
|
||||
#define RNGF() (rand()/(RAND_MAX+1.))
|
||||
|
||||
void rng_init(void);
|
||||
|
||||
|
226
src/ship.c
226
src/ship.c
@ -15,11 +15,11 @@
|
||||
#define SHIP_EXT ".png"
|
||||
#define SHIP_TARGET "_target"
|
||||
|
||||
#define VIEW_WIDTH 300
|
||||
#define VIEW_HEIGHT 300
|
||||
#define VIEW_WIDTH 300
|
||||
#define VIEW_HEIGHT 300
|
||||
|
||||
#define BUTTON_WIDTH 80
|
||||
#define BUTTON_HEIGHT 30
|
||||
#define BUTTON_WIDTH 80
|
||||
#define BUTTON_HEIGHT 30
|
||||
|
||||
static Ship* ship_stack = NULL;
|
||||
static int ships = 0;
|
||||
@ -42,37 +42,37 @@ Ship* ship_get(const char* name) {
|
||||
|
||||
// Get the ship's classname.
|
||||
static char* ship_classes[] = {
|
||||
"NULL",
|
||||
"Civialian Light", "Civilian Medium", "Civilian Heavy"
|
||||
"Military Light", "Military Medium", "Military Heavy"
|
||||
"Robotic Light", "Robotic Medium", "Robotic Heavy"
|
||||
"Hybrid Light", "Hybrid Medium", "Hybrid Heavy"
|
||||
"NULL",
|
||||
"Civialian Light", "Civilian Medium", "Civilian Heavy"
|
||||
"Military Light", "Military Medium", "Military Heavy"
|
||||
"Robotic Light", "Robotic Medium", "Robotic Heavy"
|
||||
"Hybrid Light", "Hybrid Medium", "Hybrid Heavy"
|
||||
|
||||
};
|
||||
|
||||
// Return all the ships in text form.
|
||||
char** ship_getTech(int* n, const int* tech, const int techmax) {
|
||||
int i, j;
|
||||
char** shipnames = malloc(sizeof(Ship*) * ships);
|
||||
int i, j;
|
||||
char** shipnames = malloc(sizeof(Ship*) * ships);
|
||||
|
||||
*n = 0;
|
||||
for(i = 0; i < ships; i++)
|
||||
if(ship_stack[i].tech <= tech[0]) {
|
||||
shipnames[*n] = strdup(ship_stack[i].name);
|
||||
(*n)++;
|
||||
} else {
|
||||
for(j = 0; j < techmax; j++)
|
||||
if(tech[j] == ship_stack[i].tech) {
|
||||
shipnames[*n] = strdup(ship_stack[i].name);
|
||||
(*n)++;
|
||||
}
|
||||
}
|
||||
*n = 0;
|
||||
for(i = 0; i < ships; i++)
|
||||
if(ship_stack[i].tech <= tech[0]) {
|
||||
shipnames[*n] = strdup(ship_stack[i].name);
|
||||
(*n)++;
|
||||
} else {
|
||||
for(j = 0; j < techmax; j++)
|
||||
if(tech[j] == ship_stack[i].tech) {
|
||||
shipnames[*n] = strdup(ship_stack[i].name);
|
||||
(*n)++;
|
||||
}
|
||||
}
|
||||
|
||||
return shipnames;
|
||||
return shipnames;
|
||||
}
|
||||
|
||||
char* ship_class(Ship* s) {
|
||||
return ship_classes[s->class];
|
||||
return ship_classes[s->class];
|
||||
}
|
||||
|
||||
static Ship* ship_parse(xmlNodePtr parent) {
|
||||
@ -81,7 +81,7 @@ static Ship* ship_parse(xmlNodePtr parent) {
|
||||
ShipOutfit* otmp, *ocur;
|
||||
|
||||
char str[PATH_MAX] = "\0";
|
||||
char* stmp;
|
||||
char* stmp;
|
||||
|
||||
tmp->name = xml_nodeProp(parent, "name");
|
||||
if(tmp->name == NULL) WARN("Ship in "SHIP_DATA" has invalid or no name");
|
||||
@ -91,31 +91,31 @@ static Ship* ship_parse(xmlNodePtr parent) {
|
||||
do {
|
||||
// Load all the data.
|
||||
if(xml_isNode(node,"GFX")) {
|
||||
snprintf(str, strlen(xml_get(node)) +
|
||||
sizeof(SHIP_GFX) + sizeof(SHIP_EXT),
|
||||
SHIP_GFX"%s"SHIP_EXT, xml_get(node));
|
||||
snprintf(str, strlen(xml_get(node)) +
|
||||
sizeof(SHIP_GFX) + sizeof(SHIP_EXT),
|
||||
SHIP_GFX"%s"SHIP_EXT, xml_get(node));
|
||||
tmp->gfx_space = gl_newSprite(str, 6, 6);
|
||||
// Target.
|
||||
snprintf(str, strlen(xml_get(node)) +
|
||||
sizeof(SHIP_GFX)+sizeof(SHIP_TARGET)+sizeof(SHIP_EXT),
|
||||
sizeof(SHIP_GFX)+sizeof(SHIP_TARGET)+sizeof(SHIP_EXT),
|
||||
SHIP_GFX"%s"SHIP_TARGET SHIP_EXT, xml_get(node));
|
||||
tmp->gfx_target = gl_newImage(str);
|
||||
|
||||
}
|
||||
else if(xml_isNode(node, "GUI"))
|
||||
tmp->gui = strdup(xml_get(node));
|
||||
else if(xml_isNode(node, "sound"))
|
||||
tmp->sound = sound_get(xml_get(node));
|
||||
else if(xml_isNode(node, "sound"))
|
||||
tmp->sound = sound_get(xml_get(node));
|
||||
else if(xml_isNode(node, "class"))
|
||||
tmp->class = xml_getInt(node);
|
||||
else if(xml_isNode(node, "price"))
|
||||
tmp->price = xml_getInt(node);
|
||||
else if(xml_isNode(node, "tech"))
|
||||
tmp->tech = xml_getInt(node);
|
||||
else if(xml_isNode(node, "fabricator"))
|
||||
tmp->fabricator = strdup(xml_get(node));
|
||||
else if(xml_isNode(node, "description"))
|
||||
tmp->description = strdup(xml_get(node));
|
||||
else if(xml_isNode(node, "price"))
|
||||
tmp->price = xml_getInt(node);
|
||||
else if(xml_isNode(node, "tech"))
|
||||
tmp->tech = xml_getInt(node);
|
||||
else if(xml_isNode(node, "fabricator"))
|
||||
tmp->fabricator = strdup(xml_get(node));
|
||||
else if(xml_isNode(node, "description"))
|
||||
tmp->description = strdup(xml_get(node));
|
||||
else if(xml_isNode(node, "movement")) {
|
||||
cur = node->children;
|
||||
do {
|
||||
@ -166,7 +166,7 @@ static Ship* ship_parse(xmlNodePtr parent) {
|
||||
stmp = xml_nodeProp(cur, "quantity");
|
||||
if(!stmp)
|
||||
WARN("Ship '%s' is missing tag 'quantity for outfit '%s'",
|
||||
tmp->name, otmp->data->name);
|
||||
tmp->name, otmp->data->name);
|
||||
otmp->quantity = atoi(stmp);
|
||||
free(stmp);
|
||||
otmp->next = NULL;
|
||||
@ -185,26 +185,26 @@ static Ship* ship_parse(xmlNodePtr parent) {
|
||||
|
||||
#define MELEMENT(o,s) if(o) WARN("Ship '%s' missing '"s"' element", tmp->name)
|
||||
MELEMENT(tmp->name == NULL, "name");
|
||||
MELEMENT(tmp->gfx_space == NULL, "GFX");
|
||||
MELEMENT(tmp->gui == NULL, "GUI");
|
||||
MELEMENT(tmp->class==0, "class");
|
||||
MELEMENT(tmp->price==0, "price");
|
||||
MELEMENT(tmp->tech==0, "tech");
|
||||
MELEMENT(tmp->fabricator==0, "fabricator");
|
||||
MELEMENT(tmp->description==0, "description");
|
||||
MELEMENT(tmp->thrust==0, "thrust");
|
||||
MELEMENT(tmp->turn==0, "turn");
|
||||
MELEMENT(tmp->speed==0, "speed");
|
||||
MELEMENT(tmp->armour==0, "armour");
|
||||
MELEMENT(tmp->armour_regen==0, "armour_regen");
|
||||
MELEMENT(tmp->shield==0, "shield");
|
||||
MELEMENT(tmp->shield_regen==0, "shield_regen");
|
||||
MELEMENT(tmp->energy==0, "energy");
|
||||
MELEMENT(tmp->energy_regen==0, "energt_regen");
|
||||
MELEMENT(tmp->crew==0, "crew");
|
||||
MELEMENT(tmp->mass==0, "mass");
|
||||
MELEMENT(tmp->cap_cargo==0, "cap_cargo");
|
||||
MELEMENT(tmp->cap_weapon==0, "cap_weapon");
|
||||
MELEMENT(tmp->gfx_space == NULL, "GFX");
|
||||
MELEMENT(tmp->gui == NULL, "GUI");
|
||||
MELEMENT(tmp->class==0, "class");
|
||||
MELEMENT(tmp->price==0, "price");
|
||||
MELEMENT(tmp->tech==0, "tech");
|
||||
MELEMENT(tmp->fabricator==0, "fabricator");
|
||||
MELEMENT(tmp->description==0, "description");
|
||||
MELEMENT(tmp->thrust==0, "thrust");
|
||||
MELEMENT(tmp->turn==0, "turn");
|
||||
MELEMENT(tmp->speed==0, "speed");
|
||||
MELEMENT(tmp->armour==0, "armour");
|
||||
MELEMENT(tmp->armour_regen==0, "armour_regen");
|
||||
MELEMENT(tmp->shield==0, "shield");
|
||||
MELEMENT(tmp->shield_regen==0, "shield_regen");
|
||||
MELEMENT(tmp->energy==0, "energy");
|
||||
MELEMENT(tmp->energy_regen==0, "energt_regen");
|
||||
MELEMENT(tmp->crew==0, "crew");
|
||||
MELEMENT(tmp->mass==0, "mass");
|
||||
MELEMENT(tmp->cap_cargo==0, "cap_cargo");
|
||||
MELEMENT(tmp->cap_weapon==0, "cap_weapon");
|
||||
#undef MELEMENT
|
||||
|
||||
return tmp;
|
||||
@ -244,7 +244,7 @@ int ships_load(void) {
|
||||
free(buf);
|
||||
xmlCleanupParser();
|
||||
|
||||
DEBUG("Loaded %d ship%s", ships, (ships==1) ? "" : "s");
|
||||
DEBUG("Loaded %d ship%s", ships, (ships==1) ? "" : "s");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -255,7 +255,7 @@ void ships_free(void) {
|
||||
for(i = 0; i < ships; i++) {
|
||||
// Free stored strings.
|
||||
if((ship_stack+i)->name) free(ship_stack[i].name);
|
||||
if((ship_stack+i)->description) free(ship_stack[i].description);
|
||||
if((ship_stack+i)->description) free(ship_stack[i].description);
|
||||
if((ship_stack+i)->gui) free(ship_stack[i].gui);
|
||||
so = (ship_stack+i)->outfit;
|
||||
while(so) { // free the ship outfit.
|
||||
@ -272,62 +272,62 @@ void ships_free(void) {
|
||||
|
||||
// Used to visualize the ships status.
|
||||
void ship_view(char* shipname) {
|
||||
Ship* s;
|
||||
char buf[1024];
|
||||
unsigned int wid;
|
||||
wid = window_create(shipname, -1, -1, VIEW_WIDTH, VIEW_HEIGHT);
|
||||
s = ship_get(shipname);
|
||||
Ship* s;
|
||||
char buf[1024];
|
||||
unsigned int wid;
|
||||
wid = window_create(shipname, -1, -1, VIEW_WIDTH, VIEW_HEIGHT);
|
||||
s = ship_get(shipname);
|
||||
|
||||
window_addText(wid, 20, 0, 100, VIEW_HEIGHT-40,
|
||||
0, "txtLabel", &gl_smallFont, &cDConsole,
|
||||
"Name:\n"
|
||||
"Class:\n"
|
||||
"Crew:\n"
|
||||
"Mass:\n"
|
||||
"\n"
|
||||
"Thrust:\n"
|
||||
"Max Speed:\n"
|
||||
"Turn:\n"
|
||||
"\n"
|
||||
"Shield:\n"
|
||||
"Armour:\n"
|
||||
"Energy:\n"
|
||||
"\n"
|
||||
"Weapon Space:\n"
|
||||
"Cargo Space:\n");
|
||||
window_addText(wid, 20, 0, 100, VIEW_HEIGHT-40,
|
||||
0, "txtLabel", &gl_smallFont, &cDConsole,
|
||||
"Name:\n"
|
||||
"Class:\n"
|
||||
"Crew:\n"
|
||||
"Mass:\n"
|
||||
"\n"
|
||||
"Thrust:\n"
|
||||
"Max Speed:\n"
|
||||
"Turn:\n"
|
||||
"\n"
|
||||
"Shield:\n"
|
||||
"Armour:\n"
|
||||
"Energy:\n"
|
||||
"\n"
|
||||
"Weapon Space:\n"
|
||||
"Cargo Space:\n");
|
||||
|
||||
snprintf(buf, 1024,
|
||||
"%s\n"
|
||||
"%s\n"
|
||||
"%d\n"
|
||||
"%d Tons\n"
|
||||
"\n"
|
||||
"%.2f MN\n"
|
||||
"%.2f M/s\n"
|
||||
"%.2f Grad/s\n"
|
||||
"\n"
|
||||
"%.2f MJ (%.2f MJ/s)\n)"
|
||||
"%.2f MJ (%.2f MJ/s)\n)"
|
||||
"%.2f MJ (%.2f MJ/s)\n)"
|
||||
"\n"
|
||||
"%d Tons\n"
|
||||
"%d Tons\n",
|
||||
s->name, ship_class(s), s->crew, s->mass,
|
||||
s->thrust/s->mass, s->speed, s->turn,
|
||||
s->shield, s->shield_regen, s->armour, s->armour_regen,
|
||||
s->energy, s->energy_regen, s->cap_weapon, s->cap_cargo);
|
||||
snprintf(buf, 1024,
|
||||
"%s\n"
|
||||
"%s\n"
|
||||
"%d\n"
|
||||
"%d Tons\n"
|
||||
"\n"
|
||||
"%.2f MN\n"
|
||||
"%.2f M/s\n"
|
||||
"%.2f Grad/s\n"
|
||||
"\n"
|
||||
"%.2f MJ (%.2f MJ/s)\n)"
|
||||
"%.2f MJ (%.2f MJ/s)\n)"
|
||||
"%.2f MJ (%.2f MJ/s)\n)"
|
||||
"\n"
|
||||
"%d Tons\n"
|
||||
"%d Tons\n",
|
||||
s->name, ship_class(s), s->crew, s->mass,
|
||||
s->thrust/s->mass, s->speed, s->turn,
|
||||
s->shield, s->shield_regen, s->armour, s->armour_regen,
|
||||
s->energy, s->energy_regen, s->cap_weapon, s->cap_cargo);
|
||||
|
||||
window_addText(wid, 120, 0, VIEW_WIDTH-140, VIEW_HEIGHT-40,
|
||||
0, "txtProperties", &gl_smallFont, &cBlack, buf);
|
||||
window_addText(wid, 120, 0, VIEW_WIDTH-140, VIEW_HEIGHT-40,
|
||||
0, "txtProperties", &gl_smallFont, &cBlack, buf);
|
||||
|
||||
// Close the button.
|
||||
snprintf(buf, 37, "close%s", shipname);
|
||||
window_addButton(wid, -20, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
buf, "Close", ship_view_close);
|
||||
// Close the button.
|
||||
snprintf(buf, 37, "close%s", shipname);
|
||||
window_addButton(wid, -20, 20,
|
||||
BUTTON_WIDTH, BUTTON_HEIGHT,
|
||||
buf, "Close", ship_view_close);
|
||||
}
|
||||
|
||||
static void ship_view_close(char* btn) {
|
||||
window_destroy(window_get(btn+5)); // "closefoo -> Foo"
|
||||
window_destroy(window_get(btn+5)); // "closefoo -> Foo"
|
||||
}
|
||||
|
||||
|
32
src/ship.h
32
src/ship.h
@ -12,15 +12,15 @@ typedef enum ShipClass_ {
|
||||
SHIP_CLASS_CIV_LIGHT = 1,
|
||||
SHIP_CLASS_CIV_MEDIUM = 2,
|
||||
SHIP_CLASS_CIV_HEAVY = 3,
|
||||
SHIP_CLASS_MIL_LIGHT = 4,
|
||||
SHIP_CLASS_MIL_MEDIUM = 5,
|
||||
SHIP_CLASS_MIL_HEAVY = 6,
|
||||
SHIP_CLASS_ROB_LIGHT = 7,
|
||||
SHIP_CLASS_ROB_MEDIUM = 8,
|
||||
SHIP_CLASS_ROB_HEAVY = 9,
|
||||
SHIP_CLASS_HYB_LIGHT = 10,
|
||||
SHIP_CLASS_HYB_MEDIUM = 11,
|
||||
SHIP_CLASS_HYB_HEAVY = 12
|
||||
SHIP_CLASS_MIL_LIGHT = 4,
|
||||
SHIP_CLASS_MIL_MEDIUM = 5,
|
||||
SHIP_CLASS_MIL_HEAVY = 6,
|
||||
SHIP_CLASS_ROB_LIGHT = 7,
|
||||
SHIP_CLASS_ROB_MEDIUM = 8,
|
||||
SHIP_CLASS_ROB_HEAVY = 9,
|
||||
SHIP_CLASS_HYB_LIGHT = 10,
|
||||
SHIP_CLASS_HYB_MEDIUM = 11,
|
||||
SHIP_CLASS_HYB_HEAVY = 12
|
||||
} ShipClass;
|
||||
|
||||
// Small wrapper for the outfits.
|
||||
@ -36,11 +36,11 @@ typedef struct Ship_ {
|
||||
char* name; // Ship name.
|
||||
ShipClass class; // Ship class.
|
||||
|
||||
// Store stuff.
|
||||
int price; // Price!
|
||||
int tech;
|
||||
char* fabricator; // Manufacturer.
|
||||
char* description; // Sales pitch.
|
||||
// Store stuff.
|
||||
int price; // Price!
|
||||
int tech;
|
||||
char* fabricator; // Manufacturer.
|
||||
char* description; // Sales pitch.
|
||||
|
||||
// Movement.
|
||||
double thrust, turn, speed;
|
||||
@ -51,8 +51,8 @@ typedef struct Ship_ {
|
||||
// GUI interface.
|
||||
char* gui;
|
||||
|
||||
// Sound.
|
||||
ALuint sound;
|
||||
// Sound.
|
||||
ALuint sound;
|
||||
|
||||
// Characteristics.
|
||||
int crew;
|
||||
|
512
src/sound.c
512
src/sound.c
@ -18,19 +18,19 @@
|
||||
// right now.
|
||||
// ==============================================
|
||||
|
||||
#define SOUND_PREFIX "../snd/sounds/"
|
||||
#define SOUND_SUFFIX ".wav"
|
||||
#define SOUND_PREFIX "../snd/sounds/"
|
||||
#define SOUND_SUFFIX ".wav"
|
||||
|
||||
// Give the buffers a name.
|
||||
typedef struct alSound_ {
|
||||
char* name; // Buffers name.
|
||||
ALuint buffer; // Associated OpenAL buffer.
|
||||
char* name; // Buffers name.
|
||||
ALuint buffer; // Associated OpenAL buffer.
|
||||
} alSound;
|
||||
|
||||
#define VOICE_PLAYING (1<<0) // Voice is playing.
|
||||
#define VOICE_LOOPING (1<<1) // Voice is looping.
|
||||
#define voice_set(v,f) ((v)->flags |= f)
|
||||
#define voice_is(v,f) ((v)->flags & f)
|
||||
#define VOICE_PLAYING (1<<0) // Voice is playing.
|
||||
#define VOICE_LOOPING (1<<1) // Voice is looping.
|
||||
#define voice_set(v,f) ((v)->flags |= f)
|
||||
#define voice_is(v,f) ((v)->flags & f)
|
||||
|
||||
// Global sound lock.
|
||||
SDL_mutex* sound_lock = NULL;
|
||||
@ -60,371 +60,371 @@ static void sound_free(alSound* snd);
|
||||
static int voice_getSource(alVoice* voc);
|
||||
|
||||
int sound_init(void) {
|
||||
int ret = 0;
|
||||
int ret = 0;
|
||||
|
||||
sound_lock = SDL_CreateMutex();
|
||||
sound_lock = SDL_CreateMutex();
|
||||
|
||||
SDL_mutexP(sound_lock);
|
||||
const ALchar* device = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
|
||||
DEBUG("OpenAL using device '%s'", device);
|
||||
// Open the default device.
|
||||
al_device = alcOpenDevice(NULL);
|
||||
if(al_device == NULL) {
|
||||
WARN("Unable to open default sound device");
|
||||
ret = -1;
|
||||
goto snderr_dev;
|
||||
}
|
||||
SDL_mutexP(sound_lock);
|
||||
const ALchar* device = alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER);
|
||||
DEBUG("OpenAL using device '%s'", device);
|
||||
// Open the default device.
|
||||
al_device = alcOpenDevice(NULL);
|
||||
if(al_device == NULL) {
|
||||
WARN("Unable to open default sound device");
|
||||
ret = -1;
|
||||
goto snderr_dev;
|
||||
}
|
||||
|
||||
// Create the OpenAL context.
|
||||
al_context = alcCreateContext(al_device, NULL);
|
||||
if(sound_lock == NULL) {
|
||||
WARN("Unable to create OpenAL context");
|
||||
ret = -2;
|
||||
goto snderr_ctx;
|
||||
}
|
||||
// Create the OpenAL context.
|
||||
al_context = alcCreateContext(al_device, NULL);
|
||||
if(sound_lock == NULL) {
|
||||
WARN("Unable to create OpenAL context");
|
||||
ret = -2;
|
||||
goto snderr_ctx;
|
||||
}
|
||||
|
||||
// Clear the errors.
|
||||
alGetError();
|
||||
// Clear the errors.
|
||||
alGetError();
|
||||
|
||||
// Set active context.
|
||||
if(alcMakeContextCurrent(al_context)==AL_FALSE) {
|
||||
WARN("Failure to set default context");
|
||||
ret = -4;
|
||||
goto snderr_act;
|
||||
}
|
||||
// Set active context.
|
||||
if(alcMakeContextCurrent(al_context)==AL_FALSE) {
|
||||
WARN("Failure to set default context");
|
||||
ret = -4;
|
||||
goto snderr_act;
|
||||
}
|
||||
|
||||
// Set the master gain.
|
||||
alListenerf(AL_GAIN, .1);
|
||||
// Set the master gain.
|
||||
alListenerf(AL_GAIN, .1);
|
||||
|
||||
// Set the distance model.
|
||||
alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
|
||||
// Set the distance model.
|
||||
alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
|
||||
|
||||
SDL_mutexV(sound_lock);
|
||||
SDL_mutexV(sound_lock);
|
||||
|
||||
// Load up all the sounds.
|
||||
sound_makeList();
|
||||
// Load up all the sounds.
|
||||
sound_makeList();
|
||||
|
||||
// Start the music server.
|
||||
music_init();
|
||||
music_player = SDL_CreateThread(music_thread, NULL);
|
||||
// Start the music server.
|
||||
music_init();
|
||||
music_player = SDL_CreateThread(music_thread, NULL);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
snderr_act:
|
||||
alcDestroyContext(al_context);
|
||||
alcDestroyContext(al_context);
|
||||
snderr_ctx:
|
||||
al_context = NULL;
|
||||
alcCloseDevice(al_device);
|
||||
al_context = NULL;
|
||||
alcCloseDevice(al_device);
|
||||
snderr_dev:
|
||||
al_device = NULL;
|
||||
SDL_mutexV(sound_lock);
|
||||
SDL_DestroyMutex(sound_lock);
|
||||
sound_lock = NULL;
|
||||
return ret;
|
||||
al_device = NULL;
|
||||
SDL_mutexV(sound_lock);
|
||||
SDL_DestroyMutex(sound_lock);
|
||||
sound_lock = NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
// Clean up after the sound system.
|
||||
void sound_exit(void) {
|
||||
int i;
|
||||
// Free the sounds.
|
||||
for(i = 0; i < nsound_list; i++)
|
||||
sound_free(&sound_list[i]);
|
||||
free(sound_list);
|
||||
sound_list = NULL;
|
||||
nsound_list = 0;
|
||||
int i;
|
||||
// Free the sounds.
|
||||
for(i = 0; i < nsound_list; i++)
|
||||
sound_free(&sound_list[i]);
|
||||
free(sound_list);
|
||||
sound_list = NULL;
|
||||
nsound_list = 0;
|
||||
|
||||
// Must stop the music before killing it,
|
||||
// then thread should commit suicide.
|
||||
if(music_player) {
|
||||
music_stop();
|
||||
music_kill();
|
||||
SDL_WaitThread(music_player, NULL);
|
||||
music_exit();
|
||||
}
|
||||
// Must stop the music before killing it,
|
||||
// then thread should commit suicide.
|
||||
if(music_player) {
|
||||
music_stop();
|
||||
music_kill();
|
||||
SDL_WaitThread(music_player, NULL);
|
||||
music_exit();
|
||||
}
|
||||
|
||||
if(sound_lock) {
|
||||
SDL_mutexP(sound_lock);
|
||||
if(sound_lock) {
|
||||
SDL_mutexP(sound_lock);
|
||||
|
||||
if(al_context) {
|
||||
alcMakeContextCurrent(NULL);
|
||||
alcDestroyContext(al_context);
|
||||
}
|
||||
if(al_device) alcCloseDevice(al_device);
|
||||
if(al_context) {
|
||||
alcMakeContextCurrent(NULL);
|
||||
alcDestroyContext(al_context);
|
||||
}
|
||||
if(al_device) alcCloseDevice(al_device);
|
||||
|
||||
SDL_mutexV(sound_lock);
|
||||
SDL_DestroyMutex(sound_lock);
|
||||
}
|
||||
SDL_mutexV(sound_lock);
|
||||
SDL_DestroyMutex(sound_lock);
|
||||
}
|
||||
}
|
||||
|
||||
// Get the buffer to sound of [name].
|
||||
ALuint sound_get(char* name) {
|
||||
if(sound_lock == NULL) return 0;
|
||||
if(sound_lock == NULL) return 0;
|
||||
|
||||
int i;
|
||||
for(i = 0; i < nsound_list; i++)
|
||||
if(strcmp(name, sound_list[i].name)==0)
|
||||
return sound_list[i].buffer;
|
||||
WARN("Sound '%s' not found in sound list", name);
|
||||
return 0;
|
||||
int i;
|
||||
for(i = 0; i < nsound_list; i++)
|
||||
if(strcmp(name, sound_list[i].name)==0)
|
||||
return sound_list[i].buffer;
|
||||
WARN("Sound '%s' not found in sound list", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Make list of available sounds.
|
||||
static int sound_makeList(void) {
|
||||
if(sound_lock == NULL) return 0;
|
||||
if(sound_lock == NULL) return 0;
|
||||
|
||||
char** files;
|
||||
uint32_t nfiles, i;
|
||||
char tmp[64];
|
||||
int len;
|
||||
char** files;
|
||||
uint32_t nfiles, i;
|
||||
char tmp[64];
|
||||
int len;
|
||||
|
||||
// Get the file list.
|
||||
files = pack_listfiles(data, &nfiles);
|
||||
// Get the file list.
|
||||
files = pack_listfiles(data, &nfiles);
|
||||
|
||||
// Load the profiles.
|
||||
for(i = 0; i < nfiles; i++)
|
||||
if((strncmp(files[i], SOUND_PREFIX, strlen(SOUND_PREFIX))==0) &&
|
||||
(strncmp(files[i] + strlen(files[i]) - strlen(SOUND_SUFFIX),
|
||||
SOUND_SUFFIX, strlen(SOUND_SUFFIX))==0)) {
|
||||
// Load the profiles.
|
||||
for(i = 0; i < nfiles; i++)
|
||||
if((strncmp(files[i], SOUND_PREFIX, strlen(SOUND_PREFIX))==0) &&
|
||||
(strncmp(files[i] + strlen(files[i]) - strlen(SOUND_SUFFIX),
|
||||
SOUND_SUFFIX, strlen(SOUND_SUFFIX))==0)) {
|
||||
|
||||
// Expand the selection size.
|
||||
sound_list = realloc(sound_list, ++nsound_list * sizeof(alSound));
|
||||
// Expand the selection size.
|
||||
sound_list = realloc(sound_list, ++nsound_list * sizeof(alSound));
|
||||
|
||||
// Remove the prefix and suffix.
|
||||
len = strlen(files[i]) - strlen(SOUND_SUFFIX SOUND_PREFIX);
|
||||
strncpy(tmp, files[i] + strlen(SOUND_PREFIX), len);
|
||||
tmp[len] = '\0';
|
||||
// Remove the prefix and suffix.
|
||||
len = strlen(files[i]) - strlen(SOUND_SUFFIX SOUND_PREFIX);
|
||||
strncpy(tmp, files[i] + strlen(SOUND_PREFIX), len);
|
||||
tmp[len] = '\0';
|
||||
|
||||
// give it the new name.
|
||||
sound_list[nsound_list-1].name = strdup(tmp);
|
||||
sound_load(&sound_list[nsound_list-1].buffer, files[i]);
|
||||
}
|
||||
// give it the new name.
|
||||
sound_list[nsound_list-1].name = strdup(tmp);
|
||||
sound_load(&sound_list[nsound_list-1].buffer, files[i]);
|
||||
}
|
||||
|
||||
// Free the char* allocated by pack.
|
||||
for(i = 0; i < nfiles; i++)
|
||||
free(files[i]);
|
||||
free(files);
|
||||
// Free the char* allocated by pack.
|
||||
for(i = 0; i < nfiles; i++)
|
||||
free(files[i]);
|
||||
free(files);
|
||||
|
||||
DEBUG("Loaded %d sound%c", nsound_list, (nsound_list==1)?' ':'s');
|
||||
DEBUG("Loaded %d sound%c", nsound_list, (nsound_list==1)?' ':'s');
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Loads a sound into the sound_list.
|
||||
static int sound_load(ALuint* buffer, char* filename) {
|
||||
if(sound_lock == NULL) return 0;
|
||||
if(sound_lock == NULL) return 0;
|
||||
|
||||
void* wavdata;
|
||||
unsigned int size;
|
||||
ALenum err;
|
||||
void* wavdata;
|
||||
unsigned int size;
|
||||
ALenum err;
|
||||
|
||||
// Get the file data buffer from the packfile.
|
||||
wavdata = pack_readfile(DATA, filename, &size);
|
||||
// Get the file data buffer from the packfile.
|
||||
wavdata = pack_readfile(DATA, filename, &size);
|
||||
|
||||
SDL_mutexP(sound_lock);
|
||||
SDL_mutexP(sound_lock);
|
||||
|
||||
// Bind to OpenAL buffer.
|
||||
alGenBuffers(1, buffer);
|
||||
alBufferData(*buffer, AL_FORMAT_MONO16, wavdata, size, 22050);
|
||||
// Bind to OpenAL buffer.
|
||||
alGenBuffers(1, buffer);
|
||||
alBufferData(*buffer, AL_FORMAT_MONO16, wavdata, size, 22050);
|
||||
|
||||
// Errors?
|
||||
if((err = alGetError()) != AL_NO_ERROR) {
|
||||
WARN("OpenAL erro '%d' loading sound '%s'.", err, filename);
|
||||
return 0;
|
||||
}
|
||||
// Errors?
|
||||
if((err = alGetError()) != AL_NO_ERROR) {
|
||||
WARN("OpenAL erro '%d' loading sound '%s'.", err, filename);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SDL_mutexV(sound_lock);
|
||||
SDL_mutexV(sound_lock);
|
||||
|
||||
// Finish up.
|
||||
free(wavdata);
|
||||
return 0;
|
||||
// Finish up.
|
||||
free(wavdata);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void sound_free(alSound* snd) {
|
||||
if(sound_lock) return;
|
||||
if(sound_lock) return;
|
||||
|
||||
SDL_mutexP(sound_lock);
|
||||
SDL_mutexP(sound_lock);
|
||||
|
||||
if(snd->name) free(snd->name);
|
||||
alDeleteBuffers(1, &snd->buffer);
|
||||
if(snd->name) free(snd->name);
|
||||
alDeleteBuffers(1, &snd->buffer);
|
||||
|
||||
SDL_mutexV(sound_lock);
|
||||
SDL_mutexV(sound_lock);
|
||||
}
|
||||
|
||||
// Update the sounds and prioritize them.
|
||||
void sound_update(void) {
|
||||
if(sound_lock == NULL) return;
|
||||
int i;
|
||||
if(sound_lock == NULL) return;
|
||||
int i;
|
||||
|
||||
// TODO: Prioritize the things.
|
||||
// TODO: Prioritize the things.
|
||||
|
||||
SDL_mutexP(sound_lock);
|
||||
SDL_mutexP(sound_lock);
|
||||
|
||||
for(i = 0; i < nvoice_stack; i++) {
|
||||
if(voice_is(voice_stack[i], VOICE_PLAYING)) {
|
||||
// Update position.
|
||||
alSource3f(voice_stack[i]->source, AL_POSITION,
|
||||
voice_stack[i]->px, voice_stack[i]->py, 0.);
|
||||
//alSource3f(voice_stack[i]->source, AL_VELOCITY,
|
||||
//voice_stack[i]->vx, voice_stack[i]->vy, 0.);
|
||||
for(i = 0; i < nvoice_stack; i++) {
|
||||
if(voice_is(voice_stack[i], VOICE_PLAYING)) {
|
||||
// Update position.
|
||||
alSource3f(voice_stack[i]->source, AL_POSITION,
|
||||
voice_stack[i]->px, voice_stack[i]->py, 0.);
|
||||
//alSource3f(voice_stack[i]->source, AL_VELOCITY,
|
||||
//voice_stack[i]->vx, voice_stack[i]->vy, 0.);
|
||||
|
||||
}
|
||||
}
|
||||
SDL_mutexV(sound_lock);
|
||||
}
|
||||
}
|
||||
SDL_mutexV(sound_lock);
|
||||
}
|
||||
|
||||
// Set all the sounds volume to vol.
|
||||
void sound_volume(const double vol) {
|
||||
if(sound_lock == NULL) return;
|
||||
if(sound_lock == NULL) return;
|
||||
|
||||
int i;
|
||||
int i;
|
||||
|
||||
svolume = (ALfloat) vol;
|
||||
svolume = (ALfloat) vol;
|
||||
|
||||
SDL_mutexP(sound_lock);
|
||||
for(i = 0; i < nvoice_stack; i++)
|
||||
if(voice_set(voice_stack[i], VOICE_PLAYING))
|
||||
alSourcef(voice_stack[i]->source, AL_GAIN, svolume);
|
||||
SDL_mutexV(sound_lock);
|
||||
SDL_mutexP(sound_lock);
|
||||
for(i = 0; i < nvoice_stack; i++)
|
||||
if(voice_set(voice_stack[i], VOICE_PLAYING))
|
||||
alSourcef(voice_stack[i]->source, AL_GAIN, svolume);
|
||||
SDL_mutexV(sound_lock);
|
||||
}
|
||||
|
||||
// Attempt to alloc a source for a voice.
|
||||
static int voice_getSource(alVoice* voc) {
|
||||
if(sound_lock == NULL) return -1;
|
||||
int ret;
|
||||
ALenum err;
|
||||
if(sound_lock == NULL) return -1;
|
||||
int ret;
|
||||
ALenum err;
|
||||
|
||||
ret = 0; // Default return.
|
||||
ret = 0; // Default return.
|
||||
|
||||
SDL_mutexP(sound_lock);
|
||||
SDL_mutexP(sound_lock);
|
||||
|
||||
// Try and grab a source.
|
||||
voc->source = 0;
|
||||
alGenSources(1, &voc->source);
|
||||
err = alGetError();
|
||||
// Try and grab a source.
|
||||
voc->source = 0;
|
||||
alGenSources(1, &voc->source);
|
||||
err = alGetError();
|
||||
|
||||
if(err != AL_NO_ERROR) {
|
||||
voc->source = 0;
|
||||
ret = 1;
|
||||
} else {
|
||||
// Set the properties.
|
||||
alSourcei(voc->source, AL_BUFFER, voc->buffer);
|
||||
if(err != AL_NO_ERROR) {
|
||||
voc->source = 0;
|
||||
ret = 1;
|
||||
} else {
|
||||
// Set the properties.
|
||||
alSourcei(voc->source, AL_BUFFER, voc->buffer);
|
||||
|
||||
// Distance model.
|
||||
alSourcef(voc->source, AL_MAX_DISTANCE, 200.);
|
||||
alSourcef(voc->source, AL_REFERENCE_DISTANCE, 50.);
|
||||
// Distance model.
|
||||
alSourcef(voc->source, AL_MAX_DISTANCE, 200.);
|
||||
alSourcef(voc->source, AL_REFERENCE_DISTANCE, 50.);
|
||||
|
||||
alSourcei(voc->source, AL_SOURCE_RELATIVE, AL_FALSE);
|
||||
alSourcef(voc->source, AL_GAIN, svolume);
|
||||
alSource3f(voc->source, AL_POSITION, voc->px, voc->py, 0.);
|
||||
//alSource3f(voc->source, AL_VELOCITY, voc->vx, voc->vy, 0.);
|
||||
if(voice_is(voc, VOICE_LOOPING))
|
||||
alSourcei(voc->source, AL_LOOPING, AL_TRUE);
|
||||
else
|
||||
alSourcei(voc->source, AL_LOOPING, AL_FALSE);
|
||||
alSourcei(voc->source, AL_SOURCE_RELATIVE, AL_FALSE);
|
||||
alSourcef(voc->source, AL_GAIN, svolume);
|
||||
alSource3f(voc->source, AL_POSITION, voc->px, voc->py, 0.);
|
||||
//alSource3f(voc->source, AL_VELOCITY, voc->vx, voc->vy, 0.);
|
||||
if(voice_is(voc, VOICE_LOOPING))
|
||||
alSourcei(voc->source, AL_LOOPING, AL_TRUE);
|
||||
else
|
||||
alSourcei(voc->source, AL_LOOPING, AL_FALSE);
|
||||
|
||||
// Try to play the source.
|
||||
alSourcePlay(voc->source);
|
||||
err = alGetError();
|
||||
if(err == AL_NO_ERROR) voice_set(voc, VOICE_PLAYING);
|
||||
else ret = 2;
|
||||
}
|
||||
SDL_mutexV(sound_lock);
|
||||
// Try to play the source.
|
||||
alSourcePlay(voc->source);
|
||||
err = alGetError();
|
||||
if(err == AL_NO_ERROR) voice_set(voc, VOICE_PLAYING);
|
||||
else ret = 2;
|
||||
}
|
||||
SDL_mutexV(sound_lock);
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
}
|
||||
|
||||
alVoice* sound_addVoice(int priority, double px, double py, double vx, double vy,
|
||||
const ALuint buffer, const int looping) {
|
||||
const ALuint buffer, const int looping) {
|
||||
|
||||
(void)vx;
|
||||
(void)vy;
|
||||
(void)vx;
|
||||
(void)vy;
|
||||
|
||||
if(sound_lock == NULL) return NULL;
|
||||
if(sound_lock == NULL) return NULL;
|
||||
|
||||
alVoice* voc;
|
||||
alVoice* voc;
|
||||
|
||||
nvoice_stack++;
|
||||
if(nvoice_stack > mvoice_stack)
|
||||
voice_stack = realloc(voice_stack, ++mvoice_stack*sizeof(alVoice*));
|
||||
nvoice_stack++;
|
||||
if(nvoice_stack > mvoice_stack)
|
||||
voice_stack = realloc(voice_stack, ++mvoice_stack*sizeof(alVoice*));
|
||||
|
||||
voc = malloc(sizeof(alVoice));
|
||||
voice_stack[nvoice_stack-1] = voc;
|
||||
voc = malloc(sizeof(alVoice));
|
||||
voice_stack[nvoice_stack-1] = voc;
|
||||
|
||||
// Set the data.
|
||||
voc->priority = priority;
|
||||
voc->start = SDL_GetTicks();
|
||||
voc->buffer = buffer;
|
||||
if(looping) voice_set(voc, VOICE_LOOPING);
|
||||
voc->px = px;
|
||||
voc->py = py;
|
||||
//voc->vx = vx;
|
||||
//voc->vy = vy;
|
||||
// Set the data.
|
||||
voc->priority = priority;
|
||||
voc->start = SDL_GetTicks();
|
||||
voc->buffer = buffer;
|
||||
if(looping) voice_set(voc, VOICE_LOOPING);
|
||||
voc->px = px;
|
||||
voc->py = py;
|
||||
//voc->vx = vx;
|
||||
//voc->vy = vy;
|
||||
|
||||
voice_getSource(voc);
|
||||
voice_getSource(voc);
|
||||
|
||||
return voc;
|
||||
return voc;
|
||||
}
|
||||
|
||||
void sound_delVoice(alVoice* voice) {
|
||||
if(sound_lock == NULL) return;
|
||||
ALint stat;
|
||||
int i;
|
||||
if(sound_lock == NULL) return;
|
||||
ALint stat;
|
||||
int i;
|
||||
|
||||
for(i = 0; i < nvoice_stack; i++)
|
||||
if(voice == voice_stack[i])
|
||||
break;
|
||||
for(i = 0; i < nvoice_stack; i++)
|
||||
if(voice == voice_stack[i])
|
||||
break;
|
||||
|
||||
// No match found.
|
||||
if(i >= nvoice_stack) {
|
||||
WARN("Unable to find voice to free from stack");
|
||||
return;
|
||||
}
|
||||
// No match found.
|
||||
if(i >= nvoice_stack) {
|
||||
WARN("Unable to find voice to free from stack");
|
||||
return;
|
||||
}
|
||||
|
||||
if(voice->source) {
|
||||
SDL_mutexP(sound_lock);
|
||||
if(voice->source) {
|
||||
SDL_mutexP(sound_lock);
|
||||
|
||||
alGetSourcei(voice->source, AL_SOURCE_STATE, &stat);
|
||||
if(stat == AL_PLAYING) alSourceStop(voice->source);
|
||||
alDeleteSources(1, &voice->source);
|
||||
voice->source = 0;
|
||||
alGetSourcei(voice->source, AL_SOURCE_STATE, &stat);
|
||||
if(stat == AL_PLAYING) alSourceStop(voice->source);
|
||||
alDeleteSources(1, &voice->source);
|
||||
voice->source = 0;
|
||||
|
||||
SDL_mutexV(sound_lock);
|
||||
}
|
||||
SDL_mutexV(sound_lock);
|
||||
}
|
||||
|
||||
free(voice_stack[i]);
|
||||
nvoice_stack--;
|
||||
for(; i < nvoice_stack; i++)
|
||||
voice_stack[i] = voice_stack[i+1];
|
||||
free(voice_stack[i]);
|
||||
nvoice_stack--;
|
||||
for(; i < nvoice_stack; i++)
|
||||
voice_stack[i] = voice_stack[i+1];
|
||||
}
|
||||
|
||||
void voice_update(alVoice* voice, double px, double py, double vx, double vy) {
|
||||
(void) vx;
|
||||
(void) vy;
|
||||
(void) vx;
|
||||
(void) vy;
|
||||
|
||||
if(sound_lock == NULL) return;
|
||||
if(sound_lock == NULL) return;
|
||||
|
||||
voice->px = px;
|
||||
voice->py = py;
|
||||
//voice->vx = vx;
|
||||
//voice->vy = vy;
|
||||
voice->px = px;
|
||||
voice->py = py;
|
||||
//voice->vx = vx;
|
||||
//voice->vy = vy;
|
||||
}
|
||||
|
||||
void sound_listener(double dir, double px, double py, double vx, double vy) {
|
||||
(void)vx;
|
||||
(void)vy;
|
||||
(void)vx;
|
||||
(void)vy;
|
||||
|
||||
if(sound_lock == NULL) return;
|
||||
if(sound_lock == NULL) return;
|
||||
|
||||
SDL_mutexP(sound_lock);
|
||||
SDL_mutexP(sound_lock);
|
||||
|
||||
ALfloat ori[] = { 0., 0., 0., 0., 0., 1. };
|
||||
ori[0] = cos(dir);
|
||||
ori[1] = sin(dir);
|
||||
alListenerfv(AL_ORIENTATION, ori);
|
||||
alListener3f(AL_POSITION, px, py, 0.);
|
||||
//alListener3f(AL_VELOCITY, vx, vy, 0.);
|
||||
ALfloat ori[] = { 0., 0., 0., 0., 0., 1. };
|
||||
ori[0] = cos(dir);
|
||||
ori[1] = sin(dir);
|
||||
alListenerfv(AL_ORIENTATION, ori);
|
||||
alListener3f(AL_POSITION, px, py, 0.);
|
||||
//alListener3f(AL_VELOCITY, vx, vy, 0.);
|
||||
|
||||
SDL_mutexV(sound_lock);
|
||||
SDL_mutexV(sound_lock);
|
||||
}
|
||||
|
||||
|
20
src/sound.h
20
src/sound.h
@ -2,21 +2,21 @@
|
||||
#include <AL/al.h>
|
||||
#include "physics.h"
|
||||
|
||||
#define SOUND_REFERENCE_DIST 500.
|
||||
#define SOUND_MAX_DIST 1000.
|
||||
#define SOUND_REFERENCE_DIST 500.
|
||||
#define SOUND_MAX_DIST 1000.
|
||||
|
||||
// Virtual voice.
|
||||
typedef struct alVoice_ {
|
||||
ALuint source; // Source itself, 0 if not set.
|
||||
ALuint buffer; // Buffer.
|
||||
ALuint source; // Source itself, 0 if not set.
|
||||
ALuint buffer; // Buffer.
|
||||
|
||||
int priority; // Base priority.
|
||||
int priority; // Base priority.
|
||||
|
||||
double px, py; // Position.
|
||||
double vx, vy; // Velocity.
|
||||
double px, py; // Position.
|
||||
double vx, vy; // Velocity.
|
||||
|
||||
unsigned int start; // Time started in ms.
|
||||
unsigned int flags; // Flags to set properties.
|
||||
unsigned int start; // Time started in ms.
|
||||
unsigned int flags; // Flags to set properties.
|
||||
} alVoice;
|
||||
|
||||
// Sound subsystem.
|
||||
@ -30,7 +30,7 @@ void sound_volume(const double vol);
|
||||
|
||||
// Voice manipulation function.
|
||||
alVoice* sound_addVoice(int priority, double px, double py, double vx, double vy,
|
||||
const ALuint buffer, const int looping);
|
||||
const ALuint buffer, const int looping);
|
||||
|
||||
void sound_delVoice(alVoice* voice);
|
||||
void voice_update(alVoice* voice, double px, double py, double vx, double vy);
|
||||
|
346
src/space.c
346
src/space.c
@ -35,14 +35,14 @@
|
||||
#define FLAG_YSET (1<<1)
|
||||
#define FLAG_ASTEROIDSSET (1<<2)
|
||||
#define FLAG_INTEFERENCESET (1<<3)
|
||||
#define FLAG_SERVICESET (1<<4)
|
||||
#define FLAG_TECHSET (1<<5)
|
||||
#define FLAG_SERVICESET (1<<4)
|
||||
#define FLAG_TECHSET (1<<5)
|
||||
|
||||
// Star system stack and co.
|
||||
StarSystem* systems_stack = NULL; // Star system stack.
|
||||
int systems_nstack = 0; // Number of star systems.
|
||||
static int nplanets = 0; // Total number of loaded planets - A little silly.
|
||||
StarSystem* cur_system = NULL; // Current star system.
|
||||
StarSystem* systems_stack = NULL; // Star system stack.
|
||||
int systems_nstack = 0; // Number of star systems.
|
||||
static int nplanets = 0; // Total number of loaded planets - A little silly.
|
||||
StarSystem* cur_system = NULL; // Current star system.
|
||||
|
||||
// Current stardate in nice format.
|
||||
char* stardate = "Stardate";
|
||||
@ -58,9 +58,9 @@ typedef struct Star_ {
|
||||
double brightness;
|
||||
} Star;
|
||||
|
||||
static Star* stars = NULL; // Star array.
|
||||
static int nstars = 0; // Total stars.
|
||||
static int mstars = 0; // Memory stars are taking.
|
||||
static Star* stars = NULL; // Star array.
|
||||
static int nstars = 0; // Total stars.
|
||||
static int mstars = 0; // Memory stars are taking.
|
||||
|
||||
// Intern
|
||||
static Planet* planet_get(const char* name);
|
||||
@ -76,7 +76,7 @@ extern void player_message(const char* fmt, ...);
|
||||
#define PIXEL(x,y) if((shape == RADAR_RECT && ABS(x)<w/2. && ABS(y)<h/2.) || \
|
||||
(shape == RADAR_CIRCLE && (((x)*(x)+(y)*(y)) < rc))) glVertex2i((x),(y))
|
||||
void planets_minimap(const double res,
|
||||
const double w, const double h, const RadarShape shape) {
|
||||
const double w, const double h, const RadarShape shape) {
|
||||
int i;
|
||||
int cx, cy, x, y, r, rc;
|
||||
double p;
|
||||
@ -85,11 +85,11 @@ void planets_minimap(const double res,
|
||||
|
||||
glBegin(GL_POINTS);
|
||||
for(i = 0; i < cur_system->nplanets; i++) {
|
||||
if(areEnemies(player->faction, cur_system->planets[i].faction))
|
||||
COLOUR(cHostile);
|
||||
else if(areAllies(player->faction, cur_system->planets[i].faction))
|
||||
COLOUR(cFriend);
|
||||
else COLOUR(cNeutral);
|
||||
if(areEnemies(player->faction, cur_system->planets[i].faction))
|
||||
COLOUR(cHostile);
|
||||
else if(areAllies(player->faction, cur_system->planets[i].faction))
|
||||
COLOUR(cFriend);
|
||||
else COLOUR(cNeutral);
|
||||
r = (int)(cur_system->planets[i].gfx_space->sw / res);
|
||||
cx = (int)((cur_system->planets[i].pos.x - player->solid->pos.x) / res);
|
||||
cy = (int)((cur_system->planets[i].pos.y - player->solid->pos.y) / res);
|
||||
@ -138,7 +138,7 @@ void planets_minimap(const double res,
|
||||
|
||||
static PlanetClass planetclass_get(const char a) {
|
||||
switch(a) {
|
||||
// Planets use letters.
|
||||
// Planets use letters.
|
||||
case 'A': return PLANET_CLASS_A;
|
||||
case 'B': return PLANET_CLASS_B;
|
||||
case 'C': return PLANET_CLASS_C;
|
||||
@ -163,8 +163,8 @@ static PlanetClass planetclass_get(const char a) {
|
||||
case 'Y': return PLANET_CLASS_Y;
|
||||
case 'Z': return PLANET_CLASS_Z;
|
||||
|
||||
// Stations use numbers as there isn't as many.
|
||||
case '0' : return STATION_CLASS_A;
|
||||
// Stations use numbers as there isn't as many.
|
||||
case '0' : return STATION_CLASS_A;
|
||||
|
||||
default: return PLANET_CLASS_NULL;
|
||||
};
|
||||
@ -194,63 +194,63 @@ int space_hyperspace(Pilot* p) {
|
||||
|
||||
// Basically used for spawning fleets.
|
||||
void space_update(const double dt) {
|
||||
unsigned int t;
|
||||
int i, j, f;
|
||||
unsigned int t;
|
||||
int i, j, f;
|
||||
|
||||
(void)dt; // Don't need it right now.
|
||||
(void)dt; // Don't need it right now.
|
||||
|
||||
t = SDL_GetTicks();
|
||||
t = SDL_GetTicks();
|
||||
|
||||
if(cur_system->nfleets == 0)
|
||||
// Please stop checking that there are no fleets.
|
||||
spawn_timer = t + 300000;
|
||||
if(cur_system->nfleets == 0)
|
||||
// Please stop checking that there are no fleets.
|
||||
spawn_timer = t + 300000;
|
||||
|
||||
if(spawn_timer < t) {
|
||||
// Time to possibly spawn.
|
||||
if(spawn_timer < t) {
|
||||
// Time to possibly spawn.
|
||||
|
||||
// Spawn chance is based on overall percentage.
|
||||
f = RNG(0, 100*cur_system->nfleets);
|
||||
j = 0;
|
||||
for(i = 0; i < cur_system->nfleets; i++) {
|
||||
j += cur_system->fleets[i].chance;
|
||||
if(f < j) {
|
||||
// Add one fleet.
|
||||
space_addFleet(cur_system->fleets[i].fleet);
|
||||
break;
|
||||
}
|
||||
}
|
||||
spawn_timer = t + 60000./(float)cur_system->nfleets;
|
||||
}
|
||||
// Spawn chance is based on overall percentage.
|
||||
f = RNG(0, 100*cur_system->nfleets);
|
||||
j = 0;
|
||||
for(i = 0; i < cur_system->nfleets; i++) {
|
||||
j += cur_system->fleets[i].chance;
|
||||
if(f < j) {
|
||||
// Add one fleet.
|
||||
space_addFleet(cur_system->fleets[i].fleet);
|
||||
break;
|
||||
}
|
||||
}
|
||||
spawn_timer = t + 60000./(float)cur_system->nfleets;
|
||||
}
|
||||
}
|
||||
|
||||
// Crate a fleet.
|
||||
static void space_addFleet(Fleet* fleet) {
|
||||
int i;
|
||||
double a;
|
||||
Vec2 vv, vp, vn;
|
||||
int i;
|
||||
double a;
|
||||
Vec2 vv, vp, vn;
|
||||
|
||||
// Simulate them coming from hyperspace.
|
||||
vect_pset(&vp, RNG(MIN_HYPERSPACE_DIST, MIN_HYPERSPACE_DIST*1.5),
|
||||
RNG(0, 360)*M_PI/180.);
|
||||
vectnull(&vn);
|
||||
// Simulate them coming from hyperspace.
|
||||
vect_pset(&vp, RNG(MIN_HYPERSPACE_DIST, MIN_HYPERSPACE_DIST*1.5),
|
||||
RNG(0, 360)*M_PI/180.);
|
||||
vectnull(&vn);
|
||||
|
||||
for(i = 0; i < fleet->npilots; i++)
|
||||
if(RNG(0, 100) <= fleet->pilots[i].chance) {
|
||||
vect_cadd(&vp, RNG(75, 150) * (RNG(0,1) ? 1 : -1),
|
||||
RNG(75, 150) * (RNG(0,1) ? 1 : -1));
|
||||
for(i = 0; i < fleet->npilots; i++)
|
||||
if(RNG(0, 100) <= fleet->pilots[i].chance) {
|
||||
vect_cadd(&vp, RNG(75, 150) * (RNG(0,1) ? 1 : -1),
|
||||
RNG(75, 150) * (RNG(0,1) ? 1 : -1));
|
||||
|
||||
a = vect_angle(&vp, &vn);
|
||||
vectnull(&vv);
|
||||
a = vect_angle(&vp, &vn);
|
||||
vectnull(&vv);
|
||||
|
||||
pilot_create(fleet->pilots[i].ship,
|
||||
fleet->pilots[i].name,
|
||||
fleet->faction,
|
||||
fleet->ai,
|
||||
a,
|
||||
&vp,
|
||||
&vv,
|
||||
0);
|
||||
}
|
||||
pilot_create(fleet->pilots[i].ship,
|
||||
fleet->pilots[i].name,
|
||||
fleet->faction,
|
||||
fleet->ai,
|
||||
a,
|
||||
&vp,
|
||||
&vv,
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
||||
// Init the system.
|
||||
@ -261,7 +261,7 @@ void space_init(const char* sysname) {
|
||||
player_clear(); // Clears targets.
|
||||
pilots_clean(); // Destroy all the current pilots, exept player.
|
||||
weapon_clear(); // Get rid of all the weapons.
|
||||
spfx_clear(); // Remove of explosions.
|
||||
spfx_clear(); // Remove of explosions.
|
||||
|
||||
if((sysname == NULL) && (cur_system == NULL))
|
||||
ERR("Cannot reinit system if there is no system previously loaded");
|
||||
@ -286,16 +286,16 @@ void space_init(const char* sysname) {
|
||||
}
|
||||
// Set up fleets -> pilots.
|
||||
for(i = 0; i < cur_system->nfleets; i++)
|
||||
if(RNG(0,100) <= (cur_system->fleets[i].chance/2)) // Fleet check (50% chance).
|
||||
space_addFleet(cur_system->fleets[i].fleet);
|
||||
if(RNG(0,100) <= (cur_system->fleets[i].chance/2)) // Fleet check (50% chance).
|
||||
space_addFleet(cur_system->fleets[i].fleet);
|
||||
|
||||
// Start the spawn timer.
|
||||
spawn_timer = SDL_GetTicks() + 120000./(float)(cur_system->nfleets+1);
|
||||
// Start the spawn timer.
|
||||
spawn_timer = SDL_GetTicks() + 120000./(float)(cur_system->nfleets+1);
|
||||
}
|
||||
|
||||
// Load the planets of name 'name'.
|
||||
static Planet* planet_get(const char* name) {
|
||||
int i;
|
||||
int i;
|
||||
|
||||
Planet* tmp = NULL;
|
||||
|
||||
@ -374,39 +374,39 @@ static Planet* planet_get(const char* name) {
|
||||
else if(xml_isNode(cur, "bar"))
|
||||
tmp->bar_description = strdup(xml_get(cur));
|
||||
else if(xml_isNode(cur, "services")) {
|
||||
flags |= FLAG_SERVICESET;
|
||||
flags |= FLAG_SERVICESET;
|
||||
tmp->services = xml_getInt(cur);
|
||||
}
|
||||
else if(xml_isNode(cur, "tech")) {
|
||||
ccur = cur->children;
|
||||
do {
|
||||
if(xml_isNode(ccur, "main")) {
|
||||
flags |= FLAG_TECHSET;
|
||||
tmp->tech[0] = xml_getInt(ccur);
|
||||
}
|
||||
else if(xml_isNode(ccur, "special")) {
|
||||
for(i = 1; i < PLANET_TECH_MAX; i++)
|
||||
if(tmp->tech[i]==0) {
|
||||
tmp->tech[i] = xml_getInt(ccur);
|
||||
break;
|
||||
}
|
||||
if(i == PLANET_TECH_MAX) WARN("Planet '%s' has tooo many"
|
||||
"'special tech' entries", tmp->name);
|
||||
}
|
||||
} while((ccur = ccur->next));
|
||||
}
|
||||
else if(xml_isNode(cur, "commodities")) {
|
||||
ccur = cur->children;
|
||||
do {
|
||||
if(xml_isNode(ccur, "commodity")) {
|
||||
tmp->commodities = realloc(tmp->commodities,
|
||||
(tmp->ncommodities+1) * sizeof(Commodity*));
|
||||
tmp->commodities[tmp->ncommodities] =
|
||||
commodity_get(xml_get(ccur));
|
||||
tmp->ncommodities++;
|
||||
}
|
||||
} while((ccur = ccur->next));
|
||||
}
|
||||
}
|
||||
else if(xml_isNode(cur, "tech")) {
|
||||
ccur = cur->children;
|
||||
do {
|
||||
if(xml_isNode(ccur, "main")) {
|
||||
flags |= FLAG_TECHSET;
|
||||
tmp->tech[0] = xml_getInt(ccur);
|
||||
}
|
||||
else if(xml_isNode(ccur, "special")) {
|
||||
for(i = 1; i < PLANET_TECH_MAX; i++)
|
||||
if(tmp->tech[i]==0) {
|
||||
tmp->tech[i] = xml_getInt(ccur);
|
||||
break;
|
||||
}
|
||||
if(i == PLANET_TECH_MAX) WARN("Planet '%s' has tooo many"
|
||||
"'special tech' entries", tmp->name);
|
||||
}
|
||||
} while((ccur = ccur->next));
|
||||
}
|
||||
else if(xml_isNode(cur, "commodities")) {
|
||||
ccur = cur->children;
|
||||
do {
|
||||
if(xml_isNode(ccur, "commodity")) {
|
||||
tmp->commodities = realloc(tmp->commodities,
|
||||
(tmp->ncommodities+1) * sizeof(Commodity*));
|
||||
tmp->commodities[tmp->ncommodities] =
|
||||
commodity_get(xml_get(ccur));
|
||||
tmp->ncommodities++;
|
||||
}
|
||||
} while((ccur = ccur->next));
|
||||
}
|
||||
} while((cur = cur->next));
|
||||
}
|
||||
} while((node = node->next));
|
||||
@ -423,25 +423,25 @@ static Planet* planet_get(const char* name) {
|
||||
// Check elements.
|
||||
if(tmp) {
|
||||
#define MELEMENT(o,s) if(o) WARN("Planet '%s' missing '"s"' element", tmp->name)
|
||||
MELEMENT(tmp->gfx_space==NULL, "GFX_space");
|
||||
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_LAND) &&
|
||||
tmp->gfx_exterior==NULL, "GFX exterior");
|
||||
MELEMENT((flags&FLAG_XSET)==0, "x");
|
||||
MELEMENT((flags&FLAG_YSET)==0, "y");
|
||||
MELEMENT(tmp->gfx_space==NULL, "GFX_space");
|
||||
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_LAND) &&
|
||||
tmp->gfx_exterior==NULL, "GFX exterior");
|
||||
MELEMENT((flags&FLAG_XSET)==0, "x");
|
||||
MELEMENT((flags&FLAG_YSET)==0, "y");
|
||||
MELEMENT(tmp->class==PLANET_CLASS_NULL, "class");
|
||||
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_LAND) &&
|
||||
tmp->description==NULL, "description");
|
||||
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_BASIC) &&
|
||||
tmp->bar_description==NULL, "bar");
|
||||
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_BASIC) &&
|
||||
tmp->faction==NULL, "faction");
|
||||
MELEMENT((flags&FLAG_SERVICESET)==0, "services");
|
||||
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_LAND) &&
|
||||
tmp->description==NULL, "description");
|
||||
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_BASIC) &&
|
||||
tmp->bar_description==NULL, "bar");
|
||||
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_BASIC) &&
|
||||
tmp->faction==NULL, "faction");
|
||||
MELEMENT((flags&FLAG_SERVICESET)==0, "services");
|
||||
|
||||
MELEMENT((planet_hasService(tmp, PLANET_SERVICE_OUTFITS) ||
|
||||
planet_hasService(tmp, PLANET_SERVICE_SHIPYARD)) &&
|
||||
(flags&FLAG_TECHSET)==0, "tech");
|
||||
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_COMMODITY) &&
|
||||
(tmp->ncommodities==0), "commodity");
|
||||
MELEMENT((planet_hasService(tmp, PLANET_SERVICE_OUTFITS) ||
|
||||
planet_hasService(tmp, PLANET_SERVICE_SHIPYARD)) &&
|
||||
(flags&FLAG_TECHSET)==0, "tech");
|
||||
MELEMENT(planet_hasService(tmp, PLANET_SERVICE_COMMODITY) &&
|
||||
(tmp->ncommodities==0), "commodity");
|
||||
#undef MELEMENT
|
||||
} else
|
||||
WARN("No planet found matching name '%s'", name);
|
||||
@ -499,7 +499,7 @@ static StarSystem* system_parse(const xmlNodePtr parent) {
|
||||
cur = node->children;
|
||||
do {
|
||||
if(xml_isNode(cur, "planet")) {
|
||||
nplanets++; // Increase planet counter.
|
||||
nplanets++; // Increase planet counter.
|
||||
planet = planet_get(xml_get(cur));
|
||||
planet = planet_get((const char*)cur->children->content);
|
||||
tmp->planets = realloc(tmp->planets, sizeof(Planet)*(++tmp->nplanets));
|
||||
@ -541,10 +541,10 @@ static StarSystem* system_parse(const xmlNodePtr parent) {
|
||||
MELEMENT(flags&FLAG_INTEFERENCESET, "inteference");
|
||||
#undef MELEMENT
|
||||
|
||||
// Post processing.
|
||||
if(tmp->nplanets > 0)
|
||||
// TODO: Make dependant on overall planet faction.
|
||||
tmp->faction = tmp->planets[0].faction;
|
||||
// Post processing.
|
||||
if(tmp->nplanets > 0)
|
||||
// TODO: Make dependant on overall planet faction.
|
||||
tmp->faction = tmp->planets[0].faction;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
@ -562,7 +562,7 @@ static void system_parseJumps(const xmlNodePtr parent) {
|
||||
break;
|
||||
}
|
||||
if(i == systems_nstack)
|
||||
WARN("System '%s' was not found in the stack for some reason", name);
|
||||
WARN("System '%s' was not found in the stack for some reason", name);
|
||||
free(name); // No need for it now.
|
||||
|
||||
node = parent->xmlChildrenNode;
|
||||
@ -631,9 +631,9 @@ int space_load(void) {
|
||||
free(buf);
|
||||
xmlCleanupParser();
|
||||
|
||||
DEBUG("Loaded %d star system%s with %d planet%s",
|
||||
systems_nstack, (systems_nstack==1) ? "" : "s",
|
||||
nplanets, (nplanets==1) ? "" : "s");
|
||||
DEBUG("Loaded %d star system%s with %d planet%s",
|
||||
systems_nstack, (systems_nstack==1) ? "" : "s",
|
||||
nplanets, (nplanets==1) ? "" : "s");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -641,63 +641,63 @@ int space_load(void) {
|
||||
// Render the system. -- Just playing god now.
|
||||
void space_render(double dt) {
|
||||
int i;
|
||||
unsigned int t, timer;
|
||||
double x, y, m;
|
||||
unsigned int t, timer;
|
||||
double x, y, m;
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix(); // Translation matrix.
|
||||
glTranslated(-(double)gl_screen.w/2., -(double)gl_screen.h/2., 0);
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
glPushMatrix(); // Translation matrix.
|
||||
glTranslated(-(double)gl_screen.w/2., -(double)gl_screen.h/2., 0);
|
||||
|
||||
t = SDL_GetTicks();
|
||||
if(!player_isFlag(PLAYER_DESTROYED) &&
|
||||
pilot_isFlag(player, PILOT_HYPERSPACE) && // Hyperspace fancy effect.
|
||||
!paused && (player->ptimer-HYPERSPACE_STARS_BLUR < t)) {
|
||||
t = SDL_GetTicks();
|
||||
if(!player_isFlag(PLAYER_DESTROYED) &&
|
||||
pilot_isFlag(player, PILOT_HYPERSPACE) && // Hyperspace fancy effect.
|
||||
!paused && (player->ptimer-HYPERSPACE_STARS_BLUR < t)) {
|
||||
|
||||
timer = player->ptimer - HYPERSPACE_STARS_BLUR;
|
||||
timer = player->ptimer - HYPERSPACE_STARS_BLUR;
|
||||
|
||||
// Fancy hyperspace effects.
|
||||
glShadeModel(GL_SMOOTH);
|
||||
// Fancy hyperspace effects.
|
||||
glShadeModel(GL_SMOOTH);
|
||||
|
||||
glBegin(GL_LINES);
|
||||
glBegin(GL_LINES);
|
||||
|
||||
// Lines will be based on velocity.
|
||||
m = HYPERSPACE_STARS_LENGTH * (double)(t-timer) / (HYPERSPACE_STARS_BLUR);
|
||||
x = m*cos(VANGLE(player->solid->vel)+M_PI);
|
||||
y = m*sin(VANGLE(player->solid->vel)+M_PI);
|
||||
// Lines will be based on velocity.
|
||||
m = HYPERSPACE_STARS_LENGTH * (double)(t-timer) / (HYPERSPACE_STARS_BLUR);
|
||||
x = m*cos(VANGLE(player->solid->vel)+M_PI);
|
||||
y = m*sin(VANGLE(player->solid->vel)+M_PI);
|
||||
|
||||
for(i = 0; i < nstars; i++) {
|
||||
glColor4d(1., 1., 1., stars[i].brightness);
|
||||
glVertex2d(stars[i].x, stars[i].y);
|
||||
glColor4d(1., 1., 1., 0.);
|
||||
glVertex2d(stars[i].x+x*stars[i].brightness,stars[i].y+y*stars[i].brightness);
|
||||
}
|
||||
glEnd();
|
||||
for(i = 0; i < nstars; i++) {
|
||||
glColor4d(1., 1., 1., stars[i].brightness);
|
||||
glVertex2d(stars[i].x, stars[i].y);
|
||||
glColor4d(1., 1., 1., 0.);
|
||||
glVertex2d(stars[i].x+x*stars[i].brightness,stars[i].y+y*stars[i].brightness);
|
||||
}
|
||||
glEnd();
|
||||
|
||||
glShadeModel(GL_FLAT);
|
||||
glShadeModel(GL_FLAT);
|
||||
|
||||
} else {
|
||||
glBegin(GL_POINTS);
|
||||
} else {
|
||||
glBegin(GL_POINTS);
|
||||
|
||||
for(i = 0; i < nstars; i++) {
|
||||
if(!paused && !toolkit) {
|
||||
// Update position.
|
||||
if(!player_isFlag(PLAYER_DESTROYED)) {
|
||||
stars[i].x -= VX(player->solid->vel)/(13.-10.*stars[i].brightness)*dt;
|
||||
stars[i].y -= VY(player->solid->vel)/(13.-10.*stars[i].brightness)*dt;
|
||||
}
|
||||
// Scroll those stars bitch!
|
||||
if(stars[i].x > gl_screen.w + STAR_BUF) stars[i].x = -STAR_BUF;
|
||||
else if(stars[i].x < -STAR_BUF) stars[i].x = gl_screen.w + STAR_BUF;
|
||||
if(stars[i].y > gl_screen.h + STAR_BUF) stars[i].y = -STAR_BUF;
|
||||
else if(stars[i].y < -STAR_BUF) stars[i].y = gl_screen.h + STAR_BUF;
|
||||
}
|
||||
// Render.
|
||||
glColor4d(1., 1., 1., stars[i].brightness);
|
||||
glVertex2d(stars[i].x, stars[i].y);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
glPopMatrix(); // Translation matrix.
|
||||
for(i = 0; i < nstars; i++) {
|
||||
if(!paused && !toolkit) {
|
||||
// Update position.
|
||||
if(!player_isFlag(PLAYER_DESTROYED)) {
|
||||
stars[i].x -= VX(player->solid->vel)/(13.-10.*stars[i].brightness)*dt;
|
||||
stars[i].y -= VY(player->solid->vel)/(13.-10.*stars[i].brightness)*dt;
|
||||
}
|
||||
// Scroll those stars bitch!
|
||||
if(stars[i].x > gl_screen.w + STAR_BUF) stars[i].x = -STAR_BUF;
|
||||
else if(stars[i].x < -STAR_BUF) stars[i].x = gl_screen.w + STAR_BUF;
|
||||
if(stars[i].y > gl_screen.h + STAR_BUF) stars[i].y = -STAR_BUF;
|
||||
else if(stars[i].y < -STAR_BUF) stars[i].y = gl_screen.h + STAR_BUF;
|
||||
}
|
||||
// Render.
|
||||
glColor4d(1., 1., 1., stars[i].brightness);
|
||||
glVertex2d(stars[i].x, stars[i].y);
|
||||
}
|
||||
glEnd();
|
||||
}
|
||||
glPopMatrix(); // Translation matrix.
|
||||
}
|
||||
|
||||
// Render the planets.
|
||||
|
48
src/space.h
48
src/space.h
@ -7,7 +7,7 @@
|
||||
#define MIN_HYPERSPACE_DIST 1500
|
||||
#define MAX_HYPERSPACE_VEL 25
|
||||
|
||||
#define PLANET_TECH_MAX 8
|
||||
#define PLANET_TECH_MAX 8
|
||||
|
||||
// Planet types. I didn't take them from Star Trek, I promise.
|
||||
typedef enum PlanetClass_ {
|
||||
@ -35,11 +35,11 @@ typedef enum PlanetClass_ {
|
||||
PLANET_CLASS_X, // Demon.
|
||||
PLANET_CLASS_Y, // Demon.
|
||||
PLANET_CLASS_Z, // Demon.
|
||||
STATION_CLASS_A // TODO.
|
||||
STATION_CLASS_A // TODO.
|
||||
} PlanetClass;
|
||||
|
||||
// Planet services.
|
||||
#define PLANET_SERVICE_LAND (1<<0) // Can we land?
|
||||
#define PLANET_SERVICE_LAND (1<<0) // Can we land?
|
||||
#define PLANET_SERVICE_BASIC (1<<1) // Refueling, spaceport bar, new.
|
||||
#define PLANET_SERVICE_COMMODITY (1<<2)
|
||||
#define PLANET_SERVICE_OUTFITS (1<<3)
|
||||
@ -48,44 +48,44 @@ typedef enum PlanetClass_ {
|
||||
|
||||
typedef struct Planet_ {
|
||||
char* name; // Planet name
|
||||
Vec2 pos; // Position in star system.
|
||||
Vec2 pos; // Position in star system.
|
||||
|
||||
PlanetClass class; // Planet type.
|
||||
Faction* faction; // Planet faction.
|
||||
PlanetClass class; // Planet type.
|
||||
Faction* faction; // Planet faction.
|
||||
|
||||
char* description; // Planet description.
|
||||
char* bar_description; // Spaceport bar description.
|
||||
unsigned int services; // Offered services.
|
||||
Commodity** commodities; // Commodities sold.
|
||||
int ncommodities; // Amount in stock.
|
||||
char* description; // Planet description.
|
||||
char* bar_description; // Spaceport bar description.
|
||||
unsigned int services; // Offered services.
|
||||
Commodity** commodities; // Commodities sold.
|
||||
int ncommodities; // Amount in stock.
|
||||
|
||||
// tech[0] stores global tech level (everything that and below) while
|
||||
// tech[1-PLANET_TECH_MAX] stores the unique tech levels.
|
||||
int tech[PLANET_TECH_MAX];
|
||||
// tech[0] stores global tech level (everything that and below) while
|
||||
// tech[1-PLANET_TECH_MAX] stores the unique tech levels.
|
||||
int tech[PLANET_TECH_MAX];
|
||||
|
||||
glTexture* gfx_space; // Graphics in space.
|
||||
glTexture* gfx_exterior; // Graphics in the exterior.
|
||||
glTexture* gfx_space; // Graphics in space.
|
||||
glTexture* gfx_exterior; // Graphics in the exterior.
|
||||
} Planet;
|
||||
|
||||
// Star systems.
|
||||
typedef struct SystemFleet_ {
|
||||
Fleet* fleet; // Fleet to appear.
|
||||
int chance; // Chance of fleet appearing in the system.
|
||||
int chance; // Chance of fleet appearing in the system.
|
||||
} SystemFleet;
|
||||
|
||||
typedef struct StarSystem_ {
|
||||
char* name; // Star system identifier.
|
||||
Vec2 pos; // Position.
|
||||
Vec2 pos; // Position.
|
||||
int stars, asteroids; // Un numero!
|
||||
double interference; // Un uh.. Percentage.
|
||||
double interference; // Un uh.. Percentage.
|
||||
|
||||
Faction* faction; // Overall faction.
|
||||
Faction* faction; // Overall faction.
|
||||
|
||||
Planet* planets; // Planets.
|
||||
int nplanets; // Total number of planets.
|
||||
Planet* planets; // Planets.
|
||||
int nplanets; // Total number of planets.
|
||||
|
||||
SystemFleet* fleets; // Fleets that can appear in the current system.
|
||||
int nfleets; // Total number of fleets.
|
||||
SystemFleet* fleets; // Fleets that can appear in the current system.
|
||||
int nfleets; // Total number of fleets.
|
||||
|
||||
int* jumps; // Adjacent star system index number.
|
||||
int njumps; // Number of adjacent jumps.
|
||||
|
288
src/spfx.c
288
src/spfx.c
@ -8,35 +8,35 @@
|
||||
#include "pause.h"
|
||||
#include "spfx.h"
|
||||
|
||||
#define SPFX_GFX "../gfx/spfx/" // Graphics location.
|
||||
#define SPFX_GFX "../gfx/spfx/" // Graphics location.
|
||||
#define SPFX_CHUNK 10 // Chunk to allocate when needed.
|
||||
|
||||
typedef struct SPFX_Base_ {
|
||||
char* name;
|
||||
char* name;
|
||||
|
||||
int anim; // Total duration in ms.
|
||||
glTexture* gfx; // Will use each sprite as a frame.
|
||||
int anim; // Total duration in ms.
|
||||
glTexture* gfx; // Will use each sprite as a frame.
|
||||
} SPFX_Base;
|
||||
|
||||
static SPFX_Base* spfx_effects = NULL;
|
||||
static int spfx_neffects = 0;
|
||||
|
||||
typedef struct SPFX_ {
|
||||
Vec2 pos, vel; // They don't accelerate.
|
||||
Vec2 pos, vel; // They don't accelerate.
|
||||
|
||||
int lastframe; // Need when pausing.
|
||||
int effect; // Actual effect.
|
||||
unsigned int t; // Start.
|
||||
int lastframe; // Need when pausing.
|
||||
int effect; // Actual effect.
|
||||
unsigned int t; // Start.
|
||||
} SPFX;
|
||||
|
||||
// Front stack is for effects on player.
|
||||
// Back is for everything else.
|
||||
static SPFX* spfx_stack_front = NULL;
|
||||
static int spfx_nstack_front = 0;
|
||||
static int spfx_mstack_front = 0;
|
||||
static SPFX* spfx_stack_back = NULL;
|
||||
static int spfx_nstack_back = 0;
|
||||
static int spfx_mstack_back = 0;
|
||||
static SPFX* spfx_stack_front = NULL;
|
||||
static int spfx_nstack_front = 0;
|
||||
static int spfx_mstack_front = 0;
|
||||
static SPFX* spfx_stack_back = NULL;
|
||||
static int spfx_nstack_back = 0;
|
||||
static int spfx_mstack_back = 0;
|
||||
|
||||
static int spfx_base_load(char* name, int anim, char* gfx, int sx, int sy);
|
||||
static void spfx_base_free(SPFX_Base* effect);
|
||||
@ -48,198 +48,198 @@ static void spfx_delay_layer(SPFX* layer, int nlayer, unsigned int delay);
|
||||
|
||||
// Load the SPFX_Base.
|
||||
static int spfx_base_load(char* name, int anim, char* gfx, int sx, int sy) {
|
||||
SPFX_Base* cur;
|
||||
char buf[PATH_MAX];
|
||||
SPFX_Base* cur;
|
||||
char buf[PATH_MAX];
|
||||
|
||||
spfx_effects = realloc(spfx_effects, ++spfx_neffects*sizeof(SPFX_Base));
|
||||
cur = &spfx_effects[spfx_neffects-1];
|
||||
spfx_effects = realloc(spfx_effects, ++spfx_neffects*sizeof(SPFX_Base));
|
||||
cur = &spfx_effects[spfx_neffects-1];
|
||||
|
||||
cur->name = strdup(name);
|
||||
cur->anim = anim;
|
||||
sprintf(buf, SPFX_GFX"%s", gfx);
|
||||
cur->gfx = gl_newSprite(buf, sx, sy);
|
||||
cur->name = strdup(name);
|
||||
cur->anim = anim;
|
||||
sprintf(buf, SPFX_GFX"%s", gfx);
|
||||
cur->gfx = gl_newSprite(buf, sx, sy);
|
||||
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void spfx_base_free(SPFX_Base* effect) {
|
||||
if(effect->name) free(effect->name);
|
||||
if(effect->gfx) gl_freeTexture(effect->gfx);
|
||||
if(effect->name) free(effect->name);
|
||||
if(effect->gfx) gl_freeTexture(effect->gfx);
|
||||
}
|
||||
|
||||
int spfx_get(char* name) {
|
||||
int i;
|
||||
for(i = 0; i < spfx_neffects; i++)
|
||||
if(strcmp(spfx_effects[i].name, name)==0)
|
||||
return i;
|
||||
WARN("SPFX '%s' not found!", name);
|
||||
return 0;
|
||||
int i;
|
||||
for(i = 0; i < spfx_neffects; i++)
|
||||
if(strcmp(spfx_effects[i].name, name)==0)
|
||||
return i;
|
||||
WARN("SPFX '%s' not found!", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Load/Unload.
|
||||
int spfx_load(void) {
|
||||
spfx_base_load("ExpS", 400, "exps.png", 6, 5);
|
||||
spfx_base_load("ExpM", 450, "expm.png", 6, 5);
|
||||
spfx_base_load("ExpL", 500, "expl.png", 6, 5);
|
||||
return 0;
|
||||
spfx_base_load("ExpS", 400, "exps.png", 6, 5);
|
||||
spfx_base_load("ExpM", 450, "expm.png", 6, 5);
|
||||
spfx_base_load("ExpL", 500, "expl.png", 6, 5);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void spfx_free(void) {
|
||||
int i;
|
||||
int i;
|
||||
|
||||
// Get rid of all the particles and free the stacks.
|
||||
spfx_clear();
|
||||
if(spfx_stack_front) free(spfx_stack_front);
|
||||
spfx_stack_front = NULL;
|
||||
spfx_mstack_front = 0;
|
||||
if(spfx_stack_back) free(spfx_stack_back);
|
||||
spfx_stack_back = NULL;
|
||||
spfx_mstack_back = 0;
|
||||
// Get rid of all the particles and free the stacks.
|
||||
spfx_clear();
|
||||
if(spfx_stack_front) free(spfx_stack_front);
|
||||
spfx_stack_front = NULL;
|
||||
spfx_mstack_front = 0;
|
||||
if(spfx_stack_back) free(spfx_stack_back);
|
||||
spfx_stack_back = NULL;
|
||||
spfx_mstack_back = 0;
|
||||
|
||||
for(i = 0; i < spfx_neffects; i++)
|
||||
spfx_base_free(&spfx_effects[i]);
|
||||
free(spfx_effects);
|
||||
spfx_effects = NULL;
|
||||
spfx_neffects = 0;
|
||||
for(i = 0; i < spfx_neffects; i++)
|
||||
spfx_base_free(&spfx_effects[i]);
|
||||
free(spfx_effects);
|
||||
spfx_effects = NULL;
|
||||
spfx_neffects = 0;
|
||||
}
|
||||
|
||||
void spfx_add(int effect,
|
||||
const double px, const double py,
|
||||
const double vx, const double vy,
|
||||
const int layer) {
|
||||
SPFX* cur_spfx;
|
||||
const double px, const double py,
|
||||
const double vx, const double vy,
|
||||
const int layer) {
|
||||
SPFX* cur_spfx;
|
||||
|
||||
if(layer == SPFX_LAYER_FRONT) {
|
||||
// Front layer.
|
||||
if(spfx_mstack_front < spfx_nstack_front+1) {
|
||||
// We need more memory.
|
||||
spfx_mstack_front += SPFX_CHUNK;
|
||||
spfx_stack_front = realloc(spfx_stack_front, spfx_mstack_front*sizeof(SPFX));
|
||||
}
|
||||
cur_spfx = &spfx_stack_front[spfx_nstack_front];
|
||||
spfx_nstack_front++;
|
||||
}
|
||||
else if(layer == SPFX_LAYER_BACK) {
|
||||
// Back layer.
|
||||
if(spfx_mstack_back < spfx_nstack_back+1) {
|
||||
// Need more memory.
|
||||
spfx_mstack_back += SPFX_CHUNK;
|
||||
spfx_stack_back = realloc(spfx_stack_back, spfx_mstack_back*sizeof(SPFX));
|
||||
}
|
||||
cur_spfx = &spfx_stack_back[spfx_nstack_back];
|
||||
spfx_nstack_back++;
|
||||
}
|
||||
if(layer == SPFX_LAYER_FRONT) {
|
||||
// Front layer.
|
||||
if(spfx_mstack_front < spfx_nstack_front+1) {
|
||||
// We need more memory.
|
||||
spfx_mstack_front += SPFX_CHUNK;
|
||||
spfx_stack_front = realloc(spfx_stack_front, spfx_mstack_front*sizeof(SPFX));
|
||||
}
|
||||
cur_spfx = &spfx_stack_front[spfx_nstack_front];
|
||||
spfx_nstack_front++;
|
||||
}
|
||||
else if(layer == SPFX_LAYER_BACK) {
|
||||
// Back layer.
|
||||
if(spfx_mstack_back < spfx_nstack_back+1) {
|
||||
// Need more memory.
|
||||
spfx_mstack_back += SPFX_CHUNK;
|
||||
spfx_stack_back = realloc(spfx_stack_back, spfx_mstack_back*sizeof(SPFX));
|
||||
}
|
||||
cur_spfx = &spfx_stack_back[spfx_nstack_back];
|
||||
spfx_nstack_back++;
|
||||
}
|
||||
|
||||
cur_spfx->effect = effect;
|
||||
vect_csetmin(&cur_spfx->pos, px, py);
|
||||
vect_csetmin(&cur_spfx->vel, vx, vy);
|
||||
cur_spfx->t = SDL_GetTicks();
|
||||
cur_spfx->effect = effect;
|
||||
vect_csetmin(&cur_spfx->pos, px, py);
|
||||
vect_csetmin(&cur_spfx->vel, vx, vy);
|
||||
cur_spfx->t = SDL_GetTicks();
|
||||
}
|
||||
|
||||
void spfx_clear(void) {
|
||||
int i;
|
||||
for(i = spfx_nstack_front-1; i >= 0; i--)
|
||||
spfx_destroy(spfx_stack_front, &spfx_nstack_front, i);
|
||||
int i;
|
||||
for(i = spfx_nstack_front-1; i >= 0; i--)
|
||||
spfx_destroy(spfx_stack_front, &spfx_nstack_front, i);
|
||||
|
||||
for(i = spfx_nstack_back-1; i >= 0; i--)
|
||||
spfx_destroy(spfx_stack_back, &spfx_nstack_back, i);
|
||||
for(i = spfx_nstack_back-1; i >= 0; i--)
|
||||
spfx_destroy(spfx_stack_back, &spfx_nstack_back, i);
|
||||
}
|
||||
|
||||
static void spfx_destroy(SPFX* layer, int* nlayer, int spfx) {
|
||||
(*nlayer)--;
|
||||
memmove(&layer[spfx], &layer[spfx+1], (*nlayer-spfx)*sizeof(SPFX));
|
||||
(*nlayer)--;
|
||||
memmove(&layer[spfx], &layer[spfx+1], (*nlayer-spfx)*sizeof(SPFX));
|
||||
}
|
||||
|
||||
void spfx_update(const double dt) {
|
||||
spfx_update_layer(spfx_stack_front, &spfx_nstack_front, dt);
|
||||
spfx_update_layer(spfx_stack_back, &spfx_nstack_back, dt);
|
||||
spfx_update_layer(spfx_stack_front, &spfx_nstack_front, dt);
|
||||
spfx_update_layer(spfx_stack_back, &spfx_nstack_back, dt);
|
||||
}
|
||||
|
||||
static void spfx_update_layer(SPFX* layer, int* nlayer, const double dt) {
|
||||
int i;
|
||||
unsigned int t = SDL_GetTicks();
|
||||
int i;
|
||||
unsigned int t = SDL_GetTicks();
|
||||
|
||||
for(i = 0; i < *nlayer; i++) {
|
||||
// Time to die!!!
|
||||
if(t > (layer[i].t + spfx_effects[layer[i].effect].anim)) {
|
||||
spfx_destroy(layer, nlayer, i);
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
// Mkay. Update it now.
|
||||
vect_cadd(&layer[i].pos, dt*VX(layer[i].vel), dt*VY(layer[i].vel));
|
||||
}
|
||||
for(i = 0; i < *nlayer; i++) {
|
||||
// Time to die!!!
|
||||
if(t > (layer[i].t + spfx_effects[layer[i].effect].anim)) {
|
||||
spfx_destroy(layer, nlayer, i);
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
// Mkay. Update it now.
|
||||
vect_cadd(&layer[i].pos, dt*VX(layer[i].vel), dt*VY(layer[i].vel));
|
||||
}
|
||||
}
|
||||
|
||||
void spfx_render(const int layer) {
|
||||
SPFX* spfx_stack;
|
||||
int i, spfx_nstack;
|
||||
SPFX_Base* effect;
|
||||
int sx, sy;
|
||||
unsigned int t = SDL_GetTicks();
|
||||
SPFX* spfx_stack;
|
||||
int i, spfx_nstack;
|
||||
SPFX_Base* effect;
|
||||
int sx, sy;
|
||||
unsigned int t = SDL_GetTicks();
|
||||
|
||||
// Get the appropriate layer.
|
||||
switch(layer) {
|
||||
case SPFX_LAYER_FRONT:
|
||||
spfx_stack = spfx_stack_front;
|
||||
spfx_nstack = spfx_nstack_front;
|
||||
break;
|
||||
case SPFX_LAYER_BACK:
|
||||
spfx_stack = spfx_stack_back;
|
||||
spfx_nstack = spfx_nstack_back;
|
||||
break;
|
||||
}
|
||||
for(i = 0; i < spfx_nstack; i++) {
|
||||
effect = &spfx_effects[spfx_stack[i].effect];
|
||||
// Get the appropriate layer.
|
||||
switch(layer) {
|
||||
case SPFX_LAYER_FRONT:
|
||||
spfx_stack = spfx_stack_front;
|
||||
spfx_nstack = spfx_nstack_front;
|
||||
break;
|
||||
case SPFX_LAYER_BACK:
|
||||
spfx_stack = spfx_stack_back;
|
||||
spfx_nstack = spfx_nstack_back;
|
||||
break;
|
||||
}
|
||||
for(i = 0; i < spfx_nstack; i++) {
|
||||
effect = &spfx_effects[spfx_stack[i].effect];
|
||||
|
||||
sx = (int)effect->gfx->sx;
|
||||
sy = (int)effect->gfx->sy;
|
||||
sx = (int)effect->gfx->sx;
|
||||
sy = (int)effect->gfx->sy;
|
||||
|
||||
if(!paused) // Don't calculate frame if paused.
|
||||
spfx_stack[i].lastframe = sx * sy
|
||||
* MIN(((double)(t - spfx_stack[i].t)/(double)effect->anim), 1.);
|
||||
if(!paused) // Don't calculate frame if paused.
|
||||
spfx_stack[i].lastframe = sx * sy
|
||||
* MIN(((double)(t - spfx_stack[i].t)/(double)effect->anim), 1.);
|
||||
|
||||
gl_blitSprite(effect->gfx,
|
||||
VX(spfx_stack[i].pos), VY(spfx_stack[i].pos),
|
||||
spfx_stack[i].lastframe % sx,
|
||||
spfx_stack[i].lastframe / sx,
|
||||
NULL);
|
||||
}
|
||||
gl_blitSprite(effect->gfx,
|
||||
VX(spfx_stack[i].pos), VY(spfx_stack[i].pos),
|
||||
spfx_stack[i].lastframe % sx,
|
||||
spfx_stack[i].lastframe / sx,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
|
||||
void spfx_pause(void) {
|
||||
spfx_pause_layer(spfx_stack_front, spfx_nstack_front);
|
||||
spfx_pause_layer(spfx_stack_back, spfx_nstack_back);
|
||||
spfx_pause_layer(spfx_stack_front, spfx_nstack_front);
|
||||
spfx_pause_layer(spfx_stack_back, spfx_nstack_back);
|
||||
|
||||
}
|
||||
|
||||
static void spfx_pause_layer(SPFX* layer, int nlayer) {
|
||||
int i;
|
||||
unsigned int t = SDL_GetTicks();
|
||||
for(i = 0; i < nlayer; i++)
|
||||
layer[i].t -= t;
|
||||
int i;
|
||||
unsigned int t = SDL_GetTicks();
|
||||
for(i = 0; i < nlayer; i++)
|
||||
layer[i].t -= t;
|
||||
}
|
||||
|
||||
void spfx_unpause(void) {
|
||||
spfx_unpause_layer(spfx_stack_front, spfx_nstack_front);
|
||||
spfx_unpause_layer(spfx_stack_back, spfx_nstack_back);
|
||||
spfx_unpause_layer(spfx_stack_front, spfx_nstack_front);
|
||||
spfx_unpause_layer(spfx_stack_back, spfx_nstack_back);
|
||||
}
|
||||
|
||||
static void spfx_unpause_layer(SPFX* layer, int nlayer) {
|
||||
int i;
|
||||
unsigned int t = SDL_GetTicks();
|
||||
for(i = 0; i < nlayer; i++)
|
||||
layer[i].t += t;
|
||||
int i;
|
||||
unsigned int t = SDL_GetTicks();
|
||||
for(i = 0; i < nlayer; i++)
|
||||
layer[i].t += t;
|
||||
}
|
||||
|
||||
void spfx_delay(unsigned int delay) {
|
||||
spfx_delay_layer(spfx_stack_front, spfx_nstack_front, delay);
|
||||
spfx_delay_layer(spfx_stack_back, spfx_nstack_back, delay);
|
||||
spfx_delay_layer(spfx_stack_front, spfx_nstack_front, delay);
|
||||
spfx_delay_layer(spfx_stack_back, spfx_nstack_back, delay);
|
||||
}
|
||||
|
||||
static void spfx_delay_layer(SPFX* layer, int nlayer, unsigned int delay) {
|
||||
int i;
|
||||
for(i = 0; i < nlayer; i++)
|
||||
layer[i].t += delay;
|
||||
int i;
|
||||
for(i = 0; i < nlayer; i++)
|
||||
layer[i].t += delay;
|
||||
}
|
||||
|
||||
|
10
src/spfx.h
10
src/spfx.h
@ -1,15 +1,15 @@
|
||||
#pragma once
|
||||
#include "physics.h"
|
||||
|
||||
#define SPFX_LAYER_FRONT 0
|
||||
#define SPFX_LAYER_BACK 1
|
||||
#define SPFX_LAYER_FRONT 0
|
||||
#define SPFX_LAYER_BACK 1
|
||||
|
||||
// Stack manipulation.
|
||||
int spfx_get(char* name);
|
||||
void spfx_add(const int effect,
|
||||
const double px, const double py,
|
||||
const double vx, const double vy,
|
||||
const int layer);
|
||||
const double px, const double py,
|
||||
const double vx, const double vy,
|
||||
const int layer);
|
||||
|
||||
// Stack mass manipulation functions.
|
||||
void spfx_update(const double dt);
|
||||
|
812
src/toolkit.c
812
src/toolkit.c
File diff suppressed because it is too large
Load Diff
@ -7,7 +7,7 @@ extern int toolkit;
|
||||
|
||||
// Creation.
|
||||
unsigned int window_create(char* name, const int x, const int y,
|
||||
const int w, const int h);
|
||||
const int w, const int h);
|
||||
|
||||
void window_addButton(const unsigned int wid, const int x, const int y,
|
||||
const int w, const int h, char* name, char* display,
|
||||
@ -21,22 +21,22 @@ void window_addImage(const unsigned int wid, const int x, const int y,
|
||||
char* name, glTexture* image);
|
||||
|
||||
void window_addList(const unsigned int wid,
|
||||
const int x, const int y, // Position.
|
||||
const int w, const int h, // Size.
|
||||
char* name, char** items, int nitems, int defitem,
|
||||
void(*call)(char*));
|
||||
const int x, const int y, // Position.
|
||||
const int w, const int h, // Size.
|
||||
char* name, char** items, int nitems, int defitem,
|
||||
void(*call)(char*));
|
||||
|
||||
void window_addRect(const unsigned int wid,
|
||||
const int x, const int y, // Position.
|
||||
const int w, const int h, // size.
|
||||
char* name, glColour* colour, int border); // Properties.
|
||||
const int x, const int y, // Position.
|
||||
const int w, const int h, // size.
|
||||
char* name, glColour* colour, int border); // Properties.
|
||||
|
||||
void window_addCust(const unsigned int wid,
|
||||
const int x, const int y, // Position.
|
||||
const int w, const int h, // Size.
|
||||
char* name, const int border,
|
||||
void(*render) (double x, double y, double w, double h),
|
||||
void(*mouse) (SDL_Event* event, double x, double y));
|
||||
const int x, const int y, // Position.
|
||||
const int w, const int h, // Size.
|
||||
char* name, const int border,
|
||||
void(*render) (double x, double y, double w, double h),
|
||||
void(*mouse) (SDL_Event* event, double x, double y));
|
||||
|
||||
// Popups and alerts.
|
||||
void toolkit_alert(const char* fmt, ...);
|
||||
|
214
src/weapon.c
214
src/weapon.c
@ -15,8 +15,8 @@
|
||||
|
||||
#define weapon_isSmart(w) (w->think)
|
||||
|
||||
#define VOICE_PRIORITY_BOLT 10 // Default.
|
||||
#define VOICE_PRIORITY_AMMO 8 // Higher.
|
||||
#define VOICE_PRIORITY_BOLT 10 // Default.
|
||||
#define VOICE_PRIORITY_AMMO 8 // Higher.
|
||||
|
||||
// Some stuff from pilot.
|
||||
extern Pilot** pilot_stack;
|
||||
@ -33,9 +33,9 @@ typedef struct Weapon_ {
|
||||
const Outfit* outfit; // Related outfit that fired.
|
||||
unsigned int timer; // Mainly used to see when the weapon was fired.
|
||||
|
||||
alVoice* voice; // Virtual voise.
|
||||
alVoice* voice; // Virtual voise.
|
||||
|
||||
// Update position and render.
|
||||
// Update position and render.
|
||||
void(*update)(struct Weapon_*, const double, WeaponLayer); // Position update and render.
|
||||
void(*think)(struct Weapon_*, const double); // Some missiles need to be inteligent.
|
||||
} Weapon;
|
||||
@ -67,7 +67,7 @@ static void think_smart(Weapon* w, const double dt);
|
||||
#define PIXEL(x,y) if((shape == RADAR_RECT && ABS(x) < w/2. && ABS(y)<h/2.) || \
|
||||
(shape == RADAR_CIRCLE && (((x)*(x)+(y)*(y))<rc))) glVertex2i((x),(y))
|
||||
void weapon_minimap(const double res,
|
||||
const double w, const double h, const RadarShape shape) {
|
||||
const double w, const double h, const RadarShape shape) {
|
||||
int i, rc;
|
||||
double x, y;
|
||||
|
||||
@ -108,70 +108,70 @@ void weapons_unpause(void) {
|
||||
}
|
||||
|
||||
void weapons_delay(unsigned int delay) {
|
||||
int i;
|
||||
for(i = 0; i < nwbackLayer; i++)
|
||||
wbackLayer[i]->timer += delay;
|
||||
for(i = 0; i < nwfrontLayer; i++)
|
||||
wfrontLayer[i]->timer += delay;
|
||||
int i;
|
||||
for(i = 0; i < nwbackLayer; i++)
|
||||
wbackLayer[i]->timer += delay;
|
||||
for(i = 0; i < nwfrontLayer; i++)
|
||||
wfrontLayer[i]->timer += delay;
|
||||
}
|
||||
|
||||
// Seeker brain, You get what you pay for. :)
|
||||
static void think_seeker(Weapon* w, const double dt) {
|
||||
double diff;
|
||||
double diff;
|
||||
if(w->target == w->parent) return; // HEY! Self harm is not allowed.
|
||||
|
||||
Pilot* p = pilot_get(w->target);
|
||||
if(p == NULL) {
|
||||
limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt);
|
||||
return;
|
||||
}
|
||||
limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt);
|
||||
return;
|
||||
}
|
||||
|
||||
// Ammo isn't locked on yet..
|
||||
if(SDL_GetTicks() > (w->timer + w->outfit->u.amm.lockon)) {
|
||||
diff = angle_diff(w->solid->dir, vect_angle(&w->solid->pos, &p->solid->pos));
|
||||
w->solid->dir_vel = 10 * diff * w->outfit->u.amm.turn;
|
||||
// Face the target.
|
||||
if(w->solid->dir_vel > w->outfit->u.amm.turn)
|
||||
w->solid->dir_vel = w->outfit->u.amm.turn;
|
||||
else if(w->solid->dir_vel < -w->outfit->u.amm.turn)
|
||||
w->solid->dir_vel = -w->outfit->u.amm.turn;
|
||||
}
|
||||
if(SDL_GetTicks() > (w->timer + w->outfit->u.amm.lockon)) {
|
||||
diff = angle_diff(w->solid->dir, vect_angle(&w->solid->pos, &p->solid->pos));
|
||||
w->solid->dir_vel = 10 * diff * w->outfit->u.amm.turn;
|
||||
// Face the target.
|
||||
if(w->solid->dir_vel > w->outfit->u.amm.turn)
|
||||
w->solid->dir_vel = w->outfit->u.amm.turn;
|
||||
else if(w->solid->dir_vel < -w->outfit->u.amm.turn)
|
||||
w->solid->dir_vel = -w->outfit->u.amm.turn;
|
||||
}
|
||||
|
||||
vect_pset(&w->solid->force, w->outfit->u.amm.thrust, w->solid->dir);
|
||||
|
||||
limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt);
|
||||
limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt);
|
||||
}
|
||||
|
||||
// Smart seeker brain. Much better at homing.
|
||||
static void think_smart(Weapon* w, const double dt) {
|
||||
double diff;
|
||||
Vec2 tv, sv;
|
||||
double diff;
|
||||
Vec2 tv, sv;
|
||||
|
||||
if(w->target == w->parent) return; // No self shooting here.
|
||||
if(w->target == w->parent) return; // No self shooting here.
|
||||
|
||||
Pilot* p = pilot_get(w->target); // No null pilots..
|
||||
Pilot* p = pilot_get(w->target); // No null pilots..
|
||||
|
||||
if(p == NULL) {
|
||||
limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt);
|
||||
return;
|
||||
}
|
||||
if(p == NULL) {
|
||||
limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt);
|
||||
return;
|
||||
}
|
||||
|
||||
if(SDL_GetTicks() > (w->timer + w->outfit->u.amm.lockon)) {
|
||||
vect_cset(&tv, VX(p->solid->pos) + VX(p->solid->vel),
|
||||
VY(p->solid->pos) + VY(p->solid->vel));
|
||||
vect_cset(&sv, VX(w->solid->pos) + VX(w->solid->vel),
|
||||
VY(w->solid->pos) + VY(w->solid->vel));
|
||||
diff = angle_diff(w->solid->dir, vect_angle(&tv, &sv));
|
||||
w->solid->dir_vel = 10*diff*w->outfit->u.amm.turn; // Face the target.
|
||||
if(w->solid->dir_vel > w->outfit->u.amm.turn)
|
||||
w->solid->dir_vel = w->outfit->u.amm.turn;
|
||||
else if(w->solid->dir_vel < -w->outfit->u.amm.turn)
|
||||
w->solid->dir_vel = -w->outfit->u.amm.turn;
|
||||
}
|
||||
if(SDL_GetTicks() > (w->timer + w->outfit->u.amm.lockon)) {
|
||||
vect_cset(&tv, VX(p->solid->pos) + VX(p->solid->vel),
|
||||
VY(p->solid->pos) + VY(p->solid->vel));
|
||||
vect_cset(&sv, VX(w->solid->pos) + VX(w->solid->vel),
|
||||
VY(w->solid->pos) + VY(w->solid->vel));
|
||||
diff = angle_diff(w->solid->dir, vect_angle(&tv, &sv));
|
||||
w->solid->dir_vel = 10*diff*w->outfit->u.amm.turn; // Face the target.
|
||||
if(w->solid->dir_vel > w->outfit->u.amm.turn)
|
||||
w->solid->dir_vel = w->outfit->u.amm.turn;
|
||||
else if(w->solid->dir_vel < -w->outfit->u.amm.turn)
|
||||
w->solid->dir_vel = -w->outfit->u.amm.turn;
|
||||
}
|
||||
|
||||
vect_pset(&w->solid->force, w->outfit->u.amm.thrust, w->solid->dir);
|
||||
vect_pset(&w->solid->force, w->outfit->u.amm.thrust, w->solid->dir);
|
||||
|
||||
limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt);
|
||||
limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt);
|
||||
|
||||
}
|
||||
|
||||
@ -201,27 +201,27 @@ static void weapons_updateLayer(const double dt, const WeaponLayer layer) {
|
||||
for(i = 0; i < (*nlayer); i++) {
|
||||
w = wlayer[i];
|
||||
switch(wlayer[i]->outfit->type) {
|
||||
// Most missiles behave the same.
|
||||
// Most missiles behave the same.
|
||||
case OUTFIT_TYPE_MISSILE_SEEK_AMMO:
|
||||
case OUTFIT_TYPE_MISSILE_SEEK_SMART_AMMO:
|
||||
case OUTFIT_TYPE_MISSILE_SWARM_AMMO:
|
||||
case OUTFIT_TYPE_MISSILE_SWARM_SMART_AMMO:
|
||||
case OUTFIT_TYPE_MISSILE_SEEK_SMART_AMMO:
|
||||
case OUTFIT_TYPE_MISSILE_SWARM_AMMO:
|
||||
case OUTFIT_TYPE_MISSILE_SWARM_SMART_AMMO:
|
||||
if(SDL_GetTicks() >
|
||||
(wlayer[i]->timer + wlayer[i]->outfit->u.amm.duration)) {
|
||||
(wlayer[i]->timer + wlayer[i]->outfit->u.amm.duration)) {
|
||||
weapon_destroy(wlayer[i], layer);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
case OUTFIT_TYPE_BOLT:
|
||||
// Check see if it exceeds distance.
|
||||
case OUTFIT_TYPE_TURRET_BOLT:
|
||||
if(SDL_GetTicks() > wlayer[i]->timer) {
|
||||
case OUTFIT_TYPE_TURRET_BOLT:
|
||||
if(SDL_GetTicks() > wlayer[i]->timer) {
|
||||
weapon_destroy(wlayer[i],layer);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
weapon_update(wlayer[i], dt, layer);
|
||||
// If the weapon has been deleted we are going to have to hold back one.
|
||||
@ -252,9 +252,9 @@ void weapons_render(const WeaponLayer layer) {
|
||||
// Render the weapons.
|
||||
static void weapon_render(const Weapon* w) {
|
||||
int sx, sy;
|
||||
glTexture* gfx;
|
||||
glTexture* gfx;
|
||||
|
||||
gfx = outfit_gfx(w->outfit);
|
||||
gfx = outfit_gfx(w->outfit);
|
||||
|
||||
// Get the sprite corresponding to the direction facing.
|
||||
gl_getSpriteFromDir(&sx, &sy, gfx, w->solid->dir);
|
||||
@ -265,15 +265,15 @@ static void weapon_render(const Weapon* w) {
|
||||
// Update the weapon.
|
||||
static void weapon_update(Weapon* w, const double dt, WeaponLayer layer) {
|
||||
int i, wsx, wsy, psx, psy;
|
||||
glTexture* gfx;
|
||||
glTexture* gfx;
|
||||
|
||||
gfx = outfit_gfx(w->outfit);
|
||||
gfx = outfit_gfx(w->outfit);
|
||||
|
||||
gl_getSpriteFromDir(&wsx, &wsy, gfx, w->solid->dir);
|
||||
|
||||
for(i = 0; i < pilots; i++) {
|
||||
psx = pilot_stack[i]->tsx;
|
||||
psy = pilot_stack[i]->tsy;
|
||||
psx = pilot_stack[i]->tsx;
|
||||
psy = pilot_stack[i]->tsy;
|
||||
|
||||
if(w->parent == pilot_stack[i]->id) continue; // Hey! That's you.
|
||||
|
||||
@ -292,14 +292,14 @@ static void weapon_update(Weapon* w, const double dt, WeaponLayer layer) {
|
||||
}
|
||||
}
|
||||
|
||||
if(weapon_isSmart(w)) (*w->think)(w,dt);
|
||||
if(weapon_isSmart(w)) (*w->think)(w,dt);
|
||||
|
||||
(*w->solid->update)(w->solid, dt);
|
||||
|
||||
// Update the sound.
|
||||
if(w->voice)
|
||||
voice_update(w->voice, w->solid->pos.x, w->solid->pos.y,
|
||||
w->solid->vel.x, w->solid->vel.y);
|
||||
// Update the sound.
|
||||
if(w->voice)
|
||||
voice_update(w->voice, w->solid->pos.x, w->solid->pos.y,
|
||||
w->solid->vel.x, w->solid->vel.y);
|
||||
}
|
||||
|
||||
// Good shot.
|
||||
@ -307,13 +307,13 @@ static void weapon_hit(Weapon* w, Pilot* p, WeaponLayer layer) {
|
||||
// Someone should let the ai know it's been attacked.
|
||||
if(!pilot_isPlayer(p)) {
|
||||
ai_attacked(p, w->parent);
|
||||
spfx_add(outfit_spfx(w->outfit),
|
||||
VX(w->solid->pos), VY(w->solid->pos),
|
||||
VX(p->solid->vel), VY(p->solid->vel), SPFX_LAYER_BACK);
|
||||
} else
|
||||
spfx_add(outfit_spfx(w->outfit),
|
||||
VX(w->solid->pos), VY(w->solid->pos),
|
||||
VX(p->solid->vel), VY(p->solid->vel), SPFX_LAYER_FRONT);
|
||||
spfx_add(outfit_spfx(w->outfit),
|
||||
VX(w->solid->pos), VY(w->solid->pos),
|
||||
VX(p->solid->vel), VY(p->solid->vel), SPFX_LAYER_BACK);
|
||||
} else
|
||||
spfx_add(outfit_spfx(w->outfit),
|
||||
VX(w->solid->pos), VY(w->solid->pos),
|
||||
VX(p->solid->vel), VY(p->solid->vel), SPFX_LAYER_FRONT);
|
||||
|
||||
if(w->parent == PLAYER_ID)
|
||||
// Make hostile to player.
|
||||
@ -345,45 +345,45 @@ static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2*
|
||||
if((rdir > 2.*M_PI) || (rdir < 0.)) rdir = fmod(rdir, 2.*M_PI);
|
||||
vectcpy(&v, vel);
|
||||
vect_cadd(&v, outfit->u.blt.speed*cos(rdir), outfit->u.blt.speed*sin(rdir));
|
||||
w->timer += 1000*(unsigned int)outfit->u.blt.range/outfit->u.blt.speed;
|
||||
w->timer += 1000*(unsigned int)outfit->u.blt.range/outfit->u.blt.speed;
|
||||
w->solid = solid_create(mass, rdir, pos, &v);
|
||||
w->voice = sound_addVoice(VOICE_PRIORITY_BOLT,
|
||||
w->solid->pos.x, w->solid->pos.y,
|
||||
w->solid->vel.x, w->solid->vel.y, w->outfit->u.blt.sound, 0);
|
||||
w->voice = sound_addVoice(VOICE_PRIORITY_BOLT,
|
||||
w->solid->pos.x, w->solid->pos.y,
|
||||
w->solid->vel.x, w->solid->vel.y, w->outfit->u.blt.sound, 0);
|
||||
break;
|
||||
case OUTFIT_TYPE_MISSILE_SEEK_AMMO:
|
||||
mass = w->outfit->mass;
|
||||
w->solid = solid_create(mass, dir, pos, vel);
|
||||
w->think = think_seeker; // Eeek!!!
|
||||
w->voice = sound_addVoice(VOICE_PRIORITY_AMMO,
|
||||
w->solid->pos.x, w->solid->pos.y,
|
||||
w->solid->vel.x, w->solid->vel.y, w->outfit->u.amm.sound, 0);
|
||||
w->voice = sound_addVoice(VOICE_PRIORITY_AMMO,
|
||||
w->solid->pos.x, w->solid->pos.y,
|
||||
w->solid->vel.x, w->solid->vel.y, w->outfit->u.amm.sound, 0);
|
||||
break;
|
||||
case OUTFIT_TYPE_MISSILE_SEEK_SMART_AMMO:
|
||||
mass = w->outfit->mass;
|
||||
w->solid = solid_create(mass, dir, pos, vel);
|
||||
w->think = think_smart; // Smartass.
|
||||
w->voice = sound_addVoice(VOICE_PRIORITY_AMMO,
|
||||
w->solid->pos.x, w->solid->pos.y,
|
||||
w->solid->vel.x, w->solid->vel.y, w->outfit->u.amm.sound, 0);
|
||||
break;
|
||||
case OUTFIT_TYPE_TURRET_BOLT:
|
||||
if(w->parent != w->target)
|
||||
rdir = vect_angle(pos, &pilot_get(w->target)->solid->pos);
|
||||
rdir += RNG(-outfit->u.blt.accuracy/2.,
|
||||
outfit->u.blt.accuracy/2.)/180.*M_PI;
|
||||
if((rdir > 2.*M_PI) || (rdir < 0.)) rdir = fmod(rdir, 2.*M_PI);
|
||||
vectcpy(&v, vel);
|
||||
vect_cadd(&v, outfit->u.blt.speed*cos(rdir), outfit->u.blt.speed*sin(rdir));
|
||||
w->timer += 1000*(unsigned int)outfit->u.blt.range / outfit->u.blt.speed;
|
||||
w->solid = solid_create(mass, rdir, pos, &v);
|
||||
w->voice = sound_addVoice(VOICE_PRIORITY_BOLT,
|
||||
w->solid->pos.x, w->solid->pos.y,
|
||||
w->solid->vel.x, w->solid->vel.y, w->outfit->u.blt.sound, 0);
|
||||
break;
|
||||
case OUTFIT_TYPE_MISSILE_SEEK_SMART_AMMO:
|
||||
mass = w->outfit->mass;
|
||||
w->solid = solid_create(mass, dir, pos, vel);
|
||||
w->think = think_smart; // Smartass.
|
||||
w->voice = sound_addVoice(VOICE_PRIORITY_AMMO,
|
||||
w->solid->pos.x, w->solid->pos.y,
|
||||
w->solid->vel.x, w->solid->vel.y, w->outfit->u.amm.sound, 0);
|
||||
break;
|
||||
case OUTFIT_TYPE_TURRET_BOLT:
|
||||
if(w->parent != w->target)
|
||||
rdir = vect_angle(pos, &pilot_get(w->target)->solid->pos);
|
||||
rdir += RNG(-outfit->u.blt.accuracy/2.,
|
||||
outfit->u.blt.accuracy/2.)/180.*M_PI;
|
||||
if((rdir > 2.*M_PI) || (rdir < 0.)) rdir = fmod(rdir, 2.*M_PI);
|
||||
vectcpy(&v, vel);
|
||||
vect_cadd(&v, outfit->u.blt.speed*cos(rdir), outfit->u.blt.speed*sin(rdir));
|
||||
w->timer += 1000*(unsigned int)outfit->u.blt.range / outfit->u.blt.speed;
|
||||
w->solid = solid_create(mass, rdir, pos, &v);
|
||||
w->voice = sound_addVoice(VOICE_PRIORITY_BOLT,
|
||||
w->solid->pos.x, w->solid->pos.y,
|
||||
w->solid->vel.x, w->solid->vel.y, w->outfit->u.blt.sound, 0);
|
||||
break;
|
||||
default:
|
||||
// Just dump it where the player is.
|
||||
w->voice = NULL;
|
||||
w->voice = NULL;
|
||||
w->solid = solid_create(mass, dir, pos, vel);
|
||||
break;
|
||||
}
|
||||
@ -391,11 +391,11 @@ static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2*
|
||||
}
|
||||
|
||||
// Add a new weapon.
|
||||
void weapon_add(const Outfit* outfit, const double dir, const Vec2* pos,
|
||||
const Vec2* vel, unsigned int parent, unsigned int target) {
|
||||
void weapon_add(const Outfit* outfit, const double dir, const Vec2* pos,
|
||||
const Vec2* vel, unsigned int parent, unsigned int target) {
|
||||
|
||||
if(!outfit_isWeapon(outfit) &&
|
||||
!outfit_isAmmo(outfit) && !outfit_isTurret(outfit)) {
|
||||
!outfit_isAmmo(outfit) && !outfit_isTurret(outfit)) {
|
||||
ERR("Trying to create a weapon from a non-Weapon type Outfit");
|
||||
return;
|
||||
}
|
||||
@ -463,7 +463,7 @@ static void weapon_destroy(Weapon* w, WeaponLayer layer) {
|
||||
|
||||
// Clear the weapon.
|
||||
static void weapon_free(Weapon* w) {
|
||||
sound_delVoice(w->voice);
|
||||
sound_delVoice(w->voice);
|
||||
solid_free(w->solid);
|
||||
free(w);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user