Exemplo n.º 1
0
void
EditorSectorsMenu::menu_action(MenuItem& item)
{
  if (item.get_id() >= 0)
  {
    Level* level = Editor::current()->get_level();
    Sector* sector = level->get_sector(item.get_id());
    Editor::current()->load_sector(sector->get_name());
    MenuManager::instance().clear_menu_stack();
  }
  else
  {
    switch (item.get_id())
    {
      case -1:
        break;

      case -2:
        create_sector();
        break;

      case -3:
        delete_sector();
        break;

      case -4:
        MenuManager::instance().clear_menu_stack();
        break;
    }
  }
}
void
EditorSectorsMenu::menu_action(MenuItem* item)
{
  if (item->id >= 0)
  {
    Editor::current()->load_sector(item->id);
    MenuManager::instance().clear_menu_stack();
  } else {
    switch (item->id) {
      case -1:
        break;
      case -2:
        create_sector();
        break;
      case -3:
        delete_sector();
        break;
      case -4:
        MenuManager::instance().clear_menu_stack();
        break;
    }
  }
}
Exemplo n.º 3
0
/* ----------------------------------------------------------------------------
 * Handles the events for the area editor.
 */
void area_editor::handle_controls(const ALLEGRO_EVENT &ev) {

    if(fade_mgr.is_fading()) return;
    
    gui->handle_event(ev);
    
    //Update mouse cursor in world coordinates.
    if(
        ev.type == ALLEGRO_EVENT_MOUSE_AXES ||
        ev.type == ALLEGRO_EVENT_MOUSE_WARPED ||
        ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN ||
        ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP
    ) {
        mouse_cursor_x =
            ev.mouse.x / cam_zoom - cam_x - (gui_x / 2 / cam_zoom);
        mouse_cursor_y =
            ev.mouse.y / cam_zoom - cam_y - (scr_h / 2 / cam_zoom);
        lafi::widget* wum;
        if(!is_mouse_in_gui(ev.mouse.x, ev.mouse.y)) {
            wum = NULL;
        } else {
            wum = gui->get_widget_under_mouse(ev.mouse.x, ev.mouse.y);
        }
        ((lafi::label*) gui->widgets["lbl_status_bar"])->text =
            (
                wum ?
                wum->description :
                "(" + i2s(mouse_cursor_x) + "," + i2s(mouse_cursor_y) + ")"
            );
    }
    
    
    //Moving vertexes, camera, etc.
    if(ev.type == ALLEGRO_EVENT_MOUSE_AXES) {
    
        if(
            !is_mouse_in_gui(ev.mouse.x, ev.mouse.y)
            && moving_thing == INVALID && sec_mode != ESM_TEXTURE_VIEW &&
            mode != EDITOR_MODE_OBJECTS
        ) {
            on_sector = get_sector(mouse_cursor_x, mouse_cursor_y, NULL, false);
        } else {
            on_sector = NULL;
        }
        
        //Move guide.
        if(sec_mode == ESM_GUIDE_MOUSE) {
        
            if(holding_m1) {
                guide_x += ev.mouse.dx / cam_zoom;
                guide_y += ev.mouse.dy / cam_zoom;
                
            } else if(holding_m2) {
            
                float new_w = guide_w + ev.mouse.dx / cam_zoom;
                float new_h = guide_h + ev.mouse.dy / cam_zoom;
                
                if(guide_aspect_ratio) {
                    //Find the most significant change.
                    if(ev.mouse.dx != 0 || ev.mouse.dy != 0) {
                        bool most_is_width =
                            fabs((double) ev.mouse.dx) >
                            fabs((double) ev.mouse.dy);
                            
                        if(most_is_width) {
                            float ratio = guide_h / guide_w;
                            guide_w = new_w;
                            guide_h = new_w * ratio;
                        } else {
                            float ratio = guide_w / guide_h;
                            guide_h = new_h;
                            guide_w = new_h * ratio;
                        }
                    }
                } else {
                    guide_w = new_w;
                    guide_h = new_h;
                }
                
            }
            
            guide_to_gui();
            
        } else if(holding_m2) {
            //Move camera.
            cam_x += ev.mouse.dx / cam_zoom;
            cam_y += ev.mouse.dy / cam_zoom;
        }
        
        //Move thing.
        if(moving_thing != INVALID) {
            if(mode == EDITOR_MODE_SECTORS) {
                vertex* v_ptr = cur_area_data.vertexes[moving_thing];
                v_ptr->x = snap_to_grid(mouse_cursor_x);
                v_ptr->y = snap_to_grid(mouse_cursor_y);
            } else if(mode == EDITOR_MODE_OBJECTS) {
                mob_gen* m_ptr = cur_area_data.mob_generators[moving_thing];
                m_ptr->x = snap_to_grid(mouse_cursor_x);
                m_ptr->y = snap_to_grid(mouse_cursor_y);
            } else if(mode == EDITOR_MODE_PATHS) {
                path_stop* s_ptr = cur_area_data.path_stops[moving_thing];
                s_ptr->x = snap_to_grid(mouse_cursor_x);
                s_ptr->y = snap_to_grid(mouse_cursor_y);
                s_ptr->calculate_dists();
                path_preview_timeout.start(false);
            } else if(mode == EDITOR_MODE_SHADOWS) {
                tree_shadow* s_ptr = cur_area_data.tree_shadows[moving_thing];
                s_ptr->x = snap_to_grid(mouse_cursor_x - moving_thing_x);
                s_ptr->y = snap_to_grid(mouse_cursor_y - moving_thing_y);
                shadow_to_gui();
            }
            
            made_changes = true;
        }
        
        //Move path checkpoints.
        if(moving_path_preview_checkpoint != -1) {
            path_preview_checkpoints_x[moving_path_preview_checkpoint] =
                snap_to_grid(mouse_cursor_x);
            path_preview_checkpoints_y[moving_path_preview_checkpoint] =
                snap_to_grid(mouse_cursor_y);
            path_preview_timeout.start(false);
        }
        
        
        if(ev.mouse.dz != 0 && !is_mouse_in_gui(ev.mouse.x, ev.mouse.y)) {
            //Zoom.
            float new_zoom = cam_zoom + (cam_zoom * ev.mouse.dz * 0.1);
            new_zoom = max(ZOOM_MIN_LEVEL_EDITOR, new_zoom);
            new_zoom = min(ZOOM_MAX_LEVEL_EDITOR, new_zoom);
            float new_mc_x =
                ev.mouse.x / new_zoom - cam_x - (gui_x / 2 / new_zoom);
            float new_mc_y =
                ev.mouse.y / new_zoom - cam_y - (scr_h / 2 / new_zoom);
                
            cam_x -= (mouse_cursor_x - new_mc_x);
            cam_y -= (mouse_cursor_y - new_mc_y);
            mouse_cursor_x = new_mc_x;
            mouse_cursor_y = new_mc_y;
            cam_zoom = new_zoom;
        }
        
        if(sec_mode == ESM_NEW_SECTOR) {
            new_sector_valid_line =
                is_new_sector_line_valid(
                    snap_to_grid(mouse_cursor_x),
                    snap_to_grid(mouse_cursor_y)
                );
        }
        
        
    } else if(
        ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN &&
        !is_mouse_in_gui(ev.mouse.x, ev.mouse.y)
    ) {
        //Clicking.
        
        if(ev.mouse.button == 1) holding_m1 = true;
        else if(ev.mouse.button == 2) holding_m2 = true;
        else if(ev.mouse.button == 3) cam_zoom = 1.0;
        
        if(ev.mouse.button != 1) return;
        
        //If the user was editing, save it.
        if(mode == EDITOR_MODE_SECTORS) {
            gui_to_sector();
        } else if(mode == EDITOR_MODE_OBJECTS) {
            gui_to_mob();
        } else if(mode == EDITOR_MODE_SHADOWS) {
            gui_to_shadow();
        }
        
        //Sector-related clicking.
        if(sec_mode == ESM_NONE && mode == EDITOR_MODE_SECTORS) {
        
            moving_thing = INVALID;
            
            edge* clicked_edge_ptr = NULL;
            size_t clicked_edge_nr = INVALID;
            bool created_vertex = false;
            
            for(size_t e = 0; e < cur_area_data.edges.size(); ++e) {
                edge* e_ptr = cur_area_data.edges[e];
                
                if(!is_edge_valid(e_ptr)) continue;
                
                if(
                    circle_intersects_line(
                        mouse_cursor_x, mouse_cursor_y, 8 / cam_zoom,
                        e_ptr->vertexes[0]->x, e_ptr->vertexes[0]->y,
                        e_ptr->vertexes[1]->x, e_ptr->vertexes[1]->y
                    )
                ) {
                    clicked_edge_ptr = e_ptr;
                    clicked_edge_nr = e;
                    break;
                }
            }
            
            if(double_click_time == 0) double_click_time = 0.5;
            else if(clicked_edge_ptr) {
                //Create a new vertex.
                double_click_time = 0;
                
                //New vertex, on the split point.
                //TODO create it on the edge, not on the cursor.
                vertex* new_v_ptr = new vertex(mouse_cursor_x, mouse_cursor_y);
                cur_area_data.vertexes.push_back(new_v_ptr);
                
                //New edge, copied from the original one.
                edge* new_e_ptr = new edge(*clicked_edge_ptr);
                cur_area_data.edges.push_back(new_e_ptr);
                
                //Save the original end vertex for later.
                vertex* end_v_ptr = clicked_edge_ptr->vertexes[1];
                
                //Set vertexes on the new and original edges.
                new_e_ptr->vertex_nrs[0] = cur_area_data.vertexes.size() - 1;
                new_e_ptr->vertexes[0] = new_v_ptr;
                clicked_edge_ptr->vertex_nrs[1] = new_e_ptr->vertex_nrs[0];
                clicked_edge_ptr->vertexes[1] = new_v_ptr;
                
                //Set sectors on the new edge.
                if(new_e_ptr->sectors[0]) {
                    new_e_ptr->sectors[0]->edge_nrs.push_back(
                        cur_area_data.edges.size() - 1
                    );
                    new_e_ptr->sectors[0]->edges.push_back(new_e_ptr);
                }
                if(new_e_ptr->sectors[1]) {
                    new_e_ptr->sectors[1]->edge_nrs.push_back(
                        cur_area_data.edges.size() - 1
                    );
                    new_e_ptr->sectors[1]->edges.push_back(new_e_ptr);
                }
                
                //Set edges of the new vertex.
                new_v_ptr->edge_nrs.push_back(cur_area_data.edges.size() - 1);
                new_v_ptr->edge_nrs.push_back(clicked_edge_nr);
                new_v_ptr->edges.push_back(new_e_ptr);
                new_v_ptr->edges.push_back(clicked_edge_ptr);
                
                //Update edge data on the end vertex of the original edge
                //(it now links to the new edge, not the old).
                for(size_t ve = 0; ve < end_v_ptr->edges.size(); ++ve) {
                    if(end_v_ptr->edges[ve] == clicked_edge_ptr) {
                        end_v_ptr->edges[ve] =
                            new_e_ptr;
                        end_v_ptr->edge_nrs[ve] =
                            cur_area_data.edges.size() - 1;
                        break;
                    }
                }
                
                //Start dragging the new vertex.
                moving_thing = cur_area_data.vertexes.size() - 1;
                
                created_vertex = true;
                made_changes = true;
            }
            
            //Find a vertex to drag.
            if(!created_vertex) {
                for(size_t v = 0; v < cur_area_data.vertexes.size(); ++v) {
                    if(
                        dist(
                            mouse_cursor_x, mouse_cursor_y,
                            cur_area_data.vertexes[v]->x,
                            cur_area_data.vertexes[v]->y
                        ) <= 6.0 / cam_zoom
                    ) {
                        moving_thing = v;
                        break;
                    }
                }
            }
            
            //Find a sector to select.
            if(moving_thing == INVALID) {
                cur_sector =
                    get_sector(mouse_cursor_x, mouse_cursor_y, NULL, false);
                sector_to_gui();
            }
            
            
        } else if(sec_mode == ESM_NONE && mode == EDITOR_MODE_OBJECTS) {
            //Object-related clicking.
            
            cur_mob = NULL;
            moving_thing = INVALID;
            for(size_t m = 0; m < cur_area_data.mob_generators.size(); ++m) {
                mob_gen* m_ptr = cur_area_data.mob_generators[m];
                float radius =
                    m_ptr->type ? m_ptr->type->radius == 0 ? 16 :
                    m_ptr->type->radius : 16;
                if(
                    dist(m_ptr->x, m_ptr->y, mouse_cursor_x, mouse_cursor_y) <=
                    radius
                ) {
                
                    cur_mob = m_ptr;
                    moving_thing = m;
                    break;
                }
            }
            mob_to_gui();
            
        } else if(sec_mode == ESM_NONE && mode == EDITOR_MODE_PATHS) {
            //Path-related clicking.
            
            cur_stop = NULL;
            moving_thing = INVALID;
            for(size_t s = 0; s < cur_area_data.path_stops.size(); ++s) {
                path_stop* s_ptr = cur_area_data.path_stops[s];
                if(
                    dist(s_ptr->x, s_ptr->y, mouse_cursor_x, mouse_cursor_y)
                    <= STOP_RADIUS
                ) {
                
                    cur_stop = s_ptr;
                    moving_thing = s;
                    break;
                }
            }
            
            moving_path_preview_checkpoint = -1;
            if(show_path_preview) {
                for(unsigned char c = 0; c < 2; ++c) {
                    if(
                        bbox_check(
                            path_preview_checkpoints_x[c],
                            path_preview_checkpoints_y[c],
                            mouse_cursor_x, mouse_cursor_y,
                            PATH_PREVIEW_CHECKPOINT_RADIUS / cam_zoom
                        )
                    ) {
                        moving_path_preview_checkpoint = c;
                        break;
                    }
                }
            }
            
        } else if(sec_mode == ESM_NONE && mode == EDITOR_MODE_SHADOWS) {
            //Shadow-related clicking.
            
            cur_shadow = NULL;
            moving_thing = INVALID;
            for(size_t s = 0; s < cur_area_data.tree_shadows.size(); ++s) {
            
                tree_shadow* s_ptr = cur_area_data.tree_shadows[s];
                float min_x, min_y, max_x, max_y;
                get_shadow_bounding_box(s_ptr, &min_x, &min_y, &max_x, &max_y);
                
                if(
                    mouse_cursor_x >= min_x && mouse_cursor_x <= max_x &&
                    mouse_cursor_y >= min_y && mouse_cursor_y <= max_y
                ) {
                    cur_shadow = s_ptr;
                    moving_thing = s;
                    moving_thing_x = mouse_cursor_x - s_ptr->x;
                    moving_thing_y = mouse_cursor_y - s_ptr->y;
                    break;
                }
            }
            shadow_to_gui();
            
        }
        
        if(sec_mode == ESM_NEW_SECTOR) {
            //Next vertex in a new sector.
            float hotspot_x = snap_to_grid(mouse_cursor_x);
            float hotspot_y = snap_to_grid(mouse_cursor_y);
            new_sector_valid_line =
                is_new_sector_line_valid(
                    snap_to_grid(mouse_cursor_x),
                    snap_to_grid(mouse_cursor_y)
                );
                
            if(new_sector_valid_line) {
                if(
                    !new_sector_vertexes.empty() &&
                    dist(
                        hotspot_x, hotspot_y,
                        new_sector_vertexes[0]->x,
                        new_sector_vertexes[0]->y
                    ) <= VERTEX_MERGE_RADIUS
                ) {
                    //Back to the first vertex.
                    sec_mode = ESM_NONE;
                    create_sector();
                    sector_to_gui();
                    made_changes = true;
                } else {
                    //Add a new vertex.
                    vertex* merge =
                        get_merge_vertex(
                            hotspot_x, hotspot_y,
                            cur_area_data.vertexes,
                            VERTEX_MERGE_RADIUS / cam_zoom
                        );
                    if(merge) {
                        new_sector_vertexes.push_back(
                            new vertex(merge->x, merge->y)
                        );
                    } else {
                        new_sector_vertexes.push_back(
                            new vertex(hotspot_x, hotspot_y)
                        );
                    }
                }
            }
            
            
        } else if(sec_mode == ESM_NEW_OBJECT) {
            //Create a mob where the cursor is.
            
            sec_mode = ESM_NONE;
            float hotspot_x = snap_to_grid(mouse_cursor_x);
            float hotspot_y = snap_to_grid(mouse_cursor_y);
            
            cur_area_data.mob_generators.push_back(
                new mob_gen(hotspot_x, hotspot_y)
            );
            
            cur_mob = cur_area_data.mob_generators.back();
            mob_to_gui();
            made_changes = true;
            
        } else if(sec_mode == ESM_DUPLICATE_OBJECT) {
            //Duplicate the current mob to where the cursor is.
            
            sec_mode = ESM_NONE;
            
            if(cur_mob) {
                float hotspot_x = snap_to_grid(mouse_cursor_x);
                float hotspot_y = snap_to_grid(mouse_cursor_y);
                
                mob_gen* new_mg = new mob_gen(*cur_mob);
                new_mg->x = hotspot_x;
                new_mg->y = hotspot_y;
                cur_area_data.mob_generators.push_back(
                    new_mg
                );
                
                cur_mob = new_mg;
                mob_to_gui();
                made_changes = true;
            }
            
        } else if(sec_mode == ESM_NEW_STOP) {
            //Create a new stop where the cursor is.
            
            float hotspot_x = snap_to_grid(mouse_cursor_x);
            float hotspot_y = snap_to_grid(mouse_cursor_y);
            
            cur_area_data.path_stops.push_back(
                new path_stop(hotspot_x, hotspot_y, vector<path_link>())
            );
            
            cur_stop = cur_area_data.path_stops.back();
            made_changes = true;
            
            
        } else if (sec_mode == ESM_NEW_LINK1 || sec_mode == ESM_NEW_1WLINK1) {
            //Pick a stop to start the link on.
            
            for(size_t s = 0; s < cur_area_data.path_stops.size(); ++s) {
                path_stop* s_ptr = cur_area_data.path_stops[s];
                
                if(
                    dist(mouse_cursor_x, mouse_cursor_y, s_ptr->x, s_ptr->y) <=
                    STOP_RADIUS
                ) {
                    new_link_first_stop = s_ptr;
                    sec_mode =
                        sec_mode == ESM_NEW_LINK1 ? ESM_NEW_LINK2 :
                        ESM_NEW_1WLINK2;
                    break;
                }
            }
            
            path_preview_timeout.start(false);
            made_changes = true;
            
        } else if (sec_mode == ESM_NEW_LINK2 || sec_mode == ESM_NEW_1WLINK2) {
            //Pick a stop to end the link on.
            
            for(size_t s = 0; s < cur_area_data.path_stops.size(); ++s) {
                path_stop* s_ptr = cur_area_data.path_stops[s];
                
                if(
                    dist(mouse_cursor_x, mouse_cursor_y, s_ptr->x, s_ptr->y) <=
                    STOP_RADIUS
                ) {
                
                    if(new_link_first_stop == s_ptr) continue;
                    
                    //Check if these two stops already have a link.
                    //Delete it if so.
                    for(
                        size_t l = 0; l < new_link_first_stop->links.size();
                        ++l
                    ) {
                        if(new_link_first_stop->links[l].end_ptr == s_ptr) {
                            new_link_first_stop->links.erase(
                                new_link_first_stop->links.begin() + l
                            );
                            break;
                        }
                    }
                    for(size_t l = 0; l < s_ptr->links.size(); ++l) {
                        if(s_ptr->links[l].end_ptr == new_link_first_stop) {
                            s_ptr->links.erase(s_ptr->links.begin() + l);
                            break;
                        }
                    }
                    
                    
                    new_link_first_stop->links.push_back(
                        path_link(s_ptr, s)
                    );
                    
                    if(sec_mode == ESM_NEW_LINK2) {
                        s_ptr->links.push_back(
                            path_link(new_link_first_stop, INVALID)
                        );
                        s_ptr->fix_nrs(cur_area_data);
                    }
                    
                    new_link_first_stop->calculate_dists();
                    
                    sec_mode =
                        sec_mode == ESM_NEW_LINK2 ? ESM_NEW_LINK1 :
                        ESM_NEW_1WLINK1;
                    break;
                }
            }
            
            path_preview_timeout.start(false);
            made_changes = true;
            
        } else if(sec_mode == ESM_DEL_STOP) {
            //Pick a stop to delete.
            
            for(size_t s = 0; s < cur_area_data.path_stops.size(); ++s) {
                path_stop* s_ptr = cur_area_data.path_stops[s];
                
                if(
                    dist(mouse_cursor_x, mouse_cursor_y, s_ptr->x, s_ptr->y) <=
                    STOP_RADIUS
                ) {
                
                    //Check all links to this stop.
                    for(
                        size_t s2 = 0; s2 < cur_area_data.path_stops.size();
                        ++s2
                    ) {
                        path_stop* s2_ptr = cur_area_data.path_stops[s2];
                        for(size_t l = 0; l < s2_ptr->links.size(); ++l) {
                            if(s2_ptr->links[l].end_ptr == s_ptr) {
                                s2_ptr->links.erase(s2_ptr->links.begin() + l);
                                break;
                            }
                        }
                    }
                    
                    //Finally, delete the stop.
                    delete s_ptr;
                    cur_area_data.path_stops.erase(
                        cur_area_data.path_stops.begin() + s
                    );
                    break;
                }
            }
            
            for(size_t s = 0; s < cur_area_data.path_stops.size(); ++s) {
                cur_area_data.path_stops[s]->fix_nrs(cur_area_data);
            }
            
            path_preview.clear();
            path_preview_timeout.start(false);
            made_changes = true;
            
        } else if(sec_mode == ESM_DEL_LINK) {
            //Pick a link to delete.
            
            bool deleted = false;
            
            for(size_t s = 0; s < cur_area_data.path_stops.size(); ++s) {
                path_stop* s_ptr = cur_area_data.path_stops[s];
                
                for(size_t s2 = 0; s2 < s_ptr->links.size(); ++s2) {
                    path_stop* s2_ptr = s_ptr->links[s2].end_ptr;
                    if(
                        circle_intersects_line(
                            mouse_cursor_x, mouse_cursor_y, 8 / cam_zoom,
                            s_ptr->x, s_ptr->y,
                            s2_ptr->x, s2_ptr->y
                        )
                    ) {
                    
                        s_ptr->links.erase(s_ptr->links.begin() + s2);
                        
                        for(size_t s3 = 0; s3 < s2_ptr->links.size(); ++s3) {
                            if(s2_ptr->links[s3].end_ptr == s_ptr) {
                                s2_ptr->links.erase(
                                    s2_ptr->links.begin() + s3
                                );
                                break;
                            }
                        }
                        
                        deleted = true;
                        break;
                    }
                }
                
                if(deleted) break;
            }
            
            path_preview.clear();
            path_preview_timeout.start(false);
            made_changes = true;
            
        } else if(sec_mode == ESM_NEW_SHADOW) {
            //Create a new shadow where the cursor is.
            
            sec_mode = ESM_NONE;
            float hotspot_x = snap_to_grid(mouse_cursor_x);
            float hotspot_y = snap_to_grid(mouse_cursor_y);
            
            tree_shadow* new_shadow = new tree_shadow(hotspot_x, hotspot_y);
            new_shadow->bitmap = bmp_error;
            
            cur_area_data.tree_shadows.push_back(new_shadow);
            
            cur_shadow = new_shadow;
            shadow_to_gui();
            made_changes = true;
            
        }
        
        
    } else if(ev.type == ALLEGRO_EVENT_MOUSE_BUTTON_UP) {
        //Mouse button release.
        
        if(ev.mouse.button == 1) holding_m1 = false;
        else if(ev.mouse.button == 2) holding_m2 = false;
        
        if(
            ev.mouse.button == 1 &&
            mode == EDITOR_MODE_SECTORS && sec_mode == ESM_NONE &&
            moving_thing != INVALID
        ) {
            //Release the vertex.
            
            vertex* moved_v_ptr = cur_area_data.vertexes[moving_thing];
            vertex* final_vertex = moved_v_ptr;
            
            unordered_set<sector*> affected_sectors;
            
            //Check if we should merge.
            for(size_t v = 0; v < cur_area_data.vertexes.size(); ++v) {
                vertex* dest_v_ptr = cur_area_data.vertexes[v];
                if(dest_v_ptr == moved_v_ptr) continue;
                
                if(
                    dist(
                        moved_v_ptr->x, moved_v_ptr->y,
                        dest_v_ptr->x, dest_v_ptr->y
                    ) <= (VERTEX_MERGE_RADIUS / cam_zoom)
                ) {
                    merge_vertex(
                        moved_v_ptr, dest_v_ptr, &affected_sectors
                    );
                    final_vertex = dest_v_ptr;
                    break;
                }
            }
            
            //Finally, re-triangulate the affected sectors.
            for(size_t e = 0; e < final_vertex->edges.size(); ++e) {
                edge* e_ptr = final_vertex->edges[e];
                for(size_t s = 0; s < 2; ++s) {
                    if(e_ptr->sectors[s]) {
                        affected_sectors.insert(e_ptr->sectors[s]);
                    }
                }
            }
            for(
                auto s = affected_sectors.begin();
                s != affected_sectors.end(); ++s
            ) {
                if(!(*s)) continue;
                triangulate(*s);
            }
            
            //If somewhere along the line, the current sector
            //got marked for deletion, unselect it.
            if(cur_sector) {
                if(cur_sector->edges.empty()) {
                    cur_sector = NULL;
                    sector_to_gui();
                }
            }
            
            //Check if the edge's vertexes intersect with any other edges.
            //If so, they're marked with red.
            check_edge_intersections(moved_v_ptr);
            
            moving_thing = INVALID;
            
            
            
        } else if(
            ev.mouse.button == 1 && sec_mode == ESM_NONE &&
            moving_thing != INVALID
        ) {
            //Release thing.
            
            moving_thing = INVALID;
            
        }
        
        moving_path_preview_checkpoint = -1;
        
        
    } else if(ev.type == ALLEGRO_EVENT_KEY_DOWN) {
        //Key press.
        
        if(
            ev.keyboard.keycode == ALLEGRO_KEY_LSHIFT ||
            ev.keyboard.keycode == ALLEGRO_KEY_RSHIFT
        ) {
            shift_pressed = true;
        } else if(ev.keyboard.keycode == ALLEGRO_KEY_F1) {
            debug_edge_nrs = !debug_edge_nrs;
        } else if(ev.keyboard.keycode == ALLEGRO_KEY_F2) {
            debug_sector_nrs = !debug_sector_nrs;
        } else if(ev.keyboard.keycode == ALLEGRO_KEY_F3) {
            debug_vertex_nrs = !debug_vertex_nrs;
        } else if(ev.keyboard.keycode == ALLEGRO_KEY_F4) {
            debug_triangulation = !debug_triangulation;
        }
        
        
    } else if(ev.type == ALLEGRO_EVENT_KEY_UP) {
        //Key release.
        
        if(
            ev.keyboard.keycode == ALLEGRO_KEY_LSHIFT ||
            ev.keyboard.keycode == ALLEGRO_KEY_RSHIFT
        ) {
            shift_pressed = false;
        }
    }
}
Exemplo n.º 4
0
// keys_edit: Keys for the 2d editor
// ------------------------------ >>
void keys_edit()
{
    if (!map.opened)
        return;

    // Scroll up
    if (binds.pressed("view_up"))
    {
        yoff += ((MAJOR_UNIT / (int)zoom)) + 1;
        force_map_redraw(true, true);
    }

    // Scroll down
    if (binds.pressed("view_down"))
    {
        yoff -= ((MAJOR_UNIT / (int)zoom)) + 1;
        force_map_redraw(true, true);
    }

    // Scroll left
    if (binds.pressed("view_left"))
    {
        xoff += ((MAJOR_UNIT / (int)zoom)) + 1;
        force_map_redraw(true, true);
    }

    // Scroll right
    if (binds.pressed("view_right"))
    {
        xoff -= ((MAJOR_UNIT / (int)zoom)) + 1;
        force_map_redraw(true, true);
    }

    // Zoom in
    if (binds.pressed("view_zoomin"))
        view_zoom(true);

    // Zoom out
    if (binds.pressed("view_zoomout"))
        view_zoom(false);

    // Center view on mouse
    if (binds.pressed("view_mousecenter"))
    {
        xoff = -m_x(mouse.x) / MAJOR_UNIT;
        yoff = -m_y(mouse.y) / MAJOR_UNIT;
        force_map_redraw(true, true);
    }

    // Set offsets to 0, 0
    if (binds.pressed("view_origin"))
    {
        xoff = yoff = 0;
        force_map_redraw(true, true);
    }

    // Vertices mode
    if (binds.pressed("mode_vertices"))
        change_edit_mode(0);

    // Linedefs mode
    if (binds.pressed("mode_linedefs"))
        change_edit_mode(1);

    // Sectors mode
    if (binds.pressed("mode_sectors"))
        change_edit_mode(2);

    // Things mode
    if (binds.pressed("mode_things"))
        change_edit_mode(3);

    // Change mode
    if (binds.pressed("mode_change"))
        cycle_edit_mode();

    // Increase grid size
    if (binds.pressed("view_increasegrid"))
    {
        increase_grid();
        force_map_redraw(false, true);
    }

    // Decrease grid size
    if (binds.pressed("view_decreasegrid"))
    {
        decrease_grid();
        force_map_redraw(false, true);
    }

    // Clear selection
    if (binds.pressed("edit_clearselection"))
    {
        clear_selection();
        force_map_redraw(true);
    }

    // Delete item
    if (binds.pressed("edit_deleteitem"))
    {
        if (edit_mode == 0)
            delete_vertex();

        if (edit_mode == 1)
            delete_line();

        if (edit_mode == 2)
            delete_sector();

        if (edit_mode == 3)
            delete_thing();

        force_map_redraw(true);
    }

    // Create item
    if (binds.pressed("edit_createitem"))
    {
        if (edit_mode == 0)
        {
            if (!selection())
                create_vertex();
            else
                create_lines(false);

            force_map_redraw(true);
            return;
        }

        if (edit_mode == 1)
        {
            if (selection())
                create_sector();

            force_map_redraw(true);
            return;
        }

        if (edit_mode == 3)
        {
            create_thing();
            force_map_redraw(true);
            return;
        }

        binds.clear("edit_createitem");
    }

    // Sector height quick changes (8 units)
    if (binds.pressed("sector_upfloor8"))
    {
        if (edit_mode == 2)
            sector_changeheight(true, 8);
    }

    if (binds.pressed("sector_downfloor8"))
    {
        if (edit_mode == 2)
            sector_changeheight(true, -8);
    }

    if (binds.pressed("sector_upceil8"))
    {
        if (edit_mode == 2)
            sector_changeheight(false, 8);
    }

    if (binds.pressed("sector_downceil8"))
    {
        if (edit_mode == 2)
            sector_changeheight(false, -8);
    }

    if (binds.pressed("sector_upboth8"))
    {
        if (edit_mode == 2)
        {
            sector_changeheight(true, 8);
            sector_changeheight(false, 8);
        }
    }

    if (binds.pressed("sector_downboth8"))
    {
        if (edit_mode == 2)
        {
            sector_changeheight(true, -8);
            sector_changeheight(false, -8);
        }
    }

    // Sector height quick changes (1 unit)
    if (binds.pressed("sector_upfloor"))
    {
        if (edit_mode == 2)
            sector_changeheight(true, 1);
    }

    if (binds.pressed("sector_downfloor"))
    {
        if (edit_mode == 2)
            sector_changeheight(true, -1);
    }

    if (binds.pressed("sector_upceil"))
    {
        if (edit_mode == 2)
            sector_changeheight(false, 1);
    }

    if (binds.pressed("sector_downceil"))
    {
        if (edit_mode == 2)
            sector_changeheight(false, -1);
    }

    if (binds.pressed("sector_upboth"))
    {
        if (edit_mode == 2)
        {
            sector_changeheight(true, 1);
            sector_changeheight(false, 1);
        }
    }

    if (binds.pressed("sector_downboth"))
    {
        if (edit_mode == 2)
        {
            sector_changeheight(true, -1);
            sector_changeheight(false, -1);
        }
    }

    // Flip line
    if (binds.pressed("line_flip"))
    {
        if (edit_mode == 1)
            line_flip(true, false);

        force_map_redraw(true);
    }

    // Swap line sides
    if (binds.pressed("line_swapsides"))
    {
        if (edit_mode == 1)
            line_flip(false, true);

        force_map_redraw(true);
    }

    // Flip both line direction and sides
    if (binds.pressed("line_flipboth"))
    {
        if (edit_mode == 1)
            line_flip(true, true);

        force_map_redraw(true);
    }

    // Begin line draw
    if (binds.pressed("line_begindraw"))
    {
        if (!line_draw)
            line_draw = true;

        binds.clear("line_begindraw");
    }

    // Begin rectangle draw
    if (binds.pressed("line_begindraw_rect"))
    {
        if (!line_draw)
        {
            line_draw = true;
            sel_box.set(mouse.x, mouse.y, mouse.x, mouse.y);
        }

        binds.clear("line_begindraw_rect");
    }

    // Undo
    if (binds.pressed("edit_undo"))
    {
        undo();
        clear_selection();
        hilight_item = -1;
        force_map_redraw(true, true);
        //map_changelevel(3);
        map.change_level(MC_NODE_REBUILD);
        binds.clear("edit_undo");
    }

    // Edit item
    if (binds.pressed("edit_edititem"))
    {
        edit_item();
        binds.clear("edit_edititem");
    }

    // Merge sectors
    if (binds.pressed("sector_merge"))
    {
        sector_merge(false);
        binds.clear("sector_merge");
    }

    // Join sectors
    if (binds.pressed("sector_join"))
    {
        sector_merge(true);
        binds.clear("sector_join");
    }

    if (binds.pressed("view_3dmode"))
    {
        binds.clear("view_3dmode");
        binds.clear("3d_exit");
        start_3d_mode();
    }

    if (binds.pressed("open_console"))
    {
        binds.clear("open_console");
        popup_console();
    }

    if (binds.pressed("copy"))
    {
        binds.clear("copy");
        clipboard.Copy();
    }

    if (binds.pressed("paste"))
    {
        binds.clear("paste");
        paste_mode = true;
        clear_selection();
    }

    if (binds.pressed("cancel_paste"))
    {
        binds.clear("cancel_paste");
        paste_mode = false;
        force_map_redraw(true, false);
    }
}