[Add] New drone, new outfit. Also changed wpn to blt, as we will have multiple forms of weaponry.

This commit is contained in:
Allanis 2013-03-09 20:46:24 +00:00
parent 78bf7410e7
commit 51d2abe73e
10 changed files with 103 additions and 44 deletions

View File

@ -116,4 +116,26 @@
</damage>
</specific>
</outfit>
<outfit name="Neutron Disruptor">
<general>
<max>3</max>
<tech>12</tech>
<mass>8</mass>
<price>25000</price>
<description>Neutron Disruptor.</description>
</general>
<specific type="1">
<gfx>neutron</gfx>
<sound>laser</sound>
<spfx>ExpS</spfx>
<delay>400</delay>
<speed>650</speed>
<range>200</range>
<accuracy>15</accuracy>
<damage>
<armour>7</armour>
<shield>7</shield>
</damage>
</specific>
</outfit>
</Outfits>

View File

@ -91,9 +91,7 @@
<cap_cargo>20</cap_cargo>
</characteristics>
<outfits>
<outfit quantity="10">Laser</outfit>
<outfit quantity='2'>Headhunter Launcher</outfit>
<outfit quantity='20'>Headhunter</outfit>
<outfit quantity="4">Laser</outfit>
<outfit quantity='2'>Missile Launcher</outfit>
<outfit quantity='20'>Missile</outfit>
</outfits>
@ -128,6 +126,37 @@
<outfits>
<outfit quantity='2'>Laser Turret</outfit>
</outfits>
</ship>
<ship name="Drone">
<GFX>drone</GFX>
<GUI>minimal</GUI>
<sound>engine</sound>
<class>1</class>
<price>300000</price>
<fabricator>RoboSys</fabricator>
<description>A robot drone.</description>
<movement>
<thrust>450</thrust>
<turn>200</turn>
<speed>430</speed>
</movement>
<health>
<shield>70</shield>
<armour>40</armour>
<energy>300</energy>
<shield_regen>240</shield_regen>
<armour_regen>420</armour_regen>
<energy_regen>240</energy_regen>
</health>
<characteristics>
<crew>1</crew>
<mass>15</mass>
<cap_weapon>24</cap_weapon>
<cap_cargo>1</cap_cargo>
</characteristics>
<outfits>
<outfit quantity='3'>Neutron Disruptor</outfit>
</outfits>
</ship>
</Ships>

BIN
gfx/outfit/neutron.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 349 B

BIN
gfx/ship/drone.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

BIN
gfx/ship/drone_target.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.6 KiB

View File

@ -118,7 +118,9 @@ static void outfits(void) {
"Name:\n"
"Type:\n"
"Owned:\n"
"\n"
"Space taken:\n"
"Free Space:\n"
"\n"
"Price:\n"
"Money:\n");
@ -165,7 +167,7 @@ static void outfits_update(char* str) {
"%d\n"
"%d\n"
"\n"
"%s Scred\n"
"%s SCred\n"
"%s SCred\n",
outfit->name,
outfit_getType(outfit),
@ -201,7 +203,7 @@ static void outfits_buy(char* str) {
return;
}
else if(1*(int)outfit->price >= player_credits) {
else if(q*(int)outfit->price >= player_credits) {
credits2str(buf, q*outfit->price - player_credits, 2);
toolkit_alert("You need %s more SCred.", buf);
return;

View File

@ -78,38 +78,38 @@ int outfit_isTurret(const Outfit* o) {
// Get the outfit graphics.
glTexture* outfit_gfx(const Outfit* o) {
if(outfit_isWeapon(o)) return o->u.wpn.gfx_space;
if(outfit_isWeapon(o)) return o->u.blt.gfx_space;
else if(outfit_isAmmo(o)) return o->u.amm.gfx_space;
else if(outfit_isTurret(o)) return o->u.wpn.gfx_space;
else if(outfit_isTurret(o)) return o->u.blt.gfx_space;
return NULL;
}
// Get the outfit spfx if applicable.
int outfit_spfx(const Outfit* o) {
if(outfit_isWeapon(o)) return o->u.wpn.spfx;
if(outfit_isWeapon(o)) return o->u.blt.spfx;
else if(outfit_isAmmo(o)) return o->u.amm.spfx;
else if(outfit_isTurret(o)) return o->u.wpn.spfx;
else if(outfit_isTurret(o)) return o->u.blt.spfx;
return -1;
}
double outfit_dmgShield(const Outfit* o) {
if(outfit_isWeapon(o)) return o->u.wpn.damage_armour;
if(outfit_isWeapon(o)) return o->u.blt.damage_armour;
else if(outfit_isAmmo(o)) return o->u.amm.damage_armour;
else if(outfit_isTurret(o)) return o->u.wpn.damage_armour;
else if(outfit_isTurret(o)) return o->u.blt.damage_armour;
return -1;
}
double outfit_dmgArmour(const Outfit* o) {
if(outfit_isWeapon(o)) return o->u.wpn.damage_shield;
if(outfit_isWeapon(o)) return o->u.blt.damage_shield;
else if(outfit_isAmmo(o)) return o->u.amm.damage_shield;
else if(outfit_isTurret(o)) return o->u.amm.damage_shield;
else if(outfit_isTurret(o)) return o->u.blt.damage_shield;
return -1;
}
int outfit_delay(const Outfit* o) {
if(outfit_isWeapon(o)) return o->u.wpn.delay;
if(outfit_isWeapon(o)) return o->u.blt.delay;
else if(outfit_isLauncher(o)) return o->u.lau.delay;
else if(outfit_isTurret(o)) return o->u.wpn.delay;
else if(outfit_isTurret(o)) return o->u.blt.delay;
return -1;
}
@ -157,38 +157,38 @@ static void outfit_parseSWeapon(Outfit* tmp, const xmlNodePtr parent) {
do {
// Load all the things.
if(xml_isNode(node, "speed")) tmp->u.wpn.speed = xml_getFloat(node);
else if(xml_isNode(node, "delay")) tmp->u.wpn.delay = xml_getInt(node);
else if(xml_isNode(node, "range")) tmp->u.wpn.range = xml_getFloat(node);
else if(xml_isNode(node, "accuracy")) tmp->u.wpn.accuracy = xml_getFloat(node);
if(xml_isNode(node, "speed")) tmp->u.blt.speed = xml_getFloat(node);
else if(xml_isNode(node, "delay")) tmp->u.blt.delay = xml_getInt(node);
else if(xml_isNode(node, "range")) tmp->u.blt.range = xml_getFloat(node);
else if(xml_isNode(node, "accuracy")) tmp->u.blt.accuracy = xml_getFloat(node);
else if(xml_isNode(node, "gfx")) {
snprintf(str, strlen(xml_get(node))+sizeof(OUTFIT_GFX)+4, OUTFIT_GFX"%s.png", xml_get(node));
tmp->u.wpn.gfx_space = gl_newSprite(str, 6, 6);
tmp->u.blt.gfx_space = gl_newSprite(str, 6, 6);
}
else if(xml_isNode(node, "spfx"))
tmp->u.wpn.spfx = spfx_get(xml_get(node));
tmp->u.blt.spfx = spfx_get(xml_get(node));
else if(xml_isNode(node, "sound"))
tmp->u.wpn.sound = sound_get(xml_get(node));
tmp->u.blt.sound = sound_get(xml_get(node));
else if(xml_isNode(node, "damage")) {
cur = node->children;
do {
if(xml_isNode(cur, "armour"))
tmp->u.wpn.damage_armour = xml_getFloat(cur);
tmp->u.blt.damage_armour = xml_getFloat(cur);
else if(xml_isNode(cur, "shield"))
tmp->u.wpn.damage_shield = xml_getFloat(cur);
tmp->u.blt.damage_shield = xml_getFloat(cur);
} while((cur = cur->next));
}
} while((node = node->next));
#define MELEMENT(o,s) if((o) == 0) WARN("Outfit '%s' missing '"s"' element", tmp->name)
if(tmp->u.wpn.gfx_space == NULL)
if(tmp->u.blt.gfx_space == NULL)
WARN("Outfit '%s' missing 'gfx' element", tmp->name);
MELEMENT(tmp->u.wpn.sound, "sound");
MELEMENT(tmp->u.wpn.delay, "delay");
MELEMENT(tmp->u.wpn.speed, "speed");
MELEMENT(tmp->u.wpn.range, "range");
MELEMENT(tmp->u.wpn.accuracy, "accuracy");
MELEMENT(tmp->u.wpn.damage_armour, "armour' from element 'damage");
MELEMENT(tmp->u.wpn.damage_shield, "shield' from element 'damage");
MELEMENT(tmp->u.blt.sound, "sound");
MELEMENT(tmp->u.blt.delay, "delay");
MELEMENT(tmp->u.blt.speed, "speed");
MELEMENT(tmp->u.blt.range, "range");
MELEMENT(tmp->u.blt.accuracy, "accuracy");
MELEMENT(tmp->u.blt.damage_armour, "armour' from element 'damage");
MELEMENT(tmp->u.blt.damage_shield, "shield' from element 'damage");
#undef MELEMENT
}

View File

@ -45,7 +45,7 @@ typedef struct Outfit_ {
// Type dependant.
OutfitType type;
union {
struct { // Beam/Bolt.
struct { // Bolt.
unsigned int delay; // Delay between shots.
double speed; // Speed of shot. (not applicable to beam.
double range;
@ -55,7 +55,13 @@ typedef struct Outfit_ {
glTexture* gfx_space;
ALuint sound; // Sound to play.
int spfx; // Special effect on hit.
} wpn;
} blt;
struct { // Beam.
double range; // Distance it travels.
glColour colour; // Beam colour.
double energy; // Energy drained.
double damage_armour, damage_shield; // Damage.
} bem;
struct { // Launcher.
unsigned int delay; // Delay between shots.
char* ammo;

View File

@ -427,7 +427,7 @@ void player_render(void) {
&cConsole, "%s", player->ammo->outfit->u.lau.ammo);
// Print ammo underneath to the left.
gl_printMid(&gl_smallFont, gui.weapon.w, gui.weapon.x,
gl_printMid(&gl_smallFont, (int)gui.weapon.w, gui.weapon.x,
gui.weapon.y - 10 - gl_defFont.h,
NULL, "%d", (player->ammo) ? player->ammo->quantity : 0);
} else {

View File

@ -334,15 +334,15 @@ static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2*
switch(outfit->type) {
case OUTFIT_TYPE_BOLT:
// Need accuracy and speed based on player. -- Another contribution from VLack.
rdir += RNG(-outfit->u.wpn.accuracy/2., outfit->u.wpn.accuracy/2.)/180.*M_PI;
rdir += RNG(-outfit->u.blt.accuracy/2., outfit->u.blt.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;
vect_cadd(&v, outfit->u.blt.speed*cos(rdir), outfit->u.blt.speed*sin(rdir));
w->timer += 1000*(unsigned int)outfit->u.blt.range/outfit->u.blt.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);
w->solid->vel.x, w->solid->vel.y, w->outfit->u.blt.sound, 0);
break;
case OUTFIT_TYPE_MISSILE_SEEK_AMMO:
mass = w->outfit->mass;
@ -363,16 +363,16 @@ static Weapon* weapon_create(const Outfit* outfit, const double dir, const Vec2*
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;
rdir += RNG(-outfit->u.blt.accuracy/2.,
outfit->u.blt.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;
vect_cadd(&v, outfit->u.blt.speed*cos(rdir), outfit->u.blt.speed*sin(rdir));
w->timer += 1000*(unsigned int)outfit->u.blt.range / outfit->u.blt.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);
w->solid->vel.x, w->solid->vel.y, w->outfit->u.blt.sound, 0);
break;
default:
// Just dump it where the player is.