summaryrefslogtreecommitdiffstats
path: root/edit.c
diff options
context:
space:
mode:
Diffstat (limited to 'edit.c')
-rw-r--r--edit.c149
1 files changed, 145 insertions, 4 deletions
diff --git a/edit.c b/edit.c
index bb20d89..0fc01aa 100644
--- a/edit.c
+++ b/edit.c
@@ -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;
}