package main import "core:math" 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) -> (uint, bool) { for &node, index in self.nodes { if inf.node_within_snapping_radius(&node, pos) do return uint(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) -> uint { if node, ok := get_node_index_if_exists(self, pos); ok do return node node := inf.node_init(pos) append(&self.nodes, node) return uint(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: uint, old_ref: uint, new_ref: uint) -> bool { road := &self.roads[road_to_update] for i in 0.. ([2]uint, bool) { mlen: uint // Stores data about old and new index in case the deleted index is not last, meaning the swap occurs index_change: [2]uint // 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 = uint(len(self.nodes)) case .Road: mlen = uint(len(self.roads)) case .Car: mlen = uint(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(uint) { car_occupied_nodes: [dynamic]uint 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.uint_max(uint(len(self.nodes))) if !common.list_contains(car_occupied_nodes[:], node) do return node } } calculate_road_length :: proc(self: ^Simulator, start: uint, end: uint) -> f32 { start_pos := self.nodes[start].pos end_pos := self.nodes[end].pos x_diff := end_pos.x - start_pos.x y_diff := end_pos.y - start_pos.y len := math.sqrt(x_diff * x_diff - y_diff * y_diff) return len }