[Add] First round to bring more control to beam weapons.
This commit is contained in:
parent
70d4987a00
commit
4d8b462359
59
src/pilot.c
59
src/pilot.c
@ -222,6 +222,39 @@ void pilot_shoot(Pilot* p, const unsigned int target, const int secondary) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @fn void pilot_shootStop(Pilot* p, const int secondary)
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
*/
|
||||||
|
void pilot_shootStop(Pilot* p, 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. */
|
||||||
|
o = p->outfits[i].outfit;
|
||||||
|
if(!outfit_isProp(o, OUTFIT_PROP_WEAP_SECONDARY) &&
|
||||||
|
outfit_isBeam(o)) /** @todo Possibly make this neater. */
|
||||||
|
if(p->outfits[i].beamid > 0) {
|
||||||
|
p->outfits[i].beamid = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else { /* Secondary weapons. */
|
||||||
|
o = p->secondary->outfit;
|
||||||
|
|
||||||
|
if(o == NULL) return; /* No secondary weapon. */
|
||||||
|
|
||||||
|
if(outfit_isBeam(o) && (p->secondary->beamid > 0)) {
|
||||||
|
beam_end(p->id, p->secondary->beamid);
|
||||||
|
p->secondary->beamid = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @fn static void pilot_shootWeapon(Pilot* p, PilotOutfit* w, const unsigned int t)
|
* @fn static void pilot_shootWeapon(Pilot* p, PilotOutfit* w, const unsigned int t)
|
||||||
*
|
*
|
||||||
@ -254,7 +287,7 @@ static void pilot_shootWeapon(Pilot* p, PilotOutfit* w, const unsigned int t) {
|
|||||||
|
|
||||||
/** @todo Handle warmup stage. */
|
/** @todo Handle warmup stage. */
|
||||||
w->state = PILOT_OUTFIT_ON;
|
w->state = PILOT_OUTFIT_ON;
|
||||||
weapon_add(w->outfit, p->solid->dir,
|
w->beamid = beam_start(w->outfit, p->solid, p->solid->dir,
|
||||||
&p->solid->pos, &p->solid->vel, p->id, t);
|
&p->solid->pos, &p->solid->vel, p->id, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -289,6 +322,30 @@ static void pilot_shootWeapon(Pilot* p, PilotOutfit* w, const unsigned int t) {
|
|||||||
w->timer = SDL_GetTicks();
|
w->timer = SDL_GetTicks();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @fn void pilot_switchSecondary(Pilot* p, int i)
|
||||||
|
*
|
||||||
|
* @brief
|
||||||
|
*/
|
||||||
|
void pilot_switchSecondary(Pilot* p, int i) {
|
||||||
|
PilotOutfit* cur;
|
||||||
|
|
||||||
|
cur = player->secondary;
|
||||||
|
|
||||||
|
if((i < 0) || (i >= player->noutfits))
|
||||||
|
player->secondary = NULL;
|
||||||
|
else
|
||||||
|
player->secondary = &player->outfits[i];
|
||||||
|
|
||||||
|
/* Check for weapon change. */
|
||||||
|
if((cur != NULL) && (player->secondary != cur)) {
|
||||||
|
if(outfit_isBeam(cur->outfit) && (cur->beamid > 0)) {
|
||||||
|
beam_end(p->id, cur->beamid);
|
||||||
|
cur->beamid = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @fn void pilot_hit(Pilot* p, const Solid* w, const unsigned int shooter,
|
* @fn void pilot_hit(Pilot* p, const Solid* w, const unsigned int shooter,
|
||||||
* const DamageType dtype, const double damage)
|
* const DamageType dtype, const double damage)
|
||||||
|
@ -76,6 +76,7 @@ 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. */
|
PilotOutfitState state; /**< State of the outfit. */
|
||||||
|
int beamid; /**< ID of the beam used in this outfit, only for beams. */
|
||||||
unsigned int timer; /**< Used to store last used weapon time. */
|
unsigned int timer; /**< Used to store last used weapon time. */
|
||||||
} PilotOutfit;
|
} PilotOutfit;
|
||||||
|
|
||||||
@ -213,8 +214,10 @@ int pilot_getJumps(const Pilot* p);
|
|||||||
|
|
||||||
/* Misc. */
|
/* Misc. */
|
||||||
void pilot_shoot(Pilot* p, const unsigned int target, const int secondary);
|
void pilot_shoot(Pilot* p, const unsigned int target, 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);
|
||||||
|
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);
|
||||||
void pilot_setAfterburner(Pilot* p);
|
void pilot_setAfterburner(Pilot* p);
|
||||||
|
31
src/player.c
31
src/player.c
@ -1389,9 +1389,27 @@ void player_think(Pilot* pplayer) {
|
|||||||
pplayer->solid->dir_vel -= player->turn * player_turn;
|
pplayer->solid->dir_vel -= player->turn * player_turn;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(player_isFlag(PLAYER_PRIMARY)) pilot_shoot(pplayer, player_target, 0);
|
/* Weapon shooting stuff. */
|
||||||
if(player_isFlag(PLAYER_SECONDARY)) /* Needs a target. */
|
|
||||||
pilot_shoot(pplayer, player_target, 1);
|
/* Primary weapon. */
|
||||||
|
if(player_isFlag(PLAYER_PRIMARY)) {
|
||||||
|
pilot_shoot(pplayer, player_target, 0);
|
||||||
|
player_setFlag(PLAYER_PRIMARY_L);
|
||||||
|
}
|
||||||
|
else if(player_isFlag(PLAYER_PRIMARY_L)) {
|
||||||
|
pilot_shootStop(pplayer, 0);
|
||||||
|
player_rmFlag(PLAYER_PRIMARY_L);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Secondary. */
|
||||||
|
if(player_isFlag(PLAYER_SECONDARY)) {
|
||||||
|
pilot_shoot(pplayer, player_target, 0);
|
||||||
|
player_setFlag(PLAYER_SECONDARY_L);
|
||||||
|
}
|
||||||
|
else if(player_isFlag(PLAYER_SECONDARY_L)) {
|
||||||
|
pilot_shootStop(pplayer, 0);
|
||||||
|
player_rmFlag(PLAYER_SECONDARY_L);
|
||||||
|
}
|
||||||
|
|
||||||
/* Afterburn! */
|
/* Afterburn! */
|
||||||
if(player_isFlag(PLAYER_AFTERBURNER)) {
|
if(player_isFlag(PLAYER_AFTERBURNER)) {
|
||||||
@ -1405,7 +1423,7 @@ void player_think(Pilot* pplayer) {
|
|||||||
vect_pset(&pplayer->solid->force, pplayer->thrust * player_acc,
|
vect_pset(&pplayer->solid->force, pplayer->thrust * player_acc,
|
||||||
pplayer->solid->dir);
|
pplayer->solid->dir);
|
||||||
|
|
||||||
/* Update sound position. */
|
/* Sound. */
|
||||||
sound_updateListener(pplayer->solid->dir,
|
sound_updateListener(pplayer->solid->dir,
|
||||||
pplayer->solid->pos.x, pplayer->solid->pos.y);
|
pplayer->solid->pos.x, pplayer->solid->pos.y);
|
||||||
|
|
||||||
@ -1447,13 +1465,12 @@ void player_secondaryNext(void) {
|
|||||||
/* Get the next secondary weapon. */
|
/* Get the next secondary weapon. */
|
||||||
for(; i < player->noutfits; i++)
|
for(; i < player->noutfits; i++)
|
||||||
if(outfit_isProp(player->outfits[i].outfit, OUTFIT_PROP_WEAP_SECONDARY)) {
|
if(outfit_isProp(player->outfits[i].outfit, OUTFIT_PROP_WEAP_SECONDARY)) {
|
||||||
player->secondary = player->outfits + i;
|
pilot_switchSecondary(player, i);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
/* We didn't find an outfit. */
|
/* We didn't find an outfit. */
|
||||||
if(i >= player->noutfits)
|
if(i >= player->noutfits)
|
||||||
player->secondary = NULL;
|
pilot_switchSecondary(player, -1);
|
||||||
|
|
||||||
/* Set ammo. */
|
/* Set ammo. */
|
||||||
pilot_setAmmo(player);
|
pilot_setAmmo(player);
|
||||||
}
|
}
|
||||||
|
@ -9,9 +9,11 @@
|
|||||||
#define PLAYER_DESTROYED (1<<9) /* Player goes BOOM! */
|
#define PLAYER_DESTROYED (1<<9) /* Player goes BOOM! */
|
||||||
#define PLAYER_FACE (1<<10) /* Player is facing target. */
|
#define PLAYER_FACE (1<<10) /* Player is facing target. */
|
||||||
#define PLAYER_PRIMARY (1<<11) /* Player is shooting primary weapon. */
|
#define PLAYER_PRIMARY (1<<11) /* Player is shooting primary weapon. */
|
||||||
#define PLAYER_SECONDARY (1<<12) /* Player is shooting secondary weapon. */
|
#define PLAYER_PRIMARY_L (1<<12) /**< Player shot primary weapon last frame. */
|
||||||
#define PLAYER_LANDACK (1<<13) /* Player has permission to land. */
|
#define PLAYER_SECONDARY (1<<13) /* Player is shooting secondary weapon. */
|
||||||
#define PLAYER_CREATING (1<<14) /* Player is being created. */
|
#define PLAYER_SECONDARY_L (1<<14) /**< Player shot secondary last frame. */
|
||||||
|
#define PLAYER_LANDACK (1<<15) /* Player has permission to land. */
|
||||||
|
#define PLAYER_CREATING (1<<16) /* Player is being created. */
|
||||||
|
|
||||||
/* Flag functions. */
|
/* Flag functions. */
|
||||||
#define player_isFlag(f) (player_flags & f)
|
#define player_isFlag(f) (player_flags & f)
|
||||||
|
115
src/weapon.c
115
src/weapon.c
@ -39,6 +39,7 @@ extern void ai_attacked(Pilot* attacked, const unsigned int attacker);
|
|||||||
|
|
||||||
typedef struct Weapon_ {
|
typedef struct Weapon_ {
|
||||||
Solid* solid; /* Actually has its own solid. :D */
|
Solid* solid; /* Actually has its own solid. :D */
|
||||||
|
int ID; /**< Only used for beam weapons. */
|
||||||
|
|
||||||
unsigned int faction; /* Faction of pilot that shot the weapon. */
|
unsigned int faction; /* Faction of pilot that shot the weapon. */
|
||||||
unsigned int parent; /* The pilot that just shot at you! */
|
unsigned int parent; /* The pilot that just shot at you! */
|
||||||
@ -64,6 +65,9 @@ static Weapon** wfrontLayer = NULL; /* Behind pilots. */
|
|||||||
static int nwfrontLayer = 0; /* Number of elements. */
|
static int nwfrontLayer = 0; /* Number of elements. */
|
||||||
static int mwfrontLayer = 0; /* Allocated memory size. */
|
static int mwfrontLayer = 0; /* Allocated memory size. */
|
||||||
|
|
||||||
|
/* Internal stuff. */
|
||||||
|
static int beam_idgen = 0; /**< Beam identifier generator. */
|
||||||
|
|
||||||
/* Static. */
|
/* Static. */
|
||||||
static Weapon* weapon_create(const Outfit* outfit, const double dir,
|
static Weapon* weapon_create(const Outfit* outfit, const double dir,
|
||||||
const Vec2* pos, const Vec2* vel,
|
const Vec2* pos, const Vec2* vel,
|
||||||
@ -703,8 +707,8 @@ void weapon_add(const Outfit* outfit, const double dir, const Vec2* pos,
|
|||||||
Weapon** curLayer;
|
Weapon** curLayer;
|
||||||
int* mLayer, *nLayer;
|
int* mLayer, *nLayer;
|
||||||
|
|
||||||
if(!outfit_isWeapon(outfit) &&
|
if(!outfit_isBolt(outfit) &&
|
||||||
!outfit_isAmmo(outfit) && !outfit_isTurret(outfit)) {
|
!outfit_isAmmo(outfit)) {
|
||||||
ERR("Trying to create a weapon from a non-Weapon type Outfit");
|
ERR("Trying to create a weapon from a non-Weapon type Outfit");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -745,6 +749,113 @@ void weapon_add(const Outfit* outfit, const double dir, const Vec2* pos,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @fn int beam_start(const Outfit* outfit,
|
||||||
|
* const double dir, const Vec2* pos, const Vec2* vel,
|
||||||
|
* const unsigned int parent, const unsigned int target)
|
||||||
|
*
|
||||||
|
* @brief Start the beam weapon.
|
||||||
|
* @param outfit Outfit which spawns the weapon.
|
||||||
|
* @param dir Direction of the shooter.
|
||||||
|
* @param vel Velocity of the shooter.
|
||||||
|
* @param parent Pilot ID of the shooter.
|
||||||
|
* @param target Target ID that is getting shot.
|
||||||
|
* @return The identifier of the beam weapon.
|
||||||
|
*/
|
||||||
|
int beam_start(const Outfit* outfit,
|
||||||
|
const double dir, const Vec2* pos, const Vec2* vel,
|
||||||
|
const unsigned int parent, const unsigned int target) {
|
||||||
|
|
||||||
|
WeaponLayer layer;
|
||||||
|
Weapon* w;
|
||||||
|
Weapon** curLayer;
|
||||||
|
int* mLayer, *nLayer;
|
||||||
|
|
||||||
|
if(!outfit_isBeam(outfit)) {
|
||||||
|
ERR("Trying to create a Beam Weapon from a non-beam outfit.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
layer = (parent == PLAYER_ID) ? WEAPON_LAYER_FG : WEAPON_LAYER_BG;
|
||||||
|
w = weapon_create(outfit, dir, pos, vel, parent, target);
|
||||||
|
w->ID = ++beam_idgen;
|
||||||
|
|
||||||
|
switch(layer) {
|
||||||
|
case WEAPON_LAYER_BG:
|
||||||
|
curLayer = wbackLayer;
|
||||||
|
nLayer = &nwbackLayer;
|
||||||
|
mLayer = &mwbackLayer;
|
||||||
|
break;
|
||||||
|
case WEAPON_LAYER_FG:
|
||||||
|
curLayer = wfrontLayer;
|
||||||
|
nLayer = &nwfrontLayer;
|
||||||
|
mLayer = &mwbackLayer;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ERR("Invalid WEAPON_LAYER specified.");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(*mLayer > *nLayer) /* More memory allocated then needed. */
|
||||||
|
curLayer[(*nLayer)++] = w;
|
||||||
|
else { /* Need to allocate more memory. */
|
||||||
|
switch (layer) {
|
||||||
|
case WEAPON_LAYER_BG:
|
||||||
|
(*mLayer) += WEAPON_CHUNK;
|
||||||
|
curLayer = wbackLayer = realloc(curLayer, (*mLayer)*sizeof(Weapon*));
|
||||||
|
break;
|
||||||
|
case WEAPON_LAYER_FG:
|
||||||
|
(*mLayer) += WEAPON_CHUNK;
|
||||||
|
curLayer = wfrontLayer = realloc(curLayer, (*mLayer)*sizeof(Weapon*));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
curLayer[(*nLayer)++] = w;
|
||||||
|
}
|
||||||
|
|
||||||
|
return w->ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @fn void beam_end(const unsigned int parent, int beam)
|
||||||
|
*
|
||||||
|
* @brief End a beam weapon.
|
||||||
|
* @param parent
|
||||||
|
* @param beam
|
||||||
|
*/
|
||||||
|
void beam_end(const unsigned int parent, int beam) {
|
||||||
|
int i;
|
||||||
|
WeaponLayer layer;
|
||||||
|
Weapon** curLayer;
|
||||||
|
int* mLayer, *nLayer;
|
||||||
|
|
||||||
|
layer = (parent == PLAYER_ID) ? WEAPON_LAYER_FG : WEAPON_LAYER_BG;
|
||||||
|
|
||||||
|
/* Set the proper layer. */
|
||||||
|
switch(layer) {
|
||||||
|
case WEAPON_LAYER_BG:
|
||||||
|
curLayer = wbackLayer;
|
||||||
|
nLayer = &nwbackLayer;
|
||||||
|
mLayer = &mwbackLayer;
|
||||||
|
break;
|
||||||
|
case WEAPON_LAYER_FG:
|
||||||
|
curLayer = wfrontLayer;
|
||||||
|
nLayer = &nwfrontLayer;
|
||||||
|
mLayer = &mwfrontLayer;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
ERR("Invalid WEAPON_LAYER specified.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Now try to destroy the beam. */
|
||||||
|
for(i = 0; i < *nLayer; i++) {
|
||||||
|
if(curLayer[i]->ID == beam) { /* Found it. */
|
||||||
|
weapon_destroy(curLayer[i], layer);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Destroy the weapon. */
|
/* Destroy the weapon. */
|
||||||
static void weapon_destroy(Weapon* w, WeaponLayer layer) {
|
static void weapon_destroy(Weapon* w, WeaponLayer layer) {
|
||||||
int i;
|
int i;
|
||||||
|
@ -16,6 +16,12 @@ void weapon_add(const Outfit* outfit, const double dir, const Vec2* pos,
|
|||||||
const Vec2* vel, unsigned int parent,
|
const Vec2* vel, unsigned int parent,
|
||||||
const unsigned int target);
|
const unsigned int target);
|
||||||
|
|
||||||
|
int beam_start(const Outfit* outfit,
|
||||||
|
const double dir, const Vec2* pos, const Vec2* vel,
|
||||||
|
const unsigned int parent, const unsigned int beam);
|
||||||
|
|
||||||
|
void beam_end(const unsigned int parent, int beam);
|
||||||
|
|
||||||
/* 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);
|
||||||
|
Loading…
Reference in New Issue
Block a user