[Add] Afterburners are in! After buying the outfit, double tap 'w'.
This commit is contained in:
parent
4abe914310
commit
0d6ac1e5b1
@ -245,5 +245,39 @@
|
|||||||
<energy>-10</energy>
|
<energy>-10</energy>
|
||||||
</specific>
|
</specific>
|
||||||
</outfit>
|
</outfit>
|
||||||
|
<outfit name="Generic Afterburner">
|
||||||
|
<general>
|
||||||
|
<max>1</max>
|
||||||
|
<tech>3</tech>
|
||||||
|
<mass>2</mass>
|
||||||
|
<price>20000</price>
|
||||||
|
<description>Being able to run from your enemies is a very powerful ability. A generic afterburner will allow you to do that. It may not be as powerful as some of the more high-end afterburners, but ther're not nearly as affordable as a generic one.</description>
|
||||||
|
<gfx_store>afterburner</gfx_store>
|
||||||
|
</general>
|
||||||
|
<specific type="16">
|
||||||
|
<thrust_perc>50</thrust_perc>
|
||||||
|
<thrust_abs>30</thrust_abs>
|
||||||
|
<speed_perc>50</speed_perc>
|
||||||
|
<speed_abs>30</speed_abs>
|
||||||
|
<energy>60</energy>
|
||||||
|
</specific>
|
||||||
|
</outfit>
|
||||||
|
<outfit name="Hellburner">
|
||||||
|
<general>
|
||||||
|
<max>1</max>
|
||||||
|
<tech>13</tech>
|
||||||
|
<mass>1</mass>
|
||||||
|
<price>95000</price>
|
||||||
|
<description>The Hellburner is one of the best afterburners available in the market. They have a much better energy to speed ratio then the generics and are much stronger. A must for any spacefarer whose proud of thier ship.</description>
|
||||||
|
<gfx_store>afterburner</gfx_store>
|
||||||
|
</general>
|
||||||
|
<specific type="16">
|
||||||
|
<thrust_perc>85</thrust_perc>
|
||||||
|
<thrust_abs>50</thrust_abs>
|
||||||
|
<speed_perc>85</speed_perc>
|
||||||
|
<speed_abs>50</speed_abs>
|
||||||
|
<energy>65</energy>
|
||||||
|
</specific>
|
||||||
|
</outfit>
|
||||||
</Outfits>
|
</Outfits>
|
||||||
|
|
||||||
|
7
src/ai.c
7
src/ai.c
@ -556,12 +556,15 @@ static int ai_getpos(lua_State* L) {
|
|||||||
// ==> 180.*360./cur_pilot->turn
|
// ==> 180.*360./cur_pilot->turn
|
||||||
// Add it to general euler equation x = v*t + 0.5 * a * t^2
|
// Add it to general euler equation x = v*t + 0.5 * a * t^2
|
||||||
// Have fun.
|
// Have fun.
|
||||||
|
//
|
||||||
|
// I really hate this function. Why isn't it depricated yet?
|
||||||
// ========================================================
|
// ========================================================
|
||||||
static int ai_minbrakedist(lua_State* L) {
|
static int ai_minbrakedist(lua_State* L) {
|
||||||
double time = VMOD(cur_pilot->solid->vel) /
|
double time, dist;
|
||||||
|
time = VMOD(cur_pilot->solid->vel) /
|
||||||
(cur_pilot->thrust / cur_pilot->solid->mass);
|
(cur_pilot->thrust / cur_pilot->solid->mass);
|
||||||
|
|
||||||
double dist = VMOD(cur_pilot->solid->vel)*(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;
|
0.5 * (cur_pilot->thrust / cur_pilot->solid->mass)*time*time;
|
||||||
|
|
||||||
lua_pushnumber(L, dist); // return
|
lua_pushnumber(L, dist); // return
|
||||||
|
@ -44,12 +44,15 @@ if(lua_isstring(L, -1)) { \
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Some crap from main.
|
// Some crap from main.
|
||||||
|
extern int nosound;
|
||||||
extern int show_fps;
|
extern int show_fps;
|
||||||
extern int max_fps;
|
extern int max_fps;
|
||||||
extern int indjoystick;
|
extern int indjoystick;
|
||||||
extern char* namjoystick;
|
extern char* namjoystick;
|
||||||
// From player.c
|
// From player.c
|
||||||
extern const char* keybindNames[]; // Keybindings.
|
extern const char* keybindNames[]; // Keybindings.
|
||||||
|
// input.c.
|
||||||
|
extern unsigned int input_afterburnSensibility;
|
||||||
|
|
||||||
static void print_usage(char** argv);
|
static void print_usage(char** argv);
|
||||||
|
|
||||||
@ -115,6 +118,9 @@ int conf_loadConfig(const char* file) {
|
|||||||
conf_loadBool("showfps", show_fps);
|
conf_loadBool("showfps", show_fps);
|
||||||
conf_loadInt("maxfps", max_fps);
|
conf_loadInt("maxfps", max_fps);
|
||||||
|
|
||||||
|
// Input.
|
||||||
|
conf_loadInt("afterburn", input_afterburnSensibility);
|
||||||
|
|
||||||
// Sound.
|
// Sound.
|
||||||
conf_loadFloat("sound", d);
|
conf_loadFloat("sound", d);
|
||||||
if(d) { sound_volume(d); d = 0.; }
|
if(d) { sound_volume(d); d = 0.; }
|
||||||
|
25
src/input.c
25
src/input.c
@ -23,14 +23,18 @@ static Keybind** input_keybinds; // Contains the players keybindings.
|
|||||||
|
|
||||||
|
|
||||||
// Name of each keybinding.
|
// Name of each keybinding.
|
||||||
const char* keybindNames[] =
|
const char* keybindNames[] = {
|
||||||
{ "accel", "left", "right", "reverse", // Movement.
|
"accel", "left", "right", "reverse", // Movement.
|
||||||
"primary", "target", "target_nearest", "face", "board", // Combat.
|
"primary", "target", "target_nearest", "face", "board", // Combat.
|
||||||
"secondary", "secondary_next", // Secondary weapons.
|
"secondary", "secondary_next", // Secondary weapons.
|
||||||
"target_planet", "land", "thyperspace","starmap", "jump", // Navigation.
|
"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.
|
"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.
|
||||||
|
|
||||||
// From player.c
|
// From player.c
|
||||||
extern double player_turn;
|
extern double player_turn;
|
||||||
extern double player_acc;
|
extern double player_acc;
|
||||||
@ -46,7 +50,6 @@ void input_setDefault(void) {
|
|||||||
input_setKeybind("left", KEYBIND_KEYBOARD, SDLK_a, 0);
|
input_setKeybind("left", KEYBIND_KEYBOARD, SDLK_a, 0);
|
||||||
input_setKeybind("right", KEYBIND_KEYBOARD, SDLK_d, 0);
|
input_setKeybind("right", KEYBIND_KEYBOARD, SDLK_d, 0);
|
||||||
input_setKeybind("reverse", KEYBIND_KEYBOARD, SDLK_s, 0);
|
input_setKeybind("reverse", KEYBIND_KEYBOARD, SDLK_s, 0);
|
||||||
|
|
||||||
// Combat.
|
// Combat.
|
||||||
input_setKeybind("primary", KEYBIND_KEYBOARD, SDLK_SPACE, 0);
|
input_setKeybind("primary", KEYBIND_KEYBOARD, SDLK_SPACE, 0);
|
||||||
input_setKeybind("target", KEYBIND_KEYBOARD, SDLK_TAB, 0);
|
input_setKeybind("target", KEYBIND_KEYBOARD, SDLK_TAB, 0);
|
||||||
@ -123,11 +126,23 @@ void input_setKeybind(char* keybind, KeybindType type, int key, int reverse) {
|
|||||||
!pilot_isFlag(player, PILOT_HYP_BEGIN) && \
|
!pilot_isFlag(player, PILOT_HYP_BEGIN) && \
|
||||||
!pilot_isFlag(player, PILOT_HYPERSPACE))
|
!pilot_isFlag(player, PILOT_HYPERSPACE))
|
||||||
static void input_key(int keynum, double value, int abs) {
|
static void input_key(int keynum, double value, int abs) {
|
||||||
|
unsigned int t;
|
||||||
|
|
||||||
// Accelerating.
|
// Accelerating.
|
||||||
if(KEY("accel")) {
|
if(KEY("accel")) {
|
||||||
if(abs)player_acc = value;
|
if(abs)player_acc = value;
|
||||||
else player_acc += value;
|
else player_acc += value;
|
||||||
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;
|
||||||
}
|
}
|
||||||
// Turning left.
|
// Turning left.
|
||||||
else if(KEY("left")) {
|
else if(KEY("left")) {
|
||||||
@ -159,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_LEFT)) { player_turn -= 1; }
|
||||||
if(player_isFlag(PLAYER_TURN_RIGHT)) { player_turn += 1; }
|
if(player_isFlag(PLAYER_TURN_RIGHT)) { player_turn += 1; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Shoot primary weapon. BOOM BOOM.
|
// Shoot primary weapon. BOOM BOOM.
|
||||||
else if(KEY("primary")) {
|
else if(KEY("primary")) {
|
||||||
if(value == KEY_PRESS) { player_setFlag(PLAYER_PRIMARY); }
|
if(value == KEY_PRESS) { player_setFlag(PLAYER_PRIMARY); }
|
||||||
|
@ -295,7 +295,11 @@ static void outfits_buy(char* str) {
|
|||||||
toolkit_alert("You can only carry %d of this outfit.", outfit->max);
|
toolkit_alert("You can only carry %d of this outfit.", outfit->max);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// Not enough.
|
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) {
|
else if(q*(int)outfit->price >= player_credits) {
|
||||||
credits2str(buf, q*outfit->price - player_credits, 2);
|
credits2str(buf, q*outfit->price - player_credits, 2);
|
||||||
toolkit_alert("You need %s more SCred.", buf);
|
toolkit_alert("You need %s more SCred.", buf);
|
||||||
|
50
src/outfit.c
50
src/outfit.c
@ -29,6 +29,7 @@ static void outfit_parseSWeapon(Outfit* tmp, const xmlNodePtr parent);
|
|||||||
static void outfit_parseSLauncher(Outfit* tmp, const xmlNodePtr parent);
|
static void outfit_parseSLauncher(Outfit* tmp, const xmlNodePtr parent);
|
||||||
static void outfit_parseSAmmo(Outfit* tmp, const xmlNodePtr parent);
|
static void outfit_parseSAmmo(Outfit* tmp, const xmlNodePtr parent);
|
||||||
static void outfit_parseSMod(Outfit* tmp, const xmlNodePtr parent);
|
static void outfit_parseSMod(Outfit* tmp, const xmlNodePtr parent);
|
||||||
|
static void outfit_parseSAfterburner(Outfit* tmp, const xmlNodePtr parent);
|
||||||
|
|
||||||
// Return an outfit.
|
// Return an outfit.
|
||||||
Outfit* outfit_get(const char* name) {
|
Outfit* outfit_get(const char* name) {
|
||||||
@ -95,6 +96,11 @@ 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);
|
||||||
|
}
|
||||||
|
|
||||||
// Get the outfit graphics.
|
// Get the outfit graphics.
|
||||||
glTexture* outfit_gfx(const Outfit* o) {
|
glTexture* outfit_gfx(const Outfit* o) {
|
||||||
if(outfit_isWeapon(o)) return o->u.blt.gfx_space;
|
if(outfit_isWeapon(o)) return o->u.blt.gfx_space;
|
||||||
@ -155,7 +161,8 @@ const char* outfit_typename[] = {
|
|||||||
"Smart Swarm Missile Ammunition Pack",
|
"Smart Swarm Missile Ammunition Pack",
|
||||||
"Bolt Turret",
|
"Bolt Turret",
|
||||||
"Beam Turret",
|
"Beam Turret",
|
||||||
"Modification"
|
"Ship Modification",
|
||||||
|
"Afterburner"
|
||||||
};
|
};
|
||||||
|
|
||||||
const char* outfit_getType(const Outfit* o) {
|
const char* outfit_getType(const Outfit* o) {
|
||||||
@ -169,16 +176,18 @@ const char* outfit_typenamebroad[] = {
|
|||||||
"Launcher",
|
"Launcher",
|
||||||
"Ammo",
|
"Ammo",
|
||||||
"Turret",
|
"Turret",
|
||||||
"Modification"
|
"Modification",
|
||||||
|
"Afterburner"
|
||||||
};
|
};
|
||||||
|
|
||||||
const char* outfit_getTypeBroad(const Outfit* o) {
|
const char* outfit_getTypeBroad(const Outfit* o) {
|
||||||
int i = 0;
|
int i = 0;
|
||||||
if(outfit_isWeapon(o)) i = 1;
|
if(outfit_isWeapon(o)) i = 1;
|
||||||
else if(outfit_isLauncher(o)) i = 2;
|
else if(outfit_isLauncher(o)) i = 2;
|
||||||
else if(outfit_isAmmo(o)) i = 3;
|
else if(outfit_isAmmo(o)) i = 3;
|
||||||
else if(outfit_isTurret(o)) i = 4;
|
else if(outfit_isTurret(o)) i = 4;
|
||||||
else if(outfit_isMod(o)) i = 5;
|
else if(outfit_isMod(o)) i = 5;
|
||||||
|
else if(outfit_isAfterburner(o)) i = 6;
|
||||||
|
|
||||||
return outfit_typenamebroad[i];
|
return outfit_typenamebroad[i];
|
||||||
}
|
}
|
||||||
@ -295,7 +304,7 @@ static void outfit_parseSAmmo(Outfit* tmp, const xmlNodePtr parent) {
|
|||||||
|
|
||||||
static void outfit_parseSMod(Outfit* tmp, const xmlNodePtr parent) {
|
static void outfit_parseSMod(Outfit* tmp, const xmlNodePtr parent) {
|
||||||
xmlNodePtr node;
|
xmlNodePtr node;
|
||||||
node = parent->xmlChildrenNode;
|
node = parent->children;
|
||||||
|
|
||||||
// Load all the data.
|
// Load all the data.
|
||||||
do {
|
do {
|
||||||
@ -324,6 +333,29 @@ static void outfit_parseSMod(Outfit* tmp, const xmlNodePtr parent) {
|
|||||||
} 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;
|
||||||
|
|
||||||
|
// 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));
|
||||||
|
}
|
||||||
|
|
||||||
// Parse and return Outfits from parent node.
|
// Parse and return Outfits from parent node.
|
||||||
static Outfit* outfit_parse(const xmlNodePtr parent) {
|
static Outfit* outfit_parse(const xmlNodePtr parent) {
|
||||||
Outfit* tmp = CALLOC_L(Outfit);
|
Outfit* tmp = CALLOC_L(Outfit);
|
||||||
@ -381,6 +413,8 @@ static Outfit* outfit_parse(const xmlNodePtr parent) {
|
|||||||
outfit_parseSWeapon(tmp, node);
|
outfit_parseSWeapon(tmp, node);
|
||||||
else if(outfit_isMod(tmp))
|
else if(outfit_isMod(tmp))
|
||||||
outfit_parseSMod(tmp, node);
|
outfit_parseSMod(tmp, node);
|
||||||
|
else if(outfit_isAfterburner(tmp))
|
||||||
|
outfit_parseSAfterburner(tmp, node);
|
||||||
}
|
}
|
||||||
} while((node = node->next));
|
} while((node = node->next));
|
||||||
#define MELEMENT(o,s) if(o) WARN("Outfit '%s' missing '"s"' element", tmp->name)
|
#define MELEMENT(o,s) if(o) WARN("Outfit '%s' missing '"s"' element", tmp->name)
|
||||||
|
@ -23,7 +23,8 @@ typedef enum OutfitType_ {
|
|||||||
OUTFIT_TYPE_MISSILE_SWARM_SMART_AMMO = 12,
|
OUTFIT_TYPE_MISSILE_SWARM_SMART_AMMO = 12,
|
||||||
OUTFIT_TYPE_TURRET_BOLT = 13,
|
OUTFIT_TYPE_TURRET_BOLT = 13,
|
||||||
OUTFIT_TYPE_TURRET_BEAM = 14,
|
OUTFIT_TYPE_TURRET_BEAM = 14,
|
||||||
OUTFIT_TYPE_MODIFICATION = 15
|
OUTFIT_TYPE_MODIFICATION = 15,
|
||||||
|
OUTFIT_TYPE_AFTERBURNER = 16
|
||||||
} OutfitType;
|
} OutfitType;
|
||||||
|
|
||||||
// An outfit depends a lot on the type.
|
// An outfit depends a lot on the type.
|
||||||
@ -90,6 +91,11 @@ typedef struct Outfit_ {
|
|||||||
double shield, shield_regen;
|
double shield, shield_regen;
|
||||||
double energy, energy_regen;
|
double energy, energy_regen;
|
||||||
} mod;
|
} 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;
|
} u;
|
||||||
} Outfit;
|
} Outfit;
|
||||||
|
|
||||||
@ -102,6 +108,7 @@ int outfit_isLauncher(const Outfit* o);
|
|||||||
int outfit_isAmmo(const Outfit* o);
|
int outfit_isAmmo(const Outfit* o);
|
||||||
int outfit_isTurret(const Outfit* o);
|
int outfit_isTurret(const Outfit* o);
|
||||||
int outfit_isMod(const Outfit* o);
|
int outfit_isMod(const Outfit* o);
|
||||||
|
int outfit_isAfterburner(const Outfit* o);
|
||||||
const char* outfit_getType(const Outfit* o);
|
const char* outfit_getType(const Outfit* o);
|
||||||
const char* outfit_getTypeBroad(const Outfit* o);
|
const char* outfit_getTypeBroad(const Outfit* o);
|
||||||
|
|
||||||
|
@ -14,14 +14,8 @@ double angle_diff(const double ref, double a) {
|
|||||||
return (d <= M_PI) ? d : d - 2*M_PI;
|
return (d <= M_PI) ? d : d - 2*M_PI;
|
||||||
}
|
}
|
||||||
|
|
||||||
void limit_speed(Vec2* vel, const double speed) {
|
void limit_speed(Vec2* vel, const double speed, const double dt) {
|
||||||
if(VMOD(*vel) > speed) // Should not go faster.
|
double vmod = VMOD(*vel);
|
||||||
vect_pset(vel, speed, VANGLE(*vel));
|
|
||||||
}
|
|
||||||
|
|
||||||
void limit_speeddt(Vec2* vel, const double speed, const double dt) {
|
|
||||||
double vmod;
|
|
||||||
vmod = VMOD(*vel);
|
|
||||||
if(vmod > speed) // Should not go faster.
|
if(vmod > speed) // Should not go faster.
|
||||||
vect_pset(vel, (vmod-speed)*(1.-dt*3.) + speed, VANGLE(*vel));
|
vect_pset(vel, (vmod-speed)*(1.-dt*3.) + speed, VANGLE(*vel));
|
||||||
}
|
}
|
||||||
|
@ -22,8 +22,7 @@ typedef struct Vec2_ {
|
|||||||
|
|
||||||
// Misc
|
// Misc
|
||||||
double angle_diff(const double ref, double a);
|
double angle_diff(const double ref, double a);
|
||||||
void limit_speed(Vec2* vel, const double speed);
|
void limit_speed(Vec2* vel, const double speed, const double dt);
|
||||||
void limit_speeddt(Vec2* vel, const double speed, const double dt);
|
|
||||||
|
|
||||||
// Vector manupulation.
|
// Vector manupulation.
|
||||||
void vect_cset(Vec2* v, const double x, const double y);
|
void vect_cset(Vec2* v, const double x, const double y);
|
||||||
|
24
src/pilot.c
24
src/pilot.c
@ -375,9 +375,16 @@ static void pilot_update(Pilot* pilot, const double dt) {
|
|||||||
gl_getSpriteFromDir(&pilot->tsx, &pilot->tsy,
|
gl_getSpriteFromDir(&pilot->tsx, &pilot->tsy,
|
||||||
pilot->ship->gfx_space, pilot->solid->dir);
|
pilot->ship->gfx_space, pilot->solid->dir);
|
||||||
|
|
||||||
if(!pilot_isFlag(pilot, PILOT_HYPERSPACE))
|
if(!pilot_isFlag(pilot, PILOT_HYPERSPACE)) { // Limit the speed.
|
||||||
// Should not go faster.
|
if(pilot_isFlag(pilot, PILOT_AFTERBURNER) && // Must have enough energy.
|
||||||
limit_speeddt(&pilot->solid->vel, pilot->speed, dt);
|
(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.
|
// Pilot is getting ready or is in, hyperspace.
|
||||||
@ -482,6 +489,9 @@ int pilot_rmOutfit(Pilot* pilot, Outfit* outfit, int quantity) {
|
|||||||
q += pilot->outfits[i].quantity;
|
q += pilot->outfits[i].quantity;
|
||||||
// Hack in case it reallocs - Can happen even when shrinking.
|
// Hack in case it reallocs - Can happen even when shrinking.
|
||||||
s = (pilot->secondary) ? pilot->secondary->outfit->name : NULL;
|
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.
|
// Remove the outfit.
|
||||||
memmove(pilot->outfits+i, pilot->outfits+i+1,
|
memmove(pilot->outfits+i, pilot->outfits+i+1,
|
||||||
@ -524,7 +534,7 @@ static void pilot_calcStats(Pilot* pilot) {
|
|||||||
pilot->energy_regen = pilot->ship->energy_regen;
|
pilot->energy_regen = pilot->ship->energy_regen;
|
||||||
|
|
||||||
// Now add outfit changes.
|
// Now add outfit changes.
|
||||||
for(i = 0; i < pilot->noutfits; i++)
|
for(i = 0; i < pilot->noutfits; i++) {
|
||||||
if(outfit_isMod(pilot->outfits[i].outfit)) {
|
if(outfit_isMod(pilot->outfits[i].outfit)) {
|
||||||
q = (double) pilot->outfits[i].quantity;
|
q = (double) pilot->outfits[i].quantity;
|
||||||
o = pilot->outfits[i].outfit;
|
o = pilot->outfits[i].outfit;
|
||||||
@ -542,6 +552,11 @@ static void pilot_calcStats(Pilot* pilot) {
|
|||||||
pilot->energy_regen += o->u.mod.energy_regen * 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];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Give the pilot her health proportion back.
|
// Give the pilot her health proportion back.
|
||||||
pilot->armour = ac * pilot->armour_max;
|
pilot->armour = ac * pilot->armour_max;
|
||||||
@ -641,6 +656,7 @@ void pilot_init(Pilot* pilot, Ship* ship, char* name, Faction* faction,
|
|||||||
pilot->outfits = NULL;
|
pilot->outfits = NULL;
|
||||||
pilot->secondary = NULL;
|
pilot->secondary = NULL;
|
||||||
pilot->ammo = NULL;
|
pilot->ammo = NULL;
|
||||||
|
pilot->afterburner = NULL;
|
||||||
ShipOutfit* so;
|
ShipOutfit* so;
|
||||||
if(ship->outfit) {
|
if(ship->outfit) {
|
||||||
pilot->noutfits = 0;
|
pilot->noutfits = 0;
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
// Dynamic.
|
// Dynamic.
|
||||||
#define PILOT_HOSTILE (1<<1) // Pilot is hostile to the player.
|
#define PILOT_HOSTILE (1<<1) // Pilot is hostile to the player.
|
||||||
#define PILOT_COMBAT (1<<2) // Pilot is engaged in combat.
|
#define PILOT_COMBAT (1<<2) // Pilot is engaged in combat.
|
||||||
|
#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_PREP (1<<5) // Pilot is getting ready for hyperspace.
|
||||||
#define PILOT_HYP_BEGIN (1<<6) // Pilot is starting engines.
|
#define PILOT_HYP_BEGIN (1<<6) // Pilot is starting engines.
|
||||||
#define PILOT_HYPERSPACE (1<<7) // Pilot is in hyperspace.
|
#define PILOT_HYPERSPACE (1<<7) // Pilot is in hyperspace.
|
||||||
@ -81,8 +82,9 @@ typedef struct Pilot_ {
|
|||||||
// Outfit management.
|
// Outfit management.
|
||||||
PilotOutfit* outfits;
|
PilotOutfit* outfits;
|
||||||
int noutfits;
|
int noutfits;
|
||||||
PilotOutfit* secondary; // Secondary weapon.
|
PilotOutfit* secondary; // Secondary weapon.
|
||||||
PilotOutfit* ammo; // Secondary ammo (if needed).
|
PilotOutfit* ammo; // Secondary ammo (if needed).
|
||||||
|
PilotOutfit* afterburner; // Ze afterburner.
|
||||||
|
|
||||||
// Cargo.
|
// Cargo.
|
||||||
int credits; // Moniez the pilot has.
|
int credits; // Moniez the pilot has.
|
||||||
|
29
src/player.c
29
src/player.c
@ -907,8 +907,13 @@ void player_think(Pilot* player) {
|
|||||||
if(player_isFlag(PLAYER_SECONDARY)) // Needs a target.
|
if(player_isFlag(PLAYER_SECONDARY)) // Needs a target.
|
||||||
pilot_shoot(player, player_target, 1);
|
pilot_shoot(player, player_target, 1);
|
||||||
|
|
||||||
vect_pset(&player->solid->force, player->thrust * player_acc,
|
if(player_isFlag(PLAYER_AFTERBURNER))
|
||||||
player->solid->dir);
|
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.
|
// Set the listener stuff.
|
||||||
sound_listener(player->solid->dir,
|
sound_listener(player->solid->dir,
|
||||||
@ -1055,8 +1060,8 @@ void player_brokeHyperspace(void) {
|
|||||||
space_init(systems_stack[cur_system->jumps[hyperspace_target]].name);
|
space_init(systems_stack[cur_system->jumps[hyperspace_target]].name);
|
||||||
|
|
||||||
// Set position, pilot_update will handle the lowering of velocity.
|
// Set position, pilot_update will handle the lowering of velocity.
|
||||||
player_warp(-cos(player->solid->dir) * MIN_HYPERSPACE_DIST * 1.5,
|
player_warp(-cos(player->solid->dir) * MIN_HYPERSPACE_DIST * 2.5,
|
||||||
-sin(player->solid->dir) * MIN_HYPERSPACE_DIST * 1.5);
|
-sin(player->solid->dir) * MIN_HYPERSPACE_DIST * 2.5);
|
||||||
|
|
||||||
// Stop hyperspace.
|
// Stop hyperspace.
|
||||||
pilot_rmFlag(player, PILOT_HYPERSPACE | PILOT_HYP_BEGIN | PILOT_HYP_PREP);
|
pilot_rmFlag(player, PILOT_HYPERSPACE | PILOT_HYP_BEGIN | PILOT_HYP_PREP);
|
||||||
@ -1075,6 +1080,22 @@ double player_faceHyperspace(void) {
|
|||||||
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void player_afterburnOver(void) {
|
||||||
|
if(player->afterburner != NULL) {
|
||||||
|
player_rmFlag(PLAYER_AFTERBURNER);
|
||||||
|
pilot_rmFlag(player, PILOT_AFTERBURNER);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Take a screenshot.
|
// Take a screenshot.
|
||||||
static int screenshot_cur = 0;
|
static int screenshot_cur = 0;
|
||||||
void player_screenshot(void) {
|
void player_screenshot(void) {
|
||||||
|
17
src/player.h
17
src/player.h
@ -2,13 +2,14 @@
|
|||||||
#include "pilot.h"
|
#include "pilot.h"
|
||||||
|
|
||||||
// Flag definitions.
|
// Flag definitions.
|
||||||
#define PLAYER_TURN_LEFT (1<<0) // Player is turning left.
|
#define PLAYER_TURN_LEFT (1<<0) // Player is turning left.
|
||||||
#define PLAYER_TURN_RIGHT (1<<1) // Player is turning right.
|
#define PLAYER_TURN_RIGHT (1<<1) // Player is turning right.
|
||||||
#define PLAYER_REVERSE (1<<2) // Player is facint opposite vel.
|
#define PLAYER_REVERSE (1<<2) // Player is facint opposite vel.
|
||||||
#define PLAYER_FACE (1<<10) // Player is facing target.
|
#define PLAYER_AFTERBURNER (1<<3) // Player is burning it up.
|
||||||
#define PLAYER_PRIMARY (1<<11) // Player is shooting primary weapon.
|
#define PLAYER_FACE (1<<10) // Player is facing target.
|
||||||
#define PLAYER_SECONDARY (1<<12) // Player is shooting secondary weapon.
|
#define PLAYER_PRIMARY (1<<11) // Player is shooting primary weapon.
|
||||||
#define PLAYER_LANDACK (1<<13) // Player has permission to land.
|
#define PLAYER_SECONDARY (1<<12) // Player is shooting secondary weapon.
|
||||||
|
#define PLAYER_LANDACK (1<<13) // Player has permission to land.
|
||||||
|
|
||||||
// Flag functions.
|
// Flag functions.
|
||||||
#define player_isFlag(f) (player_flags & f)
|
#define player_isFlag(f) (player_flags & f)
|
||||||
@ -52,4 +53,6 @@ void player_land(void);
|
|||||||
void player_targetHyperspace(void);
|
void player_targetHyperspace(void);
|
||||||
void player_jump(void);
|
void player_jump(void);
|
||||||
void player_screenshot(void);
|
void player_screenshot(void);
|
||||||
|
void player_afterburn(void);
|
||||||
|
void player_afterburnOver(void);
|
||||||
|
|
||||||
|
16
src/space.c
16
src/space.c
@ -226,25 +226,29 @@ void space_update(const double dt) {
|
|||||||
// Crate a fleet.
|
// Crate a fleet.
|
||||||
static void space_addFleet(Fleet* fleet) {
|
static void space_addFleet(Fleet* fleet) {
|
||||||
int i;
|
int i;
|
||||||
Vec2 v, vn;
|
double a;
|
||||||
|
Vec2 vv, vp, vn;
|
||||||
|
|
||||||
// Simulate them coming from hyperspace.
|
// Simulate them coming from hyperspace.
|
||||||
vect_pset(&v, 2*RNG(MIN_HYPERSPACE_DIST/2, MIN_HYPERSPACE_DIST),
|
vect_pset(&vp, RNG(MIN_HYPERSPACE_DIST, MIN_HYPERSPACE_DIST*1.5),
|
||||||
RNG(0, 360)*M_PI/180.);
|
RNG(0, 360)*M_PI/180.);
|
||||||
vectnull(&vn);
|
vectnull(&vn);
|
||||||
|
|
||||||
for(i = 0; i < fleet->npilots; i++)
|
for(i = 0; i < fleet->npilots; i++)
|
||||||
if(RNG(0, 100) <= fleet->pilots[i].chance) {
|
if(RNG(0, 100) <= fleet->pilots[i].chance) {
|
||||||
vect_cadd(&v, RNG(75, 150) * (RNG(0,1) ? 1 : -1),
|
vect_cadd(&vp, RNG(75, 150) * (RNG(0,1) ? 1 : -1),
|
||||||
RNG(75, 150) * (RNG(0,1) ? 1 : -1));
|
RNG(75, 150) * (RNG(0,1) ? 1 : -1));
|
||||||
|
|
||||||
|
a = vect_angle(&vp, &vn);
|
||||||
|
vectnull(&vv);
|
||||||
|
|
||||||
pilot_create(fleet->pilots[i].ship,
|
pilot_create(fleet->pilots[i].ship,
|
||||||
fleet->pilots[i].name,
|
fleet->pilots[i].name,
|
||||||
fleet->faction,
|
fleet->faction,
|
||||||
fleet->ai,
|
fleet->ai,
|
||||||
vect_angle(&v, &vn),
|
a,
|
||||||
&v,
|
&vp,
|
||||||
NULL,
|
&vv,
|
||||||
0);
|
0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
21
src/weapon.c
21
src/weapon.c
@ -37,7 +37,7 @@ typedef struct Weapon_ {
|
|||||||
|
|
||||||
// Update position and render.
|
// Update position and render.
|
||||||
void(*update)(struct Weapon_*, const double, WeaponLayer); // Position update and render.
|
void(*update)(struct Weapon_*, const double, WeaponLayer); // Position update and render.
|
||||||
void(*think)(struct Weapon_*); // Some missiles need to be inteligent.
|
void(*think)(struct Weapon_*, const double); // Some missiles need to be inteligent.
|
||||||
} Weapon;
|
} Weapon;
|
||||||
|
|
||||||
// Behind Pilot layer.
|
// Behind Pilot layer.
|
||||||
@ -60,7 +60,8 @@ static void weapon_hit(Weapon* w, Pilot* p, WeaponLayer layer);
|
|||||||
static void weapon_destroy(Weapon* w, WeaponLayer layer);
|
static void weapon_destroy(Weapon* w, WeaponLayer layer);
|
||||||
static void weapon_free(Weapon* w);
|
static void weapon_free(Weapon* w);
|
||||||
// Think.
|
// Think.
|
||||||
static void think_seeker(Weapon* w);
|
static void think_seeker(Weapon* w, const double dt);
|
||||||
|
static void think_smart(Weapon* w, const double dt);
|
||||||
|
|
||||||
// Draw the minimap weapons (player.c).
|
// Draw the minimap weapons (player.c).
|
||||||
#define PIXEL(x,y) if((shape == RADAR_RECT && ABS(x) < w/2. && ABS(y)<h/2.) || \
|
#define PIXEL(x,y) if((shape == RADAR_RECT && ABS(x) < w/2. && ABS(y)<h/2.) || \
|
||||||
@ -115,13 +116,13 @@ void weapons_delay(unsigned int delay) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Seeker brain, You get what you pay for. :)
|
// Seeker brain, You get what you pay for. :)
|
||||||
static void think_seeker(Weapon* w) {
|
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.
|
if(w->target == w->parent) return; // HEY! Self harm is not allowed.
|
||||||
|
|
||||||
Pilot* p = pilot_get(w->target);
|
Pilot* p = pilot_get(w->target);
|
||||||
if(p == NULL) {
|
if(p == NULL) {
|
||||||
limit_speed(&w->solid->vel, w->outfit->u.amm.speed);
|
limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -138,11 +139,11 @@ static void think_seeker(Weapon* w) {
|
|||||||
|
|
||||||
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);
|
limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Smart seeker brain. Much better at homing.
|
// Smart seeker brain. Much better at homing.
|
||||||
static void think_smart(Weapon* w) {
|
static void think_smart(Weapon* w, const double dt) {
|
||||||
double diff;
|
double diff;
|
||||||
Vec2 tv, sv;
|
Vec2 tv, sv;
|
||||||
|
|
||||||
@ -151,7 +152,7 @@ static void think_smart(Weapon* w) {
|
|||||||
Pilot* p = pilot_get(w->target); // No null pilots..
|
Pilot* p = pilot_get(w->target); // No null pilots..
|
||||||
|
|
||||||
if(p == NULL) {
|
if(p == NULL) {
|
||||||
limit_speed(&w->solid->vel, w->outfit->u.amm.speed);
|
limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,7 +171,7 @@ static void think_smart(Weapon* w) {
|
|||||||
|
|
||||||
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);
|
limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -290,7 +291,9 @@ static void weapon_update(Weapon* w, const double dt, WeaponLayer layer) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(weapon_isSmart(w)) (*w->think)(w);
|
|
||||||
|
if(weapon_isSmart(w)) (*w->think)(w,dt);
|
||||||
|
|
||||||
(*w->solid->update)(w->solid, dt);
|
(*w->solid->update)(w->solid, dt);
|
||||||
|
|
||||||
// Update the sound.
|
// Update the sound.
|
||||||
|
Loading…
Reference in New Issue
Block a user