/** * @brief Gets all the adjacent systems to a system. * * @usage for _,s in ipairs( sys:adjacentSystems() ) do -- Iterate over adjacent systems. * * @luatparam System s System to get adjacent systems of. * @luatparam[opt=false] boolean hidden Whether or not to show hidden jumps also. * @luatreturn {System,...} An ordered table with all the adjacent systems. * @luafunc adjacentSystems( s, hidden ) */ static int systemL_adjacent( lua_State *L ) { int i, id, h; LuaSystem sysp; StarSystem *s; id = 1; s = luaL_validsystem(L,1); h = lua_toboolean(L,2); /* Push all adjacent systems. */ lua_newtable(L); for (i=0; i<s->njumps; i++) { if (jp_isFlag(&s->jumps[i], JP_EXITONLY )) continue; if (!h && jp_isFlag(&s->jumps[i], JP_HIDDEN)) continue; sysp = system_index( s->jumps[i].target ); lua_pushnumber(L, id); /* key. */ lua_pushsystem(L, sysp); /* value. */ lua_rawset(L,-3); id++; } return 1; }
/** * @brief Check to see if a jump point is in sensor range of the pilot. * * @param p Pilot who is trying to check to see if the jump point is in sensor range. * @param target Jump point to see if is in sensor range. * @return 1 if they are in range, 0 if they aren't. */ int pilot_inRangeJump( const Pilot *p, int i ) { double d; JumpPoint *jp; double sense; double hide; /* pilot must exist */ if ( p == NULL ) return 0; /* Get the jump point. */ jp = &cur_system->jumps[i]; /* We don't want exit-only or unknown hidden jumps. */ if ((jp_isFlag(jp, JP_EXITONLY)) || ((jp_isFlag(jp, JP_HIDDEN)) && (!jp_isKnown(jp)) )) return 0; sense = sensor_curRange * p->ew_jumpDetect; hide = jp->hide; /* Get distance. */ d = vect_dist2( &p->solid->pos, &jp->pos ); if (d * hide < sense) return 1; return 0; }
/** * @brief Check to see if a jump point is in sensor range of the pilot. * * @param p Pilot who is trying to check to see if the jump point is in sensor range. * @param target Jump point to see if is in sensor range. * @return 1 if they are in range, 0 if they aren't. */ int pilot_inRangeJump( const Pilot *p, int i ) { double d; JumpPoint *jp; double sense; double hide; /* pilot must exist */ if ( p == NULL ) return 0; /* Get the jump point. */ jp = &cur_system->jumps[i]; /* We don't want exit-only jumps. */ if (jp_isFlag(jp, JP_EXITONLY)) return 0; /* Handle hidden jumps separately, as they use a special range parameter. */ if (jp_isFlag(jp, JP_HIDDEN)) sense = pow(p->stats.misc_hidden_jump_detect, 2); else sense = sensor_curRange * p->ew_jump_detect; hide = jp->hide; /* Get distance. */ d = vect_dist2( &p->solid->pos, &jp->pos ); if (d * hide < sense) return 1; return 0; }
/** * @brief Checks whether a jump is exit-only. * * @usage if jump.exitonly("Eneguoz", "Zied") then -- The jump point in Eneguoz cannot be entered. * @luaparam j Jump to get the exit-only status of. * @luareturn Whether the jump is exit-only. * @luafunc exitonly( j ) */ static int jumpL_exitonly( lua_State *L ) { JumpPoint *jp; jp = luaL_validjump(L,1); lua_pushboolean(L, jp_isFlag(jp, JP_EXITONLY) ); return 1; }
/** * @brief Checks whether a jump is hidden. * * @usage if not j:hidden() then -- Exclude hidden jumps. * @luaparam j Jump to get the hidden status of. * @luareturn Whether the jump is hidden. * @luafunc hidden( j ) */ static int jumpL_hidden( lua_State *L ) { JumpPoint *jp; jp = luaL_validjump(L,1); lua_pushboolean(L, jp_isFlag(jp, JP_HIDDEN) ); return 1; }
/** * @brief Gets all the jumps in a system. * * @usage for _,s in ipairs( sys:jumps() ) do -- Iterate over jumps. * * @luaparam s System to get the jumps of. * @luaparam exitonly Whether to exclude exit-only jumps (default false). * @luareturn An ordered table with all the jumps. * @luafunc jumps( s ) */ static int systemL_jumps( lua_State *L ) { int i, exitonly, pushed; LuaJump lj; StarSystem *s; s = luaL_validsystem(L,1); exitonly = lua_toboolean(L,2); pushed = 0; /* Push all jumps. */ lua_newtable(L); for (i=0; i<s->njumps; i++) { /* Skip exit-only jumps if requested. */ if ((exitonly) && (jp_isFlag( jump_getTarget( s->jumps[i].target, s ), JP_EXITONLY))) continue; lj.srcid = s->id; lj.destid = s->jumps[i].targetid; lua_pushnumber(L,++pushed); /* key. */ lua_pushjump(L,lj); /* value. */ lua_rawset(L,-3); } return 1; }
/** * @brief Renders the overlay map. * * @param dt Current delta tick. */ void ovr_render( double dt ) { (void) dt; int i, j; Pilot **pstk; int n; double w, h, res; double x,y; glColour c = { .r=0., .g=0., .b=0., .a=0.5 }; /* Must be open. */ if (!ovr_open) return; /* Player must be alive. */ if (player_isFlag( PLAYER_DESTROYED ) || (player.p == NULL)) return; /* Default values. */ w = SCREEN_W; h = SCREEN_H; res = ovr_res; /* First render the background overlay. */ gl_renderRect( 0., 0., w, h, &c ); /* Render planets. */ for (i=0; i<cur_system->nplanets; i++) if ((cur_system->planets[ i ]->real == ASSET_REAL) && (i != player.p->nav_planet)) gui_renderPlanet( i, RADAR_RECT, w, h, res, 1 ); if (player.p->nav_planet > -1) gui_renderPlanet( player.p->nav_planet, RADAR_RECT, w, h, res, 1 ); /* Render jump points. */ for (i=0; i<cur_system->njumps; i++) if ((i != player.p->nav_hyperspace) && !jp_isFlag(&cur_system->jumps[i], JP_EXITONLY)) gui_renderJumpPoint( i, RADAR_RECT, w, h, res, 1 ); if (player.p->nav_hyperspace > -1) gui_renderJumpPoint( player.p->nav_hyperspace, RADAR_RECT, w, h, res, 1 ); /* Render pilots. */ pstk = pilot_getAll( &n ); j = 0; for (i=0; i<n; i++) { if (pstk[i]->id == PLAYER_ID) /* Skip player. */ continue; if (pstk[i]->id == player.p->target) j = i; else gui_renderPilot( pstk[i], RADAR_RECT, w, h, res, 1 ); } /* Render the targeted pilot */ if (j!=0) gui_renderPilot( pstk[j], RADAR_RECT, w, h, res, 1 ); /* Check if player has goto target. */ if (player_isFlag(PLAYER_AUTONAV) && (player.autonav == AUTONAV_POS_APPROACH)) { x = player.autonav_pos.x / res + w / 2.; y = player.autonav_pos.y / res + h / 2.; gl_renderCross( x, y, 5., &cRadar_hilight ); gl_printRaw( &gl_smallFont, x+10., y-gl_smallFont.h/2., &cRadar_hilight, "GOTO" ); } /* Render the player. */ gui_renderPlayer( res, 1 ); /* Render markers. */ ovr_mrkRenderAll( res ); } /** * @brief Renders all the markers. * * @param res Resolution to render at. */ static void ovr_mrkRenderAll( double res ) { int i; ovr_marker_t *mrk; double x, y; if (ovr_markers == NULL) return; for (i=0; i<array_size(ovr_markers); i++) { mrk = &ovr_markers[i]; x = mrk->u.pt.x / res + SCREEN_W / 2.; y = mrk->u.pt.y / res + SCREEN_H / 2.; gl_renderCross( x, y, 5., &cRadar_hilight ); if (mrk->text != NULL) gl_printRaw( &gl_smallFont, x+10., y-gl_smallFont.h/2., &cRadar_hilight, mrk->text ); } }
/** * @brief Saves a star system. * * @param writer Write to use for saving the star system. * @param sys Star system to save. * @return 0 on success. */ int dsys_saveSystem( StarSystem *sys ) { int i; xmlDocPtr doc; xmlTextWriterPtr writer; const Planet **sorted_planets; const JumpPoint **sorted_jumps, *jp; char file[PATH_MAX], *cleanName; /* Reconstruct jumps so jump pos are updated. */ system_reconstructJumps(sys); /* 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, "ssys" ); /* Attributes. */ xmlw_attr( writer, "name", "%s", sys->name ); /* General. */ xmlw_startElem( writer, "general" ); if (sys->background != NULL) xmlw_elem( writer, "background", "%s", sys->background ); xmlw_elem( writer, "radius", "%f", sys->radius ); xmlw_elem( writer, "stars", "%d", sys->stars ); xmlw_elem( writer, "interference", "%f", sys->interference ); xmlw_startElem( writer, "nebula" ); xmlw_attr( writer, "volatility", "%f", sys->nebu_volatility ); xmlw_str( writer, "%f", sys->nebu_density ); xmlw_endElem( writer ); /* "nebula" */ xmlw_endElem( writer ); /* "general" */ /* Position. */ xmlw_startElem( writer, "pos" ); xmlw_elem( writer, "x", "%f", sys->pos.x ); xmlw_elem( writer, "y", "%f", sys->pos.y ); xmlw_endElem( writer ); /* "pos" */ /* Planets. */ sorted_planets = malloc( sizeof(Planet*) * sys->nplanets); memcpy( sorted_planets, sys->planets, sizeof(Planet*) * sys->nplanets ); qsort( sorted_planets, sys->nplanets, sizeof(Planet*), dsys_compPlanet ); xmlw_startElem( writer, "assets" ); for (i=0; i<sys->nplanets; i++) xmlw_elem( writer, "asset", "%s", sorted_planets[i]->name ); xmlw_endElem( writer ); /* "assets" */ free(sorted_planets); /* Jumps. */ sorted_jumps = malloc( sizeof(JumpPoint*) * sys->njumps ); for (i=0; i<sys->njumps; i++) sorted_jumps[i] = &sys->jumps[i]; qsort( sorted_jumps, sys->njumps, sizeof(JumpPoint*), dsys_compJump ); xmlw_startElem( writer, "jumps" ); for (i=0; i<sys->njumps; i++) { jp = sorted_jumps[i]; xmlw_startElem( writer, "jump" ); xmlw_attr( writer, "target", "%s", jp->target->name ); /* Position. */ if (!jp_isFlag( jp, JP_AUTOPOS )) { xmlw_startElem( writer, "pos" ); xmlw_attr( writer, "x", "%f", jp->pos.x ); xmlw_attr( writer, "y", "%f", jp->pos.y ); xmlw_endElem( writer ); /* "pos" */ } else xmlw_elemEmpty( writer, "autopos" ); /* Radius and misc properties. */ if (jp->radius != 200.) xmlw_elem( writer, "radius", "%f", jp->radius ); /* More flags. */ if (jp_isFlag( jp, JP_HIDDEN )) xmlw_elemEmpty( writer, "hidden" ); if (jp_isFlag( jp, JP_EXITONLY )) xmlw_elemEmpty( writer, "exitonly" ); xmlw_elem( writer, "hide", "%f", sqrt(jp->hide) ); xmlw_endElem( writer ); /* "jump" */ } xmlw_endElem( writer ); /* "jumps" */ free(sorted_jumps); xmlw_endElem( writer ); /** "ssys" */ xmlw_done(writer); /* No need for writer anymore. */ xmlFreeTextWriter(writer); /* Write data. */ cleanName = uniedit_nameFilter( sys->name ); nsnprintf( file, sizeof(file), "%s/%s.xml", conf.dev_save_sys, cleanName ); xmlSaveFileEnc( file, doc, "UTF-8" ); /* Clean up. */ xmlFreeDoc(doc); free(cleanName); return 0; }
/** * @brief Saves selected systems as a map outfit file. * * @return 0 on success. */ int dsys_saveMap (StarSystem **uniedit_sys, int uniedit_nsys) { int i, j, k; xmlDocPtr doc; xmlTextWriterPtr writer; StarSystem *s; char file[PATH_MAX], *cleanName; /* 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, "outfit" ); /* Attributes. */ xmlw_attr( writer, "name", "Editor-generated Map" ); /* General. */ xmlw_startElem( writer, "general" ); xmlw_elem( writer, "mass", "%d", 0 ); xmlw_elem( writer, "price", "%d", 1000 ); xmlw_elem( writer, "description", "%s", "This map has been created by the universe editor." ); xmlw_elem( writer, "gfx_store", "%s", "map" ); xmlw_endElem( writer ); /* "general" */ xmlw_startElem( writer, "specific" ); xmlw_attr( writer, "type", "map" ); /* Iterate over all selected systems. Save said systems and any NORMAL jumps they might share. */ for (i = 0; i < uniedit_nsys; i++) { s = uniedit_sys[i]; xmlw_startElem( writer, "sys" ); xmlw_attr( writer, "name", "%s", s->name ); /* Iterate jumps and see if they lead to any other systems in our array. */ for (j = 0; j < s->njumps; j++) { /* Ignore hidden and exit-only jumps. */ if (jp_isFlag(&s->jumps[j], JP_EXITONLY )) continue; if (jp_isFlag(&s->jumps[j], JP_HIDDEN)) continue; /* This is a normal jump. */ for (k = 0; k < uniedit_nsys; k++) { if (s->jumps[j].target == uniedit_sys[k]) { xmlw_elem( writer, "jump", "%s", uniedit_sys[k]->name ); break; } } } /* Iterate assets and add them */ for (j = 0; j < s->nplanets; j++) { if (s->planets[j]->real) xmlw_elem( writer, "asset", "%s", s->planets[j]->name ); } xmlw_endElem( writer ); /* "sys" */ } xmlw_endElem( writer ); /* "specific" */ xmlw_endElem( writer ); /* "outfit" */ xmlw_done(writer); /* No need for writer anymore. */ xmlFreeTextWriter(writer); /* Write data. */ cleanName = uniedit_nameFilter( "saved map" ); nsnprintf( file, sizeof(file), "%s/%s.xml", conf.dev_save_map, cleanName ); xmlSaveFileEnc( file, doc, "UTF-8" ); /* Clean up. */ xmlFreeDoc(doc); free(cleanName); return 0; }