[Add] Turrets!!

This commit is contained in:
Allanis 2013-02-28 17:38:44 +00:00
parent 79e08280e5
commit 8f6b02cfc1
5 changed files with 69 additions and 24 deletions

View File

@ -38,23 +38,11 @@ Outfit* outfit_get(const char* name) {
return NULL; return NULL;
} }
// Return 1 if outfit is a weapon. // Return 1 if outfit is a weapon (beam/bolt).
int outfit_isWeapon(const Outfit* o) { int outfit_isWeapon(const Outfit* o) {
return ((o->type == OUTFIT_TYPE_BOLT) || (o->type == OUTFIT_TYPE_BEAM)); return ((o->type == OUTFIT_TYPE_BOLT) || (o->type == OUTFIT_TYPE_BEAM));
} }
// Return the broad outfit type.
const char* outfit_typenamebroad[] = { "NULL", "Weapon", "Launcher", "Ammo" };
const char* outfit_getTypeBroad(const Outfit* o) {
int i = 0;
if(outfit_isWeapon(o)) i = 1;
else if(outfit_isLauncher(o)) i = 2;
else if(outfit_isAmmo(0)) i = 3;
return outfit_typenamebroad[i];
}
// Return 1 if outfit is a launcher. // Return 1 if outfit is a launcher.
int outfit_isLauncher(const Outfit* o) { int outfit_isLauncher(const Outfit* o) {
return((o->type == OUTFIT_TYPE_MISSILE_DUMB) || return((o->type == OUTFIT_TYPE_MISSILE_DUMB) ||
@ -74,10 +62,15 @@ int outfit_isAmmo(const Outfit* o) {
} }
int outfit_isTurret(const Outfit* o) {
return ((o->type == OUTFIT_TYPE_TURRET_BOLT) || (o->type == OUTFIT_TYPE_TURRET_BEAM));
}
// Get the outfit graphics. // Get the outfit graphics.
glTexture* outfit_gfx(const Outfit* o) { glTexture* outfit_gfx(const Outfit* o) {
if(outfit_isWeapon(o)) return o->u.wpn.gfx_space; if(outfit_isWeapon(o)) return o->u.wpn.gfx_space;
else if(outfit_isAmmo(o)) return o->u.amm.gfx_space; else if(outfit_isAmmo(o)) return o->u.amm.gfx_space;
else if(outfit_isTurret(o)) return o->u.wpn.gfx_space;
return NULL; return NULL;
} }
@ -85,18 +78,28 @@ glTexture* outfit_gfx(const Outfit* o) {
int outfit_spfx(const Outfit* o) { int outfit_spfx(const Outfit* o) {
if(outfit_isWeapon(o)) return o->u.wpn.spfx; if(outfit_isWeapon(o)) return o->u.wpn.spfx;
else if(outfit_isAmmo(o)) return o->u.amm.spfx; else if(outfit_isAmmo(o)) return o->u.amm.spfx;
else if(outfit_isTurret(o)) return o->u.wpn.spfx;
return -1; return -1;
} }
double outfit_dmgShield(const Outfit* o) { double outfit_dmgShield(const Outfit* o) {
if(outfit_isWeapon(o)) return o->u.wpn.damage_armour; if(outfit_isWeapon(o)) return o->u.wpn.damage_armour;
else if(outfit_isAmmo(o)) return o->u.amm.damage_armour; else if(outfit_isAmmo(o)) return o->u.amm.damage_armour;
else if(outfit_isTurret(o)) return o->u.wpn.damage_armour;
return -1; return -1;
} }
double outfit_dmgArmour(const Outfit* o) { double outfit_dmgArmour(const Outfit* o) {
if(outfit_isWeapon(o)) return o->u.wpn.damage_shield; if(outfit_isWeapon(o)) return o->u.wpn.damage_shield;
else if(outfit_isAmmo(o)) return o->u.amm.damage_shield; else if(outfit_isAmmo(o)) return o->u.amm.damage_shield;
else if(outfit_isTurret(o)) return o->u.amm.damage_shield;
return -1;
}
int outfit_delay(const Outfit* o) {
if(outfit_isWeapon(o)) return o->u.wpn.delay;
else if(outfit_isLauncher(o)) return o->u.lau.delay;
else if(outfit_isTurret(o)) return o->u.wpn.delay;
return -1; return -1;
} }
@ -113,9 +116,24 @@ const char* outfit_typename[] = {
"Swam Missile", "Swam Missile",
"Swarm Missile Ammunition Pack", "Swarm Missile Ammunition Pack",
"Smart Swarm Missile", "Smart Swarm Missile",
"Smart Swarm Missile Ammunition Pack" "Smart Swarm Missile Ammunition Pack",
"Bolt Turret",
"Beam Turret"
}; };
// Return the broad outfit type.
const char* outfit_typenamebroad[] = { "NULL", "Weapon", "Launcher", "Ammo", "Turret" };
const char* outfit_getTypeBroad(const Outfit* o) {
int i = 0;
if(outfit_isWeapon(o)) i = 1;
else if(outfit_isLauncher(o)) i = 2;
else if(outfit_isAmmo(o)) i = 3;
else if(outfit_isTurret(o)) i = 4;
return outfit_typenamebroad[i];
}
const char* outfit_getType(const Outfit* o) { const char* outfit_getType(const Outfit* o) {
return outfit_typename[o->type]; return outfit_typename[o->type];
} }
@ -271,6 +289,8 @@ static Outfit* outfit_parse(const xmlNodePtr parent) {
outfit_parseSLauncher(tmp, node); outfit_parseSLauncher(tmp, node);
else if(outfit_isAmmo(tmp)) else if(outfit_isAmmo(tmp))
outfit_parseSAmmo(tmp, node); outfit_parseSAmmo(tmp, node);
else if(outfit_isTurret(tmp))
outfit_parseSWeapon(tmp, node);
} }
} while((node = node->next)); } while((node = node->next));
#define MELEMENT(o,s) if(o) WARN("Outfit '%s' missing '"s"' element", tmp->name) #define MELEMENT(o,s) if(o) WARN("Outfit '%s' missing '"s"' element", tmp->name)

View File

@ -20,7 +20,9 @@ typedef enum OutfitType_ {
OUTFIT_TYPE_MISSILE_SWARM = 9, OUTFIT_TYPE_MISSILE_SWARM = 9,
OUTFIT_TYPE_MISSILE_SWARM_AMMO = 10, OUTFIT_TYPE_MISSILE_SWARM_AMMO = 10,
OUTFIT_TYPE_MISSILE_SWARM_SMART = 11, OUTFIT_TYPE_MISSILE_SWARM_SMART = 11,
OUTFIT_TYPE_MISSILE_SWARM_SMART_AMMO = 12 OUTFIT_TYPE_MISSILE_SWARM_SMART_AMMO = 12,
OUTFIT_TYPE_TURRET_BOLT = 13,
OUTFIT_TYPE_TURRET_BEAM = 14
} OutfitType; } OutfitType;
// An outfit depends a lot on the type. // An outfit depends a lot on the type.
@ -75,6 +77,7 @@ Outfit* outfit_get(const char* name);
int outfit_isWeapon(const Outfit* o); int outfit_isWeapon(const Outfit* o);
int outfit_isLauncher(const Outfit* o); int outfit_isLauncher(const Outfit* o);
int outfit_isAmmo(const Outfit* o); int outfit_isAmmo(const Outfit* o);
int outfit_isTurret(const Outfit* o);
const char* outfit_getType(const Outfit* o); const char* outfit_getType(const Outfit* o);
const char* outfit_getTypeBroad(const Outfit* o); const char* outfit_getTypeBroad(const Outfit* o);
@ -83,6 +86,7 @@ glTexture* outfit_gfx(const Outfit* o);
int outfit_spfx(const Outfit* o); int outfit_spfx(const Outfit* o);
double outfit_dmgShield(const Outfit* o); double outfit_dmgShield(const Outfit* o);
double outfit_dmgArmour(const Outfit* o); double outfit_dmgArmour(const Outfit* o);
int outfit_delay(const Outfit* o);
// Load/free outfit stack. // Load/free outfit stack.
int outfit_load(void); int outfit_load(void);

View File

@ -45,6 +45,7 @@ void pilot_render(Pilot* pilot);
static void pilot_free(Pilot* p); static void pilot_free(Pilot* p);
static Fleet* fleet_parse(const xmlNodePtr parent); static Fleet* fleet_parse(const xmlNodePtr parent);
static void pilot_dead(Pilot* p); static void pilot_dead(Pilot* p);
static int pilot_oquantity(Pilot* p, PilotOutfit* w);
// Get the next pilot based on id. // Get the next pilot based on id.
unsigned int pilot_getNext(const unsigned int id) { unsigned int pilot_getNext(const unsigned int id) {
@ -130,6 +131,12 @@ double pilot_face(Pilot* p, const float dir) {
return diff; return diff;
} }
// Return quantity of a pilot outfit.
static int pilot_oquantity(Pilot* p, PilotOutfit* w) {
return (outfit_isAmmo(w->outfit) && p->secondary) ?
p->secondary->quantity : w->quantity;
}
// 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;
@ -151,16 +158,16 @@ void pilot_shoot(Pilot* p, const unsigned int target, const int secondary) {
static void pilot_shootWeapon(Pilot* p, PilotOutfit* w, const unsigned int t) { static void pilot_shootWeapon(Pilot* p, PilotOutfit* w, const unsigned int t) {
int quantity, delay; int quantity, delay;
// WElll... Trying to shoot when you have no ammo?? FUUU // WElll... Trying to shoot when you have no ammo?? FUUU
quantity = (outfit_isAmmo(w->outfit) && p->secondary) ? quantity = pilot_oquantity(p,w);
p->secondary->quantity : w->quantity; delay = outfit_delay(w->outfit);
delay = (outfit_isWeapon(w->outfit)) ? w->outfit->u.wpn.delay : w->outfit->u.wpn.delay;
// Check to see if weapon is ready. // Check to see if weapon is ready.
if((SDL_GetTicks() - w->timer) < (unsigned int)(delay/quantity)) return; if((SDL_GetTicks() - w->timer) < (unsigned int)(delay/quantity)) return;
// Regular weapons. // Regular weapons.
if(outfit_isWeapon(w->outfit)) { if(outfit_isWeapon(w->outfit) || (outfit_isTurret(w->outfit))) {
// Different weapons. // Different weapons.
switch(w->outfit->type) { switch(w->outfit->type) {
case OUTFIT_TYPE_TURRET_BOLT:
case OUTFIT_TYPE_BOLT: case OUTFIT_TYPE_BOLT:
weapon_add(w->outfit, p->solid->dir, &p->solid->pos, &p->solid->vel, p->id, t); weapon_add(w->outfit, p->solid->dir, &p->solid->pos, &p->solid->vel, p->id, t);

View File

@ -817,7 +817,7 @@ void player_think(Pilot* player) {
player->solid->dir_vel -= player->ship->turn * player_turn; player->solid->dir_vel -= player->ship->turn * player_turn;
} }
if(player_isFlag(PLAYER_PRIMARY)) pilot_shoot(player, 0, 0); if(player_isFlag(PLAYER_PRIMARY)) pilot_shoot(player, player_target, 0);
if(player_isFlag(PLAYER_SECONDARY)) // Needs a target. if(player_isFlag(PLAYER_SECONDARY)) // Needs a target.
pilot_shoot(player, player_target, 1); pilot_shoot(player, player_target, 1);

View File

@ -209,8 +209,8 @@ static void weapons_updateLayer(const double dt, const WeaponLayer layer) {
break; break;
case OUTFIT_TYPE_BOLT: case OUTFIT_TYPE_BOLT:
// Check see if it exceeds distance. // Check see if it exceeds distance.
if(SDL_GetTicks() > (wlayer[i]->timer + 1000*(unsigned int) case OUTFIT_TYPE_TURRET_BOLT:
wlayer[i]->outfit->u.wpn.range/wlayer[i]->outfit->u.wpn.speed)) { if(SDL_GetTicks() > wlayer[i]->timer) {
weapon_destroy(wlayer[i],layer); weapon_destroy(wlayer[i],layer);
continue; continue;
} }
@ -359,6 +359,20 @@ static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2*
w->solid->pos.x, w->solid->pos.y, w->solid->pos.x, w->solid->pos.y,
w->solid->vel.x, w->solid->vel.y, w->outfit->u.amm.sound, 0); w->solid->vel.x, w->solid->vel.y, w->outfit->u.amm.sound, 0);
break; break;
case OUTFIT_TYPE_TURRET_BOLT:
if(w->parent != w->target)
rdir = vect_angle(pos, &pilot_get(w->target)->solid->pos);
rdir += RNG(-outfit->u.wpn.accuracy/2.,
outfit->u.wpn.accuracy/2.)/180.*M_PI;
if((rdir > 2.*M_PI) || (rdir < 0.)) rdir = fmod(rdir, 2.*M_PI);
vectcpy(&v, vel);
vect_cadd(&v, outfit->u.wpn.speed*cos(rdir), outfit->u.wpn.speed*sin(rdir));
w->timer += 1000*(unsigned int)outfit->u.wpn.range / outfit->u.wpn.speed;
w->solid = solid_create(mass, rdir, pos, &v);
w->voice = sound_addVoice(VOICE_PRIORITY_BOLT,
w->solid->pos.x, w->solid->pos.y,
w->solid->vel.x, w->solid->vel.y, w->outfit->u.wpn.sound, 0);
break;
default: default:
// Just dump it where the player is. // Just dump it where the player is.
w->voice = NULL; w->voice = NULL;
@ -372,7 +386,7 @@ static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2*
void weapon_add(const Outfit* outfit, const double dir, const Vec2* pos, const Vec2* vel, void weapon_add(const Outfit* outfit, const double dir, const Vec2* pos, const Vec2* vel,
unsigned int parent, unsigned int target) { unsigned int parent, unsigned int target) {
if(!outfit_isWeapon(outfit) && !outfit_isAmmo(outfit)) { if(!outfit_isWeapon(outfit) && !outfit_isAmmo(outfit) && !outfit_isTurret(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;
} }