diff --git a/src/outfit.c b/src/outfit.c index 222abd0..80e53f4 100644 --- a/src/outfit.c +++ b/src/outfit.c @@ -36,6 +36,7 @@ static void outfit_parseSAmmo(Outfit* tmp, const xmlNodePtr parent); static void outfit_parseSMod(Outfit* tmp, const xmlNodePtr parent); static void outfit_parseSAfterburner(Outfit* tmp, const xmlNodePtr parent); static void outfit_parseSMap(Outfit* tmp, const xmlNodePtr parent); +static void outfit_parseSJammer(Outfit* tmp, const xmlNodePtr parent); /* Return an outfit. */ Outfit* outfit_get(const char* name) { @@ -186,6 +187,11 @@ int outfit_isMap(const Outfit* o) { return(o->type == OUTFIT_TYPE_MAP); } +/* Return 1 if o is a jammer. */ +int outfit_isJammer(const Outfit* o) { + return(o->type == OUTFIT_TYPE_JAMMER); +} + /* Get the outfit graphics. */ glTexture* outfit_gfx(const Outfit* o) { if(outfit_isWeapon(o)) return o->u.blt.gfx_space; @@ -264,7 +270,8 @@ const char* outfit_typename[] = { "Smart Swarm Missile Ammunition Pack", "Ship Modification", "Afterburner", - "Map" + "Map", + "Jammer" }; const char* outfit_getType(const Outfit* o) { @@ -280,7 +287,8 @@ const char* outfit_typenamebroad[] = { "Turret", "Modification", "Afterburner", - "Map" + "Map", + "Jammer" }; const char* outfit_getTypeBroad(const Outfit* o) { @@ -292,6 +300,7 @@ const char* outfit_getTypeBroad(const Outfit* o) { else if(outfit_isMod(o)) i = 5; else if(outfit_isAfterburner(o)) i = 6; else if(outfit_isMap(o)) i = 7; + else if(outfit_isJammer(o)) i = 8; return outfit_typenamebroad[i]; } @@ -328,6 +337,7 @@ static OutfitType outfit_strToOutfitType(char* buf) { O_CMP("modification", OUTFIT_TYPE_MODIFICATION); O_CMP("afterburner", OUTFIT_TYPE_AFTERBURNER); O_CMP("map", OUTFIT_TYPE_MAP); + O_CMP("jammer", OUTFIT_TYPE_JAMMER); WARN("Invalid outfit type '%s'", buf); return OUTFIT_TYPE_NULL; @@ -338,14 +348,17 @@ static int outfit_parseDamage(DamageType* dtype, double* dmg, xmlNodePtr node) { char* buf; if(xml_isNode(node, "damage")) { + /* Get type. */ xmlr_attr(node, "type", buf); (*dtype) = outfit_strToDamageType(buf); if(buf) free(buf); + /* Get damage. */ (*dmg) = xml_getFloat(node); return 0; } + /* Unknown type. */ (*dtype) = DAMAGE_TYPE_NULL; (*dmg) = 0; WARN("Trying to parse non-damage node as damage node!"); @@ -504,9 +517,31 @@ static void outfit_parseSMap(Outfit* tmp, const xmlNodePtr parent) { node = parent->children; do { - if(xml_isNode(node, "radius")) - tmp->u.map.radius = xml_getInt(node); + xmlr_int(node, "radius", tmp->u.map.radius); } while(xml_nextNode(node)); + + if(tmp->u.map.radius == 0) + WARN("Outfit '%s' missing/invalid 'radius' element", tmp->name); +} + +/* Parses the jammer tidbits of the outfit. */ +static void outfit_parseSJammer(Outfit* tmp, const xmlNodePtr parent) { + xmlNodePtr node; + node = parent->children; + + do { + xmlr_float(node, "range", tmp->u.jam.range); + xmlr_float(node, "chance", tmp->u.jam.chance); + xmlr_float(node, "energy", tmp->u.jam.energy); + } while(xml_nextNode(node)); + + tmp->u.jam.chance /= 100.; /* Put in per one, instead of percent. */ + +#define MELEMENT(o, s) \ + if(o) WARN("Outfit '%s' missing/invalid '"s"' element", tmp->name) + MELEMENT(tmp->u.jam.range==0., "range"); + MELEMENT(tmp->u.jam.chance==0., "chance"); +#undef MELEMENT } /* Parse and return Outfits from parent node. */ @@ -569,6 +604,8 @@ static Outfit* outfit_parse(const xmlNodePtr parent) { outfit_parseSAfterburner(tmp, node); else if(outfit_isMap(tmp)) outfit_parseSMap(tmp, node); + else if(outfit_isJammer(tmp)) + outfit_parseSJammer(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 d85a6a5..afce9ce 100644 --- a/src/outfit.h +++ b/src/outfit.h @@ -26,6 +26,7 @@ typedef enum OutfitType_ { OUTFIT_TYPE_MODIFICATION, OUTFIT_TYPE_AFTERBURNER, OUTFIT_TYPE_MAP, + OUTFIT_TYPE_JAMMER, OUTFIT_TYPE_SENTINEL /* Indicates last type. */ } OutfitType; @@ -117,6 +118,11 @@ typedef struct Outfit_ { struct { /* Map. */ double radius; /* Amount of systems to add */ } map; + struct { + double range; /* Range it starts to do effect. */ + double chance; /* Chance of it nullifying the missile. */ + double energy; /* Energy it uses to run. */ + } jam; } u; } Outfit; @@ -135,6 +141,7 @@ int outfit_isTurret(const Outfit* o); int outfit_isMod(const Outfit* o); int outfit_isAfterburner(const Outfit* o); int outfit_isMap(const Outfit* o); +int outfit_isJammer(const Outfit* o); const char* outfit_getType(const Outfit* o); const char* outfit_getTypeBroad(const Outfit* o);