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 } 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 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 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 = 16.0 var pstart = ep while dst > 0.0: var ok = true 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) 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 # grid.build(border2, 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 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 = 16.0 var pstart = ep while dst > 0.0: var ok = true 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) 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.add_traffic_vehicle(car) 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: # convert to distant traffic here for n in get_tree().get_nodes_in_group("traffic_vehicle"): var p1 = cam.global_transform.origin var p2 = n.global_transform.origin # p2 has both vertical and lane offset, correct these and write to path_pos var path_pos = Traffic.get_path_position(n) var check_coords = cam.global_transform.xform_inv(path_pos) var steer = 0.0 var orientation = n.global_transform orientation.origin = Vector3() var direction = orientation.xform(Vector3(0, 0, -1)) var good_path = false var engine_force = n.engine_force if !n.has_meta("curve"): continue if n.has_meta("curve"): # next_target has corrected vertical position (up from path) steer = Traffic.get_steer(n, true) * 0.6 if !n.has_meta("space"): var v = n.get_linear_velocity() var l = v.length() print("physics: velocity: ", v, " velocity norm: ", v.normalized()) if true: if abs(steer) > 3.0: engine_force *= 0.9 engine_force = clamp(engine_force, 2500.0, max(2500, engine_force)) else: if abs(steer) > 4.0 && l > 5.0: engine_force = engine_force * 0.9996 if l > 7.0: engine_force = engine_force * 0.9996 elif l < 1.1: engine_force = clamp(engine_force * 1.004, 6000, 8000) elif l < 2.5: engine_force = clamp(engine_force * 1.002, 5000, 7000) elif l < 5.0: engine_force = clamp(engine_force * 1.001, 4000, 6000) elif l < 6.0: engine_force = clamp(engine_force * 1.001, 3000, 5000) engine_force = clamp(engine_force, 0, 3500) # print("engine_force: ", engine_force) n.engine_force = engine_force n.brake = 0 var base_steering = n.steering var main_steering = base_steering * 0.95 + steer * 0.05 n.steering = clamp(main_steering, -1, 1) n.set_meta("steering", n.steering) 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 = [] func spawn_child(n: String, xform: Transform) -> void: var sp = {"node": n, "xform": xform} spawn.push_back(sp) func real_spawn_child(): var count = 0 while spawn.size() > 0: var e = spawn.pop_front() Spawner.place_scene(e.node, e.xform) count += 1 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