91 lines
2.9 KiB
Zig
91 lines
2.9 KiB
Zig
const std = @import("std");
|
|
const rl = @import("raylib");
|
|
const str_node = @import("../road/node.zig");
|
|
const spawn_area = @import("spawn-area.zig");
|
|
const structures = @import("../structures.zig");
|
|
|
|
pub const Areas = struct {
|
|
allocator: std.mem.Allocator,
|
|
areas: []spawn_area.SpawnArea,
|
|
|
|
pub fn init(allocator: std.mem.Allocator, size: usize) !Areas {
|
|
const values = std.enums.values(structures.AreaLocation);
|
|
var max_areas = size;
|
|
if (size > values.len) max_areas = values.len;
|
|
|
|
var used_areas = std.ArrayList(structures.AreaLocation).init(allocator);
|
|
defer used_areas.deinit();
|
|
|
|
var prng = std.Random.DefaultPrng.init(blk: {
|
|
var seed: u64 = undefined;
|
|
try std.posix.getrandom(std.mem.asBytes(&seed));
|
|
break :blk seed;
|
|
});
|
|
|
|
const rand = prng.random();
|
|
const area_data = try allocator.alloc(spawn_area.SpawnArea, size);
|
|
|
|
for (area_data) |*area| {
|
|
// give us all valid values we can use for AreaLocation
|
|
const valid_values = try getEnumValuesMinusUsed(allocator, used_areas, values);
|
|
defer allocator.free(valid_values);
|
|
|
|
const num = rand.intRangeAtMost(usize, 0, valid_values.len - 1); // random number
|
|
// here we create new spawnarea
|
|
area.* = spawn_area.SpawnArea.init(valid_values[num]);
|
|
try used_areas.append(valid_values[num]);
|
|
}
|
|
|
|
return Areas{
|
|
.allocator = allocator,
|
|
.areas = area_data,
|
|
};
|
|
}
|
|
|
|
pub fn deinit(self: *Areas) void {
|
|
self.allocator.free(self.areas);
|
|
}
|
|
|
|
pub fn draw(self: *const Areas) void {
|
|
for (self.areas) |area| {
|
|
area.draw();
|
|
}
|
|
}
|
|
|
|
pub fn recalculate(self: *Areas) void {
|
|
for (self.areas) |*area| {
|
|
area.setLocation();
|
|
}
|
|
}
|
|
|
|
fn getEnumValuesMinusUsed(allocator: std.mem.Allocator, used_values: std.ArrayList(structures.AreaLocation), values: []const structures.AreaLocation) ![]structures.AreaLocation {
|
|
var valuesToRandomise = try allocator.alloc(structures.AreaLocation, values.len - used_values.items.len);
|
|
|
|
var i: usize = 0;
|
|
|
|
outer: for (values) |value| {
|
|
for (used_values.items) |used_val| {
|
|
if (value == used_val) {
|
|
continue :outer;
|
|
}
|
|
}
|
|
// this value is clean and can get put into values good for randomisation
|
|
valuesToRandomise[i] = value;
|
|
i += 1;
|
|
}
|
|
|
|
return valuesToRandomise;
|
|
}
|
|
|
|
pub fn getNodes(self: *const Areas) ![]str_node.Node {
|
|
var nodes = try self.allocator.alloc(str_node.Node, self.areas.len);
|
|
|
|
for (0..self.areas.len) |i| {
|
|
const node_location = self.areas[i].getNodeLocation();
|
|
nodes[i] = str_node.Node.init(node_location);
|
|
}
|
|
|
|
return nodes;
|
|
}
|
|
};
|