road manager fixes, node implementation
This commit is contained in:
		
							
								
								
									
										21
									
								
								src/road/node.zig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/road/node.zig
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,21 @@
 | 
			
		||||
const std = @import("std");
 | 
			
		||||
const rl = @import("raylib");
 | 
			
		||||
const road_str = @import("road.zig");
 | 
			
		||||
const road_data = @import("road-data.zig");
 | 
			
		||||
const globals = @import("../globals.zig");
 | 
			
		||||
 | 
			
		||||
pub const Node = struct {
 | 
			
		||||
    // road_sections: std.ArrayList(road_str.Road),
 | 
			
		||||
    location: rl.Vector2,
 | 
			
		||||
    // todo validation
 | 
			
		||||
 | 
			
		||||
    pub fn init(location: rl.Vector2) Node {
 | 
			
		||||
        return Node{
 | 
			
		||||
            .location = location,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn draw(self: *const Node) void {
 | 
			
		||||
        rl.drawCircleV(self.location, globals.getScale() * road_data.road_thickness / @sqrt(2), .green);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
@@ -1,14 +1,17 @@
 | 
			
		||||
const std = @import("std");
 | 
			
		||||
const rl = @import("raylib");
 | 
			
		||||
const road_str = @import("road.zig");
 | 
			
		||||
const road_data = @import("../road-data.zig");
 | 
			
		||||
const road_data = @import("road-data.zig");
 | 
			
		||||
const node_str = @import("node.zig");
 | 
			
		||||
const globals = @import("../globals.zig");
 | 
			
		||||
const str = @import("../structures.zig");
 | 
			
		||||
 | 
			
		||||
pub const RoadManager = struct {
 | 
			
		||||
    buffer: f32,
 | 
			
		||||
    allocator: std.mem.Allocator,
 | 
			
		||||
    roads: std.ArrayList(road_str.Road),
 | 
			
		||||
    delete_mode: bool,
 | 
			
		||||
    nodes: std.ArrayList(node_str.Node),
 | 
			
		||||
    mode: str.InputMode,
 | 
			
		||||
    selected_road: ?usize,
 | 
			
		||||
 | 
			
		||||
    pub fn init(allocator: std.mem.Allocator) RoadManager {
 | 
			
		||||
@@ -16,13 +19,15 @@ pub const RoadManager = struct {
 | 
			
		||||
            .buffer = road_data.road_thickness * globals.getScale() / 2.0,
 | 
			
		||||
            .allocator = allocator,
 | 
			
		||||
            .roads = std.ArrayList(road_str.Road).init(allocator),
 | 
			
		||||
            .delete_mode = false,
 | 
			
		||||
            .nodes = std.ArrayList(node_str.Node).init(allocator),
 | 
			
		||||
            .mode = str.InputMode.normal,
 | 
			
		||||
            .selected_road = null,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn deinit(self: *RoadManager) void {
 | 
			
		||||
        self.roads.deinit();
 | 
			
		||||
        self.nodes.deinit();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn addRoad(self: *RoadManager, pos: rl.Vector2) !void {
 | 
			
		||||
@@ -46,54 +51,102 @@ pub const RoadManager = struct {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn trackRoad(self: *RoadManager, pos: rl.Vector2) void {
 | 
			
		||||
        if (!self.delete_mode) return;
 | 
			
		||||
        if (self.mode != str.InputMode.delete) return;
 | 
			
		||||
 | 
			
		||||
        self.setDefaultColour();
 | 
			
		||||
        self.selected_road = null;
 | 
			
		||||
        self.resetTrackedRoad();
 | 
			
		||||
 | 
			
		||||
        for (self.roads.items) |*road| {
 | 
			
		||||
        for (0..self.roads.items.len) |i| {
 | 
			
		||||
            // we skip because that road is not complete
 | 
			
		||||
            if (road.end_point == null) continue;
 | 
			
		||||
            if (self.roads.items[i].end_point == null) continue;
 | 
			
		||||
            std.debug.print("tracking pt1\n", .{});
 | 
			
		||||
 | 
			
		||||
            if (cursorOnRoad(road.start_point, pos, road.end_point)) {
 | 
			
		||||
                road.*.setColor(true);
 | 
			
		||||
                // todo pointer or index
 | 
			
		||||
            if (self.cursorOnRoad(self.roads.items[i].start_point, pos, self.roads.items[i].end_point.?)) {
 | 
			
		||||
                std.debug.print("tracking pt2", .{});
 | 
			
		||||
                self.roads.items[i].setColor(true);
 | 
			
		||||
                self.selected_road = i;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn cursorOnRoad(start: rl.Vector2, cursor: rl.Vector2, end: rl.Vector2) bool {}
 | 
			
		||||
    fn cursorOnRoad(self: *const RoadManager, start: rl.Vector2, cursor: rl.Vector2, end: rl.Vector2) bool {
 | 
			
		||||
        const min_x = @min(start.x, end.x) - self.buffer;
 | 
			
		||||
        const max_x = @max(start.x, end.x) + self.buffer;
 | 
			
		||||
        const min_y = @min(start.y, end.y) - self.buffer;
 | 
			
		||||
        const max_y = @max(start.y, end.y) + self.buffer;
 | 
			
		||||
 | 
			
		||||
        if (!(cursor.x >= min_x and cursor.x <= max_x and cursor.y >= min_y and cursor.y <= max_y)) return false;
 | 
			
		||||
 | 
			
		||||
        const sc = rl.Vector2{ .x = start.x - cursor.x, .y = start.y - cursor.y };
 | 
			
		||||
        const se = rl.Vector2{ .x = start.x - end.x, .y = start.y - end.y };
 | 
			
		||||
 | 
			
		||||
        const prod = @abs(sc.x * se.y - sc.y * se.x);
 | 
			
		||||
        const road_length = @sqrt((end.x - start.x) * (end.x - start.x) + (end.y - start.y) * (end.y - start.y));
 | 
			
		||||
        const threshold = road_length * self.buffer;
 | 
			
		||||
 | 
			
		||||
        return prod <= threshold;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn cancelRoadbuilding(self: *RoadManager) void {
 | 
			
		||||
        // if we're in process of building a new road cancel it
 | 
			
		||||
        const last_road = self.roads.getLastOrNull();
 | 
			
		||||
        if (last_road != null and last_road.?.end_point == null)
 | 
			
		||||
            self.removeLastRoad();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn inputHandler(self: *RoadManager) !void {
 | 
			
		||||
        const pos = rl.getMousePosition();
 | 
			
		||||
        trackRoad(pos);
 | 
			
		||||
        self.trackRoad(pos);
 | 
			
		||||
 | 
			
		||||
        // mouse inputs
 | 
			
		||||
        if (rl.isMouseButtonReleased(.left)) {
 | 
			
		||||
            if (self.delete_mode) {
 | 
			
		||||
                if (self.selected_road == null) return;
 | 
			
		||||
                // todo might be a problem in the future swapping modes must clear any unfinished roads!
 | 
			
		||||
                self.roads.swapRemove(self.selected_road.?);
 | 
			
		||||
            } else {
 | 
			
		||||
                try self.addRoad(pos);
 | 
			
		||||
            }
 | 
			
		||||
        } else if (rl.isMouseButtonReleased(.right)) {
 | 
			
		||||
            self.removeLastRoad();
 | 
			
		||||
        }
 | 
			
		||||
        try self.handleMouseInput();
 | 
			
		||||
 | 
			
		||||
        self.handleKeyboardInput();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn handleKeyboardInput(self: *RoadManager) void {
 | 
			
		||||
        // keyboard inputs
 | 
			
		||||
        if (rl.isKeyReleased(.c)) {
 | 
			
		||||
            self.clearRoads();
 | 
			
		||||
        } else if (rl.isKeyReleased(.d)) {
 | 
			
		||||
            self.delete_mode = !self.delete_mode;
 | 
			
		||||
            if (!self.delete_mode) {
 | 
			
		||||
                self.setDefaultColour();
 | 
			
		||||
                self.selected_road = null;
 | 
			
		||||
            }
 | 
			
		||||
            self.toggleDeleteMode();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn handleMouseInput(self: *RoadManager) !void {
 | 
			
		||||
        // mouse inputs
 | 
			
		||||
        if (rl.isMouseButtonReleased(.left)) {
 | 
			
		||||
            try self.handleLeftClick();
 | 
			
		||||
        } else if (rl.isMouseButtonReleased(.right)) {
 | 
			
		||||
            self.removeLastRoad();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn handleLeftClick(self: *RoadManager) !void {
 | 
			
		||||
        switch (self.mode) {
 | 
			
		||||
            .normal => try self.addRoad(rl.getMousePosition()),
 | 
			
		||||
            .delete => {
 | 
			
		||||
                if (self.selected_road == null) return;
 | 
			
		||||
 | 
			
		||||
                _ = self.roads.swapRemove(self.selected_road.?);
 | 
			
		||||
                self.selected_road = null;
 | 
			
		||||
            },
 | 
			
		||||
            .node => {},
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn toggleDeleteMode(self: *RoadManager) void {
 | 
			
		||||
        if (self.mode == str.InputMode.delete) {
 | 
			
		||||
            self.resetTrackedRoad();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        self.cancelRoadbuilding();
 | 
			
		||||
        self.mode = switch (self.mode) {
 | 
			
		||||
            .normal => str.InputMode.delete,
 | 
			
		||||
            .delete => str.InputMode.normal,
 | 
			
		||||
            .node => self.mode,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn draw(self: *const RoadManager) void {
 | 
			
		||||
        for (self.roads.items) |road| {
 | 
			
		||||
            road.draw();
 | 
			
		||||
@@ -110,4 +163,9 @@ pub const RoadManager = struct {
 | 
			
		||||
            road.setColor(false);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn resetTrackedRoad(self: *RoadManager) void {
 | 
			
		||||
        self.setDefaultColour();
 | 
			
		||||
        self.selected_road = null;
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -1,6 +1,6 @@
 | 
			
		||||
const rl = @import("raylib");
 | 
			
		||||
const globals = @import("../globals.zig");
 | 
			
		||||
const road_data = @import("../road-data.zig");
 | 
			
		||||
const road_data = @import("road-data.zig");
 | 
			
		||||
 | 
			
		||||
pub const Road = struct {
 | 
			
		||||
    color: rl.Color,
 | 
			
		||||
 
 | 
			
		||||
@@ -4,3 +4,9 @@ pub const AreaLocation = enum {
 | 
			
		||||
    bottom_left,
 | 
			
		||||
    bottom_right,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const InputMode = enum {
 | 
			
		||||
    normal,
 | 
			
		||||
    delete,
 | 
			
		||||
    node,
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user