[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 := WIN32
|
||||
|
||||
#CC = clang
|
||||
|
||||
# VERSION.
|
||||
VMAJOR = 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. */
|
||||
void pilot_shoot(Pilot* p, const unsigned int target, const int secondary) {
|
||||
int i;
|
||||
Outfit* o;
|
||||
|
||||
if(!p->outfits) return; /* No outfits. */
|
||||
|
||||
if(!secondary) {
|
||||
/* Primary weapons. */
|
||||
for(i = 0; i < p->noutfits; i++)
|
||||
/* Cycle through outfits to find primary weapons. */
|
||||
if(!outfit_isProp(p->outfits[i].outfit, OUTFIT_PROP_WEAP_SECONDARY))
|
||||
for(i = 0; i < p->noutfits; i++) {
|
||||
o = p->outfits[i].outfit;
|
||||
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);
|
||||
}
|
||||
} else {
|
||||
if(!p->secondary) return; /* No secondary weapon. */
|
||||
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);
|
||||
weapon_add(w->outfit, p->solid->dir,
|
||||
&p->solid->pos, &p->solid->vel, p->id, t);
|
||||
|
||||
/* Can't shoot it for a bit. */
|
||||
w->timer = SDL_GetTicks();
|
||||
}
|
||||
|
||||
/* Beam Weapons. */
|
||||
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,
|
||||
&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. */
|
||||
} else {
|
||||
WARN("Shooting unknown weapon type: %s", w->outfit->name);
|
||||
}
|
||||
|
||||
/* Update the weapon last used timer. */
|
||||
w->timer = SDL_GetTicks();
|
||||
}
|
||||
|
||||
/**
|
||||
|
15
src/pilot.h
15
src/pilot.h
@ -53,6 +53,19 @@
|
||||
#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. */
|
||||
|
||||
/**
|
||||
* @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
|
||||
*
|
||||
@ -61,7 +74,7 @@
|
||||
typedef struct PilotOutfit_ {
|
||||
Outfit* outfit; /**< Associated outfit. */
|
||||
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. */
|
||||
} PilotOutfit;
|
||||
|
||||
|
100
src/weapon.c
100
src/weapon.c
@ -11,6 +11,7 @@
|
||||
#include "collision.h"
|
||||
#include "player.h"
|
||||
#include "spfx.h"
|
||||
#include "opengl.h"
|
||||
#include "weapon.h"
|
||||
|
||||
#define weapon_isSmart(w) (w->think != NULL)
|
||||
@ -22,7 +23,11 @@
|
||||
#define WEAPON_STATUS_JAMMED 1 /* Got jammed. */
|
||||
#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 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 weapon_update(Weapon* w, const double dt, WeaponLayer layer);
|
||||
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_free(Weapon* w);
|
||||
/* Think. */
|
||||
@ -80,8 +87,20 @@ void weapon_minimap(const double res, const double w,
|
||||
const double h, const RadarShape shape);
|
||||
|
||||
/* Draw the minimap weapons (player.c). */
|
||||
#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))
|
||||
#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)) /**< 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,
|
||||
const double h, const RadarShape shape) {
|
||||
int i, rc;
|
||||
@ -296,6 +315,7 @@ void weapons_render(const WeaponLayer layer) {
|
||||
/* Render the weapons. */
|
||||
static void weapon_render(const Weapon* w) {
|
||||
int sx, sy;
|
||||
double x, y;
|
||||
glTexture* gfx;
|
||||
|
||||
switch(w->outfit->type) {
|
||||
@ -315,10 +335,13 @@ static void weapon_render(const Weapon* w) {
|
||||
/* Beam weapons. */
|
||||
case OUTFIT_TYPE_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);
|
||||
glVertex2d(w->solid->pos.x, w->solid->pos.y);
|
||||
glVertex2d(w->solid->pos.x + w->outfit->u.bem.range*cos(w->solid->dir),
|
||||
w->solid->pos.y + w->outfit->u.bem.range*sin(w->solid->dir));
|
||||
glVertex2d(x, y);
|
||||
glVertex2d(x + w->outfit->u.bem.range * cos(w->solid->dir),
|
||||
y + w->outfit->u.bem.range * sin(w->solid->dir));
|
||||
glEnd();
|
||||
break;
|
||||
|
||||
@ -335,10 +358,6 @@ static void weapon_update(Weapon* w, const double dt, WeaponLayer layer) {
|
||||
glTexture* gfx;
|
||||
Vec2 crash[2];
|
||||
|
||||
gfx = outfit_gfx(w->outfit);
|
||||
|
||||
gl_getSpriteFromDir(&wsx, &wsy, gfx, w->solid->dir);
|
||||
|
||||
for(i = 0; i < pilot_nstack; i++) {
|
||||
/* Check for player to exist. */
|
||||
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,
|
||||
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
|
||||
* 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. */
|
||||
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) &&
|
||||
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;
|
||||
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) &&
|
||||
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;
|
||||
return; /* Weapon is destroyed. */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Smart weapons also get to think their next move. */
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* @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,
|
||||
const Vec2* vel, unsigned int parent, const unsigned int target) {
|
||||
Vec2 v;
|
||||
@ -491,6 +556,7 @@ static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2*
|
||||
mass = 1.;
|
||||
w->solid = solid_create(mass, dir, pos, NULL);
|
||||
w->think = think_beam;
|
||||
w->timer = outfit->u.bem.duration;
|
||||
break;
|
||||
|
||||
/* Treat seekers togther. */
|
||||
|
Loading…
Reference in New Issue
Block a user