4 // Copyright (C) 2003 Ricardo Cruz <rick2@aeiou.pt>
5 // Copyright (C) 2003 Tobias Glaesser <tobi.web@gmx.de>
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License
9 // as published by the Free Software Foundation; either version 2
10 // of the License, or (at your option) any later version.
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
29 #include <SDL_image.h>
30 #include "leveleditor.h"
43 #include "resources.h"
44 #include "music_manager.h"
45 #include "display_manager.h"
47 /* definitions to aid development */
49 /* definitions that affect gameplay */
50 #define KEY_CURSOR_SPEED 32
51 #define KEY_CURSOR_FASTSPEED 64
53 /* when pagedown/up pressed speed:*/
54 #define PAGE_CURSOR_SPEED 13*32
56 #define MOUSE_LEFT_MARGIN 80
57 #define MOUSE_RIGHT_MARGIN (560-32)
60 #define KEYBOARD_SPEED 140
61 #define MOUSE_SPEED 40
64 #define SELECT_W 2 // size of the selections lines
65 #define SELECT_CLR 0, 255, 0, 255 // lines color (R, G, B, A)
67 /* own declerations */
68 /* crutial ones (main loop) */
71 int le_load_level_subset(char *filename);
73 void le_drawinterface();
74 void le_checkevents();
75 void le_change(float x, float y, int tm, unsigned int c);
78 void le_set_defaults(void);
79 void le_activate_bad_guys(void);
80 void le_goto_level(int levelnb);
81 void le_highlight_selection();
83 void apply_level_settings_menu();
84 void update_subset_settings_menu();
85 void save_subset_settings_menu();
89 TileOrObject() : tile(0), obj(NULL) { is_tile = true; };
91 void Tile(unsigned int set_to) { tile = set_to; is_tile = true; }
92 void Object(GameObject* pobj) { obj = pobj; is_tile = false; }
93 //Returns true for a tile
94 bool IsTile() { return is_tile; };
95 //Returns true for a GameObject
96 bool IsObject() { return !is_tile; };
99 void Init() { tile = 0; obj = NULL; is_tile = true; };
101 bool is_tile; //true for tile (false for object)
106 /* leveleditor internals */
107 static string_list_type level_subsets;
108 static bool le_level_changed; /* if changes, ask for saving, when quiting*/
109 static bool show_minimap;
110 static bool show_selections;
111 static bool le_help_shown;
112 static int pos_x, pos_y, cursor_x, cursor_y;
114 static World* le_world;
115 static LevelSubset* le_level_subset;
116 static int le_show_grid;
118 static Surface* le_selection;
120 static TileOrObject le_current;
121 static bool le_mouse_pressed[2];
122 static bool le_mouse_clicked[2];
123 static Button* le_save_level_bt;
124 static Button* le_exit_bt;
125 static Button* le_test_level_bt;
126 static Button* le_next_level_bt;
127 static Button* le_previous_level_bt;
128 static Button* le_move_right_bt;
129 static Button* le_move_left_bt;
130 static Button* le_move_up_bt;
131 static Button* le_move_down_bt;
132 static Button* le_rubber_bt;
133 static Button* le_select_mode_one_bt;
134 static Button* le_select_mode_two_bt;
135 static Button* le_settings_bt;
136 static Button* le_tilegroup_bt;
137 static Button* le_objects_bt;
138 static Button* le_object_select_bt;
139 static Button* le_object_properties_bt;
140 static ButtonPanel* le_tilemap_panel;
141 static Menu* leveleditor_menu;
142 static Menu* subset_load_menu;
143 static Menu* subset_new_menu;
144 static Menu* subset_settings_menu;
145 static Menu* level_settings_menu;
146 static Menu* select_tilegroup_menu;
147 static Menu* select_objects_menu;
148 static Timer select_tilegroup_menu_effect;
149 static Timer select_objects_menu_effect;
150 static Timer display_level_info;
151 typedef std::map<std::string, ButtonPanel*> ButtonPanelMap;
152 static ButtonPanelMap tilegroups_map;
153 static ButtonPanelMap objects_map;
154 static std::string cur_tilegroup;
155 static std::string cur_objects;
156 static MouseCursor* mouse_select_object;
157 static MovingObject* selected_game_object;
159 static square selection;
160 static SelectionMode le_selection_mode;
161 static SDL_Event event;
162 TileMapType active_tm;
164 int leveleditor(char* filename)
166 int last_time, now_time, i;
175 clearscreen(0, 0, 0);
178 music_manager->halt_music();
180 while (SDL_PollEvent(&event))
184 if(le_load_level_subset(filename))
189 last_time = SDL_GetTicks();
194 if(Menu::current() == select_tilegroup_menu)
196 if(select_tilegroup_menu_effect.check())
198 select_tilegroup_menu->set_pos(screen->w - 64 + select_tilegroup_menu_effect.get_left(),
202 select_tilegroup_menu->set_pos(screen->w - 64,66,-0.5,0.5);
204 else if(Menu::current() == select_objects_menu)
206 if(select_objects_menu_effect.check())
208 select_objects_menu->set_pos(screen->w - 64 + select_objects_menu_effect.get_left(),82,-0.5,0.5);
211 select_objects_menu->set_pos(screen->w - 64,82,-0.5,0.5);
216 /* making events results to be in order */
222 clearscreen(0, 0, 0);
224 /* draw editor interface */
227 Menu* menu = Menu::current();
233 if(menu == leveleditor_menu)
235 switch (leveleditor_menu->check())
237 case MNID_RETURNLEVELEDITOR:
239 Menu::set_current(0);
241 Menu::set_current(leveleditor_menu);
243 case MNID_SUBSETSETTINGS:
244 update_subset_settings_menu();
246 case MNID_QUITLEVELEDITOR:
251 else if(menu == level_settings_menu)
253 switch (level_settings_menu->check())
256 apply_level_settings_menu();
257 Menu::set_current(NULL);
264 else if(menu == select_tilegroup_menu)
267 switch (it = select_tilegroup_menu->check())
272 cur_tilegroup = select_tilegroup_menu->get_item_by_id(it).text;
273 Menu::set_current(0);
280 else if(menu == select_objects_menu)
283 switch (it = select_objects_menu->check())
288 cur_objects = select_objects_menu->get_item_by_id(it).text;
291 Menu::set_current(0);
296 else if(menu == subset_load_menu)
298 switch (i = subset_load_menu->check())
305 if(le_load_level_subset(level_subsets.item[i-1]))
311 else if(menu == subset_new_menu)
313 if(subset_new_menu->item[2].input[0] == '\0')
314 subset_new_menu->item[3].kind = MN_DEACTIVE;
317 subset_new_menu->item[3].kind = MN_ACTION;
319 switch (i = subset_new_menu->check())
321 case MNID_CREATESUBSET:
322 LevelSubset::create(subset_new_menu->get_item_by_id(MNID_SUBSETNAME).input);
323 le_level_subset->load(subset_new_menu->get_item_by_id(MNID_SUBSETNAME).input);
324 leveleditor_menu->get_item_by_id(MNID_SUBSETSETTINGS).kind = MN_GOTO;
326 subset_new_menu->get_item_by_id(MNID_SUBSETNAME).change_input("");
328 Menu::set_current(subset_settings_menu);
333 else if(menu == subset_settings_menu)
335 if(le_level_subset->title.compare(subset_settings_menu->get_item_by_id(MNID_SUBSETTITLE).input) == 0 && le_level_subset->description.compare(subset_settings_menu->get_item_by_id(MNID_SUBSETDESCRIPTION).input) == 0 )
336 subset_settings_menu->get_item_by_id(MNID_SUBSETSAVECHANGES).kind = MN_DEACTIVE;
338 subset_settings_menu->get_item_by_id(MNID_SUBSETSAVECHANGES).kind = MN_ACTION;
340 switch (i = subset_settings_menu->check())
342 case MNID_SUBSETSAVECHANGES:
343 save_subset_settings_menu();
344 Menu::set_current(leveleditor_menu);
350 MouseCursor::current()->draw();
358 ++global_frame_counter;
361 now_time = SDL_GetTicks();
362 if (now_time < last_time + FPS)
363 SDL_Delay(last_time + FPS - now_time); /* delay some time */
371 int le_load_level_subset(char *filename)
373 le_level_subset->load(filename);
374 leveleditor_menu->get_item_by_id(MNID_SUBSETSETTINGS).kind = MN_GOTO;
378 //GameSession* session = new GameSession(datadir + "/levels/" + le_level_subset->name + "/level1.stl", 0, ST_GL_DEMO_GAME);
380 Menu::set_current(NULL);
389 leveleditor_menu = new Menu();
390 subset_load_menu = new Menu();
391 subset_new_menu = new Menu();
392 subset_settings_menu = new Menu();
393 level_settings_menu = new Menu();
394 select_tilegroup_menu = new Menu();
395 select_objects_menu = new Menu();
397 leveleditor_menu->additem(MN_LABEL,"Level Editor Menu",0,0);
398 leveleditor_menu->additem(MN_HL,"",0,0);
399 leveleditor_menu->additem(MN_ACTION,"Return To Level Editor",0,0,MNID_RETURNLEVELEDITOR);
400 leveleditor_menu->additem(MN_DEACTIVE,"Level Subset Settings",0,subset_settings_menu,MNID_SUBSETSETTINGS);
401 leveleditor_menu->additem(MN_GOTO,"Load Level Subset",0,subset_load_menu);
402 leveleditor_menu->additem(MN_GOTO,"New Level Subset",0,subset_new_menu);
403 leveleditor_menu->additem(MN_HL,"",0,0);
404 leveleditor_menu->additem(MN_ACTION,"Quit Level Editor",0,0,MNID_QUITLEVELEDITOR);
406 Menu::set_current(leveleditor_menu);
408 subset_load_menu->additem(MN_LABEL, "Load Level Subset", 0, 0);
409 subset_load_menu->additem(MN_HL, "", 0, 0);
411 for(i = 0; i < level_subsets.num_items; ++i)
413 subset_load_menu->additem(MN_ACTION,level_subsets.item[i],0,0, i+1);
415 subset_load_menu->additem(MN_HL,"",0,0);
416 subset_load_menu->additem(MN_BACK,"Back",0,0);
418 subset_new_menu->additem(MN_LABEL,"New Level Subset",0,0);
419 subset_new_menu->additem(MN_HL,"",0,0);
420 subset_new_menu->additem(MN_TEXTFIELD,"Enter Name",0,0,MNID_SUBSETNAME);
421 subset_new_menu->additem(MN_ACTION,"Create",0,0, MNID_CREATESUBSET);
422 subset_new_menu->additem(MN_HL,"",0,0);
423 subset_new_menu->additem(MN_BACK,"Back",0,0);
425 subset_settings_menu->additem(MN_LABEL,"Level Subset Settings",0,0);
426 subset_settings_menu->additem(MN_HL,"",0,0);
427 subset_settings_menu->additem(MN_TEXTFIELD,"Title",0,0,MNID_SUBSETTITLE);
428 subset_settings_menu->additem(MN_TEXTFIELD,"Description",0,0,MNID_SUBSETDESCRIPTION);
429 subset_settings_menu->additem(MN_HL,"",0,0);
430 subset_settings_menu->additem(MN_ACTION,"Save Changes",0,0,MNID_SUBSETSAVECHANGES);
431 subset_settings_menu->additem(MN_HL,"",0,0);
432 subset_settings_menu->additem(MN_BACK,"Back",0,0);
434 level_settings_menu->arrange_left = true;
435 level_settings_menu->additem(MN_LABEL,"Level Settings",0,0);
436 level_settings_menu->additem(MN_HL,"",0,0);
437 level_settings_menu->additem(MN_TEXTFIELD, "Name ",0,0,MNID_NAME);
438 level_settings_menu->additem(MN_TEXTFIELD, "Author ",0,0,MNID_AUTHOR);
439 level_settings_menu->additem(MN_STRINGSELECT,"Song ",0,0,MNID_SONG);
440 level_settings_menu->additem(MN_STRINGSELECT,"Bg-Image",0,0,MNID_BGIMG);
441 level_settings_menu->additem(MN_STRINGSELECT,"Particle",0,0,MNID_PARTICLE);
442 level_settings_menu->additem(MN_NUMFIELD, "Length ",0,0,MNID_LENGTH);
443 level_settings_menu->additem(MN_NUMFIELD, "Height ",0,0,MNID_HEIGHT);
444 level_settings_menu->additem(MN_NUMFIELD, "Time ",0,0,MNID_TIME);
445 level_settings_menu->additem(MN_NUMFIELD, "Gravity ",0,0,MNID_GRAVITY);
446 level_settings_menu->additem(MN_NUMFIELD, "Bg-Img-Speed",0,0,MNID_BGSPEED);
447 level_settings_menu->additem(MN_NUMFIELD, "Top Red ",0,0,MNID_TopRed);
448 level_settings_menu->additem(MN_NUMFIELD, "Top Green ",0,0,MNID_TopGreen);
449 level_settings_menu->additem(MN_NUMFIELD, "Top Blue ",0,0,MNID_TopBlue);
450 level_settings_menu->additem(MN_NUMFIELD, "Bottom Red ",0,0,MNID_BottomRed);
451 level_settings_menu->additem(MN_NUMFIELD, "Bottom Green",0,0,MNID_BottomGreen);
452 level_settings_menu->additem(MN_NUMFIELD, "Bottom Blue ",0,0,MNID_BottomBlue);
453 level_settings_menu->additem(MN_HL,"",0,0);
454 level_settings_menu->additem(MN_ACTION,"Apply Changes",0,0,MNID_APPLY);
456 select_tilegroup_menu->arrange_left = true;
457 select_tilegroup_menu->additem(MN_LABEL,"Tilegroup",0,0);
458 select_tilegroup_menu->additem(MN_HL,"",0,0);
459 std::set<TileGroup>* tilegroups = TileManager::tilegroups();
461 for(std::set<TileGroup>::iterator it = tilegroups->begin();
462 it != tilegroups->end(); ++it )
464 select_tilegroup_menu->additem(MN_ACTION, it->name, 0, 0, tileid);
466 tilegroups_map[(*it).name] = new ButtonPanel(screen->w - 64,96, 64, 318);
469 for(std::vector<int>::const_iterator sit = (*it).tiles.begin();
470 sit != (*it).tiles.end(); ++sit, ++i)
472 std::string imagefile = "/images/tilesets/" ;
473 bool only_editor_image = false;
474 if(!TileManager::instance()->get(*sit)->filenames.empty())
476 imagefile += TileManager::instance()->get(*sit)->filenames[0];
478 else if(!TileManager::instance()->get(*sit)->editor_filenames.empty())
480 imagefile += TileManager::instance()->get(*sit)->editor_filenames[0];
481 only_editor_image = true;
485 imagefile += "notile.png";
487 Button* button = new Button(imagefile, it->name, SDLKey(SDLK_a + i),
489 if(!only_editor_image)
490 if(!TileManager::instance()->get(*sit)->editor_filenames.empty())
492 imagefile = "/images/tilesets/" + TileManager::instance()->get(*sit)->editor_filenames[0];
493 button->add_icon(imagefile,32,32);
495 tilegroups_map[it->name]->additem(button, *sit);
498 select_tilegroup_menu->additem(MN_HL,"",0,0);
500 select_objects_menu->arrange_left = true;
501 select_objects_menu->additem(MN_LABEL,"Objects",0,0);
502 select_objects_menu->additem(MN_HL,"",0,0);
505 select_objects_menu->additem(MN_ACTION,"BadGuys",0,0,1);
506 objects_map["BadGuys"] = new ButtonPanel(screen->w - 64,96, 64, 318);
508 DisplayManager dummy;
509 for(int i = 0; i < NUM_BadGuyKinds; ++i)
511 BadGuy bad_tmp(dummy, 0,0,BadGuyKind(i),false);
512 objects_map["BadGuys"]->additem(new Button("", "BadGuy",(SDLKey)(i+'a'),0,0,32,32),1000000+i);
513 objects_map["BadGuys"]->manipulate_button(i)->set_drawable(new
515 objects_map["BadGuys"]->manipulate_button(i)->get_pos().x,
516 objects_map["BadGuys"]->manipulate_button(i)->get_pos().y,
517 BadGuyKind(i), false));
521 select_objects_menu->additem(MN_HL,"",0,0);
529 level_subsets = dsubdirs("/levels", "level1.stl");
530 le_level_subset = new LevelSubset;
533 selected_game_object = NULL;
537 show_selections = true;
541 le_frame = 0; /* support for frames in some tiles, like waves and bad guys */
542 le_level_changed = false;
543 le_help_shown = false;
545 le_mouse_pressed[LEFT] = false;
546 le_mouse_pressed[RIGHT] = false;
548 le_mouse_clicked[LEFT] = false;
549 le_mouse_clicked[RIGHT] = false;
551 le_selection = new Surface(datadir + "/images/leveleditor/select.png", USE_ALPHA);
553 select_tilegroup_menu_effect.init(false);
554 select_objects_menu_effect.init(false);
555 display_level_info.init(false);
558 le_save_level_bt = new Button("/images/icons/save.png","Save level", SDLK_F6,screen->w-64,32);
559 le_exit_bt = new Button("/images/icons/exit.png","Exit", SDLK_F10,screen->w-32,32);
560 le_next_level_bt = new Button("/images/icons/next.png","Next level", SDLK_PAGEUP,screen->w-64,0);
561 le_previous_level_bt = new Button("/images/icons/previous.png","Previous level",SDLK_PAGEDOWN,screen->w-32,0);
562 le_rubber_bt = new Button("/images/icons/rubber.png","Rubber",SDLK_DELETE,screen->w-32,48);
563 le_select_mode_one_bt = new Button ("/images/icons/select-mode1.png","Select single tile",SDLK_F3,screen->w-64,48);
564 le_select_mode_two_bt = new Button("/images/icons/select-mode2.png","Select multiple tiles",SDLK_F3,screen->w-64,48);
565 le_test_level_bt = new Button("/images/icons/test-level.png","Test level",SDLK_F4,screen->w-64,screen->h - 64);
566 le_settings_bt = new Button("/images/icons/settings.png","Level settings",SDLK_F5,screen->w-32,screen->h - 64);
567 le_move_left_bt = new Button("/images/icons/left.png","Move left",SDLK_LEFT,screen->w-80-16,0);
568 le_move_right_bt = new Button("/images/icons/right.png","Move right",SDLK_RIGHT,screen->w-80,0);
569 le_move_up_bt = new Button("/images/icons/up.png","Move up",SDLK_UP,screen->w-80,16);
570 le_move_down_bt = new Button("/images/icons/down.png","Move down",SDLK_DOWN,screen->w-80,32);
571 le_tilegroup_bt = new Button("/images/icons/tilegroup.png","Select Tilegroup", SDLK_F7,screen->w-64,64);
572 le_objects_bt = new Button("/images/icons/objects.png","Select Objects", SDLK_F8,screen->w-64,80);
573 le_object_select_bt = new Button("/images/icons/select-one.png","Select an Object", SDLK_s, screen->w - 64, screen->h-98);
574 le_object_properties_bt = new Button("/images/icons/properties.png","Edit object properties", SDLK_p, screen->w - 32, screen->h-98);
575 le_object_properties_bt->set_active(false);
577 mouse_select_object = new MouseCursor(datadir + "/images/status/select-cursor.png",1);
578 mouse_select_object->set_mid(16,16);
580 le_tilemap_panel = new ButtonPanel(screen->w-64,screen->h-32,32,32);
581 le_tilemap_panel->set_button_size(32,10);
582 le_tilemap_panel->additem(new Button("/images/icons/bkgrd.png","Background",SDLK_b,0,0),TM_BG);
583 le_tilemap_panel->additem(new Button("/images/icons/intact.png","Interactive",SDLK_i,0,0),TM_IA);
584 le_tilemap_panel->additem(new Button("/images/icons/frgrd.png","Foreground",SDLK_f,0,0),TM_FG);
585 le_tilemap_panel->highlight_last(true);
586 le_tilemap_panel->set_last_clicked(TM_IA);
592 SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
598 void update_level_settings_menu()
603 level_settings_menu->get_item_by_id(MNID_NAME).change_input(le_world->get_level()->name.c_str());
604 level_settings_menu->get_item_by_id(MNID_AUTHOR).change_input(le_world->get_level()->author.c_str());
606 string_list_copy(level_settings_menu->get_item_by_id(MNID_SONG).list, dfiles("music/",NULL, "-fast"));
607 string_list_copy(level_settings_menu->get_item_by_id(MNID_BGIMG).list, dfiles("images/background",NULL, NULL));
608 string_list_add_item(level_settings_menu->get_item_by_id(MNID_BGIMG).list,"");
609 string_list_add_item(level_settings_menu->get_item_by_id(MNID_PARTICLE).list,"");
610 string_list_add_item(level_settings_menu->get_item_by_id(MNID_PARTICLE).list,"snow");
611 string_list_add_item(level_settings_menu->get_item_by_id(MNID_PARTICLE).list,"clouds");
613 if((i = string_list_find(level_settings_menu->get_item_by_id(MNID_SONG).list,le_world->get_level()->song_title.c_str())) != -1)
614 level_settings_menu->get_item_by_id(MNID_SONG).list->active_item = i;
615 if((i = string_list_find(level_settings_menu->get_item_by_id(MNID_BGIMG).list,le_world->get_level()->bkgd_image.c_str())) != -1)
616 level_settings_menu->get_item_by_id(MNID_BGIMG).list->active_item = i;
617 if((i = string_list_find(level_settings_menu->get_item_by_id(MNID_PARTICLE).list,le_world->get_level()->particle_system.c_str())) != -1)
618 level_settings_menu->get_item_by_id(MNID_PARTICLE).list->active_item = i;
620 sprintf(str,"%d",le_world->get_level()->width);
621 level_settings_menu->get_item_by_id(MNID_LENGTH).change_input(str);
622 sprintf(str,"%d",le_world->get_level()->height);
623 level_settings_menu->get_item_by_id(MNID_HEIGHT).change_input(str);
624 sprintf(str,"%d",le_world->get_level()->time_left);
625 level_settings_menu->get_item_by_id(MNID_TIME).change_input(str);
626 sprintf(str,"%2.0f",le_world->get_level()->gravity);
627 level_settings_menu->get_item_by_id(MNID_GRAVITY).change_input(str);
628 sprintf(str,"%d",le_world->get_level()->bkgd_speed);
629 level_settings_menu->get_item_by_id(MNID_BGSPEED).change_input(str);
630 sprintf(str,"%d",le_world->get_level()->bkgd_top.red);
631 level_settings_menu->get_item_by_id(MNID_TopRed).change_input(str);
632 sprintf(str,"%d",le_world->get_level()->bkgd_top.green);
633 level_settings_menu->get_item_by_id(MNID_TopGreen).change_input(str);
634 sprintf(str,"%d",le_world->get_level()->bkgd_top.blue);
635 level_settings_menu->get_item_by_id(MNID_TopBlue).change_input(str);
636 sprintf(str,"%d",le_world->get_level()->bkgd_bottom.red);
637 level_settings_menu->get_item_by_id(MNID_BottomRed).change_input(str);
638 sprintf(str,"%d",le_world->get_level()->bkgd_bottom.green);
639 level_settings_menu->get_item_by_id(MNID_BottomGreen).change_input(str);
640 sprintf(str,"%d",le_world->get_level()->bkgd_bottom.blue);
641 level_settings_menu->get_item_by_id(MNID_BottomBlue).change_input(str);
644 void update_subset_settings_menu()
646 subset_settings_menu->item[2].change_input(le_level_subset->title.c_str());
647 subset_settings_menu->item[3].change_input(le_level_subset->description.c_str());
650 void apply_level_settings_menu()
654 le_level_changed = true;
656 le_world->get_level()->name = level_settings_menu->get_item_by_id(MNID_NAME).input;
657 le_world->get_level()->author = level_settings_menu->get_item_by_id(MNID_AUTHOR).input;
659 if(le_world->get_level()->bkgd_image.compare(string_list_active(level_settings_menu->get_item_by_id(MNID_BGIMG).list)) != 0)
661 le_world->get_level()->bkgd_image = string_list_active(level_settings_menu->get_item_by_id(MNID_BGIMG).list);
665 if(le_world->get_level()->particle_system.compare(string_list_active(level_settings_menu->get_item_by_id(MNID_PARTICLE).list)) != 0)
667 le_world->get_level()->particle_system = string_list_active(level_settings_menu->get_item_by_id(MNID_PARTICLE).list);
672 le_world->get_level()->load_gfx();
675 le_world->get_level()->song_title = string_list_active(level_settings_menu->get_item_by_id(MNID_SONG).list);
677 le_world->get_level()->resize(
678 atoi(level_settings_menu->get_item_by_id(MNID_LENGTH).input),
679 atoi(level_settings_menu->get_item_by_id(MNID_HEIGHT).input));
680 le_world->get_level()->time_left = atoi(level_settings_menu->get_item_by_id(MNID_TIME).input);
681 le_world->get_level()->gravity = atof(level_settings_menu->get_item_by_id(MNID_GRAVITY).input);
682 le_world->get_level()->bkgd_speed = atoi(level_settings_menu->get_item_by_id(MNID_BGSPEED).input);
683 le_world->get_level()->bkgd_top.red = atoi(level_settings_menu->get_item_by_id(MNID_TopRed).input);
684 le_world->get_level()->bkgd_top.green = atoi(level_settings_menu->get_item_by_id(MNID_TopGreen).input);
685 le_world->get_level()->bkgd_top.blue = atoi(level_settings_menu->get_item_by_id(MNID_TopBlue).input);
686 le_world->get_level()->bkgd_bottom.red = atoi(level_settings_menu->get_item_by_id(MNID_BottomRed).input);
687 le_world->get_level()->bkgd_bottom.green = atoi(level_settings_menu->get_item_by_id(MNID_BottomGreen).input);
688 le_world->get_level()->bkgd_bottom.blue = atoi(level_settings_menu->get_item_by_id(MNID_BottomBlue).input);
691 void save_subset_settings_menu()
693 le_level_subset->title = subset_settings_menu->item[2].input;
694 le_level_subset->description = subset_settings_menu->item[3].input;
695 le_level_subset->save();
696 le_level_changed = false;
699 void le_unload_level()
706 sprintf(str,"Save changes to level %d of %s?",le_level,le_level_subset->name.c_str());
707 if(confirm_dialog(str))
709 le_world->get_level()->save(le_level_subset->name.c_str(), le_level,
715 le_level_changed = false;
718 void le_goto_level(int levelnb)
721 le_world = new World(le_level_subset->name, levelnb);
722 display_level_info.start(2500);
728 SDL_EnableKeyRepeat(0, 0); // disables key repeating
732 delete leveleditor_menu;
733 delete subset_load_menu;
734 delete subset_new_menu;
735 delete subset_settings_menu;
736 delete level_settings_menu;
737 delete select_tilegroup_menu;
738 delete select_objects_menu;
739 delete le_save_level_bt;
741 delete le_test_level_bt;
742 delete le_next_level_bt;
743 delete le_previous_level_bt;
744 delete le_move_right_bt;
745 delete le_move_left_bt;
746 delete le_move_up_bt;
747 delete le_move_down_bt;
749 delete le_select_mode_one_bt;
750 delete le_select_mode_two_bt;
751 delete le_settings_bt;
752 delete le_tilegroup_bt;
753 delete le_objects_bt;
754 delete le_tilemap_panel;
755 delete le_object_select_bt;
756 delete le_object_properties_bt;
757 delete mouse_select_object;
759 delete le_level_subset;
762 for(ButtonPanelMap::iterator i = tilegroups_map.begin();
763 i != tilegroups_map.end(); ++i)
767 for(ButtonPanelMap::iterator i = objects_map.begin();
768 i != objects_map.end(); ++i)
774 void le_drawminimap()
780 if(screen->w - 64 > le_world->get_level()->width * 4)
782 else if(screen->w - 64 > le_world->get_level()->width * 2)
786 int left_offset = (screen->w - 64 - le_world->get_level()->width*mini_tile_width) / 2;
788 int mini_tile_height;
789 if(screen->h - 64 > le_world->get_level()->height * 4)
790 mini_tile_height = 4;
791 else if(screen->h - 64 > le_world->get_level()->height * 2)
792 mini_tile_height = 2;
794 mini_tile_height = 1;
796 Level* level = le_world->get_level();
797 for (int y = 0; y < le_world->get_level()->height; ++y)
798 for (int x = 0; x < le_world->get_level()->width; ++x)
801 Tile::draw_stretched(left_offset + mini_tile_width*x, y * 4,
802 mini_tile_width , 4, level->bg_tiles[y * level->width + x]);
804 Tile::draw_stretched(left_offset + mini_tile_width*x, y * 4,
805 mini_tile_width , 4, level->ia_tiles[y * level->width + x]);
807 Tile::draw_stretched(left_offset + mini_tile_width*x, y * 4,
808 mini_tile_width , 4, level->fg_tiles[y + level->width + x]);
812 fillrect(left_offset, 0, le_world->get_level()->width*mini_tile_width, le_world->get_level()->height*mini_tile_height, 200, 200, 200, 128);
814 fillrect(left_offset + (pos_x/32)*mini_tile_width, 0, 19*mini_tile_width, 2, 200, 200, 200, 200);
815 fillrect(left_offset + (pos_x/32)*mini_tile_width, 0, 2, le_world->get_level()->height*mini_tile_height, 200, 200, 200, 200);
816 fillrect(left_offset + (pos_x/32)*mini_tile_width + 19*mini_tile_width - 2, 0, 2, le_world->get_level()->height*mini_tile_height, 200, 200, 200, 200);
817 fillrect(left_offset + (pos_x/32)*mini_tile_width, le_world->get_level()->height*mini_tile_height-2, 19*mini_tile_width, 2, 200, 200, 200, 200);
821 void le_drawinterface()
828 /* draw a grid (if selected) */
831 for(x = 0; x < VISIBLE_TILES_X; x++)
832 fillrect(x*32 - ((int)pos_x % 32), 0, 1, screen->h, 225, 225, 225,255);
833 for(y = 0; y < VISIBLE_TILES_Y; y++)
834 fillrect(0, y*32 - ((int)pos_y % 32), screen->w, 1, 225, 225, 225,255);
838 if(show_minimap) // use_gl because the minimap isn't shown correctly in software mode. Any idea? FIXME Possible reasons: SDL_SoftStretch is a hack itsself || an alpha blitting issue SDL can't handle in software mode
841 if(show_selections && MouseCursor::current() != mouse_select_object)
843 if(le_selection_mode == CURSOR)
845 if(le_current.IsTile())
846 le_selection->draw(cursor_x - pos_x, cursor_y - pos_y);
848 else if(le_selection_mode == SQUARE)
851 le_highlight_selection();
852 /* draw current selection */
853 w = selection.x2 - selection.x1;
854 h = selection.y2 - selection.y1;
855 fillrect(selection.x1 - pos_x, selection.y1 - pos_y, w, SELECT_W, SELECT_CLR);
856 fillrect(selection.x1 - pos_x + w, selection.y1 - pos_y, SELECT_W, h, SELECT_CLR);
857 fillrect(selection.x1 - pos_x, selection.y1 - pos_y + h, w, SELECT_W, SELECT_CLR);
858 fillrect(selection.x1 - pos_x, selection.y1 - pos_y, SELECT_W, h, SELECT_CLR);
863 /* draw button bar */
864 fillrect(screen->w - 64, 0, 64, screen->h, 50, 50, 50,255);
866 if(le_current.IsTile())
868 Tile::draw(screen->w - 32, screen->h - 32, le_current.tile);
869 if(TileManager::instance()->get(le_current.tile)->editor_images.size() > 0)
870 TileManager::instance()->get(le_current.tile)->editor_images[0]->draw( screen->w - 32, screen->h - 32);
872 #if 0 // XXX FIXME TODO
873 if(le_current.IsObject() && MouseCursor::current() != mouse_select_object)
875 le_current.obj->draw_on_screen(screen->w - 32, screen->h - 32);
876 le_current.obj->draw_on_screen(cursor_x,cursor_y);
880 if(mouse_select_object && selected_game_object != NULL)
882 fillrect(selected_game_object->base.x-pos_x,selected_game_object->base.y-pos_y,selected_game_object->base.width,3,255,0,0,255);
883 fillrect(selected_game_object->base.x-pos_x,selected_game_object->base.y-pos_y,3,selected_game_object->base.height,255,0,0,255);
884 fillrect(selected_game_object->base.x-pos_x,selected_game_object->base.y-pos_y+selected_game_object->base.height,selected_game_object->base.width,3,255,0,0,255);
885 fillrect(selected_game_object->base.x-pos_x+selected_game_object->base.width,selected_game_object->base.y-pos_y,3,selected_game_object->base.height,255,0,0,255);
890 le_save_level_bt->draw();
892 le_test_level_bt->draw();
893 le_next_level_bt->draw();
894 le_previous_level_bt->draw();
895 le_rubber_bt->draw();
896 if(le_selection_mode == SQUARE)
897 le_select_mode_one_bt->draw();
898 else if(le_selection_mode == CURSOR)
899 le_select_mode_two_bt->draw();
900 le_settings_bt->draw();
901 le_move_right_bt->draw();
902 le_move_left_bt->draw();
903 le_move_up_bt->draw();
904 le_move_down_bt->draw();
905 le_tilegroup_bt->draw();
906 le_objects_bt->draw();
907 if(!cur_tilegroup.empty())
908 tilegroups_map[cur_tilegroup]->draw();
909 else if(!cur_objects.empty())
911 objects_map[cur_objects]->draw();
914 le_tilemap_panel->draw();
916 if(!cur_objects.empty())
918 le_object_select_bt->draw();
919 le_object_properties_bt->draw();
922 sprintf(str, "%d/%d", le_level,le_level_subset->levels);
923 white_text->drawf(str, (le_level_subset->levels < 10) ? -10 : 0, 16, A_RIGHT, A_TOP, 0);
926 white_small_text->draw("F1 for Help", 10, 430, 1);
928 if(display_level_info.check())
929 white_text->drawf(le_world->get_level()->name.c_str(), 0, 0, A_HMIDDLE, A_TOP, 0);
934 white_small_text->draw("No Level Subset loaded - Press ESC and choose one in the menu", 10, 430, 1);
936 white_small_text->draw("No Level Subset loaded", 10, 430, 1);
946 /* Draw the real background */
947 le_world->get_level()->draw_bg();
949 if(le_current.IsTile())
951 Tile::draw(cursor_x-pos_x, cursor_y-pos_y,le_current.tile,128);
952 if(!TileManager::instance()->get(le_current.tile)->images.empty())
953 fillrect(cursor_x-pos_x,cursor_y-pos_y,TileManager::instance()->get(le_current.tile)->images[0]->w,TileManager::instance()->get(le_current.tile)->images[0]->h,50,50,50,50);
955 #if 0 // XXX FIXME TODO
956 if(le_current.IsObject())
958 le_current.obj->move_to(cursor_x, cursor_y);
962 /* clearscreen(current_level.bkgd_red, current_level.bkgd_green, current_level.bkgd_blue); */
964 Level* level = le_world->get_level();
965 for (y = 0; y < VISIBLE_TILES_Y && y < (unsigned)le_world->get_level()->height; ++y)
966 for (x = 0; x < (unsigned)VISIBLE_TILES_X - 2; ++x)
969 if(active_tm == TM_BG)
974 Tile::draw(32*x - fmodf(pos_x, 32), y*32 - fmodf(pos_y, 32),
975 level->bg_tiles[ (y + (int)(pos_y / 32)) * level->width +
976 (x + (int)(pos_x / 32))],a);
978 if(active_tm == TM_IA)
983 Tile::draw(32*x - fmodf(pos_x, 32), y*32 - fmodf(pos_y, 32),
984 level->ia_tiles[ (y + (int)(pos_y / 32)) * level->width +
985 (x + (int)(pos_x / 32))],a);
988 if(active_tm == TM_FG)
993 Tile::draw(32*x - fmodf(pos_x, 32), y*32 - fmodf(pos_y, 32),
994 level->fg_tiles[ (y + (int)(pos_y / 32)) * level->width +
995 (x + (int)(pos_x / 32))],a);
997 /* draw whats inside stuff when cursor is selecting those */
998 /* (draw them all the time - is this the right behaviour?) */
999 Tile* edit_image = TileManager::instance()->get(
1001 [ (y + (int)(pos_y / 32)) * level->width + (x + (int)(pos_x / 32))]);
1002 if(edit_image && !edit_image->editor_images.empty())
1003 edit_image->editor_images[0]->draw( x * 32 - ((int)pos_x % 32), y*32 - ((int)pos_y % 32));
1007 /* Draw the Bad guys: */
1008 for (std::vector<GameObject*>::iterator it = le_world->gameobjects.begin();
1009 it != le_world->gameobjects.end(); ++it)
1011 BadGuy* badguy = dynamic_cast<BadGuy*> (*it);
1015 /* to support frames: img_bsod_left[(frame / 5) % 4] */
1017 viewport.set_translation(Vector(pos_x, pos_y));
1018 badguy->draw(viewport, 0);
1021 /* Draw the player: */
1022 /* for now, the position is fixed at (100, 240) */
1023 largetux.walk_right->draw( 100 - pos_x, 240 - pos_y);
1026 void le_change_object_properties(GameObject *pobj)
1028 Surface* cap_screen = Surface::CaptureScreen();
1029 Menu* object_properties_menu = new Menu();
1032 object_properties_menu->additem(MN_LABEL,pobj->type() + " Properties",0,0);
1033 object_properties_menu->additem(MN_HL,"",0,0);
1035 BadGuy* pbad = dynamic_cast<BadGuy*>(pobj);
1038 object_properties_menu->additem(MN_STRINGSELECT,"Kind",0,0,1);
1039 for(int i = 0; i < NUM_BadGuyKinds; ++i)
1041 string_list_add_item(object_properties_menu->get_item_by_id(1).list,
1042 badguykind_to_string(static_cast<BadGuyKind>(i)).c_str());
1044 object_properties_menu->get_item_by_id(1).list->active_item = i;
1046 object_properties_menu->additem(MN_TOGGLE,"StayOnPlatform",pbad->stay_on_platform,0,2);
1049 object_properties_menu->additem(MN_HL,"",0,0);
1050 object_properties_menu->additem(MN_ACTION,"Ok",0,0,3);
1052 Menu::set_current(object_properties_menu);
1058 while (SDL_PollEvent(&event))
1060 object_properties_menu->event(event);
1063 cap_screen->draw(0,0);
1065 object_properties_menu->draw();
1066 object_properties_menu->action();
1068 switch (object_properties_menu->check())
1072 BadGuy* pbad = dynamic_cast<BadGuy*>(pobj);
1074 BadGuy* pbad = dynamic_cast<BadGuy*>(pobj);
1075 pbad->kind = badguykind_from_string(string_list_active(object_properties_menu->get_item_by_id(1).list));
1076 pbad->stay_on_platform = object_properties_menu->get_item_by_id(2).toggled;
1085 if(Menu::current() == NULL)
1088 mouse_cursor->draw();
1094 Menu::set_current(0);
1095 delete object_properties_menu;
1099 void le_checkevents()
1106 keymod = SDL_GetModState();
1108 while(SDL_PollEvent(&event))
1110 if (Menu::current())
1112 Menu::current()->event(event);
1113 if(!le_world && !Menu::current())
1114 Menu::set_current(leveleditor_menu);
1118 mouse_cursor->set_state(MC_NORMAL);
1120 /* testing SDL_KEYDOWN, SDL_KEYUP and SDL_QUIT events*/
1121 if(event.type == SDL_KEYDOWN
1122 || ((event.type == SDL_MOUSEBUTTONDOWN || SDL_MOUSEMOTION)
1123 && (event.motion.x > 0
1124 && event.motion.x < screen->w - 64 &&
1125 event.motion.y > 0 && event.motion.y < screen->h)))
1129 case SDL_KEYDOWN: // key pressed
1130 key = event.key.keysym.sym;
1134 Menu::set_current(leveleditor_menu);
1137 if(le_world != NULL)
1145 cursor_x = (le_world->get_level()->width * 32) - 32;
1149 le_show_grid = !le_show_grid;
1155 case SDL_MOUSEBUTTONDOWN:
1156 if(event.button.button == SDL_BUTTON_LEFT)
1158 le_mouse_pressed[LEFT] = true;
1160 selection.x1 = event.motion.x + pos_x;
1161 selection.y1 = event.motion.y + pos_y;
1162 selection.x2 = event.motion.x + pos_x;
1163 selection.y2 = event.motion.y + pos_y;
1165 else if(event.button.button == SDL_BUTTON_RIGHT)
1167 le_mouse_pressed[RIGHT] = true;
1170 case SDL_MOUSEBUTTONUP:
1171 if(event.button.button == SDL_BUTTON_LEFT)
1173 le_mouse_pressed[LEFT] = false;
1174 le_mouse_clicked[LEFT] = true;
1176 else if(event.button.button == SDL_BUTTON_RIGHT)
1178 le_mouse_pressed[RIGHT] = false;
1179 le_mouse_clicked[RIGHT] = true;
1182 case SDL_MOUSEMOTION:
1184 if(!Menu::current())
1189 if(le_current.IsTile())
1191 cursor_x = ((int)(pos_x + x) / 32) * 32;
1192 cursor_y = ((int)(pos_y + y) / 32) * 32;
1200 if(le_mouse_pressed[LEFT])
1202 selection.x2 = x + pos_x;
1203 selection.y2 = y + pos_y;
1206 if(le_mouse_pressed[RIGHT])
1208 pos_x += -1 * event.motion.xrel;
1209 pos_y += -1 * event.motion.yrel;
1217 else if(event.type == SDL_QUIT) /* window closing */
1223 if(le_world != NULL)
1225 if(event.type == SDL_KEYDOWN || event.type == SDL_KEYUP || ((event.type == SDL_MOUSEBUTTONDOWN || SDL_MOUSEMOTION) && (event.motion.x > screen->w-64 && event.motion.x < screen->w &&
1226 event.motion.y > 0 && event.motion.y < screen->h)))
1228 le_mouse_pressed[LEFT] = false;
1229 le_mouse_pressed[RIGHT] = false;
1231 if(!Menu::current())
1233 /* Check for button events */
1234 le_test_level_bt->event(event);
1235 if(le_test_level_bt->get_state() == BUTTON_CLICKED)
1237 le_save_level_bt->event(event);
1238 if(le_save_level_bt->get_state() == BUTTON_CLICKED)
1239 le_world->get_level()->save(le_level_subset->name.c_str(),le_level,
1241 le_exit_bt->event(event);
1242 if(le_exit_bt->get_state() == BUTTON_CLICKED)
1244 Menu::set_current(leveleditor_menu);
1246 le_next_level_bt->event(event);
1247 if(le_next_level_bt->get_state() == BUTTON_CLICKED)
1249 if(le_level < le_level_subset->levels)
1251 le_goto_level(le_level+1);
1257 sprintf(str,"Level %d doesn't exist. Create it?",le_level+1);
1258 if(confirm_dialog(str))
1260 new_lev.init_defaults();
1261 new_lev.save(le_level_subset->name.c_str(),le_level+1, le_world);
1262 le_level_subset->levels = le_level;
1263 le_goto_level(le_level);
1267 le_previous_level_bt->event(event);
1268 if(le_previous_level_bt->get_state() == BUTTON_CLICKED)
1271 le_goto_level(le_level -1);
1273 le_rubber_bt->event(event);
1274 if(le_rubber_bt->get_state() == BUTTON_CLICKED)
1277 if(!cur_objects.empty())
1279 le_object_select_bt->event(event);
1280 if(le_object_select_bt->get_state() == BUTTON_CLICKED)
1282 MouseCursor::set_current(mouse_select_object);
1285 le_object_properties_bt->event(event);
1286 if(le_object_properties_bt->get_state() == BUTTON_CLICKED)
1288 le_change_object_properties(selected_game_object);
1293 if(le_selection_mode == SQUARE)
1295 le_select_mode_one_bt->event(event);
1296 if(le_select_mode_one_bt->get_state() == BUTTON_CLICKED)
1297 le_selection_mode = CURSOR;
1301 le_select_mode_two_bt->event(event);
1302 if(le_select_mode_two_bt->get_state() == BUTTON_CLICKED)
1303 le_selection_mode = SQUARE;
1305 ButtonPanelMap::iterator it;
1306 le_tilegroup_bt->event(event);
1307 switch (le_tilegroup_bt->get_state())
1309 case BUTTON_CLICKED:
1310 Menu::set_current(select_tilegroup_menu);
1311 select_tilegroup_menu_effect.start(200);
1312 select_tilegroup_menu->set_pos(screen->w - 64,100,-0.5,0.5);
1314 case BUTTON_WHEELUP:
1315 if(cur_tilegroup.empty())
1317 cur_tilegroup = tilegroups_map.begin()->first;
1321 it = tilegroups_map.find(cur_tilegroup);
1322 if((++it) == tilegroups_map.end())
1324 cur_tilegroup = tilegroups_map.begin()->first;
1328 cur_tilegroup = (*it).first;
1334 case BUTTON_WHEELDOWN:
1335 it = tilegroups_map.find(cur_tilegroup);
1336 if(it == tilegroups_map.begin())
1338 cur_tilegroup = tilegroups_map.rbegin()->first;
1342 if(--it != --tilegroups_map.begin())
1343 cur_tilegroup = (*it).first;
1345 cur_tilegroup = tilegroups_map.rbegin()->first;
1353 le_objects_bt->event(event);
1354 switch (le_objects_bt->get_state())
1356 case BUTTON_CLICKED:
1357 Menu::set_current(select_objects_menu);
1358 select_objects_menu_effect.start(200);
1359 select_objects_menu->set_pos(screen->w - 64,100,-0.5,0.5);
1361 case BUTTON_WHEELUP:
1362 it = objects_map.find(cur_objects);
1363 if(it == objects_map.end())
1365 cur_objects = objects_map.begin()->first;
1369 if(++it != objects_map.end())
1370 cur_objects = (*it).first;
1372 cur_objects = objects_map.begin()->first;
1376 case BUTTON_WHEELDOWN:
1377 it = objects_map.find(cur_objects);
1378 if(it == objects_map.begin())
1380 cur_objects = objects_map.rbegin()->first;
1384 if(--it != --objects_map.begin())
1385 cur_objects = (*it).first;
1387 cur_objects = objects_map.rbegin()->first;
1396 le_settings_bt->event(event);
1397 if(le_settings_bt->get_state() == BUTTON_CLICKED)
1399 update_level_settings_menu();
1400 Menu::set_current(level_settings_menu);
1402 if(!cur_tilegroup.empty())
1404 if((pbutton = tilegroups_map[cur_tilegroup]->event(event)) != NULL)
1406 if(pbutton->get_state() == BUTTON_CLICKED)
1408 le_current.Tile(pbutton->get_tag());
1412 else if(!cur_objects.empty())
1414 if((pbutton = objects_map[cur_objects]->event(event)) != NULL)
1416 if(pbutton->get_state() == BUTTON_CLICKED)
1418 #if 0 // TODO fixme!!
1419 le_current.Object(pbutton->get_drawable());
1425 if((pbutton = le_tilemap_panel->event(event)) != NULL)
1427 if(pbutton->get_state() == BUTTON_CLICKED)
1429 active_tm = static_cast<TileMapType>(pbutton->get_tag());
1435 le_settings_bt->event(event);
1436 if(le_settings_bt->get_state() == BUTTON_CLICKED)
1438 Menu::set_current(0);
1440 le_tilegroup_bt->event(event);
1441 if(le_tilegroup_bt->get_state() == BUTTON_CLICKED)
1443 Menu::set_current(0);
1445 le_objects_bt->event(event);
1446 if(le_objects_bt->get_state() == BUTTON_CLICKED)
1448 Menu::set_current(0);
1453 if(!Menu::current() && !show_minimap)
1455 if(le_mouse_pressed[LEFT])
1457 if(MouseCursor::current() != mouse_select_object)
1459 if(le_current.IsTile())
1460 le_change(cursor_x, cursor_y, active_tm, le_current.tile);
1463 else if(le_mouse_clicked[LEFT])
1465 if(MouseCursor::current() == mouse_select_object)
1467 bool object_got_hit = false;
1468 base_type cursor_base;
1469 if(le_current.IsTile())
1471 cursor_base.x = cursor_x;
1472 cursor_base.y = cursor_y;
1474 else if(le_current.IsObject())
1476 cursor_base.x = cursor_x + pos_x;
1477 cursor_base.y = cursor_y + pos_y;
1479 cursor_base.width = 32;
1480 cursor_base.height = 32;
1482 for(std::vector<GameObject*>::iterator it =
1483 le_world->gameobjects.begin();
1484 it != le_world->gameobjects.end(); ++it) {
1485 MovingObject* mobj = dynamic_cast<MovingObject*> (*it);
1489 if(rectcollision(cursor_base, mobj->base))
1491 selected_game_object = mobj;
1492 object_got_hit = true;
1499 selected_game_object = NULL;
1500 le_object_properties_bt->set_active(false);
1503 le_object_properties_bt->set_active(true);
1505 MouseCursor::set_current(mouse_cursor);
1511 if(le_current.IsObject())
1513 le_level_changed = true;
1514 std::string type = le_current.obj->type();
1515 if(type == "BadGuy")
1517 BadGuy* pbadguy = dynamic_cast<BadGuy*>(le_current.obj);
1519 le_world->bad_guys.push_back(new BadGuy(cursor_x+scroll_x, cursor_y,pbadguy->kind,false));
1520 le_world->get_level()->badguy_data.push_back(le_world->bad_guys.back());
1526 le_mouse_clicked[LEFT] = false;
1532 if(!Menu::current())
1534 show_minimap = false;
1536 le_move_left_bt->event(event);
1537 le_move_right_bt->event(event);
1538 le_move_up_bt->event(event);
1539 le_move_down_bt->event(event);
1540 switch(le_move_left_bt->get_state())
1542 case BUTTON_PRESSED:
1543 pos_x -= KEYBOARD_SPEED;
1544 show_minimap = true;
1547 pos_x -= MOUSE_SPEED;
1548 show_minimap = true;
1550 case BUTTON_CLICKED:
1551 show_minimap = true;
1557 switch(le_move_right_bt->get_state())
1559 case BUTTON_PRESSED:
1560 pos_x += KEYBOARD_SPEED;
1561 show_minimap = true;
1564 pos_x += MOUSE_SPEED;
1565 show_minimap = true;
1567 case BUTTON_CLICKED:
1568 show_minimap = true;
1574 switch(le_move_up_bt->get_state())
1576 case BUTTON_PRESSED:
1577 pos_y -= KEYBOARD_SPEED;
1578 show_minimap = true;
1581 pos_y -= MOUSE_SPEED;
1582 show_minimap = true;
1584 case BUTTON_CLICKED:
1585 show_minimap = true;
1591 switch(le_move_down_bt->get_state())
1593 case BUTTON_PRESSED:
1594 pos_y += KEYBOARD_SPEED;
1595 show_minimap = true;
1598 pos_y += MOUSE_SPEED;
1599 show_minimap = true;
1601 case BUTTON_CLICKED:
1602 show_minimap = true;
1608 /* checking if pos_x and pos_y is within the limits... */
1609 if(pos_x > (le_world->get_level()->width * 32 + 32*2) - screen->w)
1610 pos_x = (le_world->get_level()->width * 32 + 32*2) - screen->w;
1614 if(pos_y > (le_world->get_level()->height * 32) - screen->h)
1615 pos_y = (le_world->get_level()->height * 32) - screen->h;
1623 void le_highlight_selection()
1627 if(selection.x1 < selection.x2)
1637 if(selection.y1 < selection.y2)
1653 fillrect(x1*32-pos_x, y1*32-pos_y,32* (x2 - x1 + 1),32 * (y2 - y1 + 1),173,234,177,103);
1656 void le_change(float x, float y, int tm, unsigned int c)
1658 if(le_world != NULL)
1663 le_level_changed = true;
1665 switch(le_selection_mode)
1668 le_world->get_level()->change(x,y,tm,c);
1670 base_type cursor_base;
1673 cursor_base.width = 32;
1674 cursor_base.height = 32;
1676 /* if there is a bad guy over there, remove it */
1679 for(std::list<BadGuy*>::iterator it = le_world->bad_guys.begin(); it != le_world->bad_guys.end(); ++it, ++i)
1680 if(rectcollision(cursor_base,(*it)->base))
1683 le_world->bad_guys.erase(it);
1684 le_world->get_level()->badguy_data.erase(le_world->get_level()->badguy_data.begin() + i);
1691 if(selection.x1 < selection.x2)
1701 if(selection.y1 < selection.y2)
1717 /* if there is a bad guy over there, remove it */
1720 for(std::list<BadGuy*>::iterator it = le_world->bad_guys.begin();
1721 it != le_world->bad_guys.end(); /* will be at end of loop */)
1723 if((*it)->base.x/32 >= x1 && (*it)->base.x/32 <= x2
1724 && (*it)->base.y/32 >= y1 && (*it)->base.y/32 <= y2)
1727 it = le_world->bad_guys.erase(it);
1728 le_world->get_level()->badguy_data.erase(le_world->get_level()->badguy_data.begin() + i);
1739 for(xx = x1; xx <= x2; xx++)
1740 for(yy = y1; yy <= y2; yy++)
1742 le_world->get_level()->change(xx*32, yy*32, tm, c);
1754 //Make sure a time value is set when testing the level
1755 if(le_world->get_level()->time_left == 0)
1756 le_world->get_level()->time_left = 250;
1758 le_world->get_level()->save("test", le_level, le_world);
1760 GameSession session("test",le_level, ST_GL_TEST);
1762 player_status.reset();
1764 music_manager->halt_music();
1766 Menu::set_current(NULL);
1767 World::set_current(le_world);
1772 bool tmp_show_grid = le_show_grid;
1773 SelectionMode temp_le_selection_mode = le_selection_mode;
1774 le_selection_mode = NONE;
1775 show_selections = true;
1776 le_show_grid = false;
1777 le_help_shown = true;
1779 drawgradient(Color(0,0,0), Color(255,255,255));
1783 unsigned int i, done_;
1786 " - Supertux level editor tutorial - ",
1788 "To make your map, click the ",
1789 "tilegroup button and choose a ",
1791 "Pick a tile and simply hold down ",
1792 "the left mouse button over the map",
1793 "to \"paint\" your selection over",
1796 "There are three layers for painting",
1797 "tiles upon, Background layer,",
1798 "the Interactive layer, and the",
1799 "Foreground layer, which can be",
1800 "toggled by the BkGrd, IntAct and",
1801 "FrGrd buttons. The Foreground and",
1802 "Background layers do not effect",
1803 "Tux in the gameplay, but lie in",
1804 "front of him or lie behind him in",
1810 " - Supertux level editor tutorial - ",
1812 "The tiles placed on",
1813 "the Interactive layer are those",
1814 "which actually effect Tux in the",
1817 "Click the objects menu to put ",
1818 "bad guys and other objects in the",
1819 "game. Unlike placing tiles, you",
1820 "cannot \"paint\" enemies. Click",
1821 "them onto the screen one at a time.",
1823 "To change the settings of your",
1824 "level, click the button with the",
1825 "screwdriver and wrench. From here",
1826 "you can change the background,",
1827 "music, length of the level,",
1833 " - Supertux level editor tutorial - ",
1835 "You may have more than one level.",
1836 "Pressing the up and down buttons",
1837 "above the button bar lets you",
1838 "choose which one you are working on.",
1840 "If you would like to speed up your",
1841 "level editing, a useful trick is",
1842 "to learn the keyboard shortcuts.",
1843 "They are easy to learn, just right-",
1844 "click on the buttons.",
1846 "Have fun making levels! If you make",
1847 "some good ones, send them to us on",
1848 "the SuperTux mailing list!",
1854 blue_text->drawf("- Help -", 0, 30, A_HMIDDLE, A_TOP, 2);
1856 for(i = 0; i < sizeof(text)/sizeof(char *); i++)
1857 white_text->draw(text[i], 5, 80+(i*white_text->h), 1);
1859 gold_text->drawf("Press Anything to Continue - Page 1/3", 0, 0, A_LEFT, A_BOTTOM, 1);
1867 done_ = wait_for_event(event);
1871 drawgradient(Color(0,0,0), Color(255,255,255));
1875 blue_text->drawf("- Help -", 0, 30, A_HMIDDLE, A_TOP, 2);
1877 for(i = 0; i < sizeof(text2)/sizeof(char *); i++)
1878 white_text->draw(text2[i], 5, 80+(i*white_text->h), 1);
1880 gold_text->drawf("Press Anything to Continue - Page 2/3", 0, 0, A_LEFT, A_BOTTOM, 1);
1888 done_ = wait_for_event(event);
1892 drawgradient(Color(0,0,0), Color(255,255,255));
1896 blue_text->drawf("- Help -", 0, 30, A_HMIDDLE, A_TOP, 2);
1898 for(i = 0; i < sizeof(text3)/sizeof(char *); i++)
1899 white_text->draw(text3[i], 5, 80+(i*white_text->h), 1);
1901 gold_text->drawf("Press Anything to Continue - Page 3/3", 0, 0, A_LEFT, A_BOTTOM, 1);
1909 done_ = wait_for_event(event);
1913 show_selections = true;
1914 le_show_grid = tmp_show_grid;
1915 le_selection_mode = temp_le_selection_mode;
1916 le_help_shown = false;