/** * @brief Loads all the outfits. * * @return 0 on success. */ int outfit_load (void) { int i, mem; uint32_t bufsize; char *buf = ndata_read( OUTFIT_DATA, &bufsize ); xmlNodePtr node; xmlDocPtr doc = xmlParseMemory( buf, bufsize ); node = doc->xmlChildrenNode; if (!xml_isNode(node,XML_OUTFIT_ID)) { ERR("Malformed '"OUTFIT_DATA"' file: missing root element '"XML_OUTFIT_ID"'"); return -1; } node = node->xmlChildrenNode; /* first system node */ if (node == NULL) { ERR("Malformed '"OUTFIT_DATA"' file: does not contain elements"); return -1; } /* First pass, loads up ammunition. */ mem = 0; do { if (xml_isNode(node,XML_OUTFIT_TAG)) { outfit_nstack++; if (outfit_nstack > mem) { mem += CHUNK_SIZE; outfit_stack = realloc(outfit_stack, sizeof(Outfit)*mem); } outfit_parse( &outfit_stack[outfit_nstack-1], node ); } } while (xml_nextNode(node)); /* Shrink back to minimum - shouldn't change ever. */ outfit_stack = realloc(outfit_stack, sizeof(Outfit) * outfit_nstack); /* Second pass, sets up ammunition relationships. */ for (i=0; i<outfit_nstack; i++) { if (outfit_isLauncher(&outfit_stack[i])) outfit_stack[i].u.lau.ammo = outfit_get( outfit_stack[i].u.lau.ammo_name ); else if (outfit_isFighterBay(&outfit_stack[i])) outfit_stack[i].u.bay.ammo = outfit_get( outfit_stack[i].u.bay.ammo_name ); } xmlFreeDoc(doc); free(buf); DEBUG("Loaded %d Outfit%s", outfit_nstack, (outfit_nstack==1) ? "" : "s" ); return 0; }
/** * @brief Removes an outfit from the player's outfit list. * * "all" will remove all outfits. * * @usage player.rmOutfit( "Plasma Blaster", 2 ) -- Removes two plasma blasters from the player * * @luaparam name Name of the outfit to give. * @luaparam q Optional parameter that sets the quantity to give (default 1). * @luafunc rmOutfit( name, q ) */ static int playerL_rmOutfit( lua_State *L ) { const char *str; char **outfits; Outfit *o; int i, q, noutfits; /* Defaults. */ q = 1; /* Handle parameters. */ str = luaL_checkstring(L, 1); if (lua_gettop(L) > 1) q = luaL_checkint(L, 2); if (strcmp(str,"all")==0) { noutfits = player_numOutfits(); /* Removing nothing is a bad idea. */ if (noutfits == 0) return 0; outfits = malloc( sizeof(char*) * noutfits ); player_getOutfits(outfits, NULL); for (i=0; i<noutfits; i++) { o = outfit_get(outfits[i]); q = player_outfitOwned(o); player_rmOutfit(o, q); /* Free memory. */ free( outfits[i] ); } /* Clean up. */ free(outfits); } else { /* Get outfit. */ o = outfit_get( str ); if (o==NULL) { NLUA_ERROR(L, "Outfit '%s' not found.", str); return 0; } /* Remove the outfits. */ player_rmOutfit( o, q ); } /* Update equipment list. */ outfits_updateEquipmentOutfits(); return 0; }
/** * @brief Adds an outfit to the player's outfit list. * * @usage player.addOutfit( "Laser Cannon" ) -- Gives the player a laser cannon * @usage player.addOutfit( "Plasma Blaster", 2 ) -- Gives the player two plasma blasters * * @luaparam name Name of the outfit to give. * @luaparam q Optional parameter that sets the quantity to give (default 1). * @luafunc addOutfit( name, q ) */ static int playerL_addOutfit( lua_State *L ) { const char *str; Outfit *o; int q; /* Defaults. */ q = 1; /* Handle parameters. */ str = luaL_checkstring(L, 1); if (lua_gettop(L) > 1) q = luaL_checkint(L, 2); /* Get outfit. */ o = outfit_get( str ); if (o==NULL) { NLUA_ERROR(L, "Outfit '%s' not found.", str); return 0; } /* Add the outfits. */ player_addOutfit( o, q ); /* Update equipment list. */ outfits_updateEquipmentOutfits(); return 0; }
/** * @brief Adds an outfit to a pilot. * * @usage added = p:addOutfit( "Laser Cannon", 5 ) -- Adds 5 laser cannons to p * * @luaparam p Pilot to add outfit to. * @luaparam outfit Name of the outfit to add. * @luaparam q Amount to add. * @luareturn The amount actually added. * @luafunc addOutfit( p, outfit, q ) */ static int pilotL_addOutfit( lua_State *L ) { LuaPilot *lp; Pilot *p; const char *outfit; int q, n; Outfit *o; /* Get the pilot. */ lp = luaL_checkpilot(L,1); p = pilot_get(lp->pilot); if (p==NULL) { NLUA_ERROR(L,"Pilot is invalid."); return 0; } /* Get parameters. */ outfit = luaL_checkstring(L,2); q = luaL_checkint(L,3); /* Get the outfit. */ o = outfit_get( outfit ); if (o == NULL) return 0; /* Add outfit. */ n = pilot_addOutfit( p, o, q ); lua_pushnumber(L,n); return 1; }
/** * @brief Adds the "Buy Local Map" button if needed. */ void land_checkAddMap (void) { char buf[ECON_CRED_STRLEN], cred[ECON_CRED_STRLEN]; Outfit *o; /* Maps are only offered if the planet provides fuel. */ if (!planet_hasService(land_planet, PLANET_SERVICE_REFUEL)) return; o = outfit_get( LOCAL_MAP_NAME ); if (o == NULL) { WARN("Outfit '%s' does not exist!", LOCAL_MAP_NAME); return; } /* Just enable button if it exists. */ if (widget_exists( land_windows[0], "btnMap" )) window_enableButton( land_windows[0], "btnMap"); /* Else create it. */ else { /* Refuel button. */ credits2str( cred, o->price, 2 ); nsnprintf( buf, sizeof(buf), "Buy Local Map (%s)", cred ); window_addButtonKey( land_windows[0], -20, 20 + (LAND_BUTTON_HEIGHT + 20), LAND_BUTTON_WIDTH,LAND_BUTTON_HEIGHT, "btnMap", buf, spaceport_buyMap, SDLK_b ); } /* Make sure player can click it. */ if (!outfit_canBuy(LOCAL_MAP_NAME, land_planet)) window_disableButtonSoft( land_windows[0], "btnMap" ); }
/** * @brief Buys a local system map. */ static void spaceport_buyMap( unsigned int wid, char *str ) { (void) wid; (void) str; Outfit *o; unsigned int w; /* Make sure the map isn't already known, etc. */ if (land_errDialogue( LOCAL_MAP_NAME, "buyOutfit" )) return; o = outfit_get( LOCAL_MAP_NAME ); if (o == NULL) { WARN("Outfit '%s' does not exist!", LOCAL_MAP_NAME); return; } player_modCredits( -o->price ); player_addOutfit(o, 1); /* Disable the button. */ window_disableButtonSoft( land_windows[0], "btnMap" ); /* Update map quantity in outfitter. */ w = land_getWid( LAND_WINDOW_OUTFITS ); if (w > 0) outfits_regenList( w, NULL ); }
/** * @brief Removes an outfit from a pilot. * * "all" will remove all outfits. * * @usage p:rmOutfit( "all" ) -- Leaves the pilot naked. * @usage p:rmOutfit( "Neutron Disruptor", 1 ) -- Removes a neutron disruptor. * * @luparam p Pilot to remove outfit from. * @luaparam outfit Name of the outfit to remove. * @luaparam q Amount to remove. * @luareturn The amount actually removed. * @luafunc rmOutfit( p, outfit, q ) */ static int pilotL_rmOutfit( lua_State *L ) { LuaPilot *lp; Pilot *p; const char *outfit; int q, n; Outfit *o; /* Get the pilot. */ lp = luaL_checkpilot(L,1); p = pilot_get(lp->pilot); if (p==NULL) { NLUA_ERROR(L,"Pilot is invalid."); return 0; } /* Get parameters. */ outfit = luaL_checkstring(L,2); /* If outfit is "all", we remove everything. */ if (strcmp(outfit,"all")==0) { n = 0; while (p->outfits != NULL) { pilot_rmOutfit( p, p->outfits[0].outfit, p->outfits[0].quantity ); n++; } lua_pushnumber(L,n); return 1; } /* We'll need a quantity now. */ q = luaL_checkint(L,3); /* Get the outfit. */ o = outfit_get( outfit ); if (o == NULL) { NLUA_ERROR(L,"Outfit isn't found in outfit stack."); return 0; } /* Add outfit. */ n = pilot_rmOutfit( p, o, q ); lua_pushnumber(L,n); return 1; }
/** * @brief Makes sure the outfit is valid or raises a Lua error. * * @param L State currently running. * @param ind Index of the outfit to validate. * @return The outfit (doesn't return if fails - raises Lua error ). */ Outfit* luaL_validoutfit( lua_State *L, int ind ) { Outfit *o; if (lua_isoutfit(L, ind)) o = luaL_checkoutfit(L,ind); else if (lua_isstring(L, ind)) o = outfit_get( lua_tostring(L, ind) ); else { luaL_typerror(L, ind, OUTFIT_METATABLE); return NULL; } if (o == NULL) NLUA_ERROR(L, "Outfit is invalid."); return o; }
/** * @brief Gets a outfit. * * @usage s = outfit.get( "Heavy Laser" ) -- Gets the heavy laser * * @luaparam s Name of the outfit to get. * @luareturn The outfit matching name or nil if error. * @luafunc get( s ) */ static int outfitL_get( lua_State *L ) { const char *name; Outfit *lo; /* Handle parameters. */ name = luaL_checkstring(L,1); /* Get outfit. */ lo = outfit_get( name ); if (lo == NULL) { NLUA_ERROR(L,"Outfit '%s' not found!", name); return 0; } /* Push. */ lua_pushoutfit(L, lo); return 1; }
/** * @brief Gets the number of outfits the player owns in their list (excludes equipped on ships). * * @usage q = player.numOutfit( "Laser Cannon" ) -- Number of 'Laser Cannons' the player owns (unequipped) * * @luaparam name Name of the outfit to give. * @luareturn The quantity the player owns. * @luafunc numOutfit( name ) */ static int playerL_numOutfit( lua_State *L ) { const char *str; Outfit *o; int q; /* Handle parameters. */ str = luaL_checkstring(L, 1); /* Get outfit. */ o = outfit_get( str ); if (o==NULL) { NLUA_ERROR(L, "Outfit '%s' not found.", str); return 0; } /* Count the outfit. */ q = player_outfitOwned( o ); lua_pushnumber( L, q ); return 1; }
/** * @brief Updates the outfits in the outfit window. * @param wid Window to update the outfits in. * @param str Unused. */ void outfits_update( unsigned int wid, char* str ) { (void)str; char *outfitname; Outfit* outfit; char buf[PATH_MAX], buf2[ECON_CRED_STRLEN], buf3[ECON_CRED_STRLEN]; double th; int iw, ih; int w, h; /* Get dimensions. */ outfits_getSize( wid, &w, &h, &iw, &ih, NULL, NULL ); /* Get and set parameters. */ outfitname = toolkit_getImageArray( wid, "iarOutfits" ); if (strcmp(outfitname,"None")==0) { /* No outfits */ window_modifyImage( wid, "imgOutfit", NULL, 0, 0 ); window_disableButton( wid, "btnBuyOutfit" ); window_disableButton( wid, "btnSellOutfit" ); snprintf( buf, PATH_MAX, "NA\n" "\n" "NA\n" "NA\n" "NA\n" "\n" "NA\n" "NA\n" "NA\n" ); window_modifyText( wid, "txtDDesc", buf ); window_modifyText( wid, "txtOutfitName", "None" ); window_modifyText( wid, "txtDescShort", NULL ); /* Reposition. */ window_moveWidget( wid, "txtSDesc", 20+iw+20, -60 ); window_moveWidget( wid, "txtDDesc", 20+iw+20+60, -60 ); window_moveWidget( wid, "txtDescription", 20+iw+40, -240 ); return; } outfit = outfit_get( outfitname ); /* new image */ window_modifyImage( wid, "imgOutfit", outfit->gfx_store, 0, 0 ); if (outfit_canBuy(outfit,1,0) > 0) window_enableButton( wid, "btnBuyOutfit" ); else window_disableButton( wid, "btnBuyOutfit" ); /* gray out sell button */ if (outfit_canSell(outfit,1,0) > 0) window_enableButton( wid, "btnSellOutfit" ); else window_disableButton( wid, "btnSellOutfit" ); /* new text */ window_modifyText( wid, "txtDescription", outfit->description ); credits2str( buf2, outfit->price, 2 ); credits2str( buf3, player.p->credits, 2 ); snprintf( buf, PATH_MAX, "%d\n" "\n" "%s\n" "%s\n" "%.0f tons\n" "\n" "%s credits\n" "%s credits\n" "%s\n", player_outfitOwned(outfit), outfit_slotName(outfit), outfit_slotSize(outfit), outfit->mass, buf2, buf3, (outfit->license != NULL) ? outfit->license : "None" ); window_modifyText( wid, "txtDDesc", buf ); window_modifyText( wid, "txtOutfitName", outfit->name ); window_modifyText( wid, "txtDescShort", outfit->desc_short ); th = MAX( 128, gl_printHeightRaw( &gl_smallFont, 320, outfit->desc_short ) ); window_moveWidget( wid, "txtSDesc", 40+iw+20, -60-th-20 ); window_moveWidget( wid, "txtDDesc", 40+iw+20+60, -60-th-20 ); th += gl_printHeightRaw( &gl_smallFont, 250, buf ); window_moveWidget( wid, "txtDescription", 20+iw+40, -60-th-20 ); }