/** * @brief Checks if should add the refuel button and does if needed. */ void land_checkAddRefuel (void) { char buf[ECON_CRED_STRLEN], cred[ECON_CRED_STRLEN]; unsigned int w; /* Check to see if fuel conditions are met. */ if (!planet_hasService(land_planet, PLANET_SERVICE_REFUEL)) { if (!widget_exists( land_windows[0], "txtRefuel" )) window_addText( land_windows[0], -20, 20 + (LAND_BUTTON_HEIGHT + 20) + 20, 200, gl_defFont.h, 1, "txtRefuel", &gl_defFont, &cBlack, "No refueling services." ); return; } /* Full fuel. */ if (player.p->fuel >= player.p->fuel_max) { if (widget_exists( land_windows[0], "btnRefuel" )) window_destroyWidget( land_windows[0], "btnRefuel" ); if (widget_exists( land_windows[0], "txtRefuel" )) window_destroyWidget( land_windows[0], "txtRefuel" ); return; } /* Autorefuel. */ if (conf.autorefuel) { spaceport_refuel( land_windows[0], "btnRefuel" ); w = land_getWid( LAND_WINDOW_EQUIPMENT ); if (w > 0) equipment_updateShips( w, NULL ); /* Must update counter. */ if (player.p->fuel >= player.p->fuel_max) return; } /* Just enable button if it exists. */ if (widget_exists( land_windows[0], "btnRefuel" )) { window_enableButton( land_windows[0], "btnRefuel"); credits2str( cred, player.p->credits, 2 ); nsnprintf( buf, sizeof(buf), "Credits: %s", cred ); window_modifyText( land_windows[0], "txtRefuel", buf ); } /* Else create it. */ else { /* Refuel button. */ credits2str( cred, refuel_price(), 2 ); nsnprintf( buf, sizeof(buf), "Refuel %s", cred ); window_addButton( land_windows[0], -20, 20 + (LAND_BUTTON_HEIGHT + 20), LAND_BUTTON_WIDTH,LAND_BUTTON_HEIGHT, "btnRefuel", buf, spaceport_refuel ); /* Player credits. */ credits2str( cred, player.p->credits, 2 ); nsnprintf( buf, sizeof(buf), "Credits: %s", cred ); window_addText( land_windows[0], -20, 20 + 2*(LAND_BUTTON_HEIGHT + 20), LAND_BUTTON_WIDTH, gl_smallFont.h, 1, "txtRefuel", &gl_smallFont, &cBlack, buf ); } /* Make sure player can click it. */ if (!player_hasCredits( refuel_price() )) window_disableButton( land_windows[0], "btnRefuel" ); }
/** * @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 Opens up all the land dialogue stuff. * @param p Planet to open stuff for. * @param load Whether or not loading the game. */ void land( Planet* p, int load ) { /* Do not land twice. */ if (landed) return; /* Resets the player's heat. */ pilot_heatReset( player.p ); /* Stop player sounds. */ player_soundStop(); /* Load stuff */ land_planet = p; gfx_exterior = gl_newImage( p->gfx_exterior, 0 ); /* Generate the news. */ if (planet_hasService(land_planet, PLANET_SERVICE_BAR)) news_load(); /* Clear the NPC. */ npc_clear(); /* Create all the windows. */ land_genWindows( load, 0 ); /* Hack so that load can run player.takeoff(). */ if (load) hooks_run( "load" ); /* Mission forced take off. */ if (land_takeoff) takeoff(0); }
/** * @brief Checks for planet services. * * Possible services are:<br /> * - "land"<br /> * - "inhabited"<br /> * - "refuel"<br /> * - "bar"<br /> * - "missions"<br /> * - "commodity"<br /> * - "outfits"<br /> * - "shipyard"<br /> * * @usage if #p:services() > 0 then -- Planet has services * @usage if p:serivces()["refuel"] then -- PLanet has refuel service. * #usage if p:services()["shipyard"] then -- Planet has shipyard service. * @luaparam p Planet to get the services of. * @luareturn Table containing all the services. * @luafunc services( p ) */ static int planetL_services( lua_State *L ) { LuaPlanet *lp; Planet *p; lp = luaL_checkplanet(L,1); p = lp->p; /* Return result in table */ lua_newtable(L); /* allows syntax foo = space.faction("foo"); if foo["bar"] then ... end */ if (planet_hasService(p, PLANET_SERVICE_LAND)) { lua_pushboolean(L,1); /* value */ lua_setfield(L,-2,"land"); /* key */ } if (planet_hasService(p, PLANET_SERVICE_INHABITED)) { lua_pushboolean(L,1); /* value */ lua_setfield(L,-2,"inhabited"); /* key */ } if (planet_hasService(p, PLANET_SERVICE_REFUEL)) { lua_pushboolean(L,1); /* value */ lua_setfield(L,-2,"refuel"); /* key */ } if (planet_hasService(p, PLANET_SERVICE_BAR)) { lua_pushboolean(L,1); /* value */ lua_setfield(L,-2,"bar"); /* key */ } if (planet_hasService(p, PLANET_SERVICE_MISSIONS)) { lua_pushboolean(L,1); /* value */ lua_setfield(L,-2,"missions"); /* key */ } if (planet_hasService(p, PLANET_SERVICE_COMMODITY)) { lua_pushboolean(L,1); /* value */ lua_setfield(L,-2,"commodity"); /* key */ } if (planet_hasService(p, PLANET_SERVICE_OUTFITS)) { lua_pushboolean(L,1); /* value */ lua_setfield(L,-2,"outfits"); /* key */ } if (planet_hasService(p, PLANET_SERVICE_SHIPYARD)) { lua_pushboolean(L,1); /* value */ lua_setfield(L,-2,"shipyard"); /* key */ } return 1; }
/** * @brief Creates the main tab. * * @param wid Window to create main tab. */ static void land_createMainTab( unsigned int wid ) { glTexture *logo; int offset; int w,h; /* Get window dimensions. */ window_dimWindow( wid, &w, &h ); /* * Faction logo. */ offset = 20; if (land_planet->faction != -1) { logo = faction_logoSmall(land_planet->faction); if (logo != NULL) { window_addImage( wid, 440 + (w-460-logo->w)/2, -20, 0, 0, "imgFaction", logo, 0 ); offset = 84; } } /* * Pretty display. */ window_addImage( wid, 20, -40, 0, 0, "imgPlanet", gfx_exterior, 1 ); window_addText( wid, 440, -20-offset, w-460, h-20-offset-60-LAND_BUTTON_HEIGHT*2, 0, "txtPlanetDesc", &gl_smallFont, &cBlack, land_planet->description); /* * buttons */ /* first column */ window_addButtonKey( wid, -20, 20, LAND_BUTTON_WIDTH, LAND_BUTTON_HEIGHT, "btnTakeoff", "Take Off", land_buttonTakeoff, SDLK_t ); /* Add "no refueling" notice if needed. */ if (!planet_hasService(land_planet, PLANET_SERVICE_REFUEL)) { window_addText( land_windows[0], -20, 20 + (LAND_BUTTON_HEIGHT + 20) + 20, 200, gl_defFont.h, 1, "txtRefuel", &gl_defFont, &cBlack, "No refueling services." ); } }
/** * @brief Refuels the player's current ship, if possible. */ void land_refuel (void) { unsigned int w; /* Full fuel. */ if (player.p->fuel >= player.p->fuel_max) return; /* No refuel service. */ if (!planet_hasService(land_planet, PLANET_SERVICE_REFUEL)) return; player.p->fuel = player.p->fuel_max; w = land_getWid( LAND_WINDOW_EQUIPMENT ); if (w > 0) equipment_updateShips( w, NULL ); /* Must update counter. */ }
/** * @brief Calculates the intensity in a system node. * * @todo Make it time/item dependent. */ static double econ_calcSysI( unsigned int dt, StarSystem *sys, int price ) { (void) dt; (void) sys; (void) price; return 0.; #if 0 int i; double I; double prodfactor, p; double ddt; Planet *planet; ddt = (double)(dt / NTIME_UNIT_LENGTH); /* Calculate production level. */ p = 0.; for (i=0; i<sys->nplanets; i++) { planet = sys->planets[i]; if (planet_hasService(planet, PLANET_SERVICE_INHABITED)) { /* * Calculate production. */ /* We base off the current production. */ prodfactor = planet->cur_prodfactor; /* Add a variability factor based on the Gaussian distribution. */ prodfactor += ECON_PROD_VAR * RNG_2SIGMA() * ddt; /* Add a tendency to return to the planet's base production. */ prodfactor -= ECON_PROD_VAR * (planet->cur_prodfactor - prodfactor)*ddt; /* Save for next iteration. */ planet->cur_prodfactor = prodfactor; /* We base off the sqrt of the population otherwise it changes too fast. */ p += prodfactor * sqrt(planet->population); } } /* The intensity is basically the modified production. */ I = p / ECON_PROD_MODIFIER; return I; #endif }
/** * @brief Opens a communication dialogue with a planet. * * @param planet Planet to communicate with. * @return 0 on success. */ int comm_openPlanet( Planet *planet ) { unsigned int wid; /* Must not be disabled. */ if (!planet_hasService(planet, PLANET_SERVICE_BASIC)) { player_message("%s does not respond.", planet->name); return 0; } comm_planet = planet; /* Create the generic comm window. */ wid = comm_open( gl_dupTexture( comm_planet->gfx_space ), comm_planet->faction, 0, 0, comm_planet->name ); /* Add special buttons. */ if (areEnemies(player->faction, planet->faction) && !planet->bribed) window_addButton( wid, -20, 20 + BUTTON_HEIGHT + 20, BUTTON_WIDTH, BUTTON_HEIGHT, "btnBribe", "Bribe", comm_bribePlanet ); return 0; }
/** * @brief Checks for planet services. * * Possible services are:<br /> * - "land"<br /> * - "inhabited"<br /> * - "refuel"<br /> * - "bar"<br /> * - "missions"<br /> * - "commodity"<br /> * - "outfits"<br /> * - "shipyard"<br /> * - "blackmarket"<br /> * * @usage if p:services()["refuel"] then -- Planet has refuel service. * @usage if p:services()["shipyard"] then -- Planet has shipyard service. * @luatparam Planet p Planet to get the services of. * @luatreturn table Table containing all the services. * @luafunc services( p ) */ static int planetL_services( lua_State *L ) { int i; size_t len; Planet *p; char *name, lower[256]; p = luaL_validplanet(L,1); /* Return result in table */ lua_newtable(L); /* allows syntax like foo = planet.get("foo"); if foo["bar"] then ... end */ for (i=1; i<PLANET_SERVICES_MAX; i<<=1) { if (planet_hasService(p, i)) { name = planet_getServiceName(i); len = strlen(name) + 1; nsnprintf( lower, MIN(len,sizeof(lower)), "%c%s", tolower(name[0]), &name[1] ); lua_pushstring(L, name); lua_setfield(L, -2, lower ); } } return 1; }
/** * @brief Recreates the land windows. * * @param load Is loading game? * @param changetab Should it change to the last open tab? */ void land_genWindows( int load, int changetab ) { int i, j; const char *names[LAND_NUMWINDOWS]; int w, h; Planet *p; int regen; /* Destroy old window if exists. */ if (land_wid > 0) { land_regen = 2; /* Mark we're regenning. */ window_destroy(land_wid); } land_loaded = 0; /* Get planet. */ p = land_planet; regen = landed; /* Create window. */ if ((SCREEN_W < 1024) || (SCREEN_H < 768)) { w = -1; /* Fullscreen. */ h = -1; } else { w = 800 + 0.5 * (SCREEN_W - 800); h = 600 + 0.5 * (SCREEN_H - 600); } land_wid = window_create( p->name, -1, -1, w, h ); window_onClose( land_wid, land_cleanupWindow ); /* Set window map to invalid. */ for (i=0; i<LAND_NUMWINDOWS; i++) land_windowsMap[i] = -1; /* See what is available. */ j = 0; /* Main. */ land_windowsMap[LAND_WINDOW_MAIN] = j; names[j++] = land_windowNames[LAND_WINDOW_MAIN]; /* Bar. */ if (planet_hasService(land_planet, PLANET_SERVICE_BAR)) { land_windowsMap[LAND_WINDOW_BAR] = j; names[j++] = land_windowNames[LAND_WINDOW_BAR]; } /* Missions. */ if (planet_hasService(land_planet, PLANET_SERVICE_MISSIONS)) { land_windowsMap[LAND_WINDOW_MISSION] = j; names[j++] = land_windowNames[LAND_WINDOW_MISSION]; } /* Outfits. */ if (planet_hasService(land_planet, PLANET_SERVICE_OUTFITS)) { land_windowsMap[LAND_WINDOW_OUTFITS] = j; names[j++] = land_windowNames[LAND_WINDOW_OUTFITS]; } /* Shipyard. */ if (planet_hasService(land_planet, PLANET_SERVICE_SHIPYARD)) { land_windowsMap[LAND_WINDOW_SHIPYARD] = j; names[j++] = land_windowNames[LAND_WINDOW_SHIPYARD]; } /* Equipment. */ if (planet_hasService(land_planet, PLANET_SERVICE_OUTFITS) || planet_hasService(land_planet, PLANET_SERVICE_SHIPYARD)) { land_windowsMap[LAND_WINDOW_EQUIPMENT] = j; names[j++] = land_windowNames[LAND_WINDOW_EQUIPMENT]; } /* Commodity. */ if (planet_hasService(land_planet, PLANET_SERVICE_COMMODITY)) { land_windowsMap[LAND_WINDOW_COMMODITY] = j; names[j++] = land_windowNames[LAND_WINDOW_COMMODITY]; } /* Create tabbed window. */ land_windows = window_addTabbedWindow( land_wid, -1, -1, -1, -1, "tabLand", j, names ); /* * Order here is very important: * * 1) Create main tab - must have decent background. * 2) Set landed, play music and run land hooks - so hooks run well. * 3) Generate missions - so that campaigns are fluid. * 4) Create other tabs - lists depend on NPC and missions. */ /* 1) Create main tab. */ land_createMainTab( land_getWid(LAND_WINDOW_MAIN) ); /* 2) Set as landed and run hooks. */ if (!regen) { landed = 1; music_choose("land"); /* Must be before hooks in case hooks change music. */ if (!load) { events_trigger( EVENT_TRIGGER_LAND ); hooks_run("land"); } /* 3) Generate computer and bar missions. */ if (planet_hasService(land_planet, PLANET_SERVICE_MISSIONS)) mission_computer = missions_genList( &mission_ncomputer, land_planet->faction, land_planet->name, cur_system->name, MIS_AVAIL_COMPUTER ); if (planet_hasService(land_planet, PLANET_SERVICE_BAR)) npc_generate(); /* Generate bar npc. */ } /* 4) Create other tabs. */ /* Basic - bar + missions */ if (planet_hasService(land_planet, PLANET_SERVICE_BAR)) bar_open( land_getWid(LAND_WINDOW_BAR) ); if (planet_hasService(land_planet, PLANET_SERVICE_MISSIONS)) misn_open( land_getWid(LAND_WINDOW_MISSION) ); /* Outfits. */ if (planet_hasService(land_planet, PLANET_SERVICE_OUTFITS)) outfits_open( land_getWid(LAND_WINDOW_OUTFITS) ); /* Shipyard. */ if (planet_hasService(land_planet, PLANET_SERVICE_SHIPYARD)) shipyard_open( land_getWid(LAND_WINDOW_SHIPYARD) ); /* Equipment. */ if (planet_hasService(land_planet, PLANET_SERVICE_OUTFITS) || planet_hasService(land_planet, PLANET_SERVICE_SHIPYARD)) equipment_open( land_getWid(LAND_WINDOW_EQUIPMENT) ); /* Commodity. */ if (planet_hasService(land_planet, PLANET_SERVICE_COMMODITY)) commodity_exchange_open( land_getWid(LAND_WINDOW_COMMODITY) ); if (!regen) { /* Reset markers if needed. */ mission_sysMark(); /* Check land missions. */ if (!has_visited(VISITED_LAND)) { missions_run(MIS_AVAIL_LAND, land_planet->faction, land_planet->name, cur_system->name); visited(VISITED_LAND); } } /* Go to last open tab. */ window_tabWinOnChange( land_wid, "tabLand", land_changeTab ); if (changetab && land_windowsMap[ last_window ] != -1) window_tabWinSetActive( land_wid, "tabLand", land_windowsMap[ last_window ] ); /* Add fuel button if needed - AFTER missions pay :). */ land_checkAddRefuel(); /* Finished loading. */ land_loaded = 1; }
/** * @brief Handles a click event. */ static void input_clickevent( SDL_Event* event ) { unsigned int pid; Pilot *p; int mx, my, mxr, myr, pntid, jpid; int rx, ry, rh, rw, res; double x, y, m, r, rp, d, dp, px, py; double ang, angp, mouseang; Planet *pnt; JumpPoint *jp; HookParam hparam[2]; /* Generate hook. */ hparam[0].type = HOOK_PARAM_NUMBER; hparam[0].u.num = event->button.button; hparam[1].type = HOOK_PARAM_SENTINAL; hooks_runParam( "mouse", hparam ); /* Handle zoom. */ if (event->button.button == SDL_BUTTON_WHEELUP) { input_clickZoom( 1.1 ); return; } else if (event->button.button == SDL_BUTTON_WHEELDOWN) { input_clickZoom( 0.9 ); return; } /* Middle mouse enables mouse flying. */ if (event->button.button == SDL_BUTTON_MIDDLE) { player_toggleMouseFly(); return; } /* Mouse targetting is left only. */ if (event->button.button != SDL_BUTTON_LEFT) return; /* Player must not be NULL. */ if (player_isFlag(PLAYER_DESTROYED) || (player.p == NULL)) return; px = player.p->solid->pos.x; py = player.p->solid->pos.y; gl_windowToScreenPos( &mx, &my, event->button.x, event->button.y ); gl_screenToGameCoords( &x, &y, (double)mx, (double)my ); if ((mx <= 15 || my <= 15 ) || (my >= gl_screen.h - 15 || mx >= gl_screen.w - 15)) { /* Border */ x = (mx - (gl_screen.w / 2.)) + px; y = (my - (gl_screen.h / 2.)) + py; mouseang = atan2(py - y, px - x); angp = pilot_getNearestAng( player.p, &pid, mouseang, 1 ); ang = system_getClosestAng( cur_system, &pntid, &jpid, x, y, mouseang ); if ((ABS(angle_diff(mouseang, angp)) > M_PI / 64) || ABS(angle_diff(mouseang, ang)) < ABS(angle_diff(mouseang, angp))) pid = PLAYER_ID; /* Pilot angle is too great, or planet/jump is closer. */ if (ABS(angle_diff(mouseang, ang)) > M_PI / 64 ) jpid = pntid = -1; /* Asset angle difference is too great. */ } else { /* Radar targeting requires raw coordinates. */ mxr = event->button.x; myr = gl_screen.rh - event->button.y; gui_radarGetPos( &rx, &ry ); gui_radarGetDim( &rw, &rh ); if ((mxr > rx && mxr <= rx + rw ) && (myr > ry && myr <= ry + rh )) { /* Radar */ m = 1; gui_radarGetRes( &res ); x = (mxr - (rx + rw / 2.)) * res + px; y = (myr - (ry + rh / 2.)) * res + py; } else /* Visual (on-screen) */ m = res = 1. / cam_getZoom(); dp = pilot_getNearestPos( player.p, &pid, x, y, 1 ); d = system_getClosest( cur_system, &pntid, &jpid, x, y ); rp = MAX( 1.5 * PILOT_SIZE_APROX * pilot_get(pid)->ship->gfx_space->sw / 2 * m, 10. * res); if (pntid >=0) { /* Planet is closer. */ pnt = cur_system->planets[ pntid ]; r = MAX( 1.5 * pnt->radius, 100. ); } else if (jpid >= 0) { jp = &cur_system->jumps[ jpid ]; r = MAX( 1.5 * jp->radius, 100. ); } else { r = 0.; } /* Reject pilot if it's too far or a valid asset is closer. */ if (dp > pow2(rp) || (d < pow2(r) && dp < pow2(rp) && dp > d)) pid = PLAYER_ID; if (d > pow2(r)) /* Planet or jump point is too far. */ jpid = pntid = -1; } if (pid != PLAYER_ID) { /* Apply an action if already selected. */ if (!pilot_isFlag(player.p, PILOT_DEAD) && (pid == player.p->target)) { p = pilot_get(pid); if (pilot_isDisabled(p) || pilot_isFlag(p, PILOT_BOARDABLE)) player_board(); else player_hail(); } else player_targetSet( pid ); } else if (pntid >= 0) { /* Planet is closest. */ if (pntid == player.p->nav_planet) { pnt = cur_system->planets[ pntid ]; if (planet_hasService(pnt, PLANET_SERVICE_LAND) && (!areEnemies( player.p->faction, pnt->faction ) || pnt->bribed )) player_land(); else player_hailPlanet(); } else player_targetPlanetSet( pntid ); } else if (jpid >= 0) { /* Jump point is closest. */ jp = &cur_system->jumps[ jpid ]; if (jpid == player.p->nav_hyperspace) { if (space_canHyperspace(player.p)) { if (!paused) player_autonavAbort(NULL); player_jump(); } else player_autonavStart(); } else player_targetHyperspaceSet( jpid ); } }
/** * @brief Checks to see if a planet is a black market. * * @usage b = p:blackmarket() * * @luatparam Planet p Planet to check if it's a black market. * @luatreturn boolean true if the planet is a black market. * @luafunc blackmarket( p ) */ static int planetL_isBlackMarket( lua_State *L ) { Planet *p = luaL_validplanet(L,1); lua_pushboolean(L, planet_hasService(p, PLANET_SERVICE_BLACKMARKET)); return 1; }
/** * @brief Saves a planet. * * @param writer Write to use for saving the star planet. * @param p Planet to save. * @return 0 on success. */ static int dpl_savePlanet( xmlTextWriterPtr writer, const Planet *p ) { int i; xmlw_startElem( writer, "asset" ); /* Attributes. */ xmlw_attr( writer, "name", "%s", p->name ); /* Explicit virtualness. */ if (p->real == ASSET_VIRTUAL) xmlw_elemEmpty( writer, "virtual" ); /* Position. */ if (p->real == ASSET_REAL) { xmlw_startElem( writer, "pos" ); xmlw_elem( writer, "x", "%f", p->pos.x ); xmlw_elem( writer, "y", "%f", p->pos.y ); xmlw_endElem( writer ); /* "pos" */ } /* GFX. */ if (p->real == ASSET_REAL) { xmlw_startElem( writer, "GFX" ); xmlw_elem( writer, "space", "%s", p->gfx_spacePath ); xmlw_elem( writer, "exterior", "%s", p->gfx_exteriorPath ); xmlw_endElem( writer ); /* "GFX" */ } /* Presence. */ if (p->faction >= 0) { xmlw_startElem( writer, "presence" ); xmlw_elem( writer, "faction", "%s", faction_name( p->faction ) ); xmlw_elem( writer, "value", "%f", p->presenceAmount ); xmlw_elem( writer, "range", "%d", p->presenceRange ); xmlw_endElem( writer ); } /* General. */ if (p->real == ASSET_REAL) { xmlw_startElem( writer, "general" ); xmlw_elem( writer, "class", "%c", planet_getClass( p ) ); xmlw_elem( writer, "population", "%"PRIu64, p->population ); xmlw_startElem( writer, "services" ); if (planet_hasService( p, PLANET_SERVICE_LAND )) { if (p->land_func == NULL) xmlw_elemEmpty( writer, "land" ); else xmlw_elem( writer, "land", "%s", p->land_func ); } if (planet_hasService( p, PLANET_SERVICE_REFUEL )) xmlw_elemEmpty( writer, "refuel" ); if (planet_hasService( p, PLANET_SERVICE_BAR )) xmlw_elemEmpty( writer, "bar" ); if (planet_hasService( p, PLANET_SERVICE_MISSIONS )) xmlw_elemEmpty( writer, "missions" ); if (planet_hasService( p, PLANET_SERVICE_COMMODITY )) xmlw_elemEmpty( writer, "commodity" ); if (planet_hasService( p, PLANET_SERVICE_OUTFITS )) xmlw_elemEmpty( writer, "outfits" ); if (planet_hasService( p, PLANET_SERVICE_SHIPYARD )) xmlw_elemEmpty( writer, "shipyard" ); xmlw_endElem( writer ); /* "services" */ if (planet_hasService( p, PLANET_SERVICE_LAND )) { xmlw_startElem( writer, "commodities" ); for (i=0; i<p->ncommodities; i++) xmlw_elem( writer, "commodity", "%s", p->commodities[i]->name ); xmlw_endElem( writer ); /* "commodities" */ xmlw_elem( writer, "description", "%s", p->description ); if (planet_hasService( p, PLANET_SERVICE_BAR )) xmlw_elem( writer, "bar", "%s", p->bar_description ); } xmlw_endElem( writer ); /* "general" */ } /* Tech. */ if (planet_hasService( p, PLANET_SERVICE_LAND )) tech_groupWrite( writer, p->tech ); xmlw_endElem( writer ); /** "planet" */ return 0; }
/** * @brief Recreates the land windows. * * @param load Is loading game? * @param changetab Should it change to the last open tab? */ void land_genWindows( int load, int changetab ) { int i, j; const char *names[LAND_NUMWINDOWS]; int w, h; Planet *p; int regen; /* Destroy old window if exists. */ if (land_wid > 0) { land_regen = 2; /* Mark we're regenning. */ window_destroy(land_wid); /* Mark tabs as not generated. */ land_generated = 0; } land_loaded = 0; /* Get planet. */ p = land_planet; regen = landed; /* Create window. */ if ((gl_screen.rw < 1024) || (gl_screen.rh < 768)) { w = -1; /* Fullscreen. */ h = -1; } else { w = 800 + 0.5 * (SCREEN_W - 800); h = 600 + 0.5 * (SCREEN_H - 600); } land_wid = window_create( p->name, -1, -1, w, h ); window_onClose( land_wid, land_cleanupWindow ); /* Set window map to invalid. */ for (i=0; i<LAND_NUMWINDOWS; i++) land_windowsMap[i] = -1; /* See what is available. */ j = 0; /* Main. */ land_windowsMap[LAND_WINDOW_MAIN] = j; names[j++] = _("Landing Main"); /* Bar. */ if (planet_hasService(land_planet, PLANET_SERVICE_BAR)) { land_windowsMap[LAND_WINDOW_BAR] = j; names[j++] = _("Spaceport Bar"); } /* Missions. */ if (planet_hasService(land_planet, PLANET_SERVICE_MISSIONS)) { land_windowsMap[LAND_WINDOW_MISSION] = j; names[j++] = _("Missions"); } /* Outfits. */ if (planet_hasService(land_planet, PLANET_SERVICE_OUTFITS)) { land_windowsMap[LAND_WINDOW_OUTFITS] = j; names[j++] = _("Outfits"); } /* Shipyard. */ if (planet_hasService(land_planet, PLANET_SERVICE_SHIPYARD)) { land_windowsMap[LAND_WINDOW_SHIPYARD] = j; names[j++] = _("Shipyard"); } /* Equipment. */ if (planet_hasService(land_planet, PLANET_SERVICE_OUTFITS) || planet_hasService(land_planet, PLANET_SERVICE_SHIPYARD)) { land_windowsMap[LAND_WINDOW_EQUIPMENT] = j; names[j++] = _("Equipment"); } /* Commodity. */ if (planet_hasService(land_planet, PLANET_SERVICE_COMMODITY)) { land_windowsMap[LAND_WINDOW_COMMODITY] = j; names[j++] = _("Commodity"); } /* Create tabbed window. */ land_windows = window_addTabbedWindow( land_wid, -1, -1, -1, -1, "tabLand", j, names, 0 ); /* * Order here is very important: * * 1) Create main tab - must have decent background. * 2) Set landed, play music and run land hooks - so hooks run well. * 3) Generate missions - so that campaigns are fluid. * 4) Create other tabs - lists depend on NPC and missions. */ /* 1) Create main tab. */ land_createMainTab( land_getWid(LAND_WINDOW_MAIN) ); /* Add local system map button. */ land_checkAddMap(); /* 2) Set as landed and run hooks. */ if (!regen) { landed = 1; music_choose("land"); /* Must be before hooks in case hooks change music. */ if (!load) { hooks_run("land"); } events_trigger( EVENT_TRIGGER_LAND ); /* 3) Generate computer and bar missions. */ if (planet_hasService(land_planet, PLANET_SERVICE_MISSIONS)) mission_computer = missions_genList( &mission_ncomputer, land_planet->faction, land_planet->name, cur_system->name, MIS_AVAIL_COMPUTER ); if (planet_hasService(land_planet, PLANET_SERVICE_BAR)) npc_generate(); /* Generate bar npc. */ } /* 4) Create other tabs. */ #define should_open(s, w) \ (planet_hasService(land_planet, s) && (!land_tabGenerated(w))) /* Things get a bit hairy here. Hooks may have triggered a GUI reload via * e.g. player.swapShip, so the land tabs may have been generated already * and we need to check that before regenerating them. */ /* Basic - bar + missions */ if (should_open( PLANET_SERVICE_BAR, LAND_WINDOW_BAR )) bar_open( land_getWid(LAND_WINDOW_BAR) ); if (should_open( PLANET_SERVICE_MISSIONS, LAND_WINDOW_MISSION )) misn_open( land_getWid(LAND_WINDOW_MISSION) ); /* Outfits. */ if (should_open( PLANET_SERVICE_OUTFITS, LAND_WINDOW_OUTFITS )) outfits_open( land_getWid(LAND_WINDOW_OUTFITS) ); /* Shipyard. */ if (should_open( PLANET_SERVICE_SHIPYARD, LAND_WINDOW_SHIPYARD )) shipyard_open( land_getWid(LAND_WINDOW_SHIPYARD) ); /* Equipment. */ if ((planet_hasService(land_planet, PLANET_SERVICE_OUTFITS) || planet_hasService(land_planet, PLANET_SERVICE_SHIPYARD)) && !land_tabGenerated( LAND_WINDOW_EQUIPMENT )) equipment_open( land_getWid(LAND_WINDOW_EQUIPMENT) ); /* Commodity. */ if (should_open( PLANET_SERVICE_COMMODITY, LAND_WINDOW_COMMODITY )) commodity_exchange_open( land_getWid(LAND_WINDOW_COMMODITY) ); #undef should_open if (!regen) { /* Reset markers if needed. */ mission_sysMark(); /* Check land missions. */ if (!has_visited(VISITED_LAND)) { missions_run(MIS_AVAIL_LAND, land_planet->faction, land_planet->name, cur_system->name); visited(VISITED_LAND); } } /* Go to last open tab. */ window_tabWinOnChange( land_wid, "tabLand", land_changeTab ); if (changetab && land_windowsMap[ last_window ] != -1) window_tabWinSetActive( land_wid, "tabLand", land_windowsMap[ last_window ] ); /* Refresh the map button in case the player couldn't afford it prior to * mission payment. */ land_checkAddMap(); /* Refuel if necessary. */ land_refuel(); /* Finished loading. */ land_loaded = 1; }
/** * @brief Saves a planet. * * @param writer Write to use for saving the star planet. * @param p Planet to save. * @return 0 on success. */ int dpl_savePlanet( const Planet *p ) { xmlDocPtr doc; xmlTextWriterPtr writer; char file[PATH_MAX], *cleanName; int i; /* Create the writer. */ writer = xmlNewTextWriterDoc(&doc, 0); if (writer == NULL) { WARN("testXmlwriterDoc: Error creating the xml writer"); return -1; } /* Set the writer parameters. */ xmlw_setParams( writer ); /* Start writer. */ xmlw_start(writer); xmlw_startElem( writer, "asset" ); /* Attributes. */ xmlw_attr( writer, "name", "%s", p->name ); /* Explicit virtualness. */ if (p->real == ASSET_VIRTUAL) xmlw_elemEmpty( writer, "virtual" ); /* Position. */ if (p->real == ASSET_REAL) { xmlw_startElem( writer, "pos" ); xmlw_elem( writer, "x", "%f", p->pos.x ); xmlw_elem( writer, "y", "%f", p->pos.y ); xmlw_endElem( writer ); /* "pos" */ } /* GFX. */ if (p->real == ASSET_REAL) { xmlw_startElem( writer, "GFX" ); xmlw_elem( writer, "space", "%s", p->gfx_spacePath ); xmlw_elem( writer, "exterior", "%s", p->gfx_exteriorPath ); xmlw_endElem( writer ); /* "GFX" */ } /* Presence. */ if (p->faction >= 0) { xmlw_startElem( writer, "presence" ); xmlw_elem( writer, "faction", "%s", faction_name( p->faction ) ); xmlw_elem( writer, "value", "%f", p->presenceAmount ); xmlw_elem( writer, "range", "%d", p->presenceRange ); xmlw_endElem( writer ); } /* General. */ if (p->real == ASSET_REAL) { xmlw_startElem( writer, "general" ); xmlw_elem( writer, "class", "%s", p->class ); xmlw_elem( writer, "population", "%"PRIu64, p->population ); xmlw_elem( writer, "hide", "%f", sqrt(p->hide) ); xmlw_startElem( writer, "services" ); if (planet_hasService( p, PLANET_SERVICE_LAND )) { if (p->land_func == NULL) xmlw_elemEmpty( writer, "land" ); else xmlw_elem( writer, "land", "%s", p->land_func ); } if (planet_hasService( p, PLANET_SERVICE_REFUEL )) xmlw_elemEmpty( writer, "refuel" ); if (planet_hasService( p, PLANET_SERVICE_BAR )) xmlw_elemEmpty( writer, "bar" ); if (planet_hasService( p, PLANET_SERVICE_MISSIONS )) xmlw_elemEmpty( writer, "missions" ); if (planet_hasService( p, PLANET_SERVICE_COMMODITY )) xmlw_elemEmpty( writer, "commodity" ); if (planet_hasService( p, PLANET_SERVICE_OUTFITS )) xmlw_elemEmpty( writer, "outfits" ); if (planet_hasService( p, PLANET_SERVICE_SHIPYARD )) xmlw_elemEmpty( writer, "shipyard" ); xmlw_endElem( writer ); /* "services" */ if (planet_hasService( p, PLANET_SERVICE_LAND )) { xmlw_startElem( writer, "commodities" ); for (i=0; i<p->ncommodities; i++) xmlw_elem( writer, "commodity", "%s", p->commodities[i]->name ); xmlw_endElem( writer ); /* "commodities" */ if (planet_isBlackMarket(p)) xmlw_elemEmpty( writer, "blackmarket" ); xmlw_elem( writer, "description", "%s", p->description ); if (planet_hasService( p, PLANET_SERVICE_BAR )) xmlw_elem( writer, "bar", "%s", p->bar_description ); } xmlw_endElem( writer ); /* "general" */ }