@@ -198,71 +198,59 @@ void Schematic::placeStructure(Map *map, v3s16 p, u32 flags, Rotation rot,
198
198
}
199
199
200
200
201
- bool Schematic::loadSchematicFromFile ( const char *filename, INodeDefManager *ndef ,
202
- StringMap *replace_names )
201
+ bool Schematic::deserializeFromMts (std::istream *is ,
202
+ INodeDefManager *ndef, std::vector<std::string> *names )
203
203
{
204
+ std::istream &ss = *is;
204
205
content_t cignore = CONTENT_IGNORE;
205
206
bool have_cignore = false ;
206
207
207
- std::ifstream is (filename, std::ios_base::binary);
208
- if (!is.good ()) {
209
- errorstream << " loadSchematicFile: unable to open file '"
210
- << filename << " '" << std::endl;
211
- return false ;
212
- }
213
-
214
- u32 signature = readU32 (is);
208
+ u32 signature = readU32 (ss);
215
209
if (signature != MTSCHEM_FILE_SIGNATURE) {
216
- errorstream << " loadSchematicFile : invalid schematic "
210
+ errorstream << " Schematic::deserializeFromMts : invalid schematic "
217
211
" file" << std::endl;
218
212
return false ;
219
213
}
220
214
221
- u16 version = readU16 (is );
215
+ u16 version = readU16 (ss );
222
216
if (version > MTSCHEM_FILE_VER_HIGHEST_READ) {
223
- errorstream << " loadSchematicFile : unsupported schematic "
217
+ errorstream << " Schematic::deserializeFromMts : unsupported schematic "
224
218
" file version" << std::endl;
225
219
return false ;
226
220
}
227
221
228
- size = readV3S16 (is );
222
+ size = readV3S16 (ss );
229
223
230
224
delete [] slice_probs;
231
225
slice_probs = new u8[size.Y ];
232
226
for (int y = 0 ; y != size.Y ; y++)
233
- slice_probs[y] = (version >= 3 ) ? readU8 (is ) : MTSCHEM_PROB_ALWAYS;
227
+ slice_probs[y] = (version >= 3 ) ? readU8 (ss ) : MTSCHEM_PROB_ALWAYS;
234
228
235
- NodeResolveInfo *nri = new NodeResolveInfo (this );
236
-
237
- u16 nidmapcount = readU16 (is);
229
+ u16 nidmapcount = readU16 (ss);
238
230
for (int i = 0 ; i != nidmapcount; i++) {
239
- std::string name = deSerializeString (is);
231
+ std::string name = deSerializeString (ss);
232
+
233
+ // Instances of "ignore" from ver 1 are converted to air (and instances
234
+ // are fixed to have MTSCHEM_PROB_NEVER later on).
240
235
if (name == " ignore" ) {
241
236
name = " air" ;
242
237
cignore = i;
243
238
have_cignore = true ;
244
239
}
245
240
246
- std::map<std::string, std::string>::iterator it;
247
- it = replace_names->find (name);
248
- if (it != replace_names->end ())
249
- name = it->second ;
250
-
251
- nri->nodenames .push_back (name);
241
+ names->push_back (name);
252
242
}
253
243
254
- nri->nodelistinfo .push_back (NodeListInfo (nidmapcount, CONTENT_AIR));
255
- ndef->pendNodeResolve (nri);
256
-
257
244
size_t nodecount = size.X * size.Y * size.Z ;
258
245
259
246
delete [] schemdata;
260
247
schemdata = new MapNode[nodecount];
261
248
262
- MapNode::deSerializeBulk (is , SER_FMT_VER_HIGHEST_READ, schemdata,
249
+ MapNode::deSerializeBulk (ss , SER_FMT_VER_HIGHEST_READ, schemdata,
263
250
nodecount, 2 , 2 , true );
264
251
265
- if (version == 1 ) { // fix up the probability values
252
+ // fix any probability values for nodes that were ignore
253
+ if (version == 1 ) {
266
254
for (size_t i = 0 ; i != nodecount; i++) {
267
255
if (schemdata[i].param1 == 0 )
268
256
schemdata[i].param1 = MTSCHEM_PROB_ALWAYS;
@@ -275,39 +263,9 @@ bool Schematic::loadSchematicFromFile(const char *filename, INodeDefManager *nde
275
263
}
276
264
277
265
278
- /*
279
- Minetest Schematic File Format
280
-
281
- All values are stored in big-endian byte order.
282
- [u32] signature: 'MTSM'
283
- [u16] version: 3
284
- [u16] size X
285
- [u16] size Y
286
- [u16] size Z
287
- For each Y:
288
- [u8] slice probability value
289
- [Name-ID table] Name ID Mapping Table
290
- [u16] name-id count
291
- For each name-id mapping:
292
- [u16] name length
293
- [u8[]] name
294
- ZLib deflated {
295
- For each node in schematic: (for z, y, x)
296
- [u16] content
297
- For each node in schematic:
298
- [u8] probability of occurance (param1)
299
- For each node in schematic:
300
- [u8] param2
301
- }
302
-
303
- Version changes:
304
- 1 - Initial version
305
- 2 - Fixed messy never/always place; 0 probability is now never, 0xFF is always
306
- 3 - Added y-slice probabilities; this allows for variable height structures
307
- */
308
- void Schematic::saveSchematicToFile (const char *filename, INodeDefManager *ndef)
266
+ bool Schematic::serializeToMts (std::ostream *os, INodeDefManager *ndef)
309
267
{
310
- std::ostringstream ss (std::ios_base::binary) ;
268
+ std::ostream &ss = *os ;
311
269
312
270
writeU32 (ss, MTSCHEM_FILE_SIGNATURE); // signature
313
271
writeU16 (ss, MTSCHEM_FILE_VER_HIGHEST_WRITE); // version
@@ -326,35 +284,108 @@ void Schematic::saveSchematicToFile(const char *filename, INodeDefManager *ndef)
326
284
ss << serializeString (ndef->get (usednodes[i]).name ); // node names
327
285
328
286
// compressed bulk node data
329
- MapNode::serializeBulk (ss, SER_FMT_VER_HIGHEST_WRITE, schemdata,
330
- nodecount, 2 , 2 , true );
287
+ MapNode::serializeBulk (ss, SER_FMT_VER_HIGHEST_WRITE,
288
+ schemdata, nodecount, 2 , 2 , true );
331
289
332
- fs::safeWriteToFile (filename, ss. str ()) ;
290
+ return true ;
333
291
}
334
292
335
293
336
- void build_nnlist_and_update_ids (MapNode *nodes, u32 nodecount ,
337
- std::vector< content_t > *usednodes )
294
+ bool Schematic::serializeToLua (std::ostream *os ,
295
+ INodeDefManager *ndef, bool use_comments )
338
296
{
339
- std::map<content_t , content_t > nodeidmap;
340
- content_t numids = 0 ;
297
+ std::ostream &ss = *os;
298
+
299
+ // // Write header
300
+ {
301
+ ss << " schematic = {" << std::endl;
302
+ ss << " \t size = "
303
+ << " {x=" << size.X
304
+ << " , y=" << size.Y
305
+ << " , z=" << size.Z
306
+ << " }," << std::endl;
307
+ }
341
308
342
- for (u32 i = 0 ; i != nodecount; i++) {
343
- content_t id;
344
- content_t c = nodes[i]. getContent () ;
309
+ // // Write y-slice probabilities
310
+ {
311
+ ss << " \t yslice_prob = { " << std::endl ;
345
312
346
- std::map<content_t , content_t >::const_iterator it = nodeidmap.find (c);
347
- if (it == nodeidmap.end ()) {
348
- id = numids;
349
- numids++;
313
+ for (u16 y = 0 ; y != size.Y ; y++) {
314
+ ss << " \t\t {"
315
+ << " ypos=" << y
316
+ << " , prob=" << (u16)slice_probs[y]
317
+ << " }," << std::endl;
318
+ }
350
319
351
- usednodes->push_back (c);
352
- nodeidmap.insert (std::make_pair (c, id));
353
- } else {
354
- id = it->second ;
320
+ ss << " \t }," << std::endl;
321
+ }
322
+
323
+ // // Write node data
324
+ {
325
+ ss << " \t data = {" << std::endl;
326
+
327
+ u32 i = 0 ;
328
+ for (u16 z = 0 ; z != size.Z ; z++)
329
+ for (u16 y = 0 ; y != size.Y ; y++) {
330
+ if (use_comments) {
331
+ ss << std::endl
332
+ << " \t\t -- z=" << z
333
+ << " , y=" << y << std::endl;
334
+ }
335
+
336
+ for (u16 x = 0 ; x != size.X ; x++, i++) {
337
+ ss << " \t\t {"
338
+ << " name=\" " << ndef->get (schemdata[i]).name
339
+ << " \" , param1=" << (u16)schemdata[i].param1
340
+ << " , param2=" << (u16)schemdata[i].param2
341
+ << " }," << std::endl;
342
+ }
355
343
}
356
- nodes[i].setContent (id);
344
+
345
+ ss << " \t }," << std::endl;
357
346
}
347
+
348
+ ss << " }" << std::endl;
349
+
350
+ return true ;
351
+ }
352
+
353
+
354
+ bool Schematic::loadSchematicFromFile (const char *filename,
355
+ INodeDefManager *ndef, StringMap *replace_names)
356
+ {
357
+ std::ifstream is (filename, std::ios_base::binary);
358
+ if (!is.good ()) {
359
+ errorstream << " Schematic::loadSchematicFile: unable to open file '"
360
+ << filename << " '" << std::endl;
361
+ return false ;
362
+ }
363
+
364
+ std::vector<std::string> names;
365
+ if (!deserializeFromMts (&is, ndef, &names))
366
+ return false ;
367
+
368
+ NodeResolveInfo *nri = new NodeResolveInfo (this );
369
+ for (size_t i = 0 ; i != names.size (); i++) {
370
+ if (replace_names) {
371
+ StringMap::iterator it = replace_names->find (names[i]);
372
+ if (it != replace_names->end ())
373
+ names[i] = it->second ;
374
+ }
375
+ nri->nodenames .push_back (names[i]);
376
+ }
377
+ nri->nodelistinfo .push_back (NodeListInfo (names.size (), CONTENT_AIR));
378
+ ndef->pendNodeResolve (nri);
379
+
380
+ return true ;
381
+ }
382
+
383
+
384
+ bool Schematic::saveSchematicToFile (const char *filename, INodeDefManager *ndef)
385
+ {
386
+ std::ostringstream os (std::ios_base::binary);
387
+ serializeToMts (&os, ndef);
388
+ return fs::safeWriteToFile (filename, os.str ());
358
389
}
359
390
360
391
@@ -411,3 +442,28 @@ void Schematic::applyProbabilities(v3s16 p0,
411
442
slice_probs[y] = (*splist)[i].second ;
412
443
}
413
444
}
445
+
446
+
447
+ void build_nnlist_and_update_ids (MapNode *nodes, u32 nodecount,
448
+ std::vector<content_t > *usednodes)
449
+ {
450
+ std::map<content_t , content_t > nodeidmap;
451
+ content_t numids = 0 ;
452
+
453
+ for (u32 i = 0 ; i != nodecount; i++) {
454
+ content_t id;
455
+ content_t c = nodes[i].getContent ();
456
+
457
+ std::map<content_t , content_t >::const_iterator it = nodeidmap.find (c);
458
+ if (it == nodeidmap.end ()) {
459
+ id = numids;
460
+ numids++;
461
+
462
+ usednodes->push_back (c);
463
+ nodeidmap.insert (std::make_pair (c, id));
464
+ } else {
465
+ id = it->second ;
466
+ }
467
+ nodes[i].setContent (id);
468
+ }
469
+ }
0 commit comments