1 #include "xyedit.h"
2 #include <iostream>
3 #include <fstream>
4 #include <algorithm>
5 #include "xye.h"
6 using std::pair;
7 using std::max_element;
8
9
10
saveColor(std::ofstream & file,boardelement & o,bool allownocolor=false)11 void saveColor(std::ofstream &file,boardelement &o,bool allownocolor=false)
12 {
13 if(allownocolor && (o.color==EDCO_WHITE)) file << "nocolor='1' ";
14 else switch(o.color)
15 {
16 case EDCO_BLUE: file<<"bc='B' "; break;
17 case EDCO_YELLOW: file<<"bc='Y' "; break;
18 case EDCO_RED: file<<"bc='R' "; break;
19 case EDCO_PURPLE: file<<"bc='P' "; break;
20 default: file<<"bc='G' "; break;
21 }
22
23 }
24
25
saveDirection(std::ofstream & file,boardelement & o)26 void saveDirection(std::ofstream &file,boardelement &o)
27 {
28 switch(o.direction)
29 {
30 case EDITORDIRECTION_UP: file<<"dir='U' "; break;
31 case EDITORDIRECTION_DOWN: file<<"dir='D' "; break;
32 case EDITORDIRECTION_RIGHT: file<<"dir='R' "; break;
33 default: file<<"dir='L' "; break;
34 }
35
36 }
37
saveOppositeDirection(std::ofstream & file,boardelement & o)38 void saveOppositeDirection(std::ofstream &file,boardelement &o)
39 {
40 switch(o.direction)
41 {
42 case EDITORDIRECTION_UP: file<<"dir='D' "; break;
43 case EDITORDIRECTION_DOWN: file<<"dir='U' "; break;
44 case EDITORDIRECTION_RIGHT: file<<"dir='L' "; break;
45 default: file<<"dir='R' "; break;
46 }
47
48 }
49
50
saveRound(std::ofstream & file,boardelement & o)51 void saveRound(std::ofstream &file,boardelement &o)
52 {
53 if(o.round) file << "round='1' ";
54 }
55
56 int savePosition_lastx = -1;
resetSavedPosition()57 void resetSavedPosition()
58 {
59 savePosition_lastx = -1;
60 }
savePosition(std::ofstream & file,int x,int y)61 void savePosition(std::ofstream &file, int x ,int y)
62 {
63 if(x!=savePosition_lastx) {
64 file << "x='"<<x<<"' y='"<<y<<"' ";
65 savePosition_lastx = x;
66 } else {
67 file << "y='"<<y<<"' ";
68 }
69
70 }
71
saveLargeBlock(std::ofstream & file,boardelement & o,int x,int y)72 void saveLargeBlock(std::ofstream &file, boardelement &o, int x ,int y)
73 {
74 file <<"<largeblockpart ";
75 savePosition(file,x,y);
76 saveColor(file,o, true);
77 Uint8 flags = getLargeBlockFlagsByVarDir(o.variation, o.direction);
78 const char* dirs = "-U-R-D-L";
79 file<<"sharededges = '";
80 for (int i=1; i<9; i++)
81 if(flags&(1<<i))
82 file<<dirs[i];
83 file<<"' />";
84
85
86 }
87
saveColorFactory(std::ofstream & file,boardelement & o,int x,int y)88 void saveColorFactory(std::ofstream &file, boardelement &o, int x ,int y)
89 {
90 file <<"<factory ";
91 savePosition(file,x,y);
92 switch(o.direction)
93 {
94 case EDITORDIRECTION_UP: file<<"dir='U' swdir='D' "; break;
95 case EDITORDIRECTION_DOWN: file<<"dir='D' swdir='U' "; break;
96 case EDITORDIRECTION_RIGHT: file<<"dir='R' swdir='L' "; break;
97 default: file<<"dir='L' swdir='R' "; break;
98 }
99
100 saveColor(file,o, false);
101 saveRound(file,o);
102 file<<"kind='";
103 switch(o.variation)
104 {
105 case 0: case 1: case 2: file<<o.variation; break;
106 case 3: file<<4; break;
107 case 4: file<<8; break;
108 }
109
110 file<<"' />";
111
112
113 }
114
saveDangerFactory(std::ofstream & file,boardelement & o,int x,int y)115 void saveDangerFactory(std::ofstream &file, boardelement &o, int x ,int y)
116 {
117 file <<"<factory ";
118 savePosition(file,x,y);
119 switch(o.direction)
120 {
121 case EDITORDIRECTION_UP: file<<"dir='U' swdir='D' "; break;
122 case EDITORDIRECTION_DOWN: file<<"dir='D' swdir='U' "; break;
123 case EDITORDIRECTION_RIGHT: file<<"dir='R' swdir='L' "; break;
124 default: file<<"dir='L' swdir='R' "; break;
125 }
126
127 file<<"kind='";
128 switch(o.variation)
129 {
130 case 14:
131 file<<7; break;
132 case 15:
133 file<<6; break;
134 case 16:
135 file<<3; break;
136
137 default:
138 file<<5<<"' beastkind='"<<o.variation; break;
139 }
140
141 file<<"' />";
142
143
144 }
145
146 int defaultWallVariation = 0;
saveNormalObject(std::ofstream & file,boardelement & o,int x,int y)147 void saveNormalObject(std::ofstream &file, boardelement &o, int x, int y)
148 {
149 switch(o.type)
150 {
151 case EDOT_NONE : return; //nothing to do
152 case EDOT_BLOCK:
153 switch(o.color)
154 {
155 case EDCO_METAL:
156 file<<"\t\t<metalblock ";
157 savePosition(file,x,y);
158 saveRound(file,o);
159 file <<"/>\n";
160 break;
161 case EDCO_WILD:
162 file<<"\t\t<wild ";
163 savePosition(file,x,y);
164 saveRound(file,o);
165 file <<"/>\n";
166 break;
167
168 default:
169 file<<"\t\t<block ";
170 savePosition(file,x,y);
171 saveColor(file,o,true);
172 saveRound(file,o);
173 file <<"/>\n";
174 }
175 break;
176 case EDOT_GEM:
177 if(o.color == EDCO_PURPLE)
178 {
179 file<<"\t\t<star ";
180 savePosition(file,x,y);
181 file << "/>\n";
182 }
183 else
184 {
185 file<<"\t\t<gem ";
186 savePosition(file,x,y);
187 saveColor(file,o);
188 file <<"/>\n";
189 }
190 break;
191
192 case EDOT_WALL:
193 file<<"\t\t<wall ";
194 savePosition(file,x,y);
195 if(o.round)
196 {
197 //update memory in case the board wasn't drawn (which may happen when there are multiple levels)
198 editor::board->updateWallMem(x,XYE_VERT-y-1);
199 if(o.r1mem) file << "round1='1' ";
200 if(o.r7mem) file << "round7='1' ";
201 if(o.r3mem) file << "round3='1' ";
202 if(o.r9mem) file << "round9='1' ";
203 }
204
205
206 if(o.variation != defaultWallVariation) file << "type='"<<o.variation<<"' ";
207
208 file <<"/>\n";
209 break;
210
211 case EDOT_TURNER:
212 file<<"\t\t<";
213 if(o.variation) file<<"aclocker ";
214 else file << "clocker ";
215 savePosition(file,x,y);
216 saveRound(file,o);
217 saveColor(file,o,true);
218 file<<"/>\n";
219 break;
220
221
222
223 case EDOT_GEMBLOCK:
224 file<<"\t\t<gemblock ";
225 savePosition(file,x,y);
226 saveColor(file,o);
227 file <<"/>\n";
228 break;
229
230 case EDOT_EARTH:
231 file << "\t\t<earth ";
232 savePosition(file,x,y);
233 saveRound(file,o);
234 file<<"/>\n";
235 break;
236
237 case EDOT_MAGNET:
238 file << "\t\t<magnet ";
239 savePosition(file,x,y);
240
241 if ((o.direction==EDITORDIRECTION_LEFT) || (o.direction==EDITORDIRECTION_RIGHT) )
242 {
243 file << "horz='1' ";
244 }
245
246 file << "kind='"<<o.variation<<"' ";
247 file<<"/>\n";
248 break;
249
250 case EDOT_PUSHER:
251 file << "\t\t<pusher ";
252 savePosition(file,x,y);
253 saveDirection(file,o);
254 saveColor(file,o);
255
256 file<<"/>\n";
257 break;
258
259 case EDOT_ARROWMAKER:
260 file<<"\t\t<";
261 if(o.variation==0) file << "auto ";
262 else if(o.variation==2) file << "sniper ";
263 else if(o.variation==1) file << "filler ";
264 savePosition(file,x,y);
265 saveDirection(file,o);
266 saveColor(file,o);
267 saveRound(file,o);
268
269 file<<"/>\n";
270 break;
271
272 case EDOT_HAZARD: if(o.variation==2) break;
273 file<<"\t\t<";
274 if(o.variation==0) file << "blacky ";
275 else if(o.variation==1) file << "mine ";
276 savePosition(file,x,y);
277 file<<"/>\n";
278 break;
279
280 case EDOT_BEAST:
281 file<<"\t\t<beast ";
282 savePosition(file,x,y);
283 saveDirection(file,o);
284 file << "kind='"<<o.variation<<"' ";
285
286 file<<"/>\n";
287 break;
288
289 case EDOT_TELEPORT:
290 file<<"\t\t<teleport ";
291 savePosition(file,x,y);
292 saveDirection(file,o);
293 file <<"/>\n";break;
294
295 case EDOT_COLORSYSTEM:
296 if(o.variation==5) //window block:
297 {
298 file<<"\t\t<window ";
299 savePosition(file,x,y);
300 saveColor(file,o);
301 file<<"/>\n";
302 }
303 else if(o.variation==6) //block on top of area
304 {
305 file<<"\t\t<block ";
306 savePosition(file,x,y);
307 saveColor(file,o);
308 file<<"/>\n";
309 } else if (o.variation==7) { //wildcard block on top of area
310 file<<"\t\t<wild ";
311 savePosition(file,x,y);
312 file<<"/>\n";
313 }
314 break;
315
316 case EDOT_BOT:
317 file<<"\t\t<bot ";
318 savePosition(file,x,y);
319 file << "/>\n";
320 break;
321
322 case EDOT_KEYSYSTEM:
323 file<<"\t\t<";
324 if(o.variation) file<<"lock ";
325 else file<<"key ";
326 savePosition(file,x,y);
327 saveColor(file,o);
328 file << "/>\n";
329 break;
330
331 case EDOT_NUMBER:
332 file<<"\t\t<timer ";
333 savePosition(file,x,y);
334 saveRound(file,o);
335 saveColor(file,o);
336 file << "val='"<<o.variation<<"' ";
337 file << "/>\n";
338 break;
339
340
341 case EDOT_SPECIALBLOCKS:
342 file<<"\t\t<";
343
344 if (o.variation==0)
345 {
346 file<<"arrow ";
347 saveDirection(file,o);
348 }
349 else if (o.variation==1)
350 {
351 file<<"scroll ";
352 saveDirection(file,o);
353
354 }
355 else if(o.variation<=3)
356 {
357 if( o.variation==2) file << "toggle off='1' ";
358 else file << "toggle ";
359 }
360 else if (o.variation==4) file << "lblock ";
361 else file << "surprise ";
362 savePosition(file,x,y);
363 saveColor(file,o);
364 saveRound(file,o);
365 file << "/>\n";
366 break;
367 case EDOT_RATTLERHEAD:
368 file<<"\t\t<rattler ";
369 savePosition(file,x,y);
370 saveDirection(file,o);
371 if (o.variation) file << "grow='"<<o.variation<<"' ";
372
373 file << "/>\n";
374 break;
375
376 case EDOT_FOOD:
377 file<<"\t\t<rfood ";
378 savePosition(file,x,y);
379 file << "/>\n";
380 break;
381
382 case EDOT_LARGEBLOCK:
383 file<<"\t\t";
384 saveLargeBlock(file, o, x,y);
385 file<<"\n";
386 break;
387 case EDOT_COLORFACTORY:
388 file<<"\t\t";
389 saveColorFactory(file,o,x,y);
390 file<<"\n";
391 break;
392 case EDOT_DANGERFACTORY:
393 file<<"\t\t";
394 saveDangerFactory(file,o,x,y);
395 file<<"\n";
396 break;
397
398 case EDOT_PORTAL:
399 // Do nothing.
400 break;
401 }
402 }
403
savePortals(std::ofstream & file,editorboard * board)404 void savePortals(std::ofstream &file, editorboard *board)
405 {
406 for (int i=0; i<XYE_OBJECT_COLORS+1; i++)
407 if( board->portal_x[i][0] != -1)
408 {
409 int x = board->portal_x[i][0];
410 int y = board->portal_y[i][0];
411 int tx = board->portal_x[i][1];
412 int ty = board->portal_y[i][1];
413 if(tx<0) tx=0;
414 if(ty<0) ty=0;
415 file<<"\t\t<portal ";
416 savePosition(file, x,XYE_VERT-y-1);
417 int ni = i;
418 if ( i == 5 ) {
419 ni = 4;
420 } else if (i==4) {
421 ni = 5;
422 }
423
424 file<<"defcolor='"<<ni<<"' ";
425 file<<"targetx='"<<tx<<"' targety='"<<(XYE_VERT-ty-1)<<"' ";
426 file << "/>\n";
427 if(board->objects[tx][ty].variation == 1)
428 {
429 file<<"\t\t<portal ";
430 savePosition(file, tx,XYE_VERT-ty-1);
431 file<<"defcolor='"<<ni<<"' ";
432 file<<"targetx='"<<x<<"' targety='"<<(XYE_VERT-y-1)<<"' ";
433 file << "/>\n";
434
435 }
436 }
437
438 }
439
saveGroundObject(std::ofstream & file,boardelement & o,int x,int y)440 void saveGroundObject(std::ofstream &file,boardelement &o, int x, int y)
441 {
442 switch(o.type)
443 {
444 case EDOT_NONE : return; //nothing to do
445
446 case EDOT_HAZARD: if(o.variation!=2) break;
447 file<<"\t\t<pit ";
448 savePosition(file,x,y);
449 file<<"/>\n";
450 break;
451
452 case EDOT_FIREPAD:
453 file<<"\t\t<firepad ";
454 savePosition(file,x,y);
455 file<<"/>\n";
456 break;
457
458
459 case EDOT_ONEDIRECTION:
460 if (o.variation >= 2) {
461 file<<"\t\t<hiddenway ";
462 Uint32 flags = getHiddenWayFlagsByVariationAndDir(o.variation, o.direction);
463 string ent = "";
464 for (int i=2; i<=8; i+=2) {
465 if ( flags&(1<<i) ) {
466 ent += ('0'+(char)i);
467 }
468 }
469 file<<"ent='"<<ent<<"' ";
470 } else if(o.variation) {//ground arrow
471 file<<"\t\t<force ";
472 saveDirection(file,o);
473 } else {
474 file<<"\t\t<oneway ";
475 saveOppositeDirection(file,o);
476 }
477 savePosition(file,x,y);
478
479 file<<"/>\n";
480 break;
481
482
483 case EDOT_COLORSYSTEM:
484 if(o.variation==5) break;
485 file << "\t\t<";
486
487 switch(o.variation)
488 {
489 case 0 /*closed door*/: file<<"blockdoor ";break;
490 case 1 /*open door*/: file<<"blockdoor open='1' ";break;
491 case 2 /*closed trap*/: file<<"blocktrap ";break;
492 case 3 /*open trap*/: file<<"blocktrap open='1' ";break;
493 case 4 /*marked area*/: file<<"marked ";break;
494 case 6 /*block above area*/: file<<"marked "; break;
495 case 7 /*wildcard above area*/: file<<"marked "; break;
496
497 }
498 savePosition(file,x,y);
499 saveColor(file,o);
500 file<<"/>\n";
501 break;
502
503 case EDOT_HINT:
504 file << "\t\t<hint ";
505 savePosition(file,x,y);
506 file<<">"<<StripXML(o.hint)<<"</hint>";
507 break;
508
509 }
510 }
511
save()512 bool editor::save()
513 {
514 if (save(filename, false))
515 {
516 SavedFile=true;
517 return true;
518 }
519 dialogs::makeMessageDialog(editorwindow, string("Unable to save the level file, cannot rewrite ")+string(filename)+".","Ok",onDialogClickDoNothing);
520 return false;
521 }
522
523
524
525
saveDefault(std::ofstream & file,string tag,editorboard * board,int i)526 void saveDefault( std::ofstream & file, string tag, editorboard*board, int i)
527 {
528 DefaultColorData &cd = board->colors[i];
529 if (! cd.useDefault) {
530 file<<" <"<<tag<<" ";
531 file<<" color='"<<(i+1)<<"' />" <<endl;
532 }
533 }
534
saveWallDefault(std::ofstream & file,editorboard * board)535 void saveWallDefault( std::ofstream & file, editorboard*board)
536 {
537 const int MAX_WALL_VARIATIONS = 6;
538 pair<int, int> variationCount[MAX_WALL_VARIATIONS];
539 for (int i=0; i<MAX_WALL_VARIATIONS; i++) {
540 variationCount[i] = make_pair(0, i);
541 }
542 for (int i=0; i<XYE_HORZ; i++) {
543 for (int j=0; j<XYE_VERT; j++) {
544 if (board->objects[i][j].type == EDOT_WALL ) {
545 variationCount[board->objects[i][j].variation].first++;
546 }
547 }
548 }
549 defaultWallVariation = max_element(variationCount, variationCount + MAX_WALL_VARIATIONS)->second;
550 file<<" <wall type='"<< defaultWallVariation <<"' ";
551 DefaultColorData &cd = board->colors[EDITOR_COLOR_WALLS];
552 if (! cd.useDefault ) {
553 file<<" color='"<<(EDITOR_COLOR_WALLS+1)<<"' ";
554 }
555
556 file << " />" <<endl;
557
558 }
559
560
saveColorStuff(std::ofstream & file,editorboard * board)561 void saveColorStuff( std::ofstream & file, editorboard*board)
562 {
563 bool doit = false;
564 for (int i=0; i<TOTAL_EDITOR_COLOR_OPTIONS; i++) {
565 doit |= (! board->colors[i].useDefault );
566 }
567 if (doit) {
568 //first save the palette.
569 file<<" <palette>"<<endl;
570 for (int i=0; i<TOTAL_EDITOR_COLOR_OPTIONS; i++) {
571 DefaultColorData &cd = board->colors[i];
572 if ( ! cd.useDefault ) {
573 file << " <color id='"<<(i+1)<<"'";
574 file << " red='"<<(int)cd.color.r<<"'";
575 file << " green='"<<(int)cd.color.g<<"'";
576 file << " blue='"<<(int)cd.color.b<<"'";
577 file << " />"<<endl;
578 }
579
580 }
581 file<<" </palette>"<<endl;
582 }
583
584 //now save the defaults...
585 file<<" <default>"<<endl;
586
587 //saveDefault(file, "wall", board, EDITOR_COLOR_WALLS);
588 saveWallDefault(file, board);
589 saveDefault(file, "earth", board, EDITOR_COLOR_EARTH);
590 saveDefault(file, "oneway", board, EDITOR_COLOR_DOORS);
591 saveDefault(file, "force", board, EDITOR_COLOR_FORCE);
592
593 file<<" </default>"<<endl;
594
595 if (! board->colors[EDITOR_COLOR_FLOOR].useDefault) {
596 file <<" <floor><area color = '"<<(EDITOR_COLOR_FLOOR+1)<<"' ";
597 file << "x1='0' x2='29' y1='0' y2='19' /></floor>"<<endl;
598 }
599
600
601 }
save(const string & target,bool onlyOneLevel)602 bool editor::save(const string &target, bool onlyOneLevel)
603 {
604 std::ofstream file;
605 file.open (target.c_str(),std::ios::trunc | std::ios::out );
606 if (!file.is_open()) return false; //ouch just halt.
607
608 int oldcur = editorboard::CurrentLevelNumber();
609 int first = 0;
610 if (onlyOneLevel) {
611 first = oldcur;
612 }
613 editorboard::SaveCopy(board);
614 editorboard::LoadLevelNumber(board, first);
615
616 file << "<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>\n";
617 file << "<pack>\n<name>"<< StripXML(editorboard::filetitle) <<"</name><author>"<< StripXML(editorboard::author) <<"</author>\n<description>"<< StripXML(editorboard::description) <<"</description>\n";
618
619 for (int i=first; i<editorboard::CountLevels(); i++) {
620 editorboard::LoadLevelNumber(board, i);
621 file << "\n<level>\n";
622 file << "<title>"<< StripXML(board->title) <<"</title>\n";
623
624 if(board->hint!="")
625 {
626 file << "<hint>"<< StripXML(board->hint) <<"</hint>\n";
627 }
628 if(board->solution!="")
629 {
630 file << "<solution>"<< StripXML(board->solution) <<"</solution>\n";
631 }
632
633 if(board->bye!="")
634 {
635 file << "<bye>"<< StripXML(board->bye) <<"</bye>\n";
636 }
637 saveColorStuff(file, board);
638
639 int j;
640 file << "\t<ground>\n";
641 resetSavedPosition();
642 for (i=0;i<XYE_HORZ;i++) for (j=0;j<XYE_VERT;j++) saveGroundObject(file,editor::board->objects[i][j],i,XYE_VERT-j-1);
643 file << "\t</ground>\n";
644 file << "\t<objects>\n";
645 resetSavedPosition();
646 for (i=0;i<XYE_HORZ;i++) for (j=0;j<XYE_VERT;j++)
647 {
648 saveNormalObject(file,editor::board->objects[i][j],i,XYE_VERT-j-1);
649 }
650 savePortals( file, editor::board);
651
652
653 file << "\t</objects>\n";
654
655
656 if(editor::board->xye_x>=0)
657 {
658 resetSavedPosition();
659 file << "\t<xye x='"<<editor::board->xye_x<<"' y='"<<(XYE_VERT-editor::board->xye_y-1)<<"' lives='"<<(editor::board->objects[editor::board->xye_x][editor::board->xye_y].variation+1)<<"' />\n";
660 }
661
662 file << "</level>\n";
663
664 if (onlyOneLevel) break;
665 }
666
667 file << "</pack>\n";
668 editorboard::LoadLevelNumber(board, oldcur);
669
670
671
672
673
674 file.close();
675 return true;
676
677 }
678