From da5c60d76ba5110f7692b37e864010a3ac62cb57 Mon Sep 17 00:00:00 2001 From: Marto Date: Mon, 27 Apr 2026 15:29:16 +0200 Subject: [PATCH] Implemented removal of cars if the node they're on gets removed --- src/common/structures.odin | 12 ++++++++++++ src/draw.odin | 5 ++++- src/infrastructure_helpers.odin | 17 ++++++++++++----- src/input.odin | 6 ++++-- src/vehicles/car.odin | 27 ++++++++++++--------------- 5 files changed, 44 insertions(+), 23 deletions(-) diff --git a/src/common/structures.odin b/src/common/structures.odin index a83d9c0..afa5ef5 100644 --- a/src/common/structures.odin +++ b/src/common/structures.odin @@ -15,4 +15,16 @@ Entity :: enum { Node, Road, Car, +} + +Infrastructure :: enum { + Node, + Road +} + +Car_Position :: struct { + // Tracks which infrastructure the vehicle occupies + type: Infrastructure, + // Tracks the reference + ref: u32, } \ No newline at end of file diff --git a/src/draw.odin b/src/draw.odin index 8234d4f..7cc02af 100644 --- a/src/draw.odin +++ b/src/draw.odin @@ -45,7 +45,10 @@ draw_nodes :: proc(self: ^Simulator) { @(private="file") draw_cars :: proc(self: ^Simulator) { for &car in self.cars { - pos := self.nodes[car.origin].pos + ref := car.pos.ref + // TODO fix in the future + // let's fix it by tracking length of the road and + pos := car.pos.type == .Node ? self.nodes[ref].pos : self.nodes[self.roads[ref].nodes[0]].pos rect := rl.Rectangle { x = pos.x, diff --git a/src/infrastructure_helpers.odin b/src/infrastructure_helpers.odin index 6712592..9e9acd6 100644 --- a/src/infrastructure_helpers.odin +++ b/src/infrastructure_helpers.odin @@ -76,6 +76,15 @@ delete_entity :: proc(self: ^Simulator, entity_index: u32, type: common.Entity) switch type { case .Node: + // get cars that are on that node + + for i in 0.. Maybe(u32) { car_occupied_nodes: [dynamic]u32 for car in self.cars { - node, ok := car.node_pos.? - if !ok do continue + if car.pos.type != .Node do continue - if common.list_contains(car_occupied_nodes[:], node) do continue - append(&car_occupied_nodes, node) + if common.list_contains(car_occupied_nodes[:], car.pos.ref) do continue + append(&car_occupied_nodes, car.pos.ref) } if len(car_occupied_nodes) == len(self.nodes) do return nil - for { node := rand.uint32_max(u32(len(self.nodes))) diff --git a/src/input.odin b/src/input.odin index f87e2ba..06415c8 100644 --- a/src/input.odin +++ b/src/input.odin @@ -27,8 +27,10 @@ handle_keyboard_input :: proc(self: ^Simulator) { if !rl.IsKeyReleased(.N) || len(self.nodes) == 0 do return - car := v.car_init(get_free_node(self), self.nodes[:]) - append(&self.cars, car) + if node_id, ok := get_free_node(self).?; ok { + car := v.car_init(node_id, self.nodes[:]) + append(&self.cars, car) + } } // Generally mouse event handler diff --git a/src/vehicles/car.odin b/src/vehicles/car.odin index 9d19cf8..36e3328 100644 --- a/src/vehicles/car.odin +++ b/src/vehicles/car.odin @@ -14,18 +14,13 @@ Car :: struct { // Pathfinding - // Car's origin node - origin: u32, + // Car's current node/road + pos: common.Car_Position, // Car's destination node destination: Maybe(u32), - // Tracks on which node car has been last - // - // if null car is not on node - node_pos: Maybe(u32), - // if null car is not on road - road_pos: Maybe(u32), - // tracks absolute pos - actual_pos: rl.Vector2, + + // tracks absolute pos (within canvas) + absolute_pos: rl.Vector2, } // Constructor @@ -33,9 +28,11 @@ car_init :: proc(spawn_node: u32, nodes: []inf.Node) -> Car { return { fuel_level = common.FUEL_MAX, max_speed = common.CAR_MAX_SPEED, - origin = spawn_node, - node_pos = spawn_node, - actual_pos = nodes[spawn_node].pos + pos = common.Car_Position { + type = .Node, + ref = spawn_node, + }, + absolute_pos = nodes[spawn_node].pos } } @@ -43,11 +40,11 @@ car_init :: proc(spawn_node: u32, nodes: []inf.Node) -> Car { // // Does NOT guarantee the route is reachable (TODO!) car_set_route :: proc(self: ^Car, nodes_len: u32) { - for self.origin == self.destination do self.destination = rand.uint32_max(nodes_len) + for self.pos.type == .Node && self.pos.ref == self.destination do self.destination = rand.uint32_max(nodes_len) } // Updates (origin and destination) node reference car_update_node_reference :: proc(self: ^Car, old_ref: u32, new_ref: u32) { - if self.origin == old_ref do self.origin = new_ref + if self.pos.type == .Node && self.pos.ref == old_ref do self.pos.ref = new_ref if self.destination == old_ref do self.destination = new_ref } \ No newline at end of file