From 8f6b02cfc1dac70fdf96fea9cde8c364af7c881e Mon Sep 17 00:00:00 2001 From: Allanis Date: Thu, 28 Feb 2013 17:38:44 +0000 Subject: [PATCH] [Add] Turrets!! --- src/outfit.c | 50 +++++++++++++++++++++++++++++++++++--------------- src/outfit.h | 6 +++++- src/pilot.c | 15 +++++++++++---- src/player.c | 2 +- src/weapon.c | 20 +++++++++++++++++--- 5 files changed, 69 insertions(+), 24 deletions(-) diff --git a/src/outfit.c b/src/outfit.c index 7c810f4..8dc1ee3 100644 --- a/src/outfit.c +++ b/src/outfit.c @@ -38,23 +38,11 @@ Outfit* outfit_get(const char* name) { return NULL; } -// Return 1 if outfit is a weapon. +// Return 1 if outfit is a weapon (beam/bolt). int outfit_isWeapon(const Outfit* o) { 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. int outfit_isLauncher(const Outfit* o) { 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. glTexture* outfit_gfx(const Outfit* o) { if(outfit_isWeapon(o)) return o->u.wpn.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; } @@ -85,18 +78,28 @@ glTexture* outfit_gfx(const Outfit* o) { int outfit_spfx(const Outfit* o) { if(outfit_isWeapon(o)) return o->u.wpn.spfx; else if(outfit_isAmmo(o)) return o->u.amm.spfx; + else if(outfit_isTurret(o)) return o->u.wpn.spfx; return -1; } double outfit_dmgShield(const Outfit* o) { 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; } double outfit_dmgArmour(const Outfit* o) { if(outfit_isWeapon(o)) return o->u.wpn.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; } @@ -113,9 +116,24 @@ const char* outfit_typename[] = { "Swam Missile", "Swarm Missile Ammunition Pack", "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) { return outfit_typename[o->type]; } @@ -271,6 +289,8 @@ static Outfit* outfit_parse(const xmlNodePtr parent) { outfit_parseSLauncher(tmp, node); else if(outfit_isAmmo(tmp)) outfit_parseSAmmo(tmp, node); + else if(outfit_isTurret(tmp)) + outfit_parseSWeapon(tmp, node); } } while((node = node->next)); #define MELEMENT(o,s) if(o) WARN("Outfit '%s' missing '"s"' element", tmp->name) diff --git a/src/outfit.h b/src/outfit.h index 7978acc..9ce2d2a 100644 --- a/src/outfit.h +++ b/src/outfit.h @@ -20,7 +20,9 @@ typedef enum OutfitType_ { OUTFIT_TYPE_MISSILE_SWARM = 9, OUTFIT_TYPE_MISSILE_SWARM_AMMO = 10, 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; // 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_isLauncher(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_getTypeBroad(const Outfit* o); @@ -83,6 +86,7 @@ glTexture* outfit_gfx(const Outfit* o); int outfit_spfx(const Outfit* o); double outfit_dmgShield(const Outfit* o); double outfit_dmgArmour(const Outfit* o); +int outfit_delay(const Outfit* o); // Load/free outfit stack. int outfit_load(void); diff --git a/src/pilot.c b/src/pilot.c index acbc9a4..49e2e47 100644 --- a/src/pilot.c +++ b/src/pilot.c @@ -45,6 +45,7 @@ void pilot_render(Pilot* pilot); static void pilot_free(Pilot* p); static Fleet* fleet_parse(const xmlNodePtr parent); static void pilot_dead(Pilot* p); +static int pilot_oquantity(Pilot* p, PilotOutfit* w); // Get the next pilot based on id. unsigned int pilot_getNext(const unsigned int id) { @@ -130,6 +131,12 @@ double pilot_face(Pilot* p, const float dir) { 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. void pilot_shoot(Pilot* p, const unsigned int target, const int secondary) { 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) { int quantity, delay; // WElll... Trying to shoot when you have no ammo?? FUUU - quantity = (outfit_isAmmo(w->outfit) && p->secondary) ? - p->secondary->quantity : w->quantity; - delay = (outfit_isWeapon(w->outfit)) ? w->outfit->u.wpn.delay : w->outfit->u.wpn.delay; + quantity = pilot_oquantity(p,w); + delay = outfit_delay(w->outfit); // Check to see if weapon is ready. if((SDL_GetTicks() - w->timer) < (unsigned int)(delay/quantity)) return; // Regular weapons. - if(outfit_isWeapon(w->outfit)) { + if(outfit_isWeapon(w->outfit) || (outfit_isTurret(w->outfit))) { // Different weapons. switch(w->outfit->type) { + case OUTFIT_TYPE_TURRET_BOLT: case OUTFIT_TYPE_BOLT: weapon_add(w->outfit, p->solid->dir, &p->solid->pos, &p->solid->vel, p->id, t); diff --git a/src/player.c b/src/player.c index fdd89d5..a0b340f 100644 --- a/src/player.c +++ b/src/player.c @@ -817,7 +817,7 @@ void player_think(Pilot* player) { 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. pilot_shoot(player, player_target, 1); diff --git a/src/weapon.c b/src/weapon.c index 80701a2..0d8bba4 100644 --- a/src/weapon.c +++ b/src/weapon.c @@ -209,8 +209,8 @@ static void weapons_updateLayer(const double dt, const WeaponLayer layer) { break; case OUTFIT_TYPE_BOLT: // Check see if it exceeds distance. - if(SDL_GetTicks() > (wlayer[i]->timer + 1000*(unsigned int) - wlayer[i]->outfit->u.wpn.range/wlayer[i]->outfit->u.wpn.speed)) { + case OUTFIT_TYPE_TURRET_BOLT: + if(SDL_GetTicks() > wlayer[i]->timer) { weapon_destroy(wlayer[i],layer); 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->vel.x, w->solid->vel.y, w->outfit->u.amm.sound, 0); 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: // Just dump it where the player is. 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, 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"); return; }