Drive planets from definitions
This commit is contained in:
parent
2f68515f33
commit
02643c76c4
22 changed files with 183 additions and 82 deletions
|
|
@ -13,8 +13,7 @@ var return_world_position: Vector2 = Vector2.ZERO
|
||||||
var return_camera_zoom: float = 1.0
|
var return_camera_zoom: float = 1.0
|
||||||
|
|
||||||
var planet_name: String = ""
|
var planet_name: String = ""
|
||||||
var planet_type: String = ""
|
var planet_definition_id: String = "rocky"
|
||||||
var surface_profile_id: String = "rocky"
|
|
||||||
|
|
||||||
# Explored-chunk history for the world map's fog-of-war reveal. Lives
|
# Explored-chunk history for the world map's fog-of-war reveal. Lives
|
||||||
# here (not on ExplorationTracker, which gets destroyed and recreated on
|
# here (not on ExplorationTracker, which gets destroyed and recreated on
|
||||||
|
|
|
||||||
14
GasGiantDefinition.tres
Normal file
14
GasGiantDefinition.tres
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
[gd_resource type="Resource" script_class="PlanetDefinition" load_steps=3 format=3]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://PlanetDefinition.gd" id="1"]
|
||||||
|
[ext_resource type="PackedScene" path="res://GasGiantVisual.tscn" id="2"]
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
script = ExtResource("1")
|
||||||
|
definition_id = "gas_giant"
|
||||||
|
display_name = "Gas giant"
|
||||||
|
names = PackedStringArray("Aurelia", "Boreas", "Cerulean Deep", "Helios Major", "Vesper")
|
||||||
|
visual_scene = ExtResource("2")
|
||||||
|
surface_profile_id = "gas"
|
||||||
|
resource_id = "gas"
|
||||||
|
map_color = Color(0.65, 0.42, 0.9, 1)
|
||||||
31
GasGiantVisual.gd
Normal file
31
GasGiantVisual.gd
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
extends Node2D
|
||||||
|
|
||||||
|
var gas_phase: float = 0.0
|
||||||
|
|
||||||
|
|
||||||
|
func configure(_shape_seed: int) -> void:
|
||||||
|
queue_redraw()
|
||||||
|
|
||||||
|
|
||||||
|
func extractor_anchor() -> Vector2:
|
||||||
|
return Vector2(0.0, -118.0)
|
||||||
|
|
||||||
|
|
||||||
|
func _process(delta: float) -> void:
|
||||||
|
gas_phase += delta
|
||||||
|
queue_redraw()
|
||||||
|
|
||||||
|
|
||||||
|
func _draw() -> void:
|
||||||
|
var rim := PackedVector2Array()
|
||||||
|
for i in range(32):
|
||||||
|
var angle := TAU * float(i) / 32.0
|
||||||
|
rim.append(Vector2(cos(angle) * 118.0, sin(angle) * 118.0))
|
||||||
|
NeonDraw.draw_glowing_polygon(self, rim, Color(0.4, 0.78, 1.0), 0.9)
|
||||||
|
for row in [-62.0, -28.0, 8.0, 43.0, 73.0]:
|
||||||
|
var band := PackedVector2Array()
|
||||||
|
var half_width: float = sqrt(maxf(0.0, 118.0 * 118.0 - row * row))
|
||||||
|
for i in range(15):
|
||||||
|
var x := lerpf(-half_width, half_width, float(i) / 14.0)
|
||||||
|
band.append(Vector2(x, row + sin(x * 0.045 + gas_phase * 1.6 + row) * 7.0))
|
||||||
|
NeonDraw.draw_glowing_path(self, band, Color(0.85, 0.52, 1.0), 0.75, 0.65)
|
||||||
1
GasGiantVisual.gd.uid
Normal file
1
GasGiantVisual.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://bxfw4ja2hw4pf
|
||||||
6
GasGiantVisual.tscn
Normal file
6
GasGiantVisual.tscn
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
[gd_scene load_steps=2 format=3]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://GasGiantVisual.gd" id="1"]
|
||||||
|
|
||||||
|
[node name="Visual" type="Node2D"]
|
||||||
|
script = ExtResource("1")
|
||||||
80
Planet.gd
80
Planet.gd
|
|
@ -1,5 +1,7 @@
|
||||||
extends Node2D
|
extends Node2D
|
||||||
|
|
||||||
|
const PLANET_DEFINITIONS = preload("res://PlanetDefinitions.gd")
|
||||||
|
|
||||||
|
|
||||||
# A landable world-object - unlike regular Asteroid.gd, planets are
|
# A landable world-object - unlike regular Asteroid.gd, planets are
|
||||||
# stationary ("Big Stable Asteroid" - stable means it doesn't drift or
|
# stationary ("Big Stable Asteroid" - stable means it doesn't drift or
|
||||||
|
|
@ -12,16 +14,33 @@ extends Node2D
|
||||||
# while the fleet as a whole was clearly sitting on the planet.
|
# while the fleet as a whole was clearly sitting on the planet.
|
||||||
|
|
||||||
@export var planet_name: String = ""
|
@export var planet_name: String = ""
|
||||||
@export var planet_type: String = "rocky"
|
@export var definition_id: String = PLANET_DEFINITIONS.DEFAULT_DEFINITION_ID
|
||||||
@export var resource_type: String = "ore"
|
|
||||||
@export var surface_profile_id: String = "rocky"
|
|
||||||
@export var landing_radius: float = 140.0
|
@export var landing_radius: float = 140.0
|
||||||
# Set by whoever spawns this planet (PlanetField, seeded from the chunk's
|
# Set by whoever spawns this planet (PlanetField, seeded from the chunk's
|
||||||
# own coordinates) so the outline shape is stable across respawns of the
|
# own coordinates) so the outline shape is stable across respawns of the
|
||||||
# same chunk, instead of reading as a "different" planet every time.
|
# same chunk, instead of reading as a "different" planet every time.
|
||||||
@export var shape_seed: int = 0
|
@export var shape_seed: int = 0
|
||||||
|
|
||||||
var shape_points: PackedVector2Array = PackedVector2Array()
|
var definition: Resource
|
||||||
|
var visual: Node2D
|
||||||
|
|
||||||
|
var resource_type: String:
|
||||||
|
get: return String(definition.resource_id) if definition != null else "ore"
|
||||||
|
|
||||||
|
var surface_profile_id: String:
|
||||||
|
get: return String(definition.surface_profile_id) if definition != null else "rocky"
|
||||||
|
|
||||||
|
var shape_points: PackedVector2Array:
|
||||||
|
get:
|
||||||
|
if visual != null and "shape_points" in visual:
|
||||||
|
return visual.shape_points
|
||||||
|
return PackedVector2Array()
|
||||||
|
|
||||||
|
var gas_phase: float:
|
||||||
|
get:
|
||||||
|
if visual != null and "gas_phase" in visual:
|
||||||
|
return float(visual.gas_phase)
|
||||||
|
return 0.0
|
||||||
|
|
||||||
# An extractor is built down on this planet's SURFACE, in a different scene
|
# An extractor is built down on this planet's SURFACE, in a different scene
|
||||||
# the player is no longer looking at, so from space nothing distinguished a
|
# the player is no longer looking at, so from space nothing distinguished a
|
||||||
|
|
@ -39,31 +58,20 @@ const DERRICK_HALF_WIDTH: float = 16.0
|
||||||
# only at _ready() left the planet looking untouched until it happened to
|
# only at _ready() left the planet looking untouched until it happened to
|
||||||
# despawn and respawn.
|
# despawn and respawn.
|
||||||
var shows_extractor: bool = false
|
var shows_extractor: bool = false
|
||||||
var gas_phase: float = 0.0
|
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
add_to_group("planets")
|
add_to_group("planets")
|
||||||
z_index = -1
|
z_index = -1
|
||||||
|
definition = PLANET_DEFINITIONS.get_definition(definition_id)
|
||||||
var rng: RandomNumberGenerator = RandomNumberGenerator.new()
|
visual = definition.visual_scene.instantiate()
|
||||||
rng.seed = shape_seed
|
visual.configure(shape_seed)
|
||||||
var point_count: int = 10
|
get_node("VisualHost").add_child(visual)
|
||||||
for i in range(point_count):
|
|
||||||
var angle: float = (float(i) / point_count) * TAU
|
|
||||||
var radius: float = rng.randf_range(70.0, 100.0)
|
|
||||||
shape_points.append(Vector2(cos(angle), sin(angle)) * radius)
|
|
||||||
shows_extractor = GameState.has_extractor_at(planet_name)
|
shows_extractor = GameState.has_extractor_at(planet_name)
|
||||||
GameState.extractor_added.connect(_on_extractor_added)
|
GameState.extractor_added.connect(_on_extractor_added)
|
||||||
queue_redraw()
|
queue_redraw()
|
||||||
|
|
||||||
|
|
||||||
func _process(delta: float) -> void:
|
|
||||||
if planet_type == "gas_giant":
|
|
||||||
gas_phase += delta
|
|
||||||
queue_redraw()
|
|
||||||
|
|
||||||
|
|
||||||
func _on_extractor_added(built_on: String) -> void:
|
func _on_extractor_added(built_on: String) -> void:
|
||||||
# Only the planet it was actually built on, and only a redraw when the
|
# Only the planet it was actually built on, and only a redraw when the
|
||||||
# answer really changed - every other planet in range gets this too.
|
# answer really changed - every other planet in range gets this too.
|
||||||
|
|
@ -74,14 +82,9 @@ func _on_extractor_added(built_on: String) -> void:
|
||||||
|
|
||||||
|
|
||||||
func extractor_derrick_anchor() -> Vector2:
|
func extractor_derrick_anchor() -> Vector2:
|
||||||
# The rim vertex the derrick stands on: the shape's own topmost point,
|
if visual != null and visual.has_method("extractor_anchor"):
|
||||||
# rather than a fixed radius, so it sits ON the outline whatever lumpy
|
return visual.extractor_anchor()
|
||||||
# shape the seed drew instead of floating off it or sinking inside it.
|
return Vector2(0.0, -100.0)
|
||||||
var base: Vector2 = Vector2(0.0, -100.0)
|
|
||||||
for p in shape_points:
|
|
||||||
if p.y < base.y:
|
|
||||||
base = p
|
|
||||||
return base
|
|
||||||
|
|
||||||
|
|
||||||
func extractor_derrick_tip() -> Vector2:
|
func extractor_derrick_tip() -> Vector2:
|
||||||
|
|
@ -113,28 +116,5 @@ func extractor_derrick_points() -> PackedVector2Array:
|
||||||
|
|
||||||
|
|
||||||
func _draw() -> void:
|
func _draw() -> void:
|
||||||
if planet_type == "gas_giant":
|
|
||||||
_draw_gas_giant()
|
|
||||||
if shows_extractor:
|
|
||||||
NeonDraw.draw_glowing_polygon(self, extractor_derrick_points(), EXTRACTOR_MARKER_COLOR, 1.0)
|
|
||||||
return
|
|
||||||
NeonDraw.draw_glowing_polygon(self, shape_points, Color(0.6, 0.55, 0.5), 1.0)
|
|
||||||
if shows_extractor:
|
if shows_extractor:
|
||||||
NeonDraw.draw_glowing_polygon(self, extractor_derrick_points(), EXTRACTOR_MARKER_COLOR, 1.0)
|
NeonDraw.draw_glowing_polygon(self, extractor_derrick_points(), EXTRACTOR_MARKER_COLOR, 1.0)
|
||||||
|
|
||||||
|
|
||||||
func _draw_gas_giant() -> void:
|
|
||||||
# A round, animated giant with drifting latitudinal bands. It is visibly
|
|
||||||
# unlike the rocky outline and keeps moving even while the fleet is idle.
|
|
||||||
var rim := PackedVector2Array()
|
|
||||||
for i in range(32):
|
|
||||||
var a := TAU * float(i) / 32.0
|
|
||||||
rim.append(Vector2(cos(a) * 118.0, sin(a) * 118.0))
|
|
||||||
NeonDraw.draw_glowing_polygon(self, rim, Color(0.4, 0.78, 1.0), 0.9)
|
|
||||||
for row in [-62.0, -28.0, 8.0, 43.0, 73.0]:
|
|
||||||
var band := PackedVector2Array()
|
|
||||||
var half_width: float = sqrt(maxf(0.0, 118.0 * 118.0 - row * row))
|
|
||||||
for i in range(15):
|
|
||||||
var x := lerpf(-half_width, half_width, float(i) / 14.0)
|
|
||||||
band.append(Vector2(x, row + sin(x * 0.045 + gas_phase * 1.6 + row) * 7.0))
|
|
||||||
NeonDraw.draw_glowing_path(self, band, Color(0.85, 0.52, 1.0), 0.75, 0.65)
|
|
||||||
|
|
|
||||||
|
|
@ -4,3 +4,5 @@
|
||||||
|
|
||||||
[node name="Planet" type="Node2D"]
|
[node name="Planet" type="Node2D"]
|
||||||
script = ExtResource("1")
|
script = ExtResource("1")
|
||||||
|
|
||||||
|
[node name="VisualHost" type="Node2D" parent="."]
|
||||||
|
|
|
||||||
|
|
@ -113,8 +113,7 @@ func _on_enter_pressed() -> void:
|
||||||
GameState.return_world_position = current_planet.position
|
GameState.return_world_position = current_planet.position
|
||||||
GameState.return_camera_zoom = camera.zoom.x
|
GameState.return_camera_zoom = camera.zoom.x
|
||||||
GameState.planet_name = current_planet.planet_name
|
GameState.planet_name = current_planet.planet_name
|
||||||
GameState.planet_type = current_planet.planet_type
|
GameState.planet_definition_id = current_planet.definition_id
|
||||||
GameState.surface_profile_id = current_planet.surface_profile_id
|
|
||||||
|
|
||||||
var tween: Tween = create_tween()
|
var tween: Tween = create_tween()
|
||||||
tween.tween_property(fade_rect, "color:a", 1.0, fade_duration)
|
tween.tween_property(fade_rect, "color:a", 1.0, fade_duration)
|
||||||
|
|
|
||||||
10
PlanetDefinition.gd
Normal file
10
PlanetDefinition.gd
Normal file
|
|
@ -0,0 +1,10 @@
|
||||||
|
class_name PlanetDefinition
|
||||||
|
extends Resource
|
||||||
|
|
||||||
|
@export var definition_id: String = "rocky"
|
||||||
|
@export var display_name: String = "Rocky planet"
|
||||||
|
@export var names: PackedStringArray = []
|
||||||
|
@export var visual_scene: PackedScene
|
||||||
|
@export var surface_profile_id: String = "rocky"
|
||||||
|
@export var resource_id: String = "ore"
|
||||||
|
@export var map_color: Color = Color(0.7, 0.65, 0.55)
|
||||||
1
PlanetDefinition.gd.uid
Normal file
1
PlanetDefinition.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://dt6tsdmmlnfaf
|
||||||
14
PlanetDefinitions.gd
Normal file
14
PlanetDefinitions.gd
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
class_name PlanetDefinitions
|
||||||
|
extends RefCounted
|
||||||
|
|
||||||
|
const ROCKY_ID: String = "rocky"
|
||||||
|
const GAS_GIANT_ID: String = "gas_giant"
|
||||||
|
const DEFAULT_DEFINITION_ID: String = ROCKY_ID
|
||||||
|
const DEFINITIONS: Dictionary = {
|
||||||
|
ROCKY_ID: preload("res://RockyPlanetDefinition.tres"),
|
||||||
|
GAS_GIANT_ID: preload("res://GasGiantDefinition.tres"),
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static func get_definition(definition_id: String) -> Resource:
|
||||||
|
return DEFINITIONS.get(definition_id, DEFINITIONS[DEFAULT_DEFINITION_ID])
|
||||||
1
PlanetDefinitions.gd.uid
Normal file
1
PlanetDefinitions.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://ipsld2ex2t8e
|
||||||
|
|
@ -84,9 +84,7 @@ func _spawn_chunk_planet(chunk: Vector2i) -> void:
|
||||||
planet.position = origin + data.local_pos
|
planet.position = origin + data.local_pos
|
||||||
planet.planet_name = data.name
|
planet.planet_name = data.name
|
||||||
planet.shape_seed = data.shape_seed
|
planet.shape_seed = data.shape_seed
|
||||||
planet.planet_type = String(data.get("planet_type", "rocky"))
|
planet.definition_id = String(data.get("definition_id", "rocky"))
|
||||||
planet.resource_type = String(data.get("resource_type", "ore"))
|
|
||||||
planet.surface_profile_id = String(data.get("surface_profile_id", "rocky"))
|
|
||||||
# Deferred: update_chunks() can run synchronously from inside a
|
# Deferred: update_chunks() can run synchronously from inside a
|
||||||
# parent's own _ready() chain (forced once right after the fleet is
|
# parent's own _ready() chain (forced once right after the fleet is
|
||||||
# positioned, to avoid a pop-in on scene load) - Godot refuses a
|
# positioned, to avoid a pop-in on scene load) - Godot refuses a
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
extends Node2D
|
extends Node2D
|
||||||
|
|
||||||
const SURFACE_PROFILES = preload("res://PlanetSurfaceProfiles.gd")
|
const SURFACE_PROFILES = preload("res://PlanetSurfaceProfiles.gd")
|
||||||
|
const PLANET_DEFINITIONS = preload("res://PlanetDefinitions.gd")
|
||||||
|
|
||||||
# Bootstraps the surviving fleet on this scene's own startup (from
|
# Bootstraps the surviving fleet on this scene's own startup (from
|
||||||
# GameState, since this is a fresh scene tree - nothing here carries
|
# GameState, since this is a fresh scene tree - nothing here carries
|
||||||
|
|
@ -22,7 +23,8 @@ var transitioning: bool = false
|
||||||
|
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
_compose_surface(SURFACE_PROFILES.get_profile(GameState.surface_profile_id))
|
var planet_definition: Resource = PLANET_DEFINITIONS.get_definition(GameState.planet_definition_id)
|
||||||
|
_compose_surface(SURFACE_PROFILES.get_profile(planet_definition.surface_profile_id))
|
||||||
fleet.spawn_ships(GameState.surviving_ship_count, Vector2.ZERO)
|
fleet.spawn_ships(GameState.surviving_ship_count, Vector2.ZERO)
|
||||||
camera.position = Vector2.ZERO
|
camera.position = Vector2.ZERO
|
||||||
camera.zoom = Vector2(GameState.return_camera_zoom, GameState.return_camera_zoom)
|
camera.zoom = Vector2(GameState.return_camera_zoom, GameState.return_camera_zoom)
|
||||||
|
|
|
||||||
14
RockyPlanetDefinition.tres
Normal file
14
RockyPlanetDefinition.tres
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
[gd_resource type="Resource" script_class="PlanetDefinition" load_steps=3 format=3]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://PlanetDefinition.gd" id="1"]
|
||||||
|
[ext_resource type="PackedScene" path="res://RockyPlanetVisual.tscn" id="2"]
|
||||||
|
|
||||||
|
[resource]
|
||||||
|
script = ExtResource("1")
|
||||||
|
definition_id = "rocky"
|
||||||
|
display_name = "Rocky planet"
|
||||||
|
names = PackedStringArray("Kepler's Rest", "Ceres Minor", "Vesta's Shadow", "Ironhold", "Drift Anchor", "Stonefall", "Grey Watch", "Silent Quarry", "Baros Rock", "Umbra Point")
|
||||||
|
visual_scene = ExtResource("2")
|
||||||
|
surface_profile_id = "rocky"
|
||||||
|
resource_id = "ore"
|
||||||
|
map_color = Color(0.7, 0.65, 0.55, 1)
|
||||||
26
RockyPlanetVisual.gd
Normal file
26
RockyPlanetVisual.gd
Normal file
|
|
@ -0,0 +1,26 @@
|
||||||
|
extends Node2D
|
||||||
|
|
||||||
|
var shape_points: PackedVector2Array = PackedVector2Array()
|
||||||
|
|
||||||
|
|
||||||
|
func configure(shape_seed: int) -> void:
|
||||||
|
shape_points.clear()
|
||||||
|
var rng := RandomNumberGenerator.new()
|
||||||
|
rng.seed = shape_seed
|
||||||
|
for i in range(10):
|
||||||
|
var angle: float = (float(i) / 10.0) * TAU
|
||||||
|
var radius: float = rng.randf_range(70.0, 100.0)
|
||||||
|
shape_points.append(Vector2(cos(angle), sin(angle)) * radius)
|
||||||
|
queue_redraw()
|
||||||
|
|
||||||
|
|
||||||
|
func extractor_anchor() -> Vector2:
|
||||||
|
var anchor := Vector2(0.0, -100.0)
|
||||||
|
for point in shape_points:
|
||||||
|
if point.y < anchor.y:
|
||||||
|
anchor = point
|
||||||
|
return anchor
|
||||||
|
|
||||||
|
|
||||||
|
func _draw() -> void:
|
||||||
|
NeonDraw.draw_glowing_polygon(self, shape_points, Color(0.6, 0.55, 0.5), 1.0)
|
||||||
1
RockyPlanetVisual.gd.uid
Normal file
1
RockyPlanetVisual.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
||||||
|
uid://b82xh8nosedlm
|
||||||
6
RockyPlanetVisual.tscn
Normal file
6
RockyPlanetVisual.tscn
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
[gd_scene load_steps=2 format=3]
|
||||||
|
|
||||||
|
[ext_resource type="Script" path="res://RockyPlanetVisual.gd" id="1"]
|
||||||
|
|
||||||
|
[node name="Visual" type="Node2D"]
|
||||||
|
script = ExtResource("1")
|
||||||
19
WorldGen.gd
19
WorldGen.gd
|
|
@ -1,6 +1,8 @@
|
||||||
class_name WorldGen
|
class_name WorldGen
|
||||||
extends RefCounted
|
extends RefCounted
|
||||||
|
|
||||||
|
const PLANET_DEFINITIONS = preload("res://PlanetDefinitions.gd")
|
||||||
|
|
||||||
# Deterministic procedural world generation: the world is divided into
|
# Deterministic procedural world generation: the world is divided into
|
||||||
# square chunks, and each chunk's biome is derived from a seeded
|
# square chunks, and each chunk's biome is derived from a seeded
|
||||||
# low-frequency noise field sampled at the chunk's own coordinates - so
|
# low-frequency noise field sampled at the chunk's own coordinates - so
|
||||||
|
|
@ -22,13 +24,6 @@ const GAS_GIANT_THRESHOLD: float = 0.55
|
||||||
const NEARBY_GAS_GIANT_CHUNK: Vector2i = Vector2i.ZERO
|
const NEARBY_GAS_GIANT_CHUNK: Vector2i = Vector2i.ZERO
|
||||||
const NEARBY_GAS_GIANT_LOCAL_POS: Vector2 = Vector2(900.0, 600.0)
|
const NEARBY_GAS_GIANT_LOCAL_POS: Vector2 = Vector2(900.0, 600.0)
|
||||||
|
|
||||||
const PLANET_NAMES: Array = [
|
|
||||||
"Kepler's Rest", "Ceres Minor", "Vesta's Shadow", "Ironhold",
|
|
||||||
"Drift Anchor", "Stonefall", "Grey Watch", "Silent Quarry",
|
|
||||||
"Baros Rock", "Umbra Point",
|
|
||||||
]
|
|
||||||
const GAS_GIANT_NAMES: Array = ["Aurelia", "Boreas", "Cerulean Deep", "Helios Major", "Vesper"]
|
|
||||||
|
|
||||||
static var _noise: FastNoiseLite
|
static var _noise: FastNoiseLite
|
||||||
static var _planet_noise: FastNoiseLite
|
static var _planet_noise: FastNoiseLite
|
||||||
|
|
||||||
|
|
@ -88,16 +83,16 @@ static func planet_data_at_chunk(chunk: Vector2i) -> Dictionary:
|
||||||
var guaranteed_nearby_giant: bool = chunk == NEARBY_GAS_GIANT_CHUNK
|
var guaranteed_nearby_giant: bool = chunk == NEARBY_GAS_GIANT_CHUNK
|
||||||
var local_pos: Vector2 = NEARBY_GAS_GIANT_LOCAL_POS if guaranteed_nearby_giant \
|
var local_pos: Vector2 = NEARBY_GAS_GIANT_LOCAL_POS if guaranteed_nearby_giant \
|
||||||
else Vector2(rng.randf() * CHUNK_SIZE, rng.randf() * CHUNK_SIZE)
|
else Vector2(rng.randf() * CHUNK_SIZE, rng.randf() * CHUNK_SIZE)
|
||||||
var planet_name: String = PLANET_NAMES[rng.randi() % PLANET_NAMES.size()]
|
|
||||||
var shape_seed: int = rng.randi()
|
var shape_seed: int = rng.randi()
|
||||||
# A stable per-chunk roll makes gas giants persistent landmarks rather
|
# A stable per-chunk roll makes gas giants persistent landmarks rather
|
||||||
# than a different resource whenever the scene reloads.
|
# than a different resource whenever the scene reloads.
|
||||||
var gas_giant: bool = guaranteed_nearby_giant or biome_at_chunk(chunk) == Biome.SPACE
|
var gas_giant: bool = guaranteed_nearby_giant or biome_at_chunk(chunk) == Biome.SPACE
|
||||||
if gas_giant:
|
var definition_id: String = PLANET_DEFINITIONS.GAS_GIANT_ID if gas_giant else PLANET_DEFINITIONS.ROCKY_ID
|
||||||
planet_name = GAS_GIANT_NAMES[rng.randi() % GAS_GIANT_NAMES.size()]
|
var definition: Resource = PLANET_DEFINITIONS.get_definition(definition_id)
|
||||||
|
var names: PackedStringArray = definition.names
|
||||||
|
var planet_name: String = names[rng.randi() % names.size()]
|
||||||
return {"local_pos": local_pos, "name": planet_name, "shape_seed": shape_seed,
|
return {"local_pos": local_pos, "name": planet_name, "shape_seed": shape_seed,
|
||||||
"planet_type": "gas_giant" if gas_giant else "rocky", "resource_type": "gas" if gas_giant else "ore",
|
"definition_id": definition_id}
|
||||||
"surface_profile_id": "gas" if gas_giant else "rocky"}
|
|
||||||
|
|
||||||
|
|
||||||
static func biome_color(biome: int) -> Color:
|
static func biome_color(biome: int) -> Color:
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
extends Node2D
|
extends Node2D
|
||||||
|
|
||||||
|
const PLANET_DEFINITIONS = preload("res://PlanetDefinitions.gd")
|
||||||
|
|
||||||
const WORLD_TO_LOCAL: float = 0.04
|
const WORLD_TO_LOCAL: float = 0.04
|
||||||
|
|
||||||
# Mirrors Building.gd's own MOTHERSHIP_COLOR/CRAFTER_COLOR/COMMAND_COLOR so a
|
# Mirrors Building.gd's own MOTHERSHIP_COLOR/CRAFTER_COLOR/COMMAND_COLOR so a
|
||||||
|
|
@ -105,7 +107,8 @@ func _draw() -> void:
|
||||||
# spawn_radius_chunks of the fleet).
|
# spawn_radius_chunks of the fleet).
|
||||||
var data: Dictionary = WorldGen.planet_data_at_chunk(chunk)
|
var data: Dictionary = WorldGen.planet_data_at_chunk(chunk)
|
||||||
var planet_local: Vector2 = origin_local + data.local_pos * WORLD_TO_LOCAL
|
var planet_local: Vector2 = origin_local + data.local_pos * WORLD_TO_LOCAL
|
||||||
draw_circle(planet_local, 5.0, Color(0.7, 0.65, 0.55))
|
var definition: Resource = PLANET_DEFINITIONS.get_definition(String(data.definition_id))
|
||||||
|
draw_circle(planet_local, 5.0, definition.map_color)
|
||||||
draw_arc(planet_local, 5.0, 0.0, TAU, 16, Color(1.0, 1.0, 1.0, 0.9), 1.0, true)
|
draw_arc(planet_local, 5.0, 0.0, TAU, 16, Color(1.0, 1.0, 1.0, 0.9), 1.0, true)
|
||||||
|
|
||||||
if chunk_has_extractor_badge(chunk):
|
if chunk_has_extractor_badge(chunk):
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,7 @@ extends Node2D
|
||||||
|
|
||||||
func _ready() -> void:
|
func _ready() -> void:
|
||||||
GameState.planet_name = "Violet Tempest"
|
GameState.planet_name = "Violet Tempest"
|
||||||
GameState.planet_type = "gas_giant"
|
GameState.planet_definition_id = "gas_giant"
|
||||||
GameState.surface_profile_id = "gas"
|
|
||||||
GameState.surviving_ship_count = 3
|
GameState.surviving_ship_count = 3
|
||||||
GameState.rocks = 128
|
GameState.rocks = 128
|
||||||
GameState.gas = 46
|
GameState.gas = 46
|
||||||
|
|
|
||||||
|
|
@ -27,8 +27,7 @@ func _process(delta: float) -> bool:
|
||||||
return _fail("nearby gas giant chunk does not contain a planet")
|
return _fail("nearby gas giant chunk does not contain a planet")
|
||||||
if WorldGen.biome_at_chunk(nearby_chunk) != WorldGen.Biome.SPACE:
|
if WorldGen.biome_at_chunk(nearby_chunk) != WorldGen.Biome.SPACE:
|
||||||
return _fail("nearby gas giant is not in the normal space biome")
|
return _fail("nearby gas giant is not in the normal space biome")
|
||||||
if String(nearby_data.get("planet_type", "")) != "gas_giant" \
|
if String(nearby_data.get("definition_id", "")) != "gas_giant":
|
||||||
or String(nearby_data.get("resource_type", "")) != "gas":
|
|
||||||
return _fail("nearby guaranteed planet is not a gas source")
|
return _fail("nearby guaranteed planet is not a gas source")
|
||||||
if nearby_position.length() > WorldGen.CHUNK_SIZE * 2.0:
|
if nearby_position.length() > WorldGen.CHUNK_SIZE * 2.0:
|
||||||
return _fail("nearby gas giant spawned too far away: %s" % nearby_position)
|
return _fail("nearby gas giant spawned too far away: %s" % nearby_position)
|
||||||
|
|
@ -36,8 +35,7 @@ func _process(delta: float) -> bool:
|
||||||
# Gas surfaces have vents only: no deferred ore pickups, and the vent
|
# Gas surfaces have vents only: no deferred ore pickups, and the vent
|
||||||
# emission advances continuously so the source visibly looks active.
|
# emission advances continuously so the source visibly looks active.
|
||||||
game_state.planet_name = "Gas Test"
|
game_state.planet_name = "Gas Test"
|
||||||
game_state.planet_type = "gas_giant"
|
game_state.planet_definition_id = "gas_giant"
|
||||||
game_state.surface_profile_id = "gas"
|
|
||||||
var surface: Node = load("res://PlanetSurface.tscn").instantiate()
|
var surface: Node = load("res://PlanetSurface.tscn").instantiate()
|
||||||
root.add_child(surface)
|
root.add_child(surface)
|
||||||
var gas_field: Node = surface.get_node("SurfaceFeatures/ResourceProvider")
|
var gas_field: Node = surface.get_node("SurfaceFeatures/ResourceProvider")
|
||||||
|
|
@ -53,7 +51,7 @@ func _process(delta: float) -> bool:
|
||||||
return _fail("gas-source emission animation did not advance")
|
return _fail("gas-source emission animation did not advance")
|
||||||
surface.free()
|
surface.free()
|
||||||
|
|
||||||
game_state.surface_profile_id = "rocky"
|
game_state.planet_definition_id = "rocky"
|
||||||
var rocky_surface: Node = load("res://PlanetSurface.tscn").instantiate()
|
var rocky_surface: Node = load("res://PlanetSurface.tscn").instantiate()
|
||||||
root.add_child(rocky_surface)
|
root.add_child(rocky_surface)
|
||||||
var rocky_features: Node = rocky_surface.get_node("SurfaceFeatures/ResourceProvider")
|
var rocky_features: Node = rocky_surface.get_node("SurfaceFeatures/ResourceProvider")
|
||||||
|
|
@ -69,16 +67,17 @@ func _process(delta: float) -> bool:
|
||||||
for x in range(-12, 13):
|
for x in range(-12, 13):
|
||||||
for y in range(-12, 13):
|
for y in range(-12, 13):
|
||||||
var data: Dictionary = WorldGen.planet_data_at_chunk(Vector2i(x, y))
|
var data: Dictionary = WorldGen.planet_data_at_chunk(Vector2i(x, y))
|
||||||
if String(data.get("planet_type", "")) == "gas_giant":
|
if String(data.get("definition_id", "")) == "gas_giant":
|
||||||
found_giant = String(data.get("resource_type", "")) == "gas"
|
found_giant = true
|
||||||
break
|
break
|
||||||
if found_giant:
|
if found_giant:
|
||||||
break
|
break
|
||||||
if not found_giant:
|
if not found_giant:
|
||||||
return _fail("world generation produced no deterministic gas giant")
|
return _fail("world generation produced no deterministic gas giant")
|
||||||
var giant: Node2D = load("res://Planet.tscn").instantiate()
|
var giant: Node2D = load("res://Planet.tscn").instantiate()
|
||||||
giant.planet_type = "gas_giant"
|
giant.definition_id = "gas_giant"
|
||||||
giant._process(0.5)
|
root.add_child(giant)
|
||||||
|
giant.visual._process(0.5)
|
||||||
if giant.gas_phase <= 0.0:
|
if giant.gas_phase <= 0.0:
|
||||||
return _fail("gas giant animation did not advance")
|
return _fail("gas giant animation did not advance")
|
||||||
giant.free()
|
giant.free()
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue