extends Node export var trailer_house: PackedScene export var palace: PackedScene export var car: PackedScene onready var obj_names = { "palace": palace, "trailer_house": trailer_house } var done = false var side_wall: PackedScene = preload("res://objects/wall-side.scn") var bottom_side: PackedScene = preload("res://objects/bottom-side.scn") var bottom: PackedScene = preload("res://objects/bottom.scn") var bottom_wheels: PackedScene = preload("res://objects/bottom-wheels.scn") var entry: PackedScene = preload("res://objects/entry.scn") var roof_floor: PackedScene = preload("res://objects/roof-floor.scn") var roof_floor_range: PackedScene = preload("res://objects/roof-floor-range.scn") var wall_internal: PackedScene = preload("res://objects/wall-internal.scn") var window_narrow: PackedScene = preload("res://objects/window-narrow.scn") var window_wide: PackedScene = preload("res://objects/window-wide.scn") var wall_solid: PackedScene = preload("res://objects/wall-solid.scn") var courtyard_tile: PackedScene = preload("res://objects/courtyard-tile.scn") var foundation_tile: PackedScene = preload("res://objects/foundation.scn") var room_tile: PackedScene = preload("res://objects/block-room-corridoor.scn") var tower_walls_tile: PackedScene = preload("res://objects/tower-walls.scn") var tower_floor_tile: PackedScene = preload("res://objects/tower_floor.scn") var stairs_tile: PackedScene = preload("res://objects/stairs.scn") var gate_bottom_tile: PackedScene = preload("res://objects/gate_bottom.scn") var gate_top_tile: PackedScene = preload("res://objects/gate-top.scn") var entry_tile: PackedScene = preload("res://objects/block-room-entry.scn") var roof_tile: PackedScene = preload("res://objects/roof.scn") var tower_roof_tile: PackedScene = preload("res://objects/tower-roof.scn") onready var palace_map_data = { "courtyard_tile": courtyard_tile, "foundation_tile": foundation_tile, "room_tile": room_tile, "tower_walls_tile": tower_walls_tile, "tower_floor_tile": tower_floor_tile, "stairs_tile": stairs_tile, "gate_bottom_tile": gate_bottom_tile, "gate_top_tile": gate_top_tile, "entry_tile": entry_tile, "roof_tile": roof_tile, "tower_roof_tile": tower_roof_tile } onready var buildings = { "trailer_house": preload("res://buildings/trailer-house.gd").new() } func spawn_building(bname: String, xform: Transform) -> void: if !buildings.has(bname): return var objects = buildings[bname].build_house(xform) spawn_house_objects(xform, objects) var traffic_rnd: RandomNumberGenerator var traffic_astar: AStar var towns = 0 func setup_town(site): if !RoadsData.site_is_town(site): print("site ", site, " type: ", RoadsData.get_site_type(site)) return var poly = RoadsData.get_site_polygon_3d(site) var height = RoadsData.get_site_avg_height(site) var border2 = RoadsData.get_site_border(site, 60) var aabbs = [] var poly2 = [] poly2.resize(border2.size()) for p in range(border2.size()): poly2[p] = Vector2(border2[p].x, border2[p].z) var center = Vector3() for p in poly: center += p center /= poly.size() center.y = height var infl = RoadsData.get_influence_cached(center.x, center.y, 256) center.y = infl.y var radial_points = RoadsData.get_site_radial_points(site, 32.0, 64.0) var max_r = 0.0 for p in range(radial_points.size()): var ep = radial_points[p] var dst = ep.distance_to(center) if max_r < dst: max_r = dst for p in range(radial_points.size()): var ep = radial_points[p] var miff = RoadsData.get_influence_cached(ep.x, ep.z, 256.0) ep.y = center.y var d = (center - ep).normalized() assert(d.length_squared() > 0) var dst = ep.distance_to(center) print(dst) if dst < 64.0 + 12 + 8 + 4: continue var step = 32.0 var pstart = ep + d * 32.0 dst -= 32.0 while dst > 0.0: var ok = true miff = RoadsData.get_influence_cached(pstart.x, pstart.z, 256.0) if miff.x > 0.0: ok = false if ok: pstart.y = miff.y if !Geometry.is_point_in_polygon(Vector2(pstart.x, pstart.z), poly2): ok = false if ok: for b in aabbs: if b.has_point(pstart): ok = false if ok: var xform = Transform(Basis(), pstart).looking_at(pstart + d, Vector3.UP) spawn_building("trailer_house", xform) var aabb = AABB(pstart, Vector3()) aabb = aabb.grow(32) aabbs.push_back(aabb) print("placed to: ", pstart) pstart = pstart + d * step dst -= step towns += 1 func setup_first_town(): assert(!done) var poly = RoadsData.get_site_polygon_3d(0) var height = RoadsData.get_site_avg_height(0) var border = RoadsData.get_site_border(0, 32) var border1a = RoadsData.get_site_border(0, 42) var border2 = RoadsData.get_site_border(0, 60) var poly2 = [] poly2.resize(border2.size()) for p in range(border2.size()): poly2[p] = Vector2(border2[p].x, border2[p].z) var center = Vector3() for p in poly: center += p center /= poly.size() center.y = height var infl = RoadsData.get_influence_cached(center.x, center.z, 256) center.y = infl.y print("first town center: ", center) var radial_points = RoadsData.get_site_radial_points(0, 32.0, 64.0) var max_r = 0.0 for p in range(radial_points.size()): var ep = radial_points[p] var dst = ep.distance_to(center) if max_r < dst: max_r = dst var u = radial_points.size() var v = int(max_r / 32) var grid = [] grid.resize(u * v) for p in range(u): var start = radial_points[p] var end = center var step = (end - start).normalized() * (end - start).length() / float(v + 1) var val = start for q in range(v): grid[p * v + q] = {"position": val} var aabbs = [] var palace_aabb = AABB(center, Vector3()) palace_aabb = palace_aabb.grow(48) print(palace_aabb) aabbs.push_back(palace_aabb) stream_obj("palace", Transform(Basis(), center)) for p in range(radial_points.size()): var ep = radial_points[p] var miff = RoadsData.get_influence_cached(ep.x, ep.z, 256.0) ep.y = center.y var d = (center - ep).normalized() assert(d.length_squared() > 0) var dst = ep.distance_to(center) print(dst) if dst < 64.0 + 12 + 8 + 4: continue var step = 32.0 var pstart = ep + d * 32.0 dst -= 32.0 while dst > 0.0: var ok = true miff = RoadsData.get_influence_cached(pstart.x, pstart.z, 256.0) if miff.x > 0.0: ok = false if ok: pstart.y = miff.y if !Geometry.is_point_in_polygon(Vector2(pstart.x, pstart.z), poly2): ok = false if ok: for b in aabbs: if b.has_point(pstart): ok = false if ok: var xform = Transform(Basis(), pstart).looking_at(pstart + d, Vector3.UP) # stream_obj("trailer_house", xform) spawn_building("trailer_house", xform) var aabb = AABB(pstart, Vector3()) aabb = aabb.grow(32) aabbs.push_back(aabb) print("placed to: ", pstart) pstart = pstart + d * step dst -= step towns += 1 done = true func setup_traffic(site): var poly = RoadsData.get_site_polygon_3d(site) var lp = get_tree().root for p in range(poly.size()): var p1 = poly[p] var p2 = poly[(p + 1) % poly.size()] var n = (p2 - p1).cross(Vector3.UP).normalized() var t = (p2 - p1).normalized() var l = p1.distance_to(p2) assert(l > 0 && t.length_squared() > 0) var xpos = p1 + t * 8.0 var xe = 128.0 if l < xe + 16.0: xpos = p1.linear_interpolate(p2, 0.5) var x = xpos var xform = Transform(Basis(), x).looking_at(x - t * 3.0, Vector3.UP) var c = Spatial.new() lp.add_child(c) c.transform = xform c.add_to_group("spawn") c.add_to_group("keep") c.add_to_group("traffic_spawn") else: while l > xe + 16.0: var x = xpos var xform = Transform(Basis(), x).looking_at(x - t * 3.0, Vector3.UP) var c = Spatial.new() lp.add_child(c) c.transform = xform c.add_to_group("spawn") c.add_to_group("keep") c.add_to_group("traffic_spawn") xpos += t * xe l -= xe func _ready(): traffic_rnd = RandomNumberGenerator.new() traffic_rnd.randomize() traffic_astar = AStar.new() for k in obj_names.keys(): Spawner.add_scene(k, obj_names[k]) for k in palace_map_data.keys(): Spawner.add_scene(k, palace_map_data[k]) var parts = { "side_wall": side_wall, "bottom_side": bottom_side, "bottom": bottom, "bottom_wheels": bottom_wheels, "entry": entry, "roof_floor": roof_floor, "roof_floor_range": roof_floor_range, "wall_internal": wall_internal, "window_narrow": window_narrow, "window_wide": window_wide, "wall_solid": wall_solid } for k in parts.keys(): Spawner.add_scene(k, parts[k]) # Traffic.set_min_spawn_distance(50.0) # Traffic.set_deny_physics() # Traffic.set_physics_distance(Vector3(30, -10, 40)) # Traffic.set_debug(true) Traffic.set_spawn_cooldown(1, 5) Traffic.set_default_speed(8.5) Traffic.add_traffic_vehicle(car) var water_mat = load("res://water/Water.material") Water.set_material(water_mat) var delay = 3.0 var state = 0 func _process(delta): match state: 0: delay -= delta if delay < 0: state = 1 1: # Spawner.update_view(self, 200) var sc = get_tree().root var viewport: = get_viewport() if !viewport: return var cam: = viewport.get_camera() if !cam: return var cam_xform: = cam.global_transform # building parts # call_deferred("real_spawn_child") func stream_obj(obj: String, xform: Transform): Spawner.place_scene(obj, xform) func _physics_process(delta): var cam = get_viewport().get_camera() if !cam: return match state: 1: var space_state = get_viewport().get_world().direct_space_state # probaly should not be here for n in get_tree().get_nodes_in_group("spawn"): var ok = false if !n.is_in_group("keep"): var where = n.get_global_transform().origin var from = where var to = where from.y -= 8.0 to.y += 8.0 var result = space_state.intersect_ray(from, to) if result.empty() || !result.has("collider"): continue if result.collider: n.global_transform.origin = result.position ok = true if ok || n.is_in_group("keep"): if n.is_in_group("male"): characters.replace_character(n, "male", ["cmdq", "marker", "hurtboxes", "student"]) elif n.is_in_group("female"): characters.replace_character(n, "female", ["cmdq", "marker", "hurtboxes", "student"]) elif n.is_in_group("car"): var p1 = cam.global_transform.origin var p2 = n.global_transform.origin if p1.distance_squared_to(p2) < 5000.0: var c = car.instance() c.add_to_group("saved_vehicle") var p = get_tree().root p.add_child(c) c.global_transform = n.global_transform n.queue_free() # buildings #var spawn = [] onready var spawn_lock: Mutex = Mutex.new() func spawn_child(n: String, xform: Transform) -> void: spawn_lock.lock() Spawner.queue_place_scene(n, xform) spawn_lock.unlock() func update_node_position(n): var space_state = get_viewport().get_world().direct_space_state var where = n.get_global_transform().origin var from = where var to = where from.y -= 8.0 to.y += 8.0 var result = space_state.intersect_ray(from, to) if result.empty() || !result.has("collider"): return else: n.global_transform.origin = result.position func spawn_house_objects(place: Transform, objects) -> void: for obj in objects: var x = obj.xform for w in obj.data: if w.ends_with("_rotated"): x.basis = x.basis.rotated(Vector3(0, 1, 0), PI) var n = w.replace("_rotated", "") spawn_child(n, place * x) else: spawn_child(w, place * x) static func get_place_rnd(xform: Transform): var rnd = RandomNumberGenerator.new() var s = int(xform.origin.x + 100 * xform.origin.z * 2) % 0x1ffffff rnd.seed = s return rnd