[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>
|
||||
</specific>
|
||||
</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>
|
||||
|
||||
|
7
src/ai.c
7
src/ai.c
@ -556,12 +556,15 @@ static int ai_getpos(lua_State* L) {
|
||||
// ==> 180.*360./cur_pilot->turn
|
||||
// Add it to general euler equation x = v*t + 0.5 * a * t^2
|
||||
// Have fun.
|
||||
//
|
||||
// I really hate this function. Why isn't it depricated yet?
|
||||
// ========================================================
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
lua_pushnumber(L, dist); // return
|
||||
|
@ -44,12 +44,15 @@ if(lua_isstring(L, -1)) { \
|
||||
}
|
||||
|
||||
// Some crap from main.
|
||||
extern int nosound;
|
||||
extern int show_fps;
|
||||
extern int max_fps;
|
||||
extern int indjoystick;
|
||||
extern char* namjoystick;
|
||||
// From player.c
|
||||
extern const char* keybindNames[]; // Keybindings.
|
||||
// input.c.
|
||||
extern unsigned int input_afterburnSensibility;
|
||||
|
||||
static void print_usage(char** argv);
|
||||
|
||||
@ -115,6 +118,9 @@ int conf_loadConfig(const char* file) {
|
||||
conf_loadBool("showfps", show_fps);
|
||||
conf_loadInt("maxfps", max_fps);
|
||||
|
||||
// Input.
|
||||
conf_loadInt("afterburn", input_afterburnSensibility);
|
||||
|
||||
// Sound.
|
||||
conf_loadFloat("sound", d);
|
||||
if(d) { sound_volume(d); d = 0.; }
|
||||
|
21
src/input.c
21
src/input.c
@ -23,14 +23,18 @@ static Keybind** input_keybinds; // Contains the players keybindings.
|
||||
|
||||
|
||||
// Name of each keybinding.
|
||||
const char* keybindNames[] =
|
||||
{ "accel", "left", "right", "reverse", // Movement.
|
||||
const char* keybindNames[] = {
|
||||
"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.
|
||||
"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
|
||||
extern double player_turn;
|
||||
extern double player_acc;
|
||||
@ -46,7 +50,6 @@ void input_setDefault(void) {
|
||||
input_setKeybind("left", KEYBIND_KEYBOARD, SDLK_a, 0);
|
||||
input_setKeybind("right", KEYBIND_KEYBOARD, SDLK_d, 0);
|
||||
input_setKeybind("reverse", KEYBIND_KEYBOARD, SDLK_s, 0);
|
||||
|
||||
// Combat.
|
||||
input_setKeybind("primary", KEYBIND_KEYBOARD, SDLK_SPACE, 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_HYPERSPACE))
|
||||
static void input_key(int keynum, double value, int abs) {
|
||||
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.
|
||||
|
||||
if(value == KEY_PRESS) input_accelLast = t;
|
||||
}
|
||||
// Turning left.
|
||||
else if(KEY("left")) {
|
||||
|
@ -295,7 +295,11 @@ static void outfits_buy(char* str) {
|
||||
toolkit_alert("You can only carry %d of this outfit.", outfit->max);
|
||||
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) {
|
||||
credits2str(buf, q*outfit->price - player_credits, 2);
|
||||
toolkit_alert("You need %s more SCred.", buf);
|
||||
|
40
src/outfit.c
40
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_parseSAmmo(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.
|
||||
Outfit* outfit_get(const char* name) {
|
||||
@ -95,6 +96,11 @@ int outfit_isMod(const Outfit* o) {
|
||||
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.
|
||||
glTexture* outfit_gfx(const Outfit* o) {
|
||||
if(outfit_isWeapon(o)) return o->u.blt.gfx_space;
|
||||
@ -155,7 +161,8 @@ const char* outfit_typename[] = {
|
||||
"Smart Swarm Missile Ammunition Pack",
|
||||
"Bolt Turret",
|
||||
"Beam Turret",
|
||||
"Modification"
|
||||
"Ship Modification",
|
||||
"Afterburner"
|
||||
};
|
||||
|
||||
const char* outfit_getType(const Outfit* o) {
|
||||
@ -169,7 +176,8 @@ const char* outfit_typenamebroad[] = {
|
||||
"Launcher",
|
||||
"Ammo",
|
||||
"Turret",
|
||||
"Modification"
|
||||
"Modification",
|
||||
"Afterburner"
|
||||
};
|
||||
|
||||
const char* outfit_getTypeBroad(const Outfit* o) {
|
||||
@ -179,6 +187,7 @@ const char* outfit_getTypeBroad(const Outfit* o) {
|
||||
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];
|
||||
}
|
||||
@ -295,7 +304,7 @@ static void outfit_parseSAmmo(Outfit* tmp, const xmlNodePtr parent) {
|
||||
|
||||
static void outfit_parseSMod(Outfit* tmp, const xmlNodePtr parent) {
|
||||
xmlNodePtr node;
|
||||
node = parent->xmlChildrenNode;
|
||||
node = parent->children;
|
||||
|
||||
// Load all the data.
|
||||
do {
|
||||
@ -324,6 +333,29 @@ static void outfit_parseSMod(Outfit* tmp, const xmlNodePtr parent) {
|
||||
} 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.
|
||||
static Outfit* outfit_parse(const xmlNodePtr parent) {
|
||||
Outfit* tmp = CALLOC_L(Outfit);
|
||||
@ -381,6 +413,8 @@ static Outfit* outfit_parse(const xmlNodePtr parent) {
|
||||
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)
|
||||
|
@ -23,7 +23,8 @@ typedef enum OutfitType_ {
|
||||
OUTFIT_TYPE_MISSILE_SWARM_SMART_AMMO = 12,
|
||||
OUTFIT_TYPE_TURRET_BOLT = 13,
|
||||
OUTFIT_TYPE_TURRET_BEAM = 14,
|
||||
OUTFIT_TYPE_MODIFICATION = 15
|
||||
OUTFIT_TYPE_MODIFICATION = 15,
|
||||
OUTFIT_TYPE_AFTERBURNER = 16
|
||||
} OutfitType;
|
||||
|
||||
// An outfit depends a lot on the type.
|
||||
@ -90,6 +91,11 @@ typedef struct Outfit_ {
|
||||
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;
|
||||
|
||||
@ -102,6 +108,7 @@ int outfit_isLauncher(const Outfit* o);
|
||||
int outfit_isAmmo(const Outfit* o);
|
||||
int outfit_isTurret(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_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;
|
||||
}
|
||||
|
||||
void limit_speed(Vec2* vel, const double speed) {
|
||||
if(VMOD(*vel) > speed) // Should not go faster.
|
||||
vect_pset(vel, speed, VANGLE(*vel));
|
||||
}
|
||||
|
||||
void limit_speeddt(Vec2* vel, const double speed, const double dt) {
|
||||
double vmod;
|
||||
vmod = VMOD(*vel);
|
||||
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));
|
||||
}
|
||||
|
@ -22,8 +22,7 @@ typedef struct Vec2_ {
|
||||
|
||||
// Misc
|
||||
double angle_diff(const double ref, double a);
|
||||
void limit_speed(Vec2* vel, const double speed);
|
||||
void limit_speeddt(Vec2* vel, const double speed, const double dt);
|
||||
void limit_speed(Vec2* vel, const double speed, const double dt);
|
||||
|
||||
// Vector manupulation.
|
||||
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,
|
||||
pilot->ship->gfx_space, pilot->solid->dir);
|
||||
|
||||
if(!pilot_isFlag(pilot, PILOT_HYPERSPACE))
|
||||
// Should not go faster.
|
||||
limit_speeddt(&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.
|
||||
@ -482,6 +489,9 @@ int pilot_rmOutfit(Pilot* pilot, Outfit* outfit, int quantity) {
|
||||
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,
|
||||
@ -524,7 +534,7 @@ static void pilot_calcStats(Pilot* pilot) {
|
||||
pilot->energy_regen = pilot->ship->energy_regen;
|
||||
|
||||
// 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)) {
|
||||
q = (double) pilot->outfits[i].quantity;
|
||||
o = pilot->outfits[i].outfit;
|
||||
@ -542,6 +552,11 @@ static void pilot_calcStats(Pilot* pilot) {
|
||||
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.
|
||||
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->secondary = NULL;
|
||||
pilot->ammo = NULL;
|
||||
pilot->afterburner = NULL;
|
||||
ShipOutfit* so;
|
||||
if(ship->outfit) {
|
||||
pilot->noutfits = 0;
|
||||
|
@ -30,6 +30,7 @@
|
||||
// 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_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.
|
||||
@ -83,6 +84,7 @@ typedef struct Pilot_ {
|
||||
int noutfits;
|
||||
PilotOutfit* secondary; // Secondary weapon.
|
||||
PilotOutfit* ammo; // Secondary ammo (if needed).
|
||||
PilotOutfit* afterburner; // Ze afterburner.
|
||||
|
||||
// Cargo.
|
||||
int credits; // Moniez the pilot has.
|
||||
|
25
src/player.c
25
src/player.c
@ -907,6 +907,11 @@ 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);
|
||||
|
||||
@ -1055,8 +1060,8 @@ void player_brokeHyperspace(void) {
|
||||
space_init(systems_stack[cur_system->jumps[hyperspace_target]].name);
|
||||
|
||||
// Set position, pilot_update will handle the lowering of velocity.
|
||||
player_warp(-cos(player->solid->dir) * MIN_HYPERSPACE_DIST * 1.5,
|
||||
-sin(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 * 2.5);
|
||||
|
||||
// Stop hyperspace.
|
||||
pilot_rmFlag(player, PILOT_HYPERSPACE | PILOT_HYP_BEGIN | PILOT_HYP_PREP);
|
||||
@ -1075,6 +1080,22 @@ double player_faceHyperspace(void) {
|
||||
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.
|
||||
static int screenshot_cur = 0;
|
||||
void player_screenshot(void) {
|
||||
|
@ -5,6 +5,7 @@
|
||||
#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_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.
|
||||
@ -52,4 +53,6 @@ void player_land(void);
|
||||
void player_targetHyperspace(void);
|
||||
void player_jump(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.
|
||||
static void space_addFleet(Fleet* fleet) {
|
||||
int i;
|
||||
Vec2 v, vn;
|
||||
double a;
|
||||
Vec2 vv, vp, vn;
|
||||
|
||||
// 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.);
|
||||
vectnull(&vn);
|
||||
|
||||
for(i = 0; i < fleet->npilots; i++)
|
||||
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));
|
||||
|
||||
a = vect_angle(&vp, &vn);
|
||||
vectnull(&vv);
|
||||
|
||||
pilot_create(fleet->pilots[i].ship,
|
||||
fleet->pilots[i].name,
|
||||
fleet->faction,
|
||||
fleet->ai,
|
||||
vect_angle(&v, &vn),
|
||||
&v,
|
||||
NULL,
|
||||
a,
|
||||
&vp,
|
||||
&vv,
|
||||
0);
|
||||
}
|
||||
}
|
||||
|
21
src/weapon.c
21
src/weapon.c
@ -37,7 +37,7 @@ typedef struct Weapon_ {
|
||||
|
||||
// Update position 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;
|
||||
|
||||
// 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_free(Weapon* w);
|
||||
// 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).
|
||||
#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. :)
|
||||
static void think_seeker(Weapon* w) {
|
||||
static void think_seeker(Weapon* w, const double dt) {
|
||||
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);
|
||||
limit_speed(&w->solid->vel, w->outfit->u.amm.speed, dt);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -138,11 +139,11 @@ static void think_seeker(Weapon* w) {
|
||||
|
||||
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.
|
||||
static void think_smart(Weapon* w) {
|
||||
static void think_smart(Weapon* w, const double dt) {
|
||||
double diff;
|
||||
Vec2 tv, sv;
|
||||
|
||||
@ -151,7 +152,7 @@ static void think_smart(Weapon* w) {
|
||||
Pilot* p = pilot_get(w->target); // No null pilots..
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
@ -170,7 +171,7 @@ static void think_smart(Weapon* w) {
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
if(weapon_isSmart(w)) (*w->think)(w);
|
||||
|
||||
if(weapon_isSmart(w)) (*w->think)(w,dt);
|
||||
|
||||
(*w->solid->update)(w->solid, dt);
|
||||
|
||||
// Update the sound.
|
||||
|
Loading…
Reference in New Issue
Block a user