improved road implementation
This commit is contained in:
		@@ -40,8 +40,8 @@ pub fn main() !void {
 | 
			
		||||
 | 
			
		||||
        rl.clearBackground(.light_gray);
 | 
			
		||||
 | 
			
		||||
        area_manager.draw();
 | 
			
		||||
        try road_manager.inputHandler();
 | 
			
		||||
        area_manager.draw();
 | 
			
		||||
        road_manager.draw();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -7,15 +7,13 @@ 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);
 | 
			
		||||
    pub fn draw(self: *const Node, valid: bool) void {
 | 
			
		||||
        rl.drawCircleV(self.location, globals.getScale() * road_data.road_thickness / @sqrt(2.0), if (valid) .green else .red);
 | 
			
		||||
    }
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -13,6 +13,7 @@ pub const RoadManager = struct {
 | 
			
		||||
    nodes: std.ArrayList(node_str.Node),
 | 
			
		||||
    mode: str.InputMode,
 | 
			
		||||
    selected_road: ?usize,
 | 
			
		||||
    min_distance: f32,
 | 
			
		||||
 | 
			
		||||
    pub fn init(allocator: std.mem.Allocator) RoadManager {
 | 
			
		||||
        return RoadManager{
 | 
			
		||||
@@ -22,6 +23,7 @@ pub const RoadManager = struct {
 | 
			
		||||
            .nodes = std.ArrayList(node_str.Node).init(allocator),
 | 
			
		||||
            .mode = str.InputMode.normal,
 | 
			
		||||
            .selected_road = null,
 | 
			
		||||
            .min_distance = globals.getScreenWidthF32() / 25.0,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -36,18 +38,33 @@ pub const RoadManager = struct {
 | 
			
		||||
 | 
			
		||||
        // if last road exists and is not fully built
 | 
			
		||||
        if (last_id != null and self.roads.items[last_id.?].end_point == null) {
 | 
			
		||||
            // only confirm if distance is minimal or greater
 | 
			
		||||
            if (rl.Vector2.distance(self.roads.items[last_id.?].start_point, pos) < self.min_distance) return;
 | 
			
		||||
            // if too close to existing nodes, return
 | 
			
		||||
            if (!self.canCreateNode(pos)) return;
 | 
			
		||||
 | 
			
		||||
            self.roads.items[last_id.?].confirmRoad(pos);
 | 
			
		||||
            try self.nodes.append(node_str.Node.init(pos));
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        try self.roads.append(road_str.Road.init(pos));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn canCreateNode(self: *const RoadManager, pos: rl.Vector2) bool {
 | 
			
		||||
        for (self.nodes.items) |node| {
 | 
			
		||||
            if (rl.Vector2.distance(node.location, pos) < self.min_distance) return false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn removeLastRoad(self: *RoadManager) void {
 | 
			
		||||
        _ = self.roads.pop();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn clearRoads(self: *RoadManager) void {
 | 
			
		||||
        self.roads.clearAndFree();
 | 
			
		||||
        self.nodes.clearAndFree();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn trackRoad(self: *RoadManager, pos: rl.Vector2) void {
 | 
			
		||||
@@ -58,11 +75,9 @@ pub const RoadManager = struct {
 | 
			
		||||
        for (0..self.roads.items.len) |i| {
 | 
			
		||||
            // we skip because that road is not complete
 | 
			
		||||
            if (self.roads.items[i].end_point == null) continue;
 | 
			
		||||
            std.debug.print("tracking pt1\n", .{});
 | 
			
		||||
 | 
			
		||||
            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.roads.items[i].setColor(str.RoadState.selected);
 | 
			
		||||
                self.selected_road = i;
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
@@ -109,6 +124,8 @@ pub const RoadManager = struct {
 | 
			
		||||
            self.clearRoads();
 | 
			
		||||
        } else if (rl.isKeyReleased(.d)) {
 | 
			
		||||
            self.toggleDeleteMode();
 | 
			
		||||
        } else if (rl.isKeyReleased(.n)) {
 | 
			
		||||
            self.toggleNodeMode();
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -135,21 +152,62 @@ pub const RoadManager = struct {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn toggleDeleteMode(self: *RoadManager) void {
 | 
			
		||||
        if (self.mode == str.InputMode.delete) {
 | 
			
		||||
            self.resetTrackedRoad();
 | 
			
		||||
        }
 | 
			
		||||
        self.togglePrepare();
 | 
			
		||||
 | 
			
		||||
        self.cancelRoadbuilding();
 | 
			
		||||
        self.mode = switch (self.mode) {
 | 
			
		||||
            .normal => str.InputMode.delete,
 | 
			
		||||
            .delete => str.InputMode.normal,
 | 
			
		||||
            .node => self.mode,
 | 
			
		||||
            .node => str.InputMode.delete,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn toggleNodeMode(self: *RoadManager) void {
 | 
			
		||||
        self.togglePrepare();
 | 
			
		||||
 | 
			
		||||
        self.mode = switch (self.mode) {
 | 
			
		||||
            .normal => str.InputMode.node,
 | 
			
		||||
            .delete => str.InputMode.node,
 | 
			
		||||
            .node => str.InputMode.normal,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fn togglePrepare(self: *RoadManager) void {
 | 
			
		||||
        if (self.mode == str.InputMode.delete) {
 | 
			
		||||
            self.resetTrackedRoad();
 | 
			
		||||
        }
 | 
			
		||||
        self.cancelRoadbuilding();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn draw(self: *const RoadManager) void {
 | 
			
		||||
        for (self.roads.items) |road| {
 | 
			
		||||
        // if last road is being drawn display node marker
 | 
			
		||||
        const last = self.roads.getLastOrNull();
 | 
			
		||||
        const pos = rl.getMousePosition();
 | 
			
		||||
        const marker_node = node_str.Node.init(pos);
 | 
			
		||||
        var draw_marker = false;
 | 
			
		||||
 | 
			
		||||
        if (last != null and last.?.end_point == null) {
 | 
			
		||||
            draw_marker = true;
 | 
			
		||||
 | 
			
		||||
            // might have to put it in one function because we check this two times
 | 
			
		||||
            // todo canCreateNode and canCreateRoad should be part of node/road struct
 | 
			
		||||
            if (rl.Vector2.distance(last.?.start_point, pos) < self.min_distance) {
 | 
			
		||||
                draw_marker = false;
 | 
			
		||||
                self.roads.items[self.getLastIndex().?].setColor(str.RoadState.illegal);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (self.roads.items) |*road| {
 | 
			
		||||
            road.draw();
 | 
			
		||||
            if (!road.isValid())
 | 
			
		||||
                road.*.setColor(str.RoadState.valid);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (draw_marker)
 | 
			
		||||
            marker_node.draw(self.canCreateNode(pos));
 | 
			
		||||
 | 
			
		||||
        if (self.mode != str.InputMode.node) return;
 | 
			
		||||
        for (self.nodes.items) |node| {
 | 
			
		||||
            node.draw(true);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -160,7 +218,7 @@ pub const RoadManager = struct {
 | 
			
		||||
 | 
			
		||||
    fn setDefaultColour(self: *RoadManager) void {
 | 
			
		||||
        for (self.roads.items) |*road| {
 | 
			
		||||
            road.setColor(false);
 | 
			
		||||
            road.setColor(str.RoadState.valid);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -1,17 +1,18 @@
 | 
			
		||||
const rl = @import("raylib");
 | 
			
		||||
const globals = @import("../globals.zig");
 | 
			
		||||
const road_data = @import("road-data.zig");
 | 
			
		||||
const str = @import("../structures.zig");
 | 
			
		||||
 | 
			
		||||
pub const Road = struct {
 | 
			
		||||
    color: rl.Color,
 | 
			
		||||
    start_point: rl.Vector2,
 | 
			
		||||
    end_point: ?rl.Vector2,
 | 
			
		||||
    color: rl.Color,
 | 
			
		||||
 | 
			
		||||
    pub fn init(pos: rl.Vector2) Road {
 | 
			
		||||
        return Road{
 | 
			
		||||
            .color = .black,
 | 
			
		||||
            .start_point = pos,
 | 
			
		||||
            .end_point = null,
 | 
			
		||||
            .color = .black,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@@ -19,8 +20,16 @@ pub const Road = struct {
 | 
			
		||||
        self.end_point = pos;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn setColor(self: *Road, is_selected: bool) void {
 | 
			
		||||
        self.color = if (is_selected) .green else .black;
 | 
			
		||||
    pub fn setColor(self: *Road, road_state: str.RoadState) void {
 | 
			
		||||
        self.color = switch (road_state) {
 | 
			
		||||
            .valid => .black,
 | 
			
		||||
            .illegal => .red,
 | 
			
		||||
            .selected => .green,
 | 
			
		||||
        };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn isValid(self: *const Road) bool {
 | 
			
		||||
        return rl.colorIsEqual(self.color, rl.Color.black);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    pub fn draw(self: *const Road) void {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,3 +1,4 @@
 | 
			
		||||
// valid area states
 | 
			
		||||
pub const AreaLocation = enum {
 | 
			
		||||
    top_left,
 | 
			
		||||
    top_right,
 | 
			
		||||
@@ -5,8 +6,15 @@ pub const AreaLocation = enum {
 | 
			
		||||
    bottom_right,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
// road modes
 | 
			
		||||
pub const InputMode = enum {
 | 
			
		||||
    normal,
 | 
			
		||||
    delete,
 | 
			
		||||
    node,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
pub const RoadState = enum {
 | 
			
		||||
    valid,
 | 
			
		||||
    illegal,
 | 
			
		||||
    selected,
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user