Improved world generation, better notifications

This commit is contained in:
Segey Lapin
2019-08-19 04:14:12 +03:00
parent fed6229fb4
commit 005ef6cf6d
6 changed files with 569 additions and 344 deletions

View File

@@ -6,6 +6,7 @@ extends Node
# Called when the node enters the scene tree for the first time. # Called when the node enters the scene tree for the first time.
var quest_notification_scene = preload("res://ui/start_quest_notification.tscn") var quest_notification_scene = preload("res://ui/start_quest_notification.tscn")
var quest_complete_notification_scene = preload("res://ui/quest_complete_notification.tscn")
var qn: Node var qn: Node
func _ready(): func _ready():
pass # Replace with function body. pass # Replace with function body.
@@ -17,12 +18,15 @@ func _ready():
var queue = [] var queue = []
const cooldown_time: float = 3.0 const cooldown_time: float = 3.0
var time_count: float = 0.0 var time_count: float = 0.0
enum {N_QUEST, N_OTHER} enum {N_QUEST, N_QUEST_COMPLETE, N_OTHER}
enum {STATE_INIT, STATE_IDLE, STATE_DISPLAY} enum {STATE_INIT, STATE_IDLE, STATE_DISPLAY}
var state: int = STATE_INIT var state: int = STATE_INIT
func quest_notfication(title, desc): func quest_notfication(title, desc):
queue.push_back({"type": N_QUEST, "title": title, "desc": desc}) queue.push_back({"type": N_QUEST, "title": title, "desc": desc})
func quest_complete_notfication(title, desc):
queue.push_back({"type": N_QUEST_COMPLETE, "title": title, "desc": desc})
func _process(delta): func _process(delta):
match(state): match(state):
STATE_INIT: STATE_INIT:
@@ -49,6 +53,11 @@ func _process(delta):
get_node("/root/main").add_child(qn) get_node("/root/main").add_child(qn)
qn.display_notification(data.title, data.desc) qn.display_notification(data.title, data.desc)
time_count = 0.0 time_count = 0.0
N_QUEST_COMPLETE:
qn = quest_complete_notification_scene.instance()
get_node("/root/main").add_child(qn)
qn.display_notification(data.title)
time_count = 0.0
state = STATE_IDLE state = STATE_IDLE
if time_count < 2000.0: if time_count < 2000.0:
time_count += delta time_count += delta

View File

@@ -1,21 +1,21 @@
extends Node extends Node
signal complete signal complete
var map_width = 768 var map_width = 1280
var map_height = 768 var map_height = 1280
var map_rect = Rect2(0, 0, map_width, map_height) var map_rect = Rect2(0, 0, map_width, map_height)
enum {STATE_INIT, STATE_ITERATION, STATE_EDGES1, STATE_EDGES2, STATE_EDGES3, STATE_POLYGONS1, STATE_POLYGONS2, STATE_COMPLETE} enum {STATE_INIT, STATE_ITERATION, STATE_EDGES1, STATE_EDGES2, STATE_EDGES3, STATE_POLYGONS1, STATE_POLYGONS2, STATE_COMPLETE}
var state = STATE_INIT var state = STATE_INIT
var min_distance = 3.0 var min_distance = 12.0
var pgrow = 0.5 var pgrow = 0.5
var rules = {} var rules = {}
var edges = [] var edges = []
var pos2vertex = {} var pos2vertex = {}
var points = [] var lot_points = []
var triangles = [] var lot_triangles = []
var pos2edge = {} var pos2edge = {}
var road_width: float = 6.0 var road_width: float = 6.0
var pos2id = {} var pos2id = {}
@@ -24,148 +24,278 @@ var maxpos = Vector2()
var vertex_queue = [] var vertex_queue = []
var vertices = [] var vertices = []
var front = [] var front = []
var polygons = [] var lots: Lots
var extra_points = []
var polygon_queue = []
var road_points:PoolVector2Array = PoolVector2Array()
class PointDB: class Lots:
var _points: PoolVector2Array = PoolVector2Array() enum {LOT_FOREST, LOT_AIRPORT, LOT_PARK, LOT_CEMETERY, LOT_RESIDENTAL, LOT_INDUSTRIAL}
var _triangles: PoolIntArray = PoolIntArray() var lot_types = {
var _grid: Array = [] "forest": {
var _grid_size: int = -1 "w": 500,
var grid_w: int "h": 500,
var grid_h: int "type": LOT_FOREST,
var grid_offset: Vector2 "center_distance": 400.0
var _edges = {} },
var _eid2id = {} "airport": {
var _id2data = {} "w": 500,
var _id2pos = {} "h": 500,
var _pos2id = {} "type": LOT_AIRPORT,
var _id2edge = {} "center_distance": 400.0
var _edge2data = {} },
func build_grid(points: Array, grid_size: int): "park": {
_points = points "w": 300,
_triangles = Geometry.triangulate_delaunay_2d(_points) "h": 300,
_grid_size = grid_size "type": LOT_PARK,
_pos2id.clear() "center_distance": 0.0
_id2pos.clear() },
_id2data.clear() "cemetery": {
_id2edge.clear() "w": 200,
_grid.clear() "h": 200,
_edges.clear() "type": LOT_CEMETERY,
_edge2data.clear() "center_distance": 0.0
var rect: Rect2 = Rect2() },
for p in range(_points.size()): "residental1": {
rect = rect.expand(_points[p]) "w": 100,
_pos2id[_points[p]] = p "h": 100,
_id2pos[p] = _points[p] "type": LOT_RESIDENTAL,
rect.position.x = floor(rect.position.x / grid_size - 1) * grid_size "center_distance": 0.0
rect.position.y = floor(rect.position.x / grid_size - 1) * grid_size },
rect.size.x = ceil(rect.size.x / grid_size + 1) * grid_size "residental2": {
rect.size.y = ceil(rect.size.x / grid_size + 1) * grid_size "w": 50,
grid_w = int((rect.size.x + 1)/ grid_size) "h": 50,
grid_h = int((rect.size.x + 1)/ grid_size) "type": LOT_RESIDENTAL,
grid_offset = rect.position "center_distance": 0.0
_grid.resize((grid_w + 1) * (grid_h + 1)) },
for p in range(_points.size()): "residental3": {
var grid_x = int((_points[p].x - grid_offset.x) / grid_size) "w": 20,
var grid_y = int((_points[p].y - grid_offset.y) / grid_size) "h": 20,
if !_grid[grid_w * grid_y + grid_x]: "type": LOT_RESIDENTAL,
_grid[grid_w * grid_y + grid_x] = PoolIntArray() "center_distance": 0.0
_grid[grid_w * grid_y + grid_x].push_back(p) },
for tri in range(0, _triangles.size(), 3): "industrial": {
var p1 = _triangles[tri + 0] "w": 100,
var p2 = _triangles[tri + 1] "h": 100,
var p3 = _triangles[tri + 2] "type": LOT_RESIDENTAL,
add_edge_id(p1, p2) "center_distance": 200.0
add_edge_id(p2, p3) },
add_edge_id(p3, p1) }
func add_point_data(p: Vector2, data: Dictionary): var lots = []
if _pos2id.has(p): func make_lot_polygon(lot_name: String):
_id2data[_pos2id[p]] = data var lot_type = lot_types[lot_name]
else: var p1 = Vector2(-lot_type.w * 0.5, -lot_type.h * 0.5)
breakpoint var p2 = Vector2(lot_type.w * 0.5, -lot_type.h * 0.5)
print_debug("Bad point added") var p3 = Vector2(lot_type.w * 0.5, lot_type.h * 0.5)
func get_point_data(p: Vector2) -> Dictionary: var p4 = Vector2(-lot_type.w * 0.5, lot_type.h * 0.5)
if _pos2id.has(p): return [p1, p2, p3, p4]
return _id2data[_pos2id[p]] # func get_polygon_center(polygon):
else: # var ret: Vector2 = Vector2()
return {} # for m in range(polygon.size()):
func add_edge_id(a: int, b: int): # ret += polygon[m]
var edge_id = hash([a, b]) # return ret / 4.0
_edges[edge_id] = [a, b] func get_lot_transform(p1: Vector2, p2: Vector2, road_width: float, sidewalk_width: float, polygon: Array):
if _id2edge.has(a): var n = (p2-p1).tangent().normalized()
_id2edge[a].push_back(edge_id) var offset1 = n * (road_width + sidewalk_width)
else: var offset2 = Vector2()
_id2edge[a] = [edge_id] for v in range(polygon.size()):
if _id2edge.has(b): if offset2.x < polygon[v].x:
_id2edge[b].push_back(edge_id) offset2.x = polygon[v].x
else: if offset2.y < polygon[v].y:
_id2edge[b] = [edge_id] offset2.y = polygon[v].y
func add_edge(a: Vector2, b: Vector2): var ret = Transform2D((p2 - p1).angle(), p1.linear_interpolate(p2, 0.5) + offset1 + offset2)
if _pos2id.has(a) && _pos2id.has(b):
add_edge_id(_pos2id[a], _pos2id[b])
else:
breakpoint
print_debug("Bad edge added")
func add_edge_data(a: Vector2, b: Vector2, data: Dictionary):
assert a in _points
assert b in _points
var ai = _pos2id[a]
var bi = _pos2id[b]
var edge_id = hash([ai, bi])
var edge_id_rev = hash([bi, ai])
if _edges.has(edge_id):
_edge2data[edge_id] = data
return true
elif _edges.has(edge_id_rev):
_edge2data[edge_id_rev] = data
return true
else:
print_debug("No such edge ", [a, b])
return false
func get_edge_data(a: Vector2, b: Vector2) -> Dictionary:
var ai = _pos2id[a]
var bi = _pos2id[b]
var edge_id = hash([ai, bi])
var edge_id_rev = hash([bi, ai])
if _edge2data.has(edge_id):
return _edge2data[edge_id]
elif _edge2data.has(edge_id_rev):
return _edge2data[edge_id_rev]
else:
return {}
func get_point_edges(a: Vector2) -> Array:
var ret : = []
var edges = _id2edge[_pos2id[a]]
for e in edges:
var ed = _edges[e]
ret.push_back([_id2pos[ed[0]], _id2pos[ed[1]]])
return ret
func get_polygons() -> Array:
var ret = []
for t in range(0, _triangles.size(), 3):
var p1 = _points[_triangles[t + 0]]
var p2 = _points[_triangles[t + 1]]
var p3 = _points[_triangles[t + 2]]
ret.push_back([p1, p2, p3, get_edge_data(p1, p2), get_edge_data(p2, p3), get_edge_data(p3, p1)])
return ret return ret
func transformed_polygon(xform: Transform2D, polygon: Array):
return Array(Geometry.transform_points_2d(PoolVector2Array(polygon), xform))
func polygon_intersects_road(polygon, vertices):
for v in range(vertices.size()):
var p1 = vertices[v].pos
for k in vertices[v]._neighbors:
var p2 = vertices[k].pos
if Geometry.segment_intersects_segment_2d(p1, p2, polygon[0], polygon[1]):
return true
if Geometry.segment_intersects_segment_2d(p1, p2, polygon[1], polygon[2]):
return true
if Geometry.segment_intersects_segment_2d(p1, p2, polygon[2], polygon[3]):
return true
if Geometry.segment_intersects_segment_2d(p1, p2, polygon[3], polygon[0]):
return true
if Geometry.point_is_inside_triangle(p1, polygon[0], polygon[1], polygon[2]):
return true
if Geometry.point_is_inside_triangle(p1, polygon[0], polygon[2], polygon[3]):
return true
if Geometry.point_is_inside_triangle(p2, polygon[0], polygon[1], polygon[2]):
return true
if Geometry.point_is_inside_triangle(p2, polygon[0], polygon[2], polygon[3]):
return true
return false
func generate_lots(vertices, road_width, sidewalk_width, map_width, map_height):
for v in range(vertices.size()):
var p1 = vertices[v].pos
for k in vertices[v]._neighbors:
for d in range(10):
var p2 = vertices[k].pos
var lot_type_name = lot_types.keys()[randi() % lot_types.keys().size()]
var polygon = make_lot_polygon(lot_type_name)
var xform = get_lot_transform(p1, p2, road_width, sidewalk_width, polygon)
if polygon_intersects_road(transformed_polygon(xform, polygon), vertices):
continue
var xfpoly = transformed_polygon(xform, polygon)
var bad = false
for r in lots:
var poly2 = transformed_polygon(r.xform, r.polygon)
if Geometry.intersect_polygons_2d(xfpoly, poly2).size() > 0:
bad = true
break
if xform.origin.distance_to(Vector2(map_width * 0.5, map_height * 0.5)) < lot_types[lot_type_name].center_distance:
bad = true
if bad:
continue
lots.push_back({
"polygon": polygon,
"xform": xform
})
break
#class PointDB:
# var _points: PoolVector2Array = PoolVector2Array()
# var _triangles: PoolIntArray = PoolIntArray()
# var _grid: Array = []
# var _grid_size: int = -1
# var grid_w: int
# var grid_h: int
# var grid_offset: Vector2
# var _edges = {}
# var _eid2id = {}
# var _id2data = {}
# var _id2pos = {}
# var _pos2id = {}
# var _id2edge = {}
# var _edge2data = {}
# func build_grid(points: Array, grid_size: int):
# _points = points
# _triangles = Geometry.triangulate_delaunay_2d(_points)
# _grid_size = grid_size
# _pos2id.clear()
# _id2pos.clear()
# _id2data.clear()
# _id2edge.clear()
# _grid.clear()
# _edges.clear()
# _edge2data.clear()
# var rect: Rect2 = Rect2()
# for p in range(_points.size()):
# rect = rect.expand(_points[p])
# _pos2id[_points[p]] = p
# _id2pos[p] = _points[p]
# rect.position.x = floor(rect.position.x / grid_size - 1) * grid_size
# rect.position.y = floor(rect.position.x / grid_size - 1) * grid_size
# rect.size.x = ceil(rect.size.x / grid_size + 1) * grid_size
# rect.size.y = ceil(rect.size.x / grid_size + 1) * grid_size
# grid_w = int((rect.size.x + 1)/ grid_size)
# grid_h = int((rect.size.x + 1)/ grid_size)
# grid_offset = rect.position
# _grid.resize((grid_w + 1) * (grid_h + 1))
# for p in range(_points.size()):
# var grid_x = int((_points[p].x - grid_offset.x) / grid_size)
# var grid_y = int((_points[p].y - grid_offset.y) / grid_size)
# if !_grid[grid_w * grid_y + grid_x]:
# _grid[grid_w * grid_y + grid_x] = PoolIntArray()
# _grid[grid_w * grid_y + grid_x].push_back(p)
# for tri in range(0, _triangles.size(), 3):
# var p1 = _triangles[tri + 0]
# var p2 = _triangles[tri + 1]
# var p3 = _triangles[tri + 2]
# add_edge_id(p1, p2)
# add_edge_id(p2, p3)
# add_edge_id(p3, p1)
# func add_point_data(p: Vector2, data: Dictionary):
# if _pos2id.has(p):
# _id2data[_pos2id[p]] = data
# else:
# breakpoint
# print_debug("Bad point added")
# func get_point_data(p: Vector2) -> Dictionary:
# if _pos2id.has(p):
# return _id2data[_pos2id[p]]
# else:
# return {}
# func add_edge_id(a: int, b: int):
# var edge_id = hash([a, b])
# _edges[edge_id] = [a, b]
# if _id2edge.has(a):
# _id2edge[a].push_back(edge_id)
# else:
# _id2edge[a] = [edge_id]
# if _id2edge.has(b):
# _id2edge[b].push_back(edge_id)
# else:
# _id2edge[b] = [edge_id]
# func add_edge(a: Vector2, b: Vector2):
# if _pos2id.has(a) && _pos2id.has(b):
# add_edge_id(_pos2id[a], _pos2id[b])
# else:
# breakpoint
# print_debug("Bad edge added")
# func add_edge_data(a: Vector2, b: Vector2, data: Dictionary):
# assert a in _points
# assert b in _points
# var ai = _pos2id[a]
# var bi = _pos2id[b]
# var edge_id = hash([ai, bi])
# var edge_id_rev = hash([bi, ai])
# if _edges.has(edge_id):
# _edge2data[edge_id] = data
# return true
# elif _edges.has(edge_id_rev):
# _edge2data[edge_id_rev] = data
# return true
# else:
# print_debug("No such edge ", [a, b])
# return false
# func get_edge_data(a: Vector2, b: Vector2) -> Dictionary:
# var ai = _pos2id[a]
# var bi = _pos2id[b]
# var edge_id = hash([ai, bi])
# var edge_id_rev = hash([bi, ai])
# if _edge2data.has(edge_id):
# return _edge2data[edge_id]
# elif _edge2data.has(edge_id_rev):
# return _edge2data[edge_id_rev]
# else:
# return {}
# func get_point_edges(a: Vector2) -> Array:
# var ret : = []
# var edges = _id2edge[_pos2id[a]]
# for e in edges:
# var ed = _edges[e]
# ret.push_back([_id2pos[ed[0]], _id2pos[ed[1]]])
# return ret
# func get_polygons() -> Array:
# var ret = []
# for t in range(0, _triangles.size(), 3):
# var p1 = _points[_triangles[t + 0]]
# var p2 = _points[_triangles[t + 1]]
# var p3 = _points[_triangles[t + 2]]
# ret.push_back([p1, p2, p3, get_edge_data(p1, p2), get_edge_data(p2, p3), get_edge_data(p3, p1)])
# return ret
var rnd: RandomNumberGenerator var rnd: RandomNumberGenerator
var noise: OpenSimplexNoise var noise: OpenSimplexNoise
var complete = false var complete = false
var db: PointDB #var db: PointDB
var axiom = [ var axiom = [
new_vertex(10, 10), new_vertex(10, 10),
new_vertex(30, 30), new_vertex(60, 10),
new_vertex(50, 50), new_vertex(110, 10),
new_vertex(10, 70), new_vertex(110, 60),
new_vertex(80, 100), new_vertex(110, 110),
new_vertex(240, 100), new_vertex(110, 160),
new_vertex(280, 100) new_vertex(60, 160),
new_vertex(10, 160),
new_vertex(10, 110),
new_vertex(10, 60),
] ]
@@ -176,12 +306,9 @@ func cleanup():
vertices.clear() vertices.clear()
edges.clear() edges.clear()
pos2vertex.clear() pos2vertex.clear()
points.clear()
triangles.clear()
pos2edge.clear() pos2edge.clear()
pos2id.clear() pos2id.clear()
front.clear() front.clear()
polygons.clear()
func new_vertex(x, y): func new_vertex(x, y):
return { return {
@@ -331,6 +458,8 @@ func convert_vertices():
for e in range(vertices.size()): for e in range(vertices.size()):
vertices[e]._neighbors = [] vertices[e]._neighbors = []
for h in vertices[e].neighbors: for h in vertices[e].neighbors:
assert h
# print(pos2vertex[h.pos])
vertices[e]._neighbors.push_back(pos2vertex[h.pos]._index) vertices[e]._neighbors.push_back(pos2vertex[h.pos]._index)
func has_neighbor(v, n): func has_neighbor(v, n):
var ret = false var ret = false
@@ -577,27 +706,29 @@ func adjacent_edges(e1, e2):
return true return true
else: else:
return false return false
func check_triangles(): #func check_triangles():
for t in triangles: # for t in triangles:
if !adjacent_edges(t[0], t[1]): # if !adjacent_edges(t[0], t[1]):
return false # return false
if !adjacent_edges(t[1], t[2]): # if !adjacent_edges(t[1], t[2]):
return false # return false
if !adjacent_edges(t[2], t[0]): # if !adjacent_edges(t[2], t[0]):
return false # return false
return true # return true
func build(rnd_seed): func build(rnd_seed):
cleanup() cleanup()
rnd.seed = rnd_seed rnd.seed = rnd_seed
noise.seed = rnd_seed noise.seed = rnd_seed
for k in axiom: for k in range(axiom.size()):
for l in axiom: var cur = k
if k == l: var next = (k + 1) % axiom.size()
continue if !axiom[cur] in axiom[next].neighbors:
k.neighbors.push_back(l) axiom[next].neighbors.push_back(axiom[cur])
k.axiom = true if !axiom[next] in axiom[cur].neighbors:
vertices.push_back(k) axiom[cur].neighbors.push_back(axiom[next])
axiom[cur].axiom = true
vertices.push_back(axiom[k])
for k in vertices: for k in vertices:
if minpos.x > k.pos.x: if minpos.x > k.pos.x:
minpos.x = k.pos.x minpos.x = k.pos.x
@@ -677,39 +808,39 @@ func get_height(x, y):
const sidewalk_width = 1.5 const sidewalk_width = 1.5
#var potential_edges = [] #var potential_edges = []
func implode_road(): #func implode_road():
# for t in range(0, db._triangles.size(), 3): ## for t in range(0, db._triangles.size(), 3):
#
# potential_edges.clear() ## potential_edges.clear()
for v in vertices: # for v in vertices:
for n in v._neighbors: # for n in v._neighbors:
var p1 = v.pos # var p1 = v.pos
var p2 = vertices[n].pos # var p2 = vertices[n].pos
var dir = (p2 - p1).normalized() # var dir = (p2 - p1).normalized()
var t = dir.tangent() # var t = dir.tangent()
for offset in [-road_width - sidewalk_width, # for offset in [-road_width - sidewalk_width,
-road_width, # -road_width,
road_width, # road_width,
road_width + sidewalk_width]: # road_width + sidewalk_width]:
var ep1 = p1 + offset # var ep1 = p1 + offset
var ep2 = p2 + offset # var ep2 = p2 + offset
for p in [ep1, ep2]: # for p in [ep1, ep2]:
if !p in extra_points && !p in points: # if !p in extra_points && !p in points:
extra_points.push_back(p) # extra_points.push_back(p)
if !p in road_points: # if !p in road_points:
road_points.push_back(p) # road_points.push_back(p)
for offset in [-road_width - sidewalk_width - 0.1, # for offset in [-road_width - sidewalk_width - 0.1,
road_width + sidewalk_width + 0.1]: # road_width + sidewalk_width + 0.1]:
var ep1 = p1 + offset # var ep1 = p1 + offset
var ep2 = p2 + offset # var ep2 = p2 + offset
for p in [ep1, ep2]: # for p in [ep1, ep2]:
if !p in extra_points && !p in points: # if !p in extra_points && !p in points:
extra_points.push_back(p) # extra_points.push_back(p)
#
if !p1 in road_points: # if !p1 in road_points:
road_points.push_back(p1) # road_points.push_back(p1)
if !p2 in road_points: # if !p2 in road_points:
road_points.push_back(p2) # road_points.push_back(p2)
# potential_edges.push_back([p1, ep1]) # potential_edges.push_back([p1, ep1])
# potential_edges.push_back([p1, ep2]) # potential_edges.push_back([p1, ep2])
# potential_edges.push_back([p2, ep3]) # potential_edges.push_back([p2, ep3])
@@ -738,126 +869,126 @@ func implode_road():
func build_simple_mesh(): #func build_simple_mesh():
var arrays = [] # var arrays = []
var verts = PoolVector3Array() # var verts = PoolVector3Array()
var normals = PoolVector3Array() # var normals = PoolVector3Array()
arrays.resize(ArrayMesh.ARRAY_MAX) # arrays.resize(ArrayMesh.ARRAY_MAX)
var mesh = ArrayMesh.new() # var mesh = ArrayMesh.new()
for p in polygons: # for p in polygons:
for v in p.vertices: # for v in p.vertices:
var v3d = Vector3() # var v3d = Vector3()
v3d.x = v.x - float(map_width) / 2.0 # v3d.x = v.x - float(map_width) / 2.0
v3d.z = v.x - float(map_height) / 2.0 # v3d.z = v.x - float(map_height) / 2.0
v3d.y = 0 # v3d.y = 0
verts.push_back(v3d) # verts.push_back(v3d)
normals.push_back(Vector3(1, 1, 1)) # normals.push_back(Vector3(1, 1, 1))
arrays[ArrayMesh.ARRAY_VERTEX] = verts # arrays[ArrayMesh.ARRAY_VERTEX] = verts
arrays[ArrayMesh.ARRAY_NORMAL] = normals # arrays[ArrayMesh.ARRAY_NORMAL] = normals
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays) # mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays)
return mesh # return mesh
func build_d_mesh(): #func build_d_mesh():
var arrays = [] # var arrays = []
var verts = PoolVector3Array() # var verts = PoolVector3Array()
var normals = PoolVector3Array() # var normals = PoolVector3Array()
var indices = PoolIntArray(Geometry.triangulate_delaunay_2d(points)) # var indices = PoolIntArray(Geometry.triangulate_delaunay_2d(points))
arrays.resize(ArrayMesh.ARRAY_MAX) # arrays.resize(ArrayMesh.ARRAY_MAX)
var mesh = ArrayMesh.new() # var mesh = ArrayMesh.new()
for v in points: # for v in points:
var v3d = Vector3() # var v3d = Vector3()
v3d.x = v.x - float(map_width) / 2.0 # v3d.x = v.x - float(map_width) / 2.0
v3d.z = v.x - float(map_height) / 2.0 # v3d.z = v.x - float(map_height) / 2.0
v3d.y = 0 # v3d.y = 0
verts.push_back(v3d) # verts.push_back(v3d)
normals.push_back(Vector3(1, 1, 1)) # normals.push_back(Vector3(1, 1, 1))
arrays[ArrayMesh.ARRAY_VERTEX] = verts # arrays[ArrayMesh.ARRAY_VERTEX] = verts
arrays[ArrayMesh.ARRAY_NORMAL] = normals # arrays[ArrayMesh.ARRAY_NORMAL] = normals
arrays[ArrayMesh.ARRAY_INDEX] = indices # arrays[ArrayMesh.ARRAY_INDEX] = indices
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays) # mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays)
return mesh # return mesh
func build_mesh(aabb: AABB, vn: Node): #func build_mesh(aabb: AABB, vn: Node):
var polylist = [] # var polylist = []
var mesh_aabb = AABB() # var mesh_aabb = AABB()
var rect = Rect2(aabb.position.x + map_width / 2.0, # var rect = Rect2(aabb.position.x + map_width / 2.0,
aabb.position.z + map_width / 2.0, aabb.size.x, aabb.size.z) # aabb.position.z + map_width / 2.0, aabb.size.x, aabb.size.z)
for p in polygons: # for p in polygons:
for v in p.vertices: # for v in p.vertices:
# print(v) ## print(v)
if rect.has_point(v) || true: # if rect.has_point(v) || true:
polylist.push_back(p) # polylist.push_back(p)
break # break
var verts_road = PoolVector3Array() # var verts_road = PoolVector3Array()
var indices_road = PoolIntArray() # var indices_road = PoolIntArray()
var normals_road = PoolVector3Array() # var normals_road = PoolVector3Array()
var verts_lot = PoolVector3Array() # var verts_lot = PoolVector3Array()
var indices_lot = PoolIntArray() # var indices_lot = PoolIntArray()
var normals_lot = PoolVector3Array() # var normals_lot = PoolVector3Array()
var mesh = ArrayMesh.new() # var mesh = ArrayMesh.new()
var arrays_roads = [] # var arrays_roads = []
var arrays_lots = [] # var arrays_lots = []
arrays_roads.resize(ArrayMesh.ARRAY_MAX) # arrays_roads.resize(ArrayMesh.ARRAY_MAX)
arrays_lots.resize(ArrayMesh.ARRAY_MAX) # arrays_lots.resize(ArrayMesh.ARRAY_MAX)
var idx_road = 0 # var idx_road = 0
var idx_lot = 0 # var idx_lot = 0
for p in polylist: # for p in polylist:
var vid = 0 # var vid = 0
for v in p.vertices: # for v in p.vertices:
# var v = p.vertices[e.indices[0]] ## var v = p.vertices[e.indices[0]]
var v3d = Vector3() # var v3d = Vector3()
v3d.x = v.x - float(map_width) / 2.0 # v3d.x = v.x - float(map_width) / 2.0
v3d.z = v.x - float(map_height) / 2.0 # v3d.z = v.x - float(map_height) / 2.0
v3d.y = get_height(v3d.x, v3d.z) # v3d.y = get_height(v3d.x, v3d.z)
v3d.y = 0 # v3d.y = 0
v3d *= 0.005 # v3d *= 0.005
mesh_aabb = mesh_aabb.expand(v3d) # mesh_aabb = mesh_aabb.expand(v3d)
if p.road: # if p.road:
verts_road.push_back(v3d) # verts_road.push_back(v3d)
normals_road.push_back(Vector3(0, 1, 0)) # normals_road.push_back(Vector3(0, 1, 0))
indices_road.push_back(idx_road + vid) # indices_road.push_back(idx_road + vid)
else: # else:
verts_lot.push_back(v3d) # verts_lot.push_back(v3d)
normals_lot.push_back(Vector3(0, 1, 0)) # normals_lot.push_back(Vector3(0, 1, 0))
indices_lot.push_back(idx_lot + vid) # indices_lot.push_back(idx_lot + vid)
vid += 1 # vid += 1
if p.road: # if p.road:
idx_road += 3 # idx_road += 3
else: # else:
idx_lot += 3 # idx_lot += 3
print(verts_lot.size()) # print(verts_lot.size())
print(verts_lot)
# print(indices_lot)
# print(mesh_aabb)
arrays_roads[ArrayMesh.ARRAY_VERTEX] = verts_road
# arrays_roads[ArrayMesh.ARRAY_NORMAL] = normals_road
# arrays_roads[ArrayMesh.ARRAY_INDEX] = indices_road
arrays_lots[ArrayMesh.ARRAY_VERTEX] = verts_lot
# arrays_lots[ArrayMesh.ARRAY_NORMAL] = normals_lot
# arrays_lots[ArrayMesh.ARRAY_INDEX] = indices_lot
# print(verts_lot) # print(verts_lot)
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays_roads) ## print(indices_lot)
# arrays_lots[ArrayMesh.ARRAY_VERTEX] = PoolVector3Array([Vector3(-1, -1, -1), Vector3(0, 0, 0), Vector3(0, 0, 1)]) ## print(mesh_aabb)
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays_lots) # arrays_roads[ArrayMesh.ARRAY_VERTEX] = verts_road
# mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, PlaneMesh.new().get_mesh_arrays()) ## arrays_roads[ArrayMesh.ARRAY_NORMAL] = normals_road
var mat = SpatialMaterial.new() ## arrays_roads[ArrayMesh.ARRAY_INDEX] = indices_road
mat.params_cull_mode = SpatialMaterial.CULL_DISABLED # arrays_lots[ArrayMesh.ARRAY_VERTEX] = verts_lot
mesh.surface_set_material(0, mat) ## arrays_lots[ArrayMesh.ARRAY_NORMAL] = normals_lot
mesh.surface_set_material(1, mat) ## arrays_lots[ArrayMesh.ARRAY_INDEX] = indices_lot
mesh.custom_aabb = mesh_aabb ## print(verts_lot)
var mi = MeshInstance.new() # mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays_roads)
vn.add_child(mi) ## arrays_lots[ArrayMesh.ARRAY_VERTEX] = PoolVector3Array([Vector3(-1, -1, -1), Vector3(0, 0, 0), Vector3(0, 0, 1)])
mi.mesh = mesh # mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays_lots)
## mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, PlaneMesh.new().get_mesh_arrays())
return mesh # var mat = SpatialMaterial.new()
# mat.params_cull_mode = SpatialMaterial.CULL_DISABLED
# mesh.surface_set_material(0, mat)
# mesh.surface_set_material(1, mat)
# mesh.custom_aabb = mesh_aabb
# var mi = MeshInstance.new()
# vn.add_child(mi)
# mi.mesh = mesh
#
# return mesh
func _ready(): func _ready():
set_process(false) set_process(false)
rules.grid = GridRule.new() rules.grid = GridRule.new()
rnd = RandomNumberGenerator.new() rnd = RandomNumberGenerator.new()
noise = OpenSimplexNoise.new() noise = OpenSimplexNoise.new()
db = PointDB.new() # db = PointDB.new()
func inset_point(v: Dictionary, n:Dictionary, new_pos: Vector2): func inset_point(v: Dictionary, n:Dictionary, new_pos: Vector2):
var nv = new_vertex(new_pos.x, new_pos.y) var nv = new_vertex(new_pos.x, new_pos.y)
@@ -1009,36 +1140,40 @@ func _process(delta):
print("vertex num: ", vertices.size()) print("vertex num: ", vertices.size())
STATE_EDGES1: STATE_EDGES1:
print_debug("iteration finished") print_debug("iteration finished")
var ax_verts = [] # var ax_verts = []
for k in vertices: # for k in vertices:
if k.has("axiom") && k.axiom == true: # if k.has("axiom") && k.axiom == true:
for l in vertices: # for l in vertices:
if l == k: # if l == k:
continue # continue
if k in l.neighbors: # if k in l.neighbors:
l.neighbors.erase(k) # l.neighbors.erase(k)
ax_verts.push_back(k) # ax_verts.push_back(k)
for v in ax_verts: # for v in ax_verts:
vertices.erase(v) # vertices.erase(v)
print_debug("cleanup finished") # print_debug("cleanup finished")
convert_vertices() convert_vertices()
print_debug("conversion finished") print_debug("conversion finished")
state = STATE_EDGES2 state = STATE_EDGES2
STATE_EDGES2: STATE_EDGES2:
points = [] for v in range(vertices.size()):
for k in vertices: var vdata = VertexData.new(roadmap.vertices[v], roadmap.road_width, roadmap.sidewalk_width)
points.push_back(k.pos) vertices[v]._vdata = vdata
db = PointDB.new() vertices[v]._points = vdata.get_all_road_points(vertices)
db.build_grid(points, 64) # points = []
print_debug("points: ", points.size()) # for k in vertices:
assert points.size() == db._points.size() # points.push_back(k.pos)
for v in vertices: # db = PointDB.new()
assert db._pos2id.has(v.pos) # db.build_grid(points, 64)
for v in vertices: # print_debug("points: ", points.size())
for n in v.neighbors: # assert points.size() == db._points.size()
assert db._pos2id.has(n.pos) # for v in vertices:
print_debug("data tests passed") # assert db._pos2id.has(v.pos)
print(points.size(), " ", db._points.size()) # for v in vertices:
# for n in v.neighbors:
# assert db._pos2id.has(n.pos)
# print_debug("data tests passed")
# print(points.size(), " ", db._points.size())
# for e in range(vertices.size()): # for e in range(vertices.size()):
# for h in vertices[e]._neighbors: # for h in vertices[e]._neighbors:
@@ -1046,6 +1181,15 @@ func _process(delta):
# print_debug("edges added") # print_debug("edges added")
state = STATE_EDGES3 state = STATE_EDGES3
STATE_EDGES3: STATE_EDGES3:
for v in range(vertices.size()):
for entry in range(vertices[v]._points.size()):
var points = vertices[v]._points[entry].points_total
var points_3d = []
for p in points:
var p3d = Vector3(p.x - map_width * 0.5, get_height(p.x - map_width * 0.5, p.y - map_height * 0.5), p.y - map_height * 0.5)
points_3d.push_back(p3d)
vertices[v]._points[entry].points3d = points_3d
# implode_road() # implode_road()
# print(points.size(), " ", extra_points.size()) # print(points.size(), " ", extra_points.size())
# adjust_triangles() # adjust_triangles()
@@ -1056,23 +1200,23 @@ func _process(delta):
# db.build_grid(points,64) # db.build_grid(points,64)
# print_debug("edges3") # print_debug("edges3")
# #
var bad_edges = [] # var bad_edges = []
for v in vertices: # for v in vertices:
for n in v.neighbors: # for n in v.neighbors:
# print(points.size(), " ", db._points.size()) ## print(points.size(), " ", db._points.size())
assert points.size() == db._points.size() # assert points.size() == db._points.size()
assert v.pos in points # assert v.pos in points
assert n.pos in points # assert n.pos in points
assert v.pos in db._points # assert v.pos in db._points
assert n.pos in db._points # assert n.pos in db._points
if !db.add_edge_data(v.pos, n.pos, {"road": true}): # if !db.add_edge_data(v.pos, n.pos, {"road": true}):
bad_edges.push_back([v._index, n._index]) # bad_edges.push_back([v._index, n._index])
if bad_edges.size() > 0: # if bad_edges.size() > 0:
print("bad edges: ", bad_edges, " ", bad_edges.size()) # print("bad edges: ", bad_edges, " ", bad_edges.size())
for pe in extra_points: # for pe in extra_points:
var e = db.get_point_edges(pe) # var e = db.get_point_edges(pe)
for d in e: # for d in e:
db.add_edge_data(d[0], d[1], {"road": true}) # db.add_edge_data(d[0], d[1], {"road": true})
# for e in bad_edges: # for e in bad_edges:
# var p1: Vector2 = vertices[e[0]].pos # var p1: Vector2 = vertices[e[0]].pos
# var p2: Vector2 = vertices[e[1]].pos # var p2: Vector2 = vertices[e[1]].pos
@@ -1113,6 +1257,9 @@ func _process(delta):
# print("bad triangles") # print("bad triangles")
# print(triangulation) # print(triangulation)
STATE_POLYGONS1: STATE_POLYGONS1:
lots = Lots.new()
lots.generate_lots(vertices, road_width, sidewalk_width, map_width, map_height)
# db = LotsDB.new(vertices, road_width, sidewalk_width)
# polygon_queue = db.get_polygons() # polygon_queue = db.get_polygons()
# for r in range(polygon_queue.size()): # for r in range(polygon_queue.size()):
# if polygon_queue[r].size() == 6: # if polygon_queue[r].size() == 6:

View File

@@ -127,6 +127,15 @@ var raycasts : = {
"left": {}, "left": {},
"right": {} "right": {}
} }
func is_overshooting():
if _path.size() < 2:
return false
var p = _path[0]
var facing = -global_transform.basis[2]
var dir = (_path[0] - global_transform.origin).normalized()
if facing.dot(dir) <= 0:
return true
return false
func _physics_process(delta): func _physics_process(delta):
var space := get_world().direct_space_state var space := get_world().direct_space_state
var ray_origin : = global_transform.origin + Vector3(0.0, 0.5, 1.0) var ray_origin : = global_transform.origin + Vector3(0.0, 0.5, 1.0)
@@ -183,7 +192,7 @@ func _physics_process(delta):
orientation *= controls.frame_tf orientation *= controls.frame_tf
controls.frame_tf = Transform() controls.frame_tf = Transform()
if _path && _path.size() > 0: if _path && _path.size() > 0:
while _path.size() > 0 && _path[0].distance_to(global_transform.origin) < 0.5: while (_path.size() > 0 && _path[0].distance_to(global_transform.origin) < 0.5) || is_overshooting():
_path.pop_front() _path.pop_front()
if _path.size() > 0: if _path.size() > 0:
var next: Vector3 = _path[0] var next: Vector3 = _path[0]

View File

@@ -25,6 +25,8 @@ func update_quests():
q.update() q.update()
func start_quest(quest: Quest): func start_quest(quest: Quest):
notifications.quest_notfication(quest.get_title(), quest.get_description()) notifications.quest_notfication(quest.get_title(), quest.get_description())
func complete_quest(quest: Quest):
notifications.quest_complete_notfication(quest.get_title(), quest.get_description())
func start_interaction(obj): func start_interaction(obj):
print("started interaction") print("started interaction")
@@ -133,15 +135,20 @@ func _ready():
# cd.scene.set_meta("data", cd) # cd.scene.set_meta("data", cd)
var tut_quest = Quest.new("Tutorial", "This quest shortly introduces to a game") var tut_quest = Quest.new("Tutorial", "This quest shortly introduces to a game")
tut_quest.connect("started", self, "start_quest") tut_quest.connect("started", self, "start_quest")
tut_quest.connect("complete", self, "complete_quest")
world.quests.push_back(tut_quest) world.quests.push_back(tut_quest)
var tut1_quest = WalkQuest.new("Walk to closet room", "Walk to closet room designated location", get_node("quest_dst_closet")) var tut1_quest = WalkQuest.new("Walk to closet room", "Walk to closet room designated location", get_node("quest_dst_closet"))
tut1_quest.connect("started", self, "start_quest") tut1_quest.connect("started", self, "start_quest")
tut1_quest.connect("complete", self, "complete_quest")
var tut2_quest = StatsQuest.new("Hire 6 team members", "Hire six team members to start with your team", {"player_count": 6}) var tut2_quest = StatsQuest.new("Hire 6 team members", "Hire six team members to start with your team", {"player_count": 6})
tut2_quest.connect("started", self, "start_quest") tut2_quest.connect("started", self, "start_quest")
tut2_quest.connect("complete", self, "complete_quest")
var tut3_quest = WalkQuest.new("Walk to gym", "Walk to gym designated location", get_node("quest_dst_gym")) var tut3_quest = WalkQuest.new("Walk to gym", "Walk to gym designated location", get_node("quest_dst_gym"))
tut3_quest.connect("started", self, "start_quest") tut3_quest.connect("started", self, "start_quest")
tut3_quest.connect("complete", self, "complete_quest")
var tut4_quest = StatsQuest.new("Train your team once", "Complete your team training once", {"team_train_count": 1}) var tut4_quest = StatsQuest.new("Train your team once", "Complete your team training once", {"team_train_count": 1})
tut4_quest.connect("started", self, "start_quest") tut4_quest.connect("started", self, "start_quest")
tut4_quest.connect("complete", self, "complete_quest")
tut1_quest.set_next_quest(tut2_quest) tut1_quest.set_next_quest(tut2_quest)
tut2_quest.set_next_quest(tut3_quest) tut2_quest.set_next_quest(tut3_quest)
tut3_quest.set_next_quest(tut4_quest) tut3_quest.set_next_quest(tut4_quest)

View File

@@ -0,0 +1,5 @@
extends Control
func display_notification(title):
$v/quest_title.text = title
show()

View File

@@ -0,0 +1,48 @@
[gd_scene load_steps=5 format=2]
[ext_resource path="res://fonts/DroidSansFallback.ttf" type="DynamicFontData" id=1]
[ext_resource path="res://ui/quest_complete_notification.gd" type="Script" id=2]
[sub_resource type="DynamicFont" id=1]
size = 35
font_data = ExtResource( 1 )
[sub_resource type="DynamicFont" id=2]
size = 30
font_data = ExtResource( 1 )
[node name="quest_complete_notification" type="Control"]
anchor_right = 1.0
anchor_bottom = 1.0
script = ExtResource( 2 )
__meta__ = {
"_edit_use_anchors_": false
}
[node name="v" type="VBoxContainer" parent="."]
anchor_left = 0.5
anchor_top = 0.5
anchor_right = 0.5
anchor_bottom = 0.5
margin_left = -129.5
margin_top = -45.5
margin_right = 129.5
margin_bottom = 45.5
__meta__ = {
"_edit_use_anchors_": false
}
[node name="msg" type="Label" parent="v"]
margin_right = 259.0
margin_bottom = 47.0
custom_fonts/font = SubResource( 1 )
text = "Quest complete!"
align = 1
[node name="quest_title" type="Label" parent="v"]
margin_top = 51.0
margin_right = 259.0
margin_bottom = 91.0
custom_fonts/font = SubResource( 2 )
text = "quest title"
align = 1