diff --git a/project.godot b/project.godot index 5fbb305..4c8af13 100644 --- a/project.godot +++ b/project.godot @@ -36,6 +36,10 @@ config/name="Societer" run/main_scene="res://world/game.tscn" config/icon="res://icon.png" +[autoload] + +Global="*res://utils/Global.gd" + [gui] common/drop_mouse_on_gui_input_disabled=true diff --git a/ui/map/map.gd b/ui/map/map.gd index bddf3f7..f840151 100644 --- a/ui/map/map.gd +++ b/ui/map/map.gd @@ -25,18 +25,7 @@ func heightmap(): if edge.get_data("river"): draw_line(edge.line()[0], edge.line()[1], Color.blue, 5.0) draw_multiline(coastline, Color.black) - - - - - - - - - - - - + func draw_triangles_edges(color=Color("#000000")): for line in terrain.get_edges_as_line(): draw_line(line[0], line[1], color) diff --git a/utils/Global.gd b/utils/Global.gd new file mode 100644 index 0000000..6ce19df --- /dev/null +++ b/utils/Global.gd @@ -0,0 +1,9 @@ +extends Node + +var debug = true + +# Debuging messages +func print_debug(message): + if debug: + print(message) + diff --git a/utils/terrain/Terrain.gd b/utils/terrain/Terrain.gd index 77e46ee..b97a366 100644 --- a/utils/terrain/Terrain.gd +++ b/utils/terrain/Terrain.gd @@ -17,21 +17,22 @@ class Triangles: func _should_continue(): return (_curr < _end) - func _iter_init(arg): + func _iter_init(_arg): _curr = 0 return _should_continue() - func _iter_next(arg): + func _iter_next(_arg): _curr += 1 return _should_continue() - func _iter_get(arg): + func _iter_get(_arg): var triangle = Triangle.new(_curr,_terrain) return triangle func size(): return _end +# Triangle object class Triangle: var _idx var _terrain @@ -85,7 +86,8 @@ class Triangle: for point in points(): polygon.append(point.point2d()) return polygon - + +# Points iterator class Points: var _terrain var _curr @@ -99,21 +101,22 @@ class Points: func _should_continue(): return (_curr < _end) - func _iter_init(arg): + func _iter_init(_arg): _curr = 0 return _should_continue() - func _iter_next(arg): + func _iter_next(_arg): _curr += 1 return _should_continue() - func _iter_get(arg): + func _iter_get(_arg): var point = Point.new(_curr,_terrain) return point func size(): return _end - + +# Point object class Point: var _idx var _terrain @@ -176,6 +179,7 @@ class Point: break return list_points +# Edges iterator class Edges: var _terrain var _curr @@ -189,21 +193,22 @@ class Edges: func _should_continue(): return (_curr < _end) - func _iter_init(arg): + func _iter_init(_arg): _curr = 0 return _should_continue() - func _iter_next(arg): + func _iter_next(_arg): _curr += 1 return _should_continue() - func _iter_get(arg): + func _iter_get(_arg): var edge = Edge.new(_curr,_terrain) return edge func size(): return _end +# Edge object class Edge: var _idx var _terrain @@ -250,11 +255,12 @@ class Edge: line.append(end().point2d()) return line -const terrain_file = "user://terrain.save" +# Terrain instance variables -var width: int -var height: int -var spacing: int +var _width: int +var _height: int +var _spacing: int +var _name: String var _points = PoolVector3Array() var _halfedges var _triangles @@ -263,70 +269,91 @@ var _data = {} var _points_data = [] var _edges_data = [] var _triangles_data = [] -var _file = File.new() -var _debug = true -""" -func general_type_of(obj): - var typ = typeof(obj) - var builtin_type_names = ["nil", "bool", "int", "real", "string", "vector2", "rect2", "vector3", "maxtrix32", "plane", "quat", "aabb", "matrix3", "transform", "color", "image", "nodepath", "rid", null, "inputevent", "dictionary", "array", "rawarray", "intarray", "realarray", "stringarray", "vector2array", "vector3array", "colorarray", "unknown"] +var _created = false +var _loaded = false +var _list = [] - if(typ == TYPE_OBJECT): - return obj.type_of() +# Terrain constructor +func _init(width:int=1600, height:int=800, spacing:int=30, create=false, name:String=""): + var terrain_dir = Directory.new() + terrain_dir.open("user://") + if not terrain_dir.dir_exists("terrain"): + terrain_dir.make_dir("terrain") + terrain_dir.change_dir("terrain") + terrain_dir.list_dir_begin() + var filename = terrain_dir.get_next() + while filename != "": + if terrain_dir.file_exists(filename): + # Ok terrain file found + var terrain = {} + var terrain_filename = "user://terrain/%s" % (filename) + var file = File.new() + file.open(terrain_filename, File.READ) + terrain["width"] = file.get_var() + terrain["height"] = file.get_var() + terrain["spacing"] = file.get_var() + terrain["name"] = file.get_var() + file.close() + _list.append(terrain) + filename = terrain_dir.get_next() + terrain_dir.list_dir_end() + + var file = File.new() + var terrain_filename = "user://terrain/terrain_%s.save" % (name) + if file.file_exists(terrain_filename) and not create: + Global.print_debug("loading : %s ..." % (name)) + load(name) else: - return builtin_type_names[typ] -""" + if name: + create(width, height, spacing, name) -func _print_debug(message): - if _debug: - print(message) - -func _init(width:int=1600, height:int=800, spacing:int=30, create=false): - if _file.file_exists(terrain_file) and not create: - _print_debug("loading...") - _load() - else: - _print_debug("Creating...") - var delaunay: Delaunator - self.width = width - self.height = height - self.spacing = spacing - _create_points() - delaunay = Delaunator.new(_points) + +func create(width:int, height:int, spacing:int, name:String): + Global.print_debug("Creating : %s ..." % (name)) + var delaunay: Delaunator + _width = width + _height = height + _spacing = spacing + _name = name + _create_points() + delaunay = Delaunator.new(_points) - _halfedges = PoolIntArray(delaunay.halfedges) - _triangles = PoolIntArray(delaunay.triangles) + _halfedges = PoolIntArray(delaunay.halfedges) + _triangles = PoolIntArray(delaunay.triangles) - # Initialize _points_to_halfedges - for edge_idx in edges(): - var edge = get_edge(edge_idx) - var endpoint = _triangles[edge.next_half().get_index()] - if (! _points_to_halfedges.has(endpoint) or _halfedges[edge_idx] == -1): - _points_to_halfedges[endpoint] = edge_idx - - # Initialise _points_data - for point_idx in points(): - _points_data.append({}) + # Initialize _points_to_halfedges + for edge in get_edges(): + var endpoint = _triangles[edge.next_half().get_index()] + if (! _points_to_halfedges.has(endpoint) or _halfedges[edge.get_index()] == -1): + _points_to_halfedges[endpoint] = edge.get_index() + + # Initialise _points_data + for point_idx in self.get_points().size(): + _points_data.append({}) - # Initialise _edges_data - for edge_idx in edges(): - _edges_data.append({}) + # Initialise _edges_data + for edge_idx in self.get_edges().size(): + _edges_data.append({}) - # Initialise _triangle_data - for triangle_idx in triangles(): - _triangles_data.append({}) - - _save() + # Initialise _triangle_data + for triangle_idx in self.get_triangles().size(): + _triangles_data.append({}) + _created = true + save() + +# Create points on the terrain func _create_points(): - var rect = Rect2(Vector2(0, 0), Vector2(width, height)) + var rect = Rect2(Vector2(0, 0), Vector2(_width, _height)) var poisson_disc_sampling: PoissonDiscSampling = PoissonDiscSampling.new() - var points2d = poisson_disc_sampling.generate_points(spacing, rect, 5) + var points2d = poisson_disc_sampling.generate_points(_spacing, rect, 5) _points.resize(points2d.size()) for point_idx in points2d.size(): _points[point_idx].x = points2d[point_idx].x _points[point_idx].z = points2d[point_idx].y +# Terrain methodes func get_triangles(): var triangles = Triangles.new(self) return triangles @@ -347,49 +374,72 @@ func get_edge(idx): func get_triangle(idx): return Triangle.new(idx, self) - -func triangles(): - return _triangles.size() / 3 -func points(): - return _points.size() +func save(): + var terrain_dir = Directory.new() + var file = File.new() + var terrain_filename = "user://terrain/terrain_%s.save" % (_name) + terrain_dir.open("user://") + if not terrain_dir.dir_exists("terrain"): + terrain_dir.make_dir("terrain") + terrain_dir.change_dir("terrain") + Global.print_debug("Save file : %s" % (terrain_filename)) + file.open(terrain_filename, File.WRITE) + file.store_var(_width) + file.store_var(_height) + file.store_var(_spacing) + file.store_var(_name) + file.store_var(_points) + file.store_var(_halfedges) + file.store_var(_triangles) + file.store_var(_points_to_halfedges) + file.store_var(_data) + file.store_var(_points_data) + file.store_var(_edges_data) + file.store_var(_triangles_data) + file.close() -func edges(): - return _triangles.size() - -# Voronoi - -func centroid(points): - return Vector3((points[0].x + points[1].x + points[2].x) / 3.0, 0.0, (points[0].z + points[1].z + points[2].z) / 3.0) +func load(name): + var terrain_dir = Directory.new() + var file = File.new() + var terrain_filename = "user://terrain/terrain_%s.save" % (name) + terrain_dir.open("user://") + if not terrain_dir.dir_exists("terrain"): + terrain_dir.make_dir("terrain") + if terrain_dir.file_exists(terrain_filename): + Global.print_debug("Load file : %s" % (terrain_filename)) + file.open(terrain_filename, File.READ) + _width = file.get_var() + _height = file.get_var() + _spacing = file.get_var() + _name = file.get_var() + _points = file.get_var() + _halfedges = file.get_var() + _triangles = file.get_var() + _points_to_halfedges = file.get_var() + _data = file.get_var() + _points_data = file.get_var() + _edges_data = file.get_var() + _triangles_data = file.get_var() + file.close() + _loaded = true + else: + Global.print_debug("The file : %s does not exist" % (terrain_filename)) + +func list(): + return _list +func is_created(): + return _created -func _save(): - _file.open(terrain_file, File.WRITE) - _file.store_var(width) - _file.store_var(height) - _file.store_var(spacing) - _file.store_var(_points) - _file.store_var(_halfedges) - _file.store_var(_triangles) - _file.store_var(_points_to_halfedges) - _file.store_var(_points_data) - _file.store_var(_edges_data) - _file.store_var(_triangles_data) - _file.close() +func is_loaded(): + return _loaded -func _load(): - _file.open(terrain_file, File.READ) - width = _file.get_var() - height = _file.get_var() - spacing = _file.get_var() - _points = _file.get_var() - _halfedges = _file.get_var() - _triangles = _file.get_var() - _points_to_halfedges = _file.get_var() - _points_data = _file.get_var() - _edges_data = _file.get_var() - _triangles_data = _file.get_var() - _file.close() +func exists(name): + for terrain in _list: + if name == terrain["name"]: + return true + return false func get_triangles_as_polygon(): var list_polygon = [] diff --git a/world/game.gd b/world/game.gd index 0fb0553..1175dae 100644 --- a/world/game.gd +++ b/world/game.gd @@ -22,9 +22,25 @@ func _ready(): rng.randomize() noise.seed = rng.randi() noise.octaves = octaves - terrain = Terrain.new(width,height,spacing,true) - init_data() - emit_signal("world_loaded", terrain) + # terrain = Terrain.new(width,height,spacing,false) + + var terrain_name="bonjour" + terrain = Terrain.new() + + print(terrain.list()) + + if terrain.exists(terrain_name): + terrain.load(terrain_name) + else: + terrain.create(width,height,spacing,"bonjour") + + if terrain.is_created() or terrain.is_loaded(): + init_data() + emit_signal("world_loaded", terrain) + else: + Global.print_debug("Pas de terrain, pas de construction ...") + Global.print_debug("Pas de construction ..., pas de palais ...") + Global.print_debug("Pas de palais ..., pas de palais.") func init_data(): for point in terrain.get_points(): @@ -104,6 +120,7 @@ func set_river_path(point): # Point func point_find_elevation(point): + var border = border_width + rng.randf_range(-20.0, 20.0) var elevation = noise.get_noise_2d(point.x / wavelength, point.y / wavelength)