diff options
Diffstat (limited to 'edit.c')
-rw-r--r-- | edit.c | 149 |
1 files changed, 145 insertions, 4 deletions
@@ -1,4 +1,7 @@ #include "edit.h" +#include "level.h" +#include "geometry.h" +#include <stdlib.h> static int editMode = EDIT_MODE_VIEW; @@ -6,6 +9,8 @@ static int editMode = EDIT_MODE_VIEW; static ROOM *activeRoom = NULL; static ROOM *hoveredRoom = NULL; +static VERTEX hoveredVertex; +static int hasHoveredVertex = 0; int getEditMode() { return editMode; @@ -18,14 +23,150 @@ ROOM *getActiveRoom() { void setActiveRoom(ROOM *room) { activeRoom = room; - if(editMode == EDIT_MODE_VIEW || editMode == EDIT_MODE_SELECTED) - editMode = (room == NULL) ? EDIT_MODE_VIEW : EDIT_MODE_SELECTED; + if(room == NULL) { + editMode = EDIT_MODE_VIEW; + } + else if(editMode == EDIT_MODE_VIEW) { + editMode = EDIT_MODE_SELECTED; + } +} + +VERTEX *getHoveredVertex() { + if(hasHoveredVertex) return &hoveredVertex; + else return NULL; +} + +void setHoveredVertex(VERTEX *v) { + int i; + LEVEL *l; + + if(v) { + hasHoveredVertex = 1; + hoveredVertex = *v; + + l = getLevel(); + hoveredRoom = NULL; + + for(i = 0; i < l->nRooms; i++) { + if(vertexInPolygon(v, &l->rooms[i].polygon)) { + hoveredRoom = &l->rooms[i]; + break; + } + } + } + else { + hasHoveredVertex = 0; + hoveredRoom = NULL; + } +} + +void startAddMode() { + ROOM room = {{0, NULL}, calloc(1, sizeof(unsigned char))}; + + activeRoom = calloc(1, sizeof(ROOM)); + activeRoom->polygon.nVertices = 0; + activeRoom->polygon.vertices = NULL; + activeRoom->name = calloc(1, sizeof(unsigned char)); + + editMode = EDIT_MODE_ADD; +} + +void endAddMode() { + editMode = activeRoom ? EDIT_MODE_SELECTED : EDIT_MODE_VIEW; } ROOM *getHoveredRoom() { return hoveredRoom; } -void setHoveredRoom(ROOM *room) { - hoveredRoom = room; +static isLineOk(LINE *l) { + LEVEL *lvl = getLevel(); + LINE l2; + int i; + + + if(activeRoom) { + for(i = 0; i+2 < activeRoom->polygon.nVertices; i++) { + l2.v1 = activeRoom->polygon.vertices[i]; + l2.v2 = activeRoom->polygon.vertices[i+1]; + + if(lineIntersection(l, &l2, NULL) == INTERSECTION_SEGMENT_SEGMENT) return 0; + } + + if(activeRoom->polygon.nVertices > 1) { + l2.v1 = activeRoom->polygon.vertices[activeRoom->polygon.nVertices-2]; + l2.v2 = activeRoom->polygon.vertices[activeRoom->polygon.nVertices-1]; + if(vertexOnLine(&l->v2, &l2)) return 0; + } + } + + for(i = 0; i < lvl->nRooms; i++) { + if(linePolygonIntersection(l, &lvl->rooms[i].polygon)) + return 0; + } + + return 1; +} + +int isVertexOk(VERTEX *v) { + LEVEL *lvl = getLevel(); + LINE l; + int i; + + for(i = 0; i < lvl->nRooms; i++) { + if(vertexInPolygon(v, &lvl->rooms[i].polygon)) return 0; + } + + if(!(getActiveRoom() && getActiveRoom()->polygon.nVertices)) + return 1; + + l.v1 = getActiveRoom()->polygon.vertices[getActiveRoom()->polygon.nVertices-1]; + l.v2 = *v; + + return isLineOk(&l); +} + + + +int isPolygonOk(POLYGON *polygon) { + LEVEL *lvl = getLevel(); + LINE l, l2; + int i, j; + + if(!polygon->nVertices) return 0; + + for(i = 0; i < lvl->nRooms; i++) { + if(!lvl->rooms[i].polygon.nVertices) continue; + + if(vertexInPolygon(&polygon->vertices[0], &lvl->rooms[i].polygon)) + return 0; + + if(vertexInPolygon(&lvl->rooms[i].polygon.vertices[0], polygon)) + return 0; + } + + if(polygon->nVertices == 1) + return 1; + + for(i = 0; i < polygon->nVertices; i++) { + l.v1 = polygon->vertices[i]; + l.v2 = polygon->vertices[(i+1)%polygon->nVertices]; + + for(j = 0; j < lvl->nRooms; j++) { + if(linePolygonIntersection(&l, &lvl->rooms[j].polygon)) + return 0; + } + + for(j = i+2; j < polygon->nVertices; j++) { + if(i == 0 && j == polygon->nVertices-1) continue; + + l2.v1 = polygon->vertices[j]; + l2.v2 = polygon->vertices[(j+1)%polygon->nVertices]; + + if(lineIntersection(&l, &l2, NULL) == INTERSECTION_SEGMENT_SEGMENT) + return 0; + } + } + + return 1; } |