From 9fae81c3896ffdc4a75e642dad03355cb40e5ff7 Mon Sep 17 00:00:00 2001 From: Allanis <allanis@saracraft.net> Date: Thu, 14 Feb 2013 14:25:32 +0000 Subject: [PATCH] [Fix] AI's landing, it's still not as good as I wish however. [Add] A few more xml macros and cleaned up a little code to use them. --- dat/outfit.xml | 4 ++-- src/ai.c | 2 +- src/outfit.c | 58 +++++++++++++++++++++----------------------------- src/outfit.h | 26 +++++++++++----------- src/pilot.c | 40 ++++++++++++++++++++++------------ src/space.c | 3 +++ src/space.h | 1 + src/xml.h | 9 ++++++-- 8 files changed, 77 insertions(+), 66 deletions(-) diff --git a/dat/outfit.xml b/dat/outfit.xml index 8604419..7323505 100644 --- a/dat/outfit.xml +++ b/dat/outfit.xml @@ -7,8 +7,8 @@ <mass>1</mass> </general> <specific type = "1"> - <sound>laser.wav</sound> - <gfx>lasergreen.png</gfx> + <sound>laser</sound> + <gfx>lasergreen</gfx> <delay>500</delay> <speed>550</speed> <range>300</range> diff --git a/src/ai.c b/src/ai.c index 751c834..f43a299 100644 --- a/src/ai.c +++ b/src/ai.c @@ -491,7 +491,7 @@ static int ai_minbrakedist(lua_State* L) { double time = VMOD(cur_pilot->solid->vel) / (cur_pilot->ship->thrust / cur_pilot->solid->mass); - double dist = VMOD(cur_pilot->solid->vel) * (time + cur_pilot->ship->turn/180.) - + double dist = VMOD(cur_pilot->solid->vel) * (time + 180./cur_pilot->ship->turn) - 0.5 * (cur_pilot->ship->thrust / cur_pilot->solid->mass)*time*time; lua_pushnumber(L, dist); // return diff --git a/src/outfit.c b/src/outfit.c index e733b75..3f6b2f8 100644 --- a/src/outfit.c +++ b/src/outfit.c @@ -81,27 +81,20 @@ static void outfit_parseSWeapon(Outfit* tmp, const xmlNodePtr parent) { do { // Load all the things. - if(strcmp((char*)node->name, "speed")==0) - tmp->speed = (double)atoi((char*)node->children->content); - else if(strcmp((char*)node->name, "delay")==0) - tmp->delay = atoi((char*)node->children->content); - else if(strcmp((char*)node->name, "range")==0) - tmp->range = atof((char*) node->children->content); - else if(strcmp((char*)node->name, "accuracy")==0) - tmp->accuracy = atof((char*)node->children->content); - else if(strcmp((char*)node->name, "gfx")==0) { - snprintf(str, strlen((char*)node->children->content)+sizeof(OUTFIT_GFX), - OUTFIT_GFX"%s", (char*)node->children->content); + if(xml_isNode(node, "speed")) tmp->speed = xml_getFloat(node); + else if(xml_isNode(node, "delay")) tmp->delay = xml_getInt(node); + else if(xml_isNode(node, "range")) tmp->range = xml_getFloat(node); + else if(xml_isNode(node, "accuracy")) tmp->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->gfx_space = gl_newSprite(str, 6, 6); } - if(strcmp((char*)node->name, "damage")==0) { + else if(xml_isNode(node, "damage")) { cur = node->children; - while((cur = cur->next)) { - if(strcmp((char*)cur->name, "armor")==0) - tmp->damage_armor = atof((char*)cur->children->content); - else if(strcmp((char*)cur->name, "shield")==0) - tmp->damage_shield = atof((char*)cur->children->content); - } + do { + if(xml_isNode(cur, "armor")) tmp->damage_armor = xml_getFloat(cur); + else if(xml_isNode(cur, "shield")) tmp->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) @@ -119,31 +112,28 @@ static void outfit_parseSWeapon(Outfit* tmp, const xmlNodePtr parent) { static Outfit* outfit_parse(const xmlNodePtr parent) { Outfit* tmp = CALLOC_L(Outfit); xmlNodePtr cur, node; - xmlChar* prop; + char* prop; - tmp->name = (char*)xmlGetProp(parent, (xmlChar*)"name"); // Already mallocs. + tmp->name = xml_nodeProp(parent, "name"); // Already malloced. if(tmp->name == NULL) WARN("Outfit in "OUTFIT_DATA" has invalid or no name"); node = parent->xmlChildrenNode; do { // Load all the things. - if(strcmp((char*)node->name, "general")==0) { + if(xml_isNode(node, "general")) { cur = node->children; - while((cur = cur->next)) { - if(strcmp((char*)cur->name, "max")==0) - tmp->max = atoi((char*)cur->children->content); - else if(strcmp((char*)cur->name, "tech")==0) - tmp->tech = atoi((char*)cur->children->content); - else if(strcmp((char*)cur->name, "mass")== 0) - tmp->mass = atoi((char*)cur->children->content); - } + do { + if(xml_isNode(cur, "max")) tmp->max = xml_getInt(cur); + else if(xml_isNode(cur, "tech")) tmp->tech = xml_getInt(cur); + else if(xml_isNode(cur, "mass")) tmp->mass = xml_getInt(cur); + } while((cur = cur->next)); } - else if(strcmp((char*)node->name, "specific")==0) { + else if(xml_isNode(node, "specific")) { // Has to be processed seperately. - prop = xmlGetProp(node,(xmlChar*)"type"); + prop = xml_nodeProp(node, "type"); if(prop == NULL) ERR("Outfit '%s' element 'specific' missing property 'type'", tmp->name); - tmp->type = atoi((char*)prop); + tmp->type = atoi(prop); free(prop); switch(tmp->type) { case OUTFIT_TYPE_NULL: @@ -180,7 +170,7 @@ int outfit_load(void) { xmlDocPtr doc = xmlParseMemory(buf, bufsize); node = doc->xmlChildrenNode; - if(strcmp((char*)node->name, XML_OUTFIT_ID)) { + if(!xml_isNode(node, XML_OUTFIT_ID)) { ERR("Malformed "OUTFIT_DATA" file: missing root element '"XML_OUTFIT_ID"'"); return -1; } @@ -192,7 +182,7 @@ int outfit_load(void) { } do { - if(node->type == XML_NODE_START && strcmp((char*)node->name, XML_OUTFIT_TAG)==0) { + if(xml_isNode(node, XML_OUTFIT_TAG)) { tmp = outfit_parse(node); outfit_stack = realloc(outfit_stack, sizeof(Outfit)*(++outfits)); memcpy(outfit_stack+outfits-1, tmp, sizeof(Outfit)); diff --git a/src/outfit.h b/src/outfit.h index 235f674..18d41f9 100644 --- a/src/outfit.h +++ b/src/outfit.h @@ -6,19 +6,19 @@ // Outfit types. typedef enum { - OUTFIT_TYPE_NULL = 0, - OUTFIT_TYPE_BOLT, - OUTFIT_TYPE_BEAM, - OUTFIT_TYPE_MISSILE_DUMB, - OUTFIT_TYPE_MISSILE_DUMB_AMMO, - OUTFIT_TYPE_MISSILE_SEEK, - OUTFIT_TYPE_MISSILE_SEEK_AMMO, - OUTFIT_TYPE_MISSILE_SEEK_SMART, - OUTFIT_TYPE_MISSILE_SEEK_SMART_AMMO, - OUTFIT_TYPE_MISSILE_SWARM, - OUTFIT_TYPE_MISSILE_SWARM_AMMO, - OUTFIT_TYPE_MISSILE_SWARM_SMART, - OUTFIT_TYPE_MISSILE_SWARM_SMART_AMMO + OUTFIT_TYPE_NULL = 0, + OUTFIT_TYPE_BOLT = 1, + OUTFIT_TYPE_BEAM = 2, + OUTFIT_TYPE_MISSILE_DUMB = 3, + OUTFIT_TYPE_MISSILE_DUMB_AMMO = 4, + OUTFIT_TYPE_MISSILE_SEEK = 5, + OUTFIT_TYPE_MISSILE_SEEK_AMMO = 6, + OUTFIT_TYPE_MISSILE_SEEK_SMART = 7, + OUTFIT_TYPE_MISSILE_SEEK_SMART_AMMO = 8, + OUTFIT_TYPE_MISSILE_SWARM = 9, + OUTFIT_TYPE_MISSILE_SWARM_AMMO = 10, + OUTFIT_TYPE_MISSILE_SWARM_SMART = 11, + OUTFIT_TYPE_MISSILE_SWARM_SMART_AMMO = 12 } OutfitType; // An outfit depends a lot on the type. diff --git a/src/pilot.c b/src/pilot.c index a5b8e9e..a371f52 100644 --- a/src/pilot.c +++ b/src/pilot.c @@ -40,15 +40,19 @@ static Fleet* fleet_parse(const xmlNodePtr parent); // Get the next pilot based on id. unsigned int pilot_getNext(const unsigned int id) { - // Regular search. - int i; - for(i = 0; i < pilots; i++) - if(pilot_stack[i]->id == id) - break; + // Dichotmical search. + int l, m, h; + l = 0; + h = pilots-1; + while(l <= h) { + m = (l+h)/2; + if(pilot_stack[m]->id > id) h = m-1; + else if(pilot_stack[m]->id < id) l = m+1; + else break; + } - if(i == pilots-1) return PLAYER_ID; - - return pilot_stack[i+1]->id; + if(m == (pilots-1)) return PLAYER_ID; + else return pilot_stack[m+1]->id; } // Get the nearest enemy to the pilot -- Tamir's (insightful) request. @@ -87,6 +91,7 @@ unsigned pilot_getHostile(void) { // Pull a pilot out of the pilot_stack based on id. Pilot* pilot_get(const unsigned int id) { // Regular search. +#if 0 int i; for(i = 0; i < pilots; i++) if(pilot_stack[i]->id == id) @@ -94,13 +99,20 @@ Pilot* pilot_get(const unsigned int id) { return NULL; if(id == 0) return player; -#if 0 - // Dichotomical search. - int i, n; - for(i = 0, n = pilots/2; n > 0; n /= 2) - i += (pilot_stack[i+n]->id > id) ? 0 : n; - return (pilot_stack[i]->id == id) ? pilot_stack[i] : NULL; #endif + if(id == PLAYER_ID) return player; // Special case player. + + // Dichotomical search. + int l, m, h; + l = 0; + h = pilots-1; + while(l <= h) { + m = (l+h)/2; + if(pilot_stack[m]->id > id) h = m-1; + else if(pilot_stack[m]->id < id) l = m+1; + else return pilot_stack[m]; + } + return NULL; } // Mkay, this is how we shoot. Listen up. diff --git a/src/space.c b/src/space.c index 19380e4..0403cd8 100644 --- a/src/space.c +++ b/src/space.c @@ -152,6 +152,9 @@ int space_hyperspace(Pilot* p) { if(d < MIN_HYPERSPACE_DIST) return (int)(MIN_HYPERSPACE_DIST - d); } + // Too fast. + if(VMOD(p->solid->vel) > MAX_HYPERSPACE_VEL) return -1; + // TODO: All hyperspace worky work. if(p == player) { // Player crap. diff --git a/src/space.h b/src/space.h index 86fd2c1..c1d2b12 100644 --- a/src/space.h +++ b/src/space.h @@ -4,6 +4,7 @@ #include "pilot.h" #define MIN_HYPERSPACE_DIST 1500 +#define MAX_HYPERSPACE_VEL 3 // Planet types. I didn't take them from Star Trek, I promise. typedef enum { diff --git a/src/xml.h b/src/xml.h index 053300e..1d918f9 100644 --- a/src/xml.h +++ b/src/xml.h @@ -6,8 +6,13 @@ #define XML_NODE_TEXT 3 // Check if node n is of name s. -#define xml_isNode(n,s) ((n)->type == XML_NODE_START) && \ - (strcmp((char*)(n)->name, s)==0) +#define xml_isNode(n,s) (((n)->type == XML_NODE_START) && \ + (strcmp((char*)(n)->name, s)==0)) +// Get the property s of node n. This mallocs. #define xml_nodeProp(n,s) (char*)xmlGetProp(n, (xmlChar*)s) +#define xml_get(n) (char*)(n)->children->content +#define xml_getInt(n) atoi((char*)(n)->children->content) +#define xml_getFloat(n) atof((char*)(n)->children->content) +