naev 0.10.4
dev_system.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
10#include <stdlib.h> /* qsort */
11
12#include "naev.h"
15#include "dev_system.h"
16
17#include "array.h"
18#include "conf.h"
19#include "dev_uniedit.h"
20#include "nstring.h"
21#include "nxml.h"
22#include "physics.h"
23#include "space.h"
24#include "nebula.h"
25
26/*
27 * Prototypes.
28 */
29static int dsys_compSpob( const void *spob1, const void *spob2 );
30static int dsys_compJump( const void *jmp1, const void *jmp2 );
31
39static int dsys_compSpob( const void *spob1, const void *spob2 )
40{
41 const Spob *p1, *p2;
42 p1 = * (const Spob**) spob1;
43 p2 = * (const Spob**) spob2;
44 return strcmp( p1->name, p2->name );
45}
46
54static int dsys_compVirtualSpob( const void *spob1, const void *spob2 )
55{
56 const VirtualSpob *va1, *va2;
57 va1 = *(const VirtualSpob**) spob1;
58 va2 = *(const VirtualSpob**) spob2;
59 return strcmp( va1->name, va2->name );
60}
61
69static int dsys_compJump( const void *jmp1, const void *jmp2 )
70{
71 const JumpPoint *jp1, *jp2;
72 jp1 = * (const JumpPoint**) jmp1;
73 jp2 = * (const JumpPoint**) jmp2;
74 return strcmp( jp1->target->name, jp2->target->name );
75}
76
83int dsys_saveSystem( StarSystem *sys )
84{
85 xmlDocPtr doc;
86 xmlTextWriterPtr writer;
87 const Spob **sorted_spobs;
88 const VirtualSpob **sorted_virtualspobs;
89 const JumpPoint **sorted_jumps;
90 char *file, *cleanName;
91
92 /* Reconstruct jumps so jump pos are updated. */
94
95 /* Create the writer. */
96 writer = xmlNewTextWriterDoc(&doc, 0);
97 if (writer == NULL) {
98 WARN(_("testXmlwriterDoc: Error creating the xml writer"));
99 return -1;
100 }
101
102 /* Set the writer parameters. */
103 xmlw_setParams( writer );
104
105 /* Start writer. */
106 xmlw_start(writer);
107 xmlw_startElem( writer, "ssys" );
108
109 /* Attributes. */
110 xmlw_attr( writer, "name", "%s", sys->name );
111
112 /* General. */
113 xmlw_startElem( writer, "general" );
114 if (sys->background != NULL)
115 xmlw_elem( writer, "background", "%s", sys->background );
116 if (sys->map_shader != NULL)
117 xmlw_elem( writer, "map_shader", "%s", sys->map_shader );
118 if (sys->features != NULL)
119 xmlw_elem( writer, "features", "%s", sys->features );
120 xmlw_elem( writer, "radius", "%f", sys->radius );
121 xmlw_elem( writer, "stars", "%d", sys->stars );
122 xmlw_elem( writer, "interference", "%f", sys->interference );
123 xmlw_startElem( writer, "nebula" );
124 xmlw_attr( writer, "volatility", "%f", sys->nebu_volatility );
125 if (fabs(sys->nebu_hue*360.0 - NEBULA_DEFAULT_HUE) > 1e-5)
126 xmlw_attr( writer, "hue", "%f", sys->nebu_hue*360.0 );
127 xmlw_str( writer, "%f", sys->nebu_density );
128 xmlw_endElem( writer ); /* "nebula" */
129 xmlw_endElem( writer ); /* "general" */
130
131 /* Position. */
132 xmlw_startElem( writer, "pos" );
133 xmlw_attr( writer, "x", "%f", sys->pos.x );
134 xmlw_attr( writer, "y", "%f", sys->pos.y );
135 xmlw_endElem( writer ); /* "pos" */
136
137 /* Sort spobs. */
138 sorted_spobs = malloc( sizeof(Spob*) * array_size(sys->spobs) );
139 memcpy( sorted_spobs, sys->spobs, sizeof(Spob*) * array_size(sys->spobs) );
140 qsort( sorted_spobs, array_size(sys->spobs), sizeof(Spob*), dsys_compSpob );
141
142 /* Sort virtual spobs. */
143 sorted_virtualspobs = malloc( sizeof(VirtualSpob*) * array_size(sys->spobs_virtual) );
144 memcpy( sorted_virtualspobs, sys->spobs_virtual, sizeof(VirtualSpob*) * array_size(sys->spobs_virtual) );
145 qsort( sorted_virtualspobs, array_size(sys->spobs_virtual), sizeof(VirtualSpob*), dsys_compVirtualSpob );
146
147 /* Write spobs and clean up. */
148 xmlw_startElem( writer, "spobs" );
149 for (int i=0; i<array_size(sys->spobs); i++)
150 xmlw_elem( writer, "spob", "%s", sorted_spobs[i]->name );
151 for (int i=0; i<array_size(sys->spobs_virtual); i++)
152 xmlw_elem( writer, "spob_virtual", "%s", sorted_virtualspobs[i]->name );
153 xmlw_endElem( writer ); /* "spobs" */
154 free(sorted_spobs);
155 free(sorted_virtualspobs);
156
157 /* Jumps. */
158 sorted_jumps = malloc( sizeof(JumpPoint*) * array_size(sys->jumps) );
159 for (int i=0; i<array_size(sys->jumps); i++)
160 sorted_jumps[i] = &sys->jumps[i];
161 qsort( sorted_jumps, array_size(sys->jumps), sizeof(JumpPoint*), dsys_compJump );
162 xmlw_startElem( writer, "jumps" );
163 for (int i=0; i<array_size(sys->jumps); i++) {
164 const JumpPoint *jp = sorted_jumps[i];
165 xmlw_startElem( writer, "jump" );
166 xmlw_attr( writer, "target", "%s", jp->target->name );
167 /* Position. */
168 if (!jp_isFlag( jp, JP_AUTOPOS )) {
169 xmlw_startElem( writer, "pos" );
170 xmlw_attr( writer, "x", "%f", jp->pos.x );
171 xmlw_attr( writer, "y", "%f", jp->pos.y );
172 xmlw_endElem( writer ); /* "pos" */
173 }
174 else
175 xmlw_elemEmpty( writer, "autopos" );
176 /* Radius and misc properties. */
177 if (jp->radius != 200.)
178 xmlw_elem( writer, "radius", "%f", jp->radius );
179 /* More flags. */
180 if (jp_isFlag( jp, JP_HIDDEN ))
181 xmlw_elemEmpty( writer, "hidden" );
182 if (jp_isFlag( jp, JP_EXITONLY ))
183 xmlw_elemEmpty( writer, "exitonly" );
184 xmlw_elem( writer, "hide", "%f", jp->hide );
185 xmlw_endElem( writer ); /* "jump" */
186 }
187 xmlw_endElem( writer ); /* "jumps" */
188 free(sorted_jumps);
189
190 /* Asteroids. */
191 if (array_size(sys->asteroids) > 0 || array_size(sys->astexclude) > 0) {
192 xmlw_startElem( writer, "asteroids" );
193 for (int i=0; i<array_size(sys->asteroids); i++) {
194 const AsteroidAnchor *ast = &sys->asteroids[i];
195 xmlw_startElem( writer, "asteroid" );
196
197 /* Type Groups */
198 for (int j=0; j<array_size(ast->groups); j++)
199 xmlw_elem( writer, "group", "%s", ast->groups[j]->name );
200
201 /* Radius */
202 xmlw_elem( writer, "radius", "%f", ast->radius );
203
204 /* Position */
205 xmlw_startElem( writer, "pos" );
206 xmlw_attr( writer, "x", "%f", ast->pos.x );
207 xmlw_attr( writer, "y", "%f", ast->pos.y );
208 xmlw_endElem( writer ); /* "pos" */
209
210 /* Misc. properties. */
211 if (ast->density != ASTEROID_DEFAULT_DENSITY)
212 xmlw_elem( writer, "density", "%f", ast->density );
213 if (ast->maxspeed != ASTEROID_DEFAULT_MAXSPEED)
214 xmlw_elem( writer, "maxspeed", "%f", ast->maxspeed );
215 if (ast->thrust != ASTEROID_DEFAULT_THRUST)
216 xmlw_elem( writer, "thrust", "%f", ast->thrust );
217 xmlw_endElem( writer ); /* "asteroid" */
218 }
219 for (int i=0; i<array_size(sys->astexclude); i++) {
220 const AsteroidExclusion *aexcl = &sys->astexclude[i];
221 xmlw_startElem( writer, "exclusion" );
222
223 /* Radius */
224 xmlw_elem( writer, "radius", "%f", aexcl->radius );
225
226 /* Position */
227 xmlw_startElem( writer, "pos" );
228 xmlw_attr( writer, "x", "%f", aexcl->pos.x );
229 xmlw_attr( writer, "y", "%f", aexcl->pos.y );
230 xmlw_endElem( writer ); /* "pos" */
231 xmlw_endElem( writer ); /* "exclusion" */
232 }
233 xmlw_endElem( writer ); /* "asteroids" */
234 }
235
236 if (sys->stats != NULL) {
237 xmlw_startElem( writer, "stats" );
238 ss_listToXML( writer, sys->stats );
239 xmlw_endElem( writer ); /* "stats" */
240 }
241
242 if (array_size(sys->tags)>0) {
243 xmlw_startElem( writer, "tags" );
244 for (int i=0; i<array_size(sys->tags); i++)
245 xmlw_elem( writer, "tag", "%s", sys->tags[i] );
246 xmlw_endElem( writer ); /* "tags" */
247 }
248
249 xmlw_endElem( writer );
250 xmlw_done(writer);
251
252 /* No need for writer anymore. */
253 xmlFreeTextWriter(writer);
254
255 /* Write data. */
256 cleanName = uniedit_nameFilter( sys->name );
257 asprintf( &file, "%s/%s.xml", conf.dev_save_sys, cleanName );
258 if (xmlSaveFileEnc( file, doc, "UTF-8" ) < 0)
259 WARN("Failed writing '%s'!", file);
260
261 /* Clean up. */
262 xmlFreeDoc(doc);
263 free(cleanName);
264 free(file);
265
266 return 0;
267}
268
274int dsys_saveAll (void)
275{
276 StarSystem *sys = system_getAll();
277
278 /* Write systems. */
279 for (int i=0; i<array_size(sys); i++)
280 dsys_saveSystem( &sys[i] );
281
282 return 0;
283}
Provides macros to work with dynamic arrays.
static ALWAYS_INLINE int array_size(const void *array)
Returns number of elements in the array.
Definition: array.h:168
static int dsys_compVirtualSpob(const void *spob1, const void *spob2)
Compare function for spob qsort.
Definition: dev_system.c:54
int dsys_saveSystem(StarSystem *sys)
Saves a star system.
Definition: dev_system.c:83
int dsys_saveAll(void)
Saves all the star systems.
Definition: dev_system.c:274
static int dsys_compSpob(const void *spob1, const void *spob2)
Compare function for spob qsort.
Definition: dev_system.c:39
static int dsys_compJump(const void *jmp1, const void *jmp2)
Function for qsorting jumppoints.
Definition: dev_system.c:69
Header file with generic functions and naev-specifics.
int asprintf(char **strp, const char *fmt,...)
Like sprintf(), but it allocates a large-enough string and returns the pointer in the first argument....
Definition: nstring.c:161
void xmlw_setParams(xmlTextWriterPtr writer)
Sets up the standard xml write parameters.
Definition: nxml.c:64
int ss_listToXML(xmlTextWriterPtr writer, const ShipStatList *ll)
Creatse a shipstat list element from an xml node.
Definition: shipstats.c:260
StarSystem * system_getAll(void)
Gets an array (array.h) of all star systems.
Definition: space.c:847
void system_reconstructJumps(StarSystem *sys)
Reconstructs the jumps for a single system.
Definition: space.c:2640
Represents an asteroid field anchor.
Definition: asteroid.h:100
double radius
Definition: asteroid.h:107
double density
Definition: asteroid.h:104
double thrust
Definition: asteroid.h:114
double maxspeed
Definition: asteroid.h:112
Asteroid * asteroids
Definition: asteroid.h:105
AsteroidTypeGroup ** groups
Definition: asteroid.h:109
Represents an asteroid exclusion zone.
Definition: asteroid.h:121
char * dev_save_sys
Definition: conf.h:171
Represents a Space Object (SPOB), including and not limited to planets, stations, wormholes,...
Definition: space.h:88
char * name
Definition: space.h:90
Basically modifies system parameters without creating any real objects.
Definition: space.h:77
char * name
Definition: space.h:78
double y
Definition: vec2.h:34
double x
Definition: vec2.h:33