[Add] First round to bring more control to beam weapons.

This commit is contained in:
Allanis 2013-09-30 22:29:53 +01:00
parent 70d4987a00
commit 4d8b462359
6 changed files with 210 additions and 14 deletions

View File

@ -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,8 +287,8 @@ 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)

View File

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

View File

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

View File

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

View File

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

View File

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