package main import rl "vendor:raylib" import "core:math/rand" import "common" import inf "infrastructure" import v "vehicles" // This function only returns the index to the node or if it doesn't exist bool in the tuple is false @private get_node_index_if_exists :: proc(self: ^Simulator, pos: rl.Vector2) -> (u32, bool) { for &node, index in self.nodes { if inf.node_within_snapping_radius(&node, pos) do return u32(index), true } return 0, false } // Given position, the function will attempt the return the pointer to the node in near vicinity, // or if unsuccesful manually creating the node based on the position in the list and then returning the pointer to it @private get_node_or_new :: proc(self: ^Simulator, pos: rl.Vector2) -> u32 { if node, ok := get_node_index_if_exists(self, pos); ok do return node node := inf.node_init(pos) append(&self.nodes, node) return u32(len(self.nodes) - 1) } // Attempts to update node reference to the road; // Returns false if the old reference doesn't exist @private update_node_reference :: proc(self: ^Simulator, road_to_update: u32, old_ref: u32, new_ref: u32) -> bool { road := &self.roads[road_to_update] for i in 0.. ([2]u32, bool) { mlen: u32 // Stores data about old and new index in case the deleted index is not last, meaning the swap occurs index_change: [2]u32 // Tracks whether the removal of node/road will cause a swap in the (dynamic) array // and thus forcing the pre-swapped reference to be updated swap_made: bool switch type { case .Node: mlen = u32(len(self.nodes)) case .Road: mlen = u32(len(self.roads)) case .Car: mlen = u32(len(self.cars)) } last := mlen - 1 if entity_index != last { index_change = {last, entity_index} swap_made = true } 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 { if car.pos.type != .Node do continue 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))) if !common.list_contains(car_occupied_nodes[:], node) do return node } }