[Add] Added outfit states and beam hit function. Also added compile option for clang.

This commit is contained in:
Allanis 2013-09-23 22:59:01 +01:00
parent 06ea30d96e
commit 71ab2d863f
4 changed files with 124 additions and 34 deletions

View File

@ -5,6 +5,8 @@ DEBUG = 1
OS := LINUX
#OS := WIN32
#CC = clang
# VERSION.
VMAJOR = 0
VMINOR = 0

View File

@ -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();
}
/**

View File

@ -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;

View File

@ -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. */