[Add] Added explosions, only being used on deaths right now.

This commit is contained in:
Allanis 2013-11-24 21:56:40 +00:00
parent 4e054e3cf4
commit 05b1d19e55
6 changed files with 217 additions and 5 deletions

87
src/explosion.c Normal file
View File

@ -0,0 +1,87 @@
/**
* @file explosion.c
*/
#include "lephisto.h"
#include "log.h"
#include "pilot.h"
#include "weapon.h"
#include "spfx.h"
#include "rng.h"
#include "explosion.h"
/**
* @fn void expl_explode(double x, double y, double vx, double vy,
* double radius, DamageType dtype, double damage,
* unsigned int parent, int mode)
*
* @brief
*/
void expl_explode(double x, double y, double vx, double vy,
double radius, DamageType dtype, double damage,
unsigned int parent, int mode) {
int i, n;
double a, d;
double area;
double ex, ey;
double layer;
int efx;
int exp_s, exp_m, exp_l;
/* Standard stuff. */
exp_s = spfx_get("ExpS");
exp_m = spfx_get("ExpM");
exp_s = spfx_get("ExpL");
layer = SPFX_LAYER_FRONT;
/* Number of explosions. */
area = M_PI * pow2(radius);
n = (int)(area / 100.);
/* Create explosions. */
for(i = 0; i < n; i++) {
/* Get position. */
a = RNGF()*360.;
d = RNGF()*(radius-5.) + 5.;
ex = d*cos(a);
ey = d*sin(a);
/* Create explosion. */
efx = (RNG(0,2)==0) ? exp_m : exp_s;
spfx_add(efx, x+ex, y+ey, vx, vy, layer);
}
/* Final explosion. */
spfx_add(exp_l, x, y, vx, vy, layer);
/* Run the damage. */
if(damage > 0.)
expl_explodeDamage(x, y, radius, dtype, damage, parent, mode);
}
/**
* @fn
*
* @brief
*/
void expl_explodeDamage(double x, double y, double radius,
DamageType dtype, double damage,
unsigned int parent, int mode) {
/* Explosion affects ships. */
if(mode & EXPL_MODE_SHIP)
pilot_explode(x, y, radius, dtype, damage, parent);
/* Explosion affects missiles and bolts. */
if((mode & EXPL_MODE_MISSILE) && (mode & EXPL_MODE_BOLT))
weapon_explode(x, y, radius, dtype, damage, parent, mode);
/* Explosion affects missiles. */
else if(mode & EXPL_MODE_MISSILE)
weapon_explode(x, y, radius, dtype, damage, parent, mode);
/* Explosion affects bolts. */
else if(mode & EXPL_MODE_BOLT)
weapon_explode(x, y, radius, dtype, damage, parent, mode);
}

15
src/explosion.h Normal file
View File

@ -0,0 +1,15 @@
#pragma once
#include "outfit.h"
#define EXPL_MODE_SHIP (1<<0) /**< Affects ships. */
#define EXPL_MODE_MISSILE (1<<1) /**< Affects missiles. */
#define EXPL_MODE_BOLT (1<<2) /**< Affects bots. */
void expl_explode(double x, double y, double vx, double vy,
double radius, DamageType dtype, double damage,
unsigned int parent, int mode);
void expl_explodeDamage(double x, double y, double radius,
DamageType dtype, double damage,
unsigned int parent, int mode);

View File

@ -17,6 +17,7 @@
#include "rng.h" #include "rng.h"
#include "hook.h" #include "hook.h"
#include "map.h" #include "map.h"
#include "explosion.h"
#include "pilot.h" #include "pilot.h"
#define XML_ID "Fleets" /**< XML document identifier. */ #define XML_ID "Fleets" /**< XML document identifier. */
@ -554,6 +555,40 @@ void pilot_setAfterburner(Pilot* p) {
p->afterburner = NULL; p->afterburner = NULL;
} }
/**
*/
void pilot_explode(double x, double y, double radius,
DamageType dtype, double damage, unsigned int parent) {
int i;
double rx, ry;
double dist, rad2;
Pilot* p;
Solid s; /* Only need to manipulate mass and vel. */
rad2 = radius*radius;
for(i = 0; i < pilot_nstack; i++) {
p = pilot_stack[i];
/* Calculate a bit. */
rx = p->solid->pos.x - x;
ry = p->solid->pos.y - y;
dist = pow2(rx) + pow2(ry);
/* Pilot is hit. */
if(dist < rad2) {
/* Impact settings. */
s.mass = (rad2 - dist) / 10.;
s.vel.x = rx;
s.vel.y = ry;
/* Actual damage calculations. */
pilot_hit(p, &s, parent, dtype, damage);
}
}
}
/** /**
* @fn void pilot_render(Pilot* p) * @fn void pilot_render(Pilot* p)
* *
@ -601,9 +636,13 @@ static void pilot_update(Pilot* pilot, const double dt) {
/* Final explosion. */ /* Final explosion. */
else if(!pilot_isFlag(pilot, PILOT_EXPLODED) && (t > pilot->ptimer - 200)) { else if(!pilot_isFlag(pilot, PILOT_EXPLODED) && (t > pilot->ptimer - 200)) {
spfx_add(spfx_get("ExpL"), /* Damage from explosion. */
VX(pilot->solid->pos), VY(pilot->solid->pos), a = sqrt(pilot->solid->mass);
VX(pilot->solid->vel), VY(pilot->solid->vel), SPFX_LAYER_BACK); expl_explode(pilot->solid->pos.x, pilot->solid->pos.y,
pilot->solid->vel.x, pilot->solid->vel.y,
pilot->ship->gfx_space->sw / 2. + a,
DAMAGE_TYPE_KINETIC, 2.*a - 20.,
0, EXPL_MODE_SHIP);
pilot_setFlag(pilot, PILOT_EXPLODED); pilot_setFlag(pilot, PILOT_EXPLODED);
/* Release cargo. */ /* Release cargo. */

View File

@ -219,13 +219,17 @@ void pilot_shoot(Pilot* p, const unsigned int target, const int secondary);
void pilot_shootStop(Pilot* p, const int secondary); void pilot_shootStop(Pilot* p, const int secondary);
void pilot_hit(Pilot* p, const Solid* w, const unsigned int shooter, void pilot_hit(Pilot* p, const Solid* w, const unsigned int shooter,
const DamageType dtype, const double damage); const DamageType dtype, const double damage);
double pilot_face(Pilot* p, const double dir);
void pilot_hyperspaceAbort(Pilot* p);
/* Special outfit stuff. */
void pilot_switchSecondary(Pilot* p, int i); void pilot_switchSecondary(Pilot* p, int i);
void pilot_setSecondary(Pilot* p, const char* secondary); void pilot_setSecondary(Pilot* p, const char* secondary);
void pilot_setAmmo(Pilot* p); void pilot_setAmmo(Pilot* p);
int pilot_getAmmo(Pilot* p, Outfit* o); int pilot_getAmmo(Pilot* p, Outfit* o);
void pilot_setAfterburner(Pilot* p); void pilot_setAfterburner(Pilot* p);
double pilot_face(Pilot* p, const double dir); /* Explosion. */
void pilot_hyperspaceAbort(Pilot* p); void pilot_explode(double x, double y, double radius,
DamageType dtype, double damage, unsigned int parent);
/* Outfits. */ /* Outfits. */
int pilot_freeSpace(Pilot* p); /* Pilot space. */ int pilot_freeSpace(Pilot* p); /* Pilot space. */
int pilot_addOutfit(Pilot* pilot, Outfit* outfit, int quantity); int pilot_addOutfit(Pilot* pilot, Outfit* outfit, int quantity);

View File

@ -21,6 +21,7 @@
#include "player.h" #include "player.h"
#include "spfx.h" #include "spfx.h"
#include "opengl.h" #include "opengl.h"
#include "explosion.h"
#include "weapon.h" #include "weapon.h"
#define weapon_isSmart(w) (w->think != NULL) /**< Checks if the weapon w is smart. */ #define weapon_isSmart(w) (w->think != NULL) /**< Checks if the weapon w is smart. */
@ -98,6 +99,9 @@ static void weapon_hitBeam(Weapon* w, Pilot* p, WeaponLayer layer,
Vec2 pos[2], const double dt); Vec2 pos[2], const double dt);
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);
static void weapon_explodeLayer(WeaponLayer layer,
double x, double y, double radius,
unsigned int parent, int mode);
/* Think. */ /* Think. */
static void think_seeker(Weapon* w, const double dt); static void think_seeker(Weapon* w, const double dt);
static void think_beam(Weapon* w, const double dt); static void think_beam(Weapon* w, const double dt);
@ -1039,3 +1043,62 @@ void weapon_exit(void) {
} }
} }
/**
* @fn void weapon_explode(double x, double y, double radius,
DamageType dtype, double damage,
unsigned int parent, int mode)
@brief Clear possible exploded weapons.
*/
void weapon_explode(double x, double y, double radius,
DamageType dtype, double damage,
unsigned int parent, int mode) {
(void)dtype;
(void)damage;
weapon_explodeLayer(WEAPON_LAYER_FG, x, y, radius, parent, mode);
weapon_explodeLayer(WEAPON_LAYER_BG, x, y, radius, parent, mode);
}
static void weapon_explodeLayer(WeaponLayer layer,
double x, double y, double radius,
unsigned int parent, int mode) {
(void)parent;
int i;
Weapon** curLayer;
int *nLayer;
double dist, rad2;
/* Set the proper layer. */
switch(layer) {
case WEAPON_LAYER_BG:
curLayer = wbackLayer;
nLayer = &nwbackLayer;
break;
case WEAPON_LAYER_FG:
curLayer = wfrontLayer;
nLayer = &nwbackLayer;
break;
default:
ERR("Invalid WEAPON_LAYER specified.");
return;
}
rad2 = radius*radius;
/* Now try to destroy the weapons affected. */
for(i = 0; i < *nLayer; i++) {
if(((mode & EXPL_MODE_MISSILE) && outfit_isAmmo(curLayer[i]->outfit)) ||
((mode & EXPL_MODE_BOLT) && outfit_isBolt(curLayer[i]->outfit))) {
dist = pow2(curLayer[i]->solid->pos.x - x) +
pow2(curLayer[i]->solid->pos.y - y);
if(dist < rad2) {
weapon_destroy(curLayer[i], layer);
i--;
}
}
}
}

View File

@ -22,6 +22,10 @@ int beam_start(const Outfit* outfit,
void beam_end(const unsigned int parent, int beam); void beam_end(const unsigned int parent, int beam);
void weapon_explode(double x, double y, double radius,
DamageType dtype, double damage,
unsigned int parent, int mode);
/* Update. */ /* Update. */
void weapons_update(const double dt); void weapons_update(const double dt);
void weapons_render(const WeaponLayer layer); void weapons_render(const WeaponLayer layer);