Randoloot/scripts/planets/surface_world.gd

122 lines
5.4 KiB
GDScript

extends Node2D
const GENERATOR := preload("res://scripts/planets/surface_generator.gd")
var data: Dictionary
var terrain: ImageTexture
var _tree: Texture2D
var _mountain: Texture2D
var _poi_sprites: Dictionary = {}
var _poi_labels: Dictionary = {}
var _event_nodes: Array[Dictionary] = []
func _ready() -> void:
texture_filter = CanvasItem.TEXTURE_FILTER_LINEAR_WITH_MIPMAPS
terrain = GENERATOR.terrain_texture(data)
var ground := Sprite2D.new()
ground.name = "Terrain"
ground.texture = data.height_texture
ground.scale = Vector2.ONE * GENERATOR.WORLD_SIZE / ground.texture.get_width()
ground.z_index = -5
var material := ShaderMaterial.new()
material.shader = preload("res://resources/effects/planet_terrain.gdshader")
material.set_shader_parameter("height_map",data.height_texture)
material.set_shader_parameter("grass_detail",preload("res://assets/planets/grass.png"))
for kind in ["soil","rock","sand","moss"]:
material.set_shader_parameter(kind+"_detail",load("res://assets/planets/terrain/%s.png" % kind))
material.set_shader_parameter("biome_kind",int(data.landscape.index))
for key in ["low","high","sand","rock"]:
material.set_shader_parameter(key+"_color",data.landscape[key])
material.set_shader_parameter("climate",float(data.profile.temperature))
material.set_shader_parameter("seed_offset",float(posmod(int(data.seed),10000)))
ground.material = material
add_child(ground)
_tree = load("res://assets/planets/tree.png")
_mountain = load("res://assets/planets/mountain.png")
for poi in data.pois:
var sprite := Sprite2D.new()
sprite.texture = load("res://assets/planets/%s.png" % ("ruins" if poi.kind == "ruins" else "mine")) if poi.kind != "deposit" else load("res://assets/icons/resources/titanium.png")
sprite.position = poi.position
sprite.scale = Vector2.ONE * (125.0 if poi.kind != "deposit" else 60.0) / maxf(sprite.texture.get_width(), sprite.texture.get_height())
sprite.z_index = 10
add_child(sprite)
_poi_sprites[poi.id] = sprite
var label := Label.new()
label.position = poi.position + Vector2(-120, 65)
label.size.x = 240
label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
label.add_theme_font_size_override("font_size", 13)
label.add_theme_color_override("font_color", Color("f0d5a1"))
label.add_theme_color_override("font_shadow_color", Color("061310"))
label.add_theme_constant_override("shadow_outline_size", 5)
label.z_index = 15
add_child(label)
_poi_labels[poi.id] = label
for structure in data.structures:
var prop := Sprite2D.new()
prop.name = str(structure.kind).to_pascal_case()
prop.texture = load("res://assets/planets/props/%s.png" % structure.kind)
prop.position = structure.position
prop.rotation = structure.rotation
prop.scale = Vector2.ONE * float(structure.size) / maxf(prop.texture.get_width(),prop.texture.get_height())
prop.z_index = 4
add_child(prop)
for index in data.events.size():
var event: Dictionary = data.events[index]
var marker := Label.new()
marker.name = "EventMarker%d" % index
marker.text = "?"
marker.position = event.position+Vector2(-22,-28)
marker.size = Vector2(44,55)
marker.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
marker.add_theme_font_size_override("font_size",40)
marker.add_theme_color_override("font_color",Color("f8d685"))
marker.add_theme_color_override("font_outline_color",Color("17211b"))
marker.add_theme_constant_override("outline_size",7)
marker.z_index = 25
add_child(marker)
_event_nodes.append({"marker":marker})
refresh_pois(Vector2.ZERO)
func refresh_pois(lander_position: Vector2) -> void:
for index in data.events.size():
var event: Dictionary = data.events[index]
if lander_position.distance_to(event.position) < 600:
event.discovered = true
var nodes: Dictionary = _event_nodes[index]
nodes.marker.visible = not event.complete
for poi in data.pois:
if lander_position.distance_to(poi.position) < 650:
poi.discovered = true
var sprite: Sprite2D = _poi_sprites[poi.id]
sprite.visible = bool(poi.discovered)
sprite.modulate = Color(0.5, 0.55, 0.5) if poi.complete else Color.WHITE
var label: Label = _poi_labels[poi.id]
label.visible = bool(poi.discovered)
var title: String = {"mine": "Opuszczona kopalnia", "ruins": "Starożytne ruiny", "deposit": "Złoże minerałów"}[poi.kind]
label.text = title + (" · zbadano" if poi.complete else ("\n[F] Zbadaj" if lander_position.distance_to(poi.position) <= 150 else ""))
func _draw() -> void:
if terrain == null:
return
for mountain in data.mountains:
_draw_prop(_mountain, mountain.position, mountain.size, mountain.rotation, Color.WHITE)
for rock in data.rocks:
_draw_prop(_mountain,rock.position,rock.size,rock.rotation,Color("b3b0a0"))
for tree in data.trees:
var shade := float(tree.shade)
var color: Color = Color(shade,shade,shade)*data.landscape.trees
if int(data.profile.temperature) < -10:
color = color.lerp(Color("d1e1da"), 0.4)
elif int(data.profile.temperature) > 40:
color = color.lerp(Color("c6a86b"), 0.28)
_draw_prop(_tree, tree.position, tree.size, tree.rotation, color)
# Small landing beacon.
draw_circle(Vector2.ZERO, 50, Color(0.5, 0.85, 0.8, 0.12))
draw_arc(Vector2.ZERO, 48, 0, TAU, 48, Color("8cd9c2"), 2, true)
func _draw_prop(texture: Texture2D, point: Vector2, width: float, angle: float, color: Color) -> void:
draw_set_transform(point, angle)
draw_texture_rect(texture, Rect2(-width * 0.5, -width * 0.5, width, width), false, color)
draw_set_transform(Vector2.ZERO)