[Add] Added outfit states and beam hit function. Also added compile option for clang.
This commit is contained in:
parent
06ea30d96e
commit
71ab2d863f
@ -5,6 +5,8 @@ DEBUG = 1
|
|||||||
OS := LINUX
|
OS := LINUX
|
||||||
#OS := WIN32
|
#OS := WIN32
|
||||||
|
|
||||||
|
#CC = clang
|
||||||
|
|
||||||
# VERSION.
|
# VERSION.
|
||||||
VMAJOR = 0
|
VMAJOR = 0
|
||||||
VMINOR = 0
|
VMINOR = 0
|
||||||
|
23
src/pilot.c
23
src/pilot.c
@ -204,15 +204,18 @@ int pilot_freeSpace(Pilot* p) {
|
|||||||
/* Mkay, this is how we shoot. Listen up. */
|
/* Mkay, this is how we shoot. Listen up. */
|
||||||
void pilot_shoot(Pilot* p, const unsigned int target, const int secondary) {
|
void pilot_shoot(Pilot* p, const unsigned int target, const int secondary) {
|
||||||
int i;
|
int i;
|
||||||
|
Outfit* o;
|
||||||
|
|
||||||
if(!p->outfits) return; /* No outfits. */
|
if(!p->outfits) return; /* No outfits. */
|
||||||
|
|
||||||
if(!secondary) {
|
if(!secondary) {
|
||||||
/* Primary weapons. */
|
/* Primary weapons. */
|
||||||
for(i = 0; i < p->noutfits; i++)
|
for(i = 0; i < p->noutfits; i++) {
|
||||||
/* Cycle through outfits to find primary weapons. */
|
o = p->outfits[i].outfit;
|
||||||
if(!outfit_isProp(p->outfits[i].outfit, OUTFIT_PROP_WEAP_SECONDARY))
|
if(!outfit_isProp(o, OUTFIT_PROP_WEAP_SECONDARY) &&
|
||||||
|
(outfit_isBolt(o) || outfit_isBeam(o))) /** @todo Possibly make the neater. */
|
||||||
pilot_shootWeapon(p, &p->outfits[i], target);
|
pilot_shootWeapon(p, &p->outfits[i], target);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if(!p->secondary) return; /* No secondary weapon. */
|
if(!p->secondary) return; /* No secondary weapon. */
|
||||||
pilot_shootWeapon(p, p->secondary, target);
|
pilot_shootWeapon(p, p->secondary, target);
|
||||||
@ -243,14 +246,16 @@ static void pilot_shootWeapon(Pilot* p, PilotOutfit* w, const unsigned int t) {
|
|||||||
p->energy -= outfit_energy(w->outfit);
|
p->energy -= outfit_energy(w->outfit);
|
||||||
weapon_add(w->outfit, p->solid->dir,
|
weapon_add(w->outfit, p->solid->dir,
|
||||||
&p->solid->pos, &p->solid->vel, p->id, t);
|
&p->solid->pos, &p->solid->vel, p->id, t);
|
||||||
|
|
||||||
/* Can't shoot it for a bit. */
|
|
||||||
w->timer = SDL_GetTicks();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Beam Weapons. */
|
/* Beam Weapons. */
|
||||||
else if(outfit_isBeam(w->outfit)) {
|
else if(outfit_isBeam(w->outfit)) {
|
||||||
|
if(outfit_energy(w->outfit) > p->energy) return;
|
||||||
|
|
||||||
|
/** @todo Handle warmup stage. */
|
||||||
|
w->state = PILOT_OUTFIT_ON;
|
||||||
|
weapon_add(w->outfit, p->solid->dir,
|
||||||
|
&p->solid->pos, NULL, p->id, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -275,9 +280,13 @@ static void pilot_shootWeapon(Pilot* p, PilotOutfit* w, const unsigned int t) {
|
|||||||
weapon_add(p->ammo->outfit, p->solid->dir, &p->solid->pos,
|
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. */
|
p->ammo->quantity -= 1; /* There's no getting this one back. */
|
||||||
|
} else {
|
||||||
|
WARN("Shooting unknown weapon type: %s", w->outfit->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Update the weapon last used timer. */
|
||||||
|
w->timer = SDL_GetTicks();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
21
src/pilot.h
21
src/pilot.h
@ -53,16 +53,29 @@
|
|||||||
#define pilot_isPlayer(p) ((p)->flags & PILOT_PLAYER) /**< Check if pilot is a player. */
|
#define pilot_isPlayer(p) ((p)->flags & PILOT_PLAYER) /**< Check if pilot is a player. */
|
||||||
#define pilot_isDisabled(p) ((p)->flags & PILOT_DISABLED) /**< Check if pilot is disabled. */
|
#define pilot_isDisabled(p) ((p)->flags & PILOT_DISABLED) /**< Check if pilot is disabled. */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @enum PilotOutfitState
|
||||||
|
*
|
||||||
|
* @brief Contains the state of the outfit.
|
||||||
|
*
|
||||||
|
* Currently only applicable to beam weapons.
|
||||||
|
*/
|
||||||
|
typedef enum PilotOutfitState_ {
|
||||||
|
PILOT_OUTFIT_OFF, /**< Normal state. */
|
||||||
|
PILOT_OUTFIT_WARMUP, /**< Outfit is starting to warm up. */
|
||||||
|
PILOT_OUTFIT_ON /**< Outfit is activated and running. */
|
||||||
|
} PilotOutfitState;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @struct PilotOutfit
|
* @struct PilotOutfit
|
||||||
*
|
*
|
||||||
* @brief Store an outfit the pilot has.
|
* @brief Store an outfit the pilot has.
|
||||||
*/
|
*/
|
||||||
typedef struct PilotOutfit_ {
|
typedef struct PilotOutfit_ {
|
||||||
Outfit* outfit; /**< Associated outfit. */
|
Outfit* outfit; /**< Associated outfit. */
|
||||||
int quantity; /**< Number of outfits of this type that the pilot has. */
|
int quantity; /**< Number of outfits of this type that the pilot has. */
|
||||||
|
PilotOutfitState state; /**< State of the outfit. */
|
||||||
unsigned int timer; /**< Used to store last used weapon time. */
|
unsigned int timer; /**< Used to store last used weapon time. */
|
||||||
} PilotOutfit;
|
} PilotOutfit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
112
src/weapon.c
112
src/weapon.c
@ -11,6 +11,7 @@
|
|||||||
#include "collision.h"
|
#include "collision.h"
|
||||||
#include "player.h"
|
#include "player.h"
|
||||||
#include "spfx.h"
|
#include "spfx.h"
|
||||||
|
#include "opengl.h"
|
||||||
#include "weapon.h"
|
#include "weapon.h"
|
||||||
|
|
||||||
#define weapon_isSmart(w) (w->think != NULL)
|
#define weapon_isSmart(w) (w->think != NULL)
|
||||||
@ -22,7 +23,11 @@
|
|||||||
#define WEAPON_STATUS_JAMMED 1 /* Got jammed. */
|
#define WEAPON_STATUS_JAMMED 1 /* Got jammed. */
|
||||||
#define WEAPON_STATUS_UNJAMMED 2 /* Surviving jaming. */
|
#define WEAPON_STATUS_UNJAMMED 2 /* Surviving jaming. */
|
||||||
|
|
||||||
/* Some stuff from pilot. */
|
/* OpenGL stuff. */
|
||||||
|
extern Vec2* gl_camera;
|
||||||
|
extern double gui_xoff, gui_yoff;
|
||||||
|
|
||||||
|
/* Pilot stuff. */
|
||||||
extern Pilot** pilot_stack;
|
extern Pilot** pilot_stack;
|
||||||
extern int pilot_nstack;
|
extern int pilot_nstack;
|
||||||
|
|
||||||
@ -69,6 +74,8 @@ static void weapon_render(const Weapon* w);
|
|||||||
static void weapons_updateLayer(const double dt, const WeaponLayer layer);
|
static void weapons_updateLayer(const double dt, const WeaponLayer layer);
|
||||||
static void weapon_update(Weapon* w, const double dt, WeaponLayer layer);
|
static void weapon_update(Weapon* w, const double dt, WeaponLayer layer);
|
||||||
static void weapon_hit(Weapon* w, Pilot* p, WeaponLayer layer, Vec2* pos);
|
static void weapon_hit(Weapon* w, Pilot* p, WeaponLayer layer, Vec2* pos);
|
||||||
|
static void weapon_hitBeam(Weapon* w, Pilot* p, WeaponLayer layer,
|
||||||
|
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);
|
||||||
/* Think. */
|
/* Think. */
|
||||||
@ -80,8 +87,20 @@ void weapon_minimap(const double res, const double w,
|
|||||||
const double h, const RadarShape shape);
|
const double h, const RadarShape shape);
|
||||||
|
|
||||||
/* 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) \
|
||||||
(shape == RADAR_CIRCLE && (((x)*(x)+(y)*(y))<rc))) glVertex2i((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)) /**< Set a pixel if within range. */
|
||||||
|
/**
|
||||||
|
* @fn void weapon_minimap(const double res, const double w,
|
||||||
|
* const double h, const RadarShape shape)
|
||||||
|
*
|
||||||
|
* @brief Draw the minimap weapons (used in player.c).
|
||||||
|
* @param res Minimap resolution.
|
||||||
|
* @param w Width of minimap.
|
||||||
|
* @param h Height of minimap.
|
||||||
|
* @param shape Shape of the minimap.
|
||||||
|
*/
|
||||||
void weapon_minimap(const double res, const double w,
|
void weapon_minimap(const double res, const double w,
|
||||||
const double h, const RadarShape shape) {
|
const double h, const RadarShape shape) {
|
||||||
int i, rc;
|
int i, rc;
|
||||||
@ -296,6 +315,7 @@ void weapons_render(const WeaponLayer layer) {
|
|||||||
/* Render the weapons. */
|
/* Render the weapons. */
|
||||||
static void weapon_render(const Weapon* w) {
|
static void weapon_render(const Weapon* w) {
|
||||||
int sx, sy;
|
int sx, sy;
|
||||||
|
double x, y;
|
||||||
glTexture* gfx;
|
glTexture* gfx;
|
||||||
|
|
||||||
switch(w->outfit->type) {
|
switch(w->outfit->type) {
|
||||||
@ -315,10 +335,13 @@ static void weapon_render(const Weapon* w) {
|
|||||||
/* Beam weapons. */
|
/* Beam weapons. */
|
||||||
case OUTFIT_TYPE_BEAM:
|
case OUTFIT_TYPE_BEAM:
|
||||||
case OUTFIT_TYPE_TURRET_BEAM:
|
case OUTFIT_TYPE_TURRET_BEAM:
|
||||||
|
x = w->solid->pos.x - VX(*gl_camera) + gui_xoff;
|
||||||
|
y = w->solid->pos.y - VY(*gl_camera) + gui_yoff;
|
||||||
|
COLOUR(*w->outfit->u.bem.colour);
|
||||||
glBegin(GL_LINES);
|
glBegin(GL_LINES);
|
||||||
glVertex2d(w->solid->pos.x, w->solid->pos.y);
|
glVertex2d(x, y);
|
||||||
glVertex2d(w->solid->pos.x + w->outfit->u.bem.range*cos(w->solid->dir),
|
glVertex2d(x + w->outfit->u.bem.range * cos(w->solid->dir),
|
||||||
w->solid->pos.y + w->outfit->u.bem.range*sin(w->solid->dir));
|
y + w->outfit->u.bem.range * sin(w->solid->dir));
|
||||||
glEnd();
|
glEnd();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -335,10 +358,6 @@ static void weapon_update(Weapon* w, const double dt, WeaponLayer layer) {
|
|||||||
glTexture* gfx;
|
glTexture* gfx;
|
||||||
Vec2 crash[2];
|
Vec2 crash[2];
|
||||||
|
|
||||||
gfx = outfit_gfx(w->outfit);
|
|
||||||
|
|
||||||
gl_getSpriteFromDir(&wsx, &wsy, gfx, w->solid->dir);
|
|
||||||
|
|
||||||
for(i = 0; i < pilot_nstack; i++) {
|
for(i = 0; i < pilot_nstack; i++) {
|
||||||
/* Check for player to exist. */
|
/* Check for player to exist. */
|
||||||
if((i == 0) && (player == NULL)) continue;
|
if((i == 0) && (player == NULL)) continue;
|
||||||
@ -356,7 +375,7 @@ static void weapon_update(Weapon* w, const double dt, WeaponLayer layer) {
|
|||||||
&pilot_stack[i]->solid->pos,
|
&pilot_stack[i]->solid->pos,
|
||||||
crash)) {
|
crash)) {
|
||||||
|
|
||||||
/** @todo beam_hit Needs it's own function. */
|
weapon_hitBeam(w, pilot_stack[i], layer, crash, dt);
|
||||||
|
|
||||||
/* No return because beam can still think, it's not
|
/* No return because beam can still think, it's not
|
||||||
* destroyed like the other weapons. */
|
* destroyed like the other weapons. */
|
||||||
@ -365,27 +384,31 @@ static void weapon_update(Weapon* w, const double dt, WeaponLayer layer) {
|
|||||||
|
|
||||||
/* Smart weapons only collide with their target. */
|
/* Smart weapons only collide with their target. */
|
||||||
else if(weapon_isSmart(w)) {
|
else if(weapon_isSmart(w)) {
|
||||||
|
gfx = outfit_gfx(w->outfit);
|
||||||
|
gl_getSpriteFromDir(&wsx, &wsy, gfx, w->solid->dir);
|
||||||
if((pilot_stack[i]->id == w->target) &&
|
if((pilot_stack[i]->id == w->target) &&
|
||||||
CollideSprite(gfx, wsx, wsy, &w->solid->pos,
|
CollideSprite(gfx, wsx, wsy, &w->solid->pos,
|
||||||
pilot_stack[i]->ship->gfx_space, psx, psy, &pilot_stack[i]->solid->pos,
|
pilot_stack[i]->ship->gfx_space, psx, psy, &pilot_stack[i]->solid->pos,
|
||||||
&crash[0])) {
|
&crash[0])) {
|
||||||
|
|
||||||
weapon_hit(w, pilot_stack[i], layer, &crash[0]);
|
weapon_hit(w, pilot_stack[i], layer, &crash[0]);
|
||||||
return;
|
return; /* Weapon is destroyed. */
|
||||||
}
|
|
||||||
/* Dumb weapons hit anything not of the same faction. */
|
|
||||||
else if(!weapon_isSmart(w) &&
|
|
||||||
!areAllies(w->faction, pilot_stack[i]->faction) &&
|
|
||||||
CollideSprite(gfx, wsx, wsy, &w->solid->pos,
|
|
||||||
pilot_stack[i]->ship->gfx_space, psx, psy, &pilot_stack[i]->solid->pos,
|
|
||||||
&crash[0])) {
|
|
||||||
|
|
||||||
weapon_hit(w, pilot_stack[i], layer, &crash[0]);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
/* Dumb weapons hit anything not of the same faction. */
|
||||||
|
else if(!weapon_isSmart(w)) {
|
||||||
|
gfx = outfit_gfx(w->outfit);
|
||||||
|
gl_getSpriteFromDir(&wsx, &wsy, gfx, w->solid->dir);
|
||||||
|
|
||||||
|
if(!areAllies(w->faction, pilot_stack[i]->faction) &&
|
||||||
|
CollideSprite(gfx, wsx, wsy, &w->solid->pos,
|
||||||
|
pilot_stack[i]->ship->gfx_space, psx, psy, &pilot_stack[i]->solid->pos,
|
||||||
|
&crash[0])) {
|
||||||
|
weapon_hit(w, pilot_stack[i], layer, &crash[0]);
|
||||||
|
return; /* Weapon is destroyed. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
/* Smart weapons also get to think their next move. */
|
/* Smart weapons also get to think their next move. */
|
||||||
if(weapon_isSmart(w)) (*w->think)(w,dt);
|
if(weapon_isSmart(w)) (*w->think)(w,dt);
|
||||||
|
|
||||||
@ -425,6 +448,48 @@ static void weapon_hit(Weapon* w, Pilot* p, WeaponLayer layer, Vec2* pos) {
|
|||||||
weapon_destroy(w, layer);
|
weapon_destroy(w, layer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @fn static void weapon_hitBeam(Weapon* w, Pilot* p, WeaponLayer layer,
|
||||||
|
* Vec2 pos[2], const double dt)
|
||||||
|
*
|
||||||
|
* @brief Weapon hit the pilot.
|
||||||
|
* @param w Weapon involved in the collision.
|
||||||
|
* @param p Pilot that got hit.
|
||||||
|
* @param layer Layer to which the weapon belongs.
|
||||||
|
* @param pos Position of the hit.
|
||||||
|
*/
|
||||||
|
static void weapon_hitBeam(Weapon* w, Pilot* p, WeaponLayer layer,
|
||||||
|
Vec2 pos[2], const double dt) {
|
||||||
|
|
||||||
|
(void)layer;
|
||||||
|
|
||||||
|
/* Inform the ai it has been attacked, useless if player. */
|
||||||
|
if(!pilot_isPlayer(p)) {
|
||||||
|
if((player_target == p->id) || (RNGF()*dt < 0.70)) { /* 70% chance per second. */
|
||||||
|
if((w->parent == PLAYER_ID) &&
|
||||||
|
(!pilot_isFlag(p, PILOT_HOSTILE) || (RNGF() < 0.5))) { /* 50% chance. */
|
||||||
|
faction_modPlayer(p->faction, -1); /* Slowly lower faction. */
|
||||||
|
pilot_setFlag(p, PILOT_HOSTILE);
|
||||||
|
}
|
||||||
|
ai_attacked(p, w->parent);
|
||||||
|
}
|
||||||
|
spfx_add(outfit_spfx(w->outfit), pos[0].x, pos[0].y,
|
||||||
|
VX(p->solid->vel), VY(p->solid->vel), SPFX_LAYER_BACK);
|
||||||
|
spfx_add(outfit_spfx(w->outfit), pos[1].x, pos[1].y,
|
||||||
|
VX(p->solid->vel), VY(p->solid->vel), SPFX_LAYER_BACK);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
spfx_add(outfit_spfx(w->outfit), pos[0].x, pos[0].y,
|
||||||
|
VX(p->solid->vel), VY(p->solid->vel), SPFX_LAYER_FRONT);
|
||||||
|
spfx_add(outfit_spfx(w->outfit), pos[1].x, pos[1].y,
|
||||||
|
VX(p->solid->vel), VY(p->solid->vel), SPFX_LAYER_FRONT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Inform the ship that it should take some damage. */
|
||||||
|
pilot_hit(p, w->solid, w->parent,
|
||||||
|
outfit_damageType(w->outfit), outfit_damage(w->outfit)*dt);
|
||||||
|
}
|
||||||
|
|
||||||
static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2* pos,
|
static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2* pos,
|
||||||
const Vec2* vel, unsigned int parent, const unsigned int target) {
|
const Vec2* vel, unsigned int parent, const unsigned int target) {
|
||||||
Vec2 v;
|
Vec2 v;
|
||||||
@ -491,6 +556,7 @@ static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2*
|
|||||||
mass = 1.;
|
mass = 1.;
|
||||||
w->solid = solid_create(mass, dir, pos, NULL);
|
w->solid = solid_create(mass, dir, pos, NULL);
|
||||||
w->think = think_beam;
|
w->think = think_beam;
|
||||||
|
w->timer = outfit->u.bem.duration;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Treat seekers togther. */
|
/* Treat seekers togther. */
|
||||||
|
Loading…
Reference in New Issue
Block a user