gros dev pre proto
* Changement de l'UI, ajouts de l'inspecteur par carte et changement de police * Ajout d'un semblant d'exploration * Ajout de la sauvegarde des entités * Restructuration mineure de l'arborescence * Fix divers et réécriture des textes
@@ -1,23 +1,15 @@
|
||||
[gd_scene load_steps=15 format=3 uid="uid://d28cp7a21kwou"]
|
||||
[gd_scene load_steps=10 format=3 uid="uid://d28cp7a21kwou"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://12nak7amd1uq" path="res://gui/game/game_gui.tscn" id="1_yy1uy"]
|
||||
[ext_resource type="PackedScene" uid="uid://csiacsndm62ll" path="res://gui/game/pause/pause.tscn" id="2_bt4fd"]
|
||||
[ext_resource type="PackedScene" uid="uid://v41hfc7haaye" path="res://gui/game/win/win.tscn" id="3_6guxm"]
|
||||
[ext_resource type="PackedScene" uid="uid://doxm7uab8i3tq" path="res://gui/game/reward_choice/reward_choice.tscn" id="4_fbkgs"]
|
||||
[ext_resource type="PackedScene" uid="uid://bgvbgeq46wee2" path="res://entities/player/player.tscn" id="4_g33f4"]
|
||||
[ext_resource type="Script" uid="uid://dedg615xudpoq" path="res://entities/interactables/item_object/script/item_object.gd" id="5_kgrdw"]
|
||||
[ext_resource type="PackedScene" uid="uid://dt6mptqg80dew" path="res://gui/game/tutorial/tutorial.tscn" id="5_orelw"]
|
||||
[ext_resource type="Script" uid="uid://dya38x1h1uiyg" path="res://common/inventory/scripts/items/shovel.gd" id="7_fbkgs"]
|
||||
[ext_resource type="PackedScene" uid="uid://tsi5j1uxppa4" path="res://stages/terrain/planet/planet.tscn" id="8_t31p7"]
|
||||
[ext_resource type="PackedScene" uid="uid://cg1visg52i21a" path="res://entities/interactables/truck/ladder/truck_ladder.tscn" id="9_gisiu"]
|
||||
[ext_resource type="PackedScene" uid="uid://d324mlmgls4fs" path="res://entities/interactables/truck/recharge/truck_recharge.tscn" id="10_cnjsq"]
|
||||
[ext_resource type="PackedScene" uid="uid://ceplumcunebag" path="res://stages/terrain/truck/truck_interior.tscn" id="13_cnjsq"]
|
||||
[ext_resource type="PackedScene" uid="uid://dj7gp3crtg2yt" path="res://entities/camera/camera.tscn" id="16_m18ms"]
|
||||
|
||||
[sub_resource type="Resource" id="Resource_orelw"]
|
||||
script = ExtResource("7_fbkgs")
|
||||
metadata/_custom_type_script = "uid://dya38x1h1uiyg"
|
||||
|
||||
[node name="PlanetRun" type="Node2D"]
|
||||
|
||||
[node name="CanvasLayer" type="CanvasLayer" parent="."]
|
||||
@@ -27,38 +19,26 @@ metadata/_edit_use_anchors_ = true
|
||||
|
||||
[node name="RewardChoice" parent="CanvasLayer" instance=ExtResource("4_fbkgs")]
|
||||
|
||||
[node name="Pause" parent="CanvasLayer" instance=ExtResource("2_bt4fd")]
|
||||
process_mode = 3
|
||||
z_index = 1000
|
||||
|
||||
[node name="Win" parent="CanvasLayer" instance=ExtResource("3_6guxm")]
|
||||
visible = false
|
||||
|
||||
[node name="Tutorial" parent="CanvasLayer" node_paths=PackedStringArray("player") instance=ExtResource("5_orelw")]
|
||||
[node name="Tutorial" parent="CanvasLayer" node_paths=PackedStringArray("player", "planet") instance=ExtResource("5_orelw")]
|
||||
player = NodePath("../../Entities/Player")
|
||||
planet = NodePath("../../Planet")
|
||||
|
||||
[node name="Entities" type="Node2D" parent="."]
|
||||
y_sort_enabled = true
|
||||
|
||||
[node name="Player" parent="Entities" instance=ExtResource("4_g33f4")]
|
||||
position = Vector2(0, 13.49)
|
||||
position = Vector2(33, -75)
|
||||
|
||||
[node name="ItemObject" type="Area2D" parent="Entities"]
|
||||
position = Vector2(0, 129)
|
||||
script = ExtResource("5_kgrdw")
|
||||
item = SubResource("Resource_orelw")
|
||||
metadata/_custom_type_script = "uid://dedg615xudpoq"
|
||||
|
||||
[node name="TruckLadder" parent="Entities" node_paths=PackedStringArray("truck_interior", "planet_camera") instance=ExtResource("9_gisiu")]
|
||||
[node name="TruckLadder" parent="Entities" instance=ExtResource("9_gisiu")]
|
||||
position = Vector2(33, -139)
|
||||
truck_interior = NodePath("../../TruckInterior")
|
||||
planet_camera = NodePath("../../Camera")
|
||||
|
||||
[node name="TruckRecharge" parent="Entities" instance=ExtResource("10_cnjsq")]
|
||||
position = Vector2(-36, -154)
|
||||
|
||||
[node name="Planet" parent="." node_paths=PackedStringArray("import_entities_from_node") instance=ExtResource("8_t31p7")]
|
||||
loot_number = Array[int]([1])
|
||||
loot_item_number = Array[int]([1])
|
||||
import_entities_from_node = NodePath("../Entities")
|
||||
|
||||
@@ -66,15 +46,7 @@ import_entities_from_node = NodePath("../Entities")
|
||||
position = Vector2(2.22, 0)
|
||||
following = NodePath("../Entities/Player")
|
||||
|
||||
[node name="TruckInterior" parent="." instance=ExtResource("13_cnjsq")]
|
||||
position = Vector2(-372, -4191)
|
||||
|
||||
[connection signal="pause_asked" from="CanvasLayer/RootGui" to="CanvasLayer/Pause" method="_on_root_gui_pause_asked"]
|
||||
[connection signal="player_updated" from="Entities/Player" to="CanvasLayer/RootGui" method="_on_player_updated"]
|
||||
[connection signal="upgraded" from="Entities/Player" to="CanvasLayer/RootGui" method="_on_player_upgraded"]
|
||||
[connection signal="day_limit_exceed" from="Planet" to="CanvasLayer/Win" method="_on_planet_day_limit_exceed"]
|
||||
[connection signal="new_quota_started" from="Planet" to="CanvasLayer/RootGui" method="_on_planet_new_quota_started"]
|
||||
[connection signal="pass_day_ended" from="Planet" to="CanvasLayer/RootGui" method="_on_planet_pass_day_ended"]
|
||||
[connection signal="pass_day_started" from="Planet" to="CanvasLayer/RootGui" method="_on_planet_pass_day_started"]
|
||||
[connection signal="planet_updated" from="Planet" to="CanvasLayer/RootGui" method="_on_planet_updated"]
|
||||
[connection signal="quota_reward_asked" from="Planet" to="CanvasLayer/RewardChoice" method="_on_planet_quota_reward_asked"]
|
||||
|
||||
|
After Width: | Height: | Size: 46 KiB |
@@ -3,21 +3,23 @@
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bnrjnvceprxfn"
|
||||
path="res://.godot/imported/sol_gamejam_normal.png-a8a63b9f57f727b96585445cbd74ba15.ctex"
|
||||
path="res://.godot/imported/garden_background_texture.png-15af9185e7f2afb324adf3e5bc16d734.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://stages/terrain/planet/assets/textures/sol_gamejam_normal.png"
|
||||
dest_files=["res://.godot/imported/sol_gamejam_normal.png-a8a63b9f57f727b96585445cbd74ba15.ctex"]
|
||||
source_file="res://stages/terrain/planet/assets/textures/garden_background_texture.png"
|
||||
dest_files=["res://.godot/imported/garden_background_texture.png-15af9185e7f2afb324adf3e5bc16d734.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
@@ -25,6 +27,10 @@ mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 105 KiB |
@@ -2,22 +2,24 @@
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://73topi3k4iia"
|
||||
path="res://.godot/imported/sol_gamejam_pollution_transparent.png-e0f6a469ee35256b6f08efb9025c9a38.ctex"
|
||||
uid="uid://c3t26nlbnkxg7"
|
||||
path="res://.godot/imported/garden_decontamined_background_texture.png-059bd195ae2e24916e642e6f3275cffd.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://stages/terrain/planet/resources/textures/sol_gamejam_pollution_transparent.png"
|
||||
dest_files=["res://.godot/imported/sol_gamejam_pollution_transparent.png-e0f6a469ee35256b6f08efb9025c9a38.ctex"]
|
||||
source_file="res://stages/terrain/planet/assets/textures/garden_decontamined_background_texture.png"
|
||||
dest_files=["res://.godot/imported/garden_decontamined_background_texture.png-059bd195ae2e24916e642e6f3275cffd.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
@@ -25,6 +27,10 @@ mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
|
After Width: | Height: | Size: 190 KiB |
@@ -2,22 +2,24 @@
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://dcn4cq53h1qiy"
|
||||
path="res://.godot/imported/sol_gamejam_fleurs_transp.png-9f83431996765c9ee6ae75623dc9a6ca.ctex"
|
||||
uid="uid://beqx4rmgthkql"
|
||||
path="res://.godot/imported/rock_background_texture.png-7bbae13b0384e1483bd66633981b566b.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://stages/terrain/planet/resources/textures/sol_gamejam_fleurs_transp.png"
|
||||
dest_files=["res://.godot/imported/sol_gamejam_fleurs_transp.png-9f83431996765c9ee6ae75623dc9a6ca.ctex"]
|
||||
source_file="res://stages/terrain/planet/assets/textures/rock_background_texture.png"
|
||||
dest_files=["res://.godot/imported/rock_background_texture.png-7bbae13b0384e1483bd66633981b566b.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/uastc_level=0
|
||||
compress/rdo_quality_loss=0.0
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
@@ -25,6 +27,10 @@ mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/channel_remap/red=0
|
||||
process/channel_remap/green=1
|
||||
process/channel_remap/blue=2
|
||||
process/channel_remap/alpha=3
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
|
After Width: | Height: | Size: 315 KiB |
|
Before Width: | Height: | Size: 114 KiB |
@@ -1,10 +1,48 @@
|
||||
[gd_scene load_steps=4 format=3 uid="uid://tsi5j1uxppa4"]
|
||||
[gd_scene load_steps=10 format=3 uid="uid://tsi5j1uxppa4"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://d1mp5sguc0b6u" path="res://stages/terrain/planet/scripts/planet.gd" id="1_y7d8a"]
|
||||
[ext_resource type="Material" uid="uid://ljvaj1vab53a" path="res://stages/terrain/planet/resources/materials/ground_contamination.tres" id="2_02xai"]
|
||||
[ext_resource type="Texture2D" uid="uid://bhs47ar83jfmr" path="res://stages/terrain/planet/resources/textures/sol_gamejam_normal.png" id="2_6qoee"]
|
||||
[ext_resource type="Shader" uid="uid://bglep64ppn74p" path="res://common/vfx/materials/shaders/textures_data_filter.gdshader" id="3_6qoee"]
|
||||
|
||||
[sub_resource type="FastNoiseLite" id="FastNoiseLite_3v4ta"]
|
||||
frequency = 0.04
|
||||
offset = Vector3(0, 10, 0)
|
||||
fractal_weighted_strength = 1.0
|
||||
|
||||
[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_7jtco"]
|
||||
width = 50
|
||||
height = 50
|
||||
noise = SubResource("FastNoiseLite_3v4ta")
|
||||
seamless_blend_skirt = 0.0
|
||||
|
||||
[sub_resource type="Gradient" id="Gradient_ydx6d"]
|
||||
colors = PackedColorArray(1, 1, 1, 1, 1, 1, 1, 1)
|
||||
|
||||
[sub_resource type="GradientTexture1D" id="GradientTexture1D_6cs2h"]
|
||||
gradient = SubResource("Gradient_ydx6d")
|
||||
width = 1
|
||||
|
||||
[sub_resource type="Gradient" id="Gradient_qxify"]
|
||||
offsets = PackedFloat32Array(0)
|
||||
colors = PackedColorArray(0, 0, 0, 1)
|
||||
|
||||
[sub_resource type="GradientTexture1D" id="GradientTexture1D_sd6ll"]
|
||||
gradient = SubResource("Gradient_qxify")
|
||||
width = 1
|
||||
|
||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_hyapw"]
|
||||
shader = ExtResource("3_6qoee")
|
||||
shader_parameter/data_texture = SubResource("NoiseTexture2D_7jtco")
|
||||
shader_parameter/data_texture_size = Vector2(120, 120)
|
||||
shader_parameter/data_texture_threshold = 0.5
|
||||
shader_parameter/texture_0 = SubResource("GradientTexture1D_6cs2h")
|
||||
shader_parameter/texture_1 = SubResource("GradientTexture1D_sd6ll")
|
||||
shader_parameter/texture_scale = 5.0
|
||||
|
||||
[node name="Planet" type="Node2D"]
|
||||
script = ExtResource("1_y7d8a")
|
||||
background_texture = ExtResource("2_6qoee")
|
||||
contamination_material = ExtResource("2_02xai")
|
||||
|
||||
[node name="Polygon2D2" type="Polygon2D" parent="."]
|
||||
visible = false
|
||||
material = SubResource("ShaderMaterial_hyapw")
|
||||
position = Vector2(-10, -10)
|
||||
polygon = PackedVector2Array(10, 10, 10, 110, 110, 110, 110, 10)
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
[gd_resource type="ShaderMaterial" load_steps=6 format=3 uid="uid://bq3dmwkej5gmx"]
|
||||
|
||||
[ext_resource type="Shader" uid="uid://bglep64ppn74p" path="res://common/vfx/materials/shaders/textures_data_filter.gdshader" id="1_kujx0"]
|
||||
[ext_resource type="Texture2D" uid="uid://beqx4rmgthkql" path="res://stages/terrain/planet/assets/textures/rock_background_texture.png" id="2_6cs2h"]
|
||||
[ext_resource type="Texture2D" uid="uid://bnrjnvceprxfn" path="res://stages/terrain/planet/assets/textures/garden_background_texture.png" id="2_ydx6d"]
|
||||
|
||||
[sub_resource type="FastNoiseLite" id="FastNoiseLite_kujx0"]
|
||||
noise_type = 0
|
||||
frequency = 0.02
|
||||
|
||||
[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_ydx6d"]
|
||||
width = 20
|
||||
height = 20
|
||||
noise = SubResource("FastNoiseLite_kujx0")
|
||||
|
||||
[resource]
|
||||
shader = ExtResource("1_kujx0")
|
||||
shader_parameter/data_texture = SubResource("NoiseTexture2D_ydx6d")
|
||||
shader_parameter/data_texture_size = Vector2(200, 200)
|
||||
shader_parameter/data_texture_threshold = 0.5
|
||||
shader_parameter/texture_0 = ExtResource("2_6cs2h")
|
||||
shader_parameter/texture_1 = ExtResource("2_ydx6d")
|
||||
shader_parameter/texture_scale = 5.0
|
||||
@@ -1,7 +1,8 @@
|
||||
[gd_resource type="ShaderMaterial" load_steps=7 format=3 uid="uid://ljvaj1vab53a"]
|
||||
[gd_resource type="ShaderMaterial" load_steps=6 format=3 uid="uid://ljvaj1vab53a"]
|
||||
|
||||
[ext_resource type="Shader" uid="uid://bglep64ppn74p" path="res://stages/terrain/planet/resources/materials/shaders/textures_data_filter.gdshader" id="1_ye8oh"]
|
||||
[ext_resource type="Texture2D" uid="uid://dcn4cq53h1qiy" path="res://stages/terrain/planet/resources/textures/sol_gamejam_fleurs_transp.png" id="3_j3avn"]
|
||||
[ext_resource type="Shader" uid="uid://bglep64ppn74p" path="res://common/vfx/materials/shaders/textures_data_filter.gdshader" id="1_ye8oh"]
|
||||
[ext_resource type="Texture2D" uid="uid://bnrjnvceprxfn" path="res://stages/terrain/planet/assets/textures/garden_background_texture.png" id="2_6hswu"]
|
||||
[ext_resource type="Texture2D" uid="uid://c3t26nlbnkxg7" path="res://stages/terrain/planet/assets/textures/garden_decontamined_background_texture.png" id="2_r7pv0"]
|
||||
|
||||
[sub_resource type="FastNoiseLite" id="FastNoiseLite_6hswu"]
|
||||
frequency = 0.0109
|
||||
@@ -9,18 +10,11 @@ frequency = 0.0109
|
||||
[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_j3avn"]
|
||||
noise = SubResource("FastNoiseLite_6hswu")
|
||||
|
||||
[sub_resource type="Gradient" id="Gradient_r7pv0"]
|
||||
offsets = PackedFloat32Array(0)
|
||||
colors = PackedColorArray(0, 0, 0, 0.12549)
|
||||
|
||||
[sub_resource type="GradientTexture1D" id="GradientTexture1D_6hswu"]
|
||||
gradient = SubResource("Gradient_r7pv0")
|
||||
|
||||
[resource]
|
||||
shader = ExtResource("1_ye8oh")
|
||||
shader_parameter/data_texture = SubResource("NoiseTexture2D_j3avn")
|
||||
shader_parameter/data_texture_size = Vector2(1000, 1000)
|
||||
shader_parameter/data_texture_threshold = 0.5
|
||||
shader_parameter/texture_0 = SubResource("GradientTexture1D_6hswu")
|
||||
shader_parameter/texture_1 = ExtResource("3_j3avn")
|
||||
shader_parameter/texture_0 = ExtResource("2_6hswu")
|
||||
shader_parameter/texture_1 = ExtResource("2_r7pv0")
|
||||
shader_parameter/texture_scale = 5.0
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
shader_type canvas_item;
|
||||
|
||||
#define pow2(x) (x * x)
|
||||
#define iResolution 1.0/SCREEN_PIXEL_SIZE
|
||||
|
||||
uniform sampler2D data_texture;
|
||||
uniform vec2 data_texture_size;
|
||||
uniform float data_texture_threshold = 0.5;
|
||||
uniform sampler2D texture_0 : filter_nearest, repeat_enable;
|
||||
uniform sampler2D texture_1 : filter_nearest, repeat_enable;
|
||||
|
||||
uniform float texture_scale = 10.;
|
||||
|
||||
//uniform float smooth_change_range = 0.15;
|
||||
|
||||
varying vec2 vert;
|
||||
|
||||
void vertex() {
|
||||
vert = VERTEX;
|
||||
}
|
||||
|
||||
void fragment() {
|
||||
vec4 pixel_color = texture(data_texture, vert/data_texture_size);
|
||||
float value = pixel_color.x;
|
||||
|
||||
vec2 texture_0_size = vec2(float(textureSize(texture_0, 0).x), float(textureSize(texture_0, 0).y)) / texture_scale;
|
||||
vec2 texture_1_size = vec2(float(textureSize(texture_1, 0).x), float(textureSize(texture_1, 0).y)) / texture_scale;
|
||||
|
||||
vec4 color = texture(texture_0, vert/texture_0_size);
|
||||
|
||||
if (value > data_texture_threshold)
|
||||
color = texture(texture_1, vert / texture_1_size);
|
||||
|
||||
COLOR = color;
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
uid://bglep64ppn74p
|
||||
|
Before Width: | Height: | Size: 931 KiB |
|
Before Width: | Height: | Size: 114 KiB |
@@ -1,34 +0,0 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://bhs47ar83jfmr"
|
||||
path="res://.godot/imported/sol_gamejam_normal.png-026e1b07759fe660eb66a9c8a302cb82.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://stages/terrain/planet/resources/textures/sol_gamejam_normal.png"
|
||||
dest_files=["res://.godot/imported/sol_gamejam_normal.png-026e1b07759fe660eb66a9c8a302cb82.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
compress/hdr_compression=1
|
||||
compress/normal_map=0
|
||||
compress/channel_pack=0
|
||||
mipmaps/generate=false
|
||||
mipmaps/limit=-1
|
||||
roughness/mode=0
|
||||
roughness/src_normal=""
|
||||
process/fix_alpha_border=true
|
||||
process/premult_alpha=false
|
||||
process/normal_map_invert_y=false
|
||||
process/hdr_as_srgb=false
|
||||
process/hdr_clamp_exposure=false
|
||||
process/size_limit=0
|
||||
detect_3d/compress_to=1
|
||||
|
Before Width: | Height: | Size: 653 KiB |
141
stages/terrain/planet/scripts/chunk.gd
Normal file
@@ -0,0 +1,141 @@
|
||||
extends Node2D
|
||||
class_name Chunk
|
||||
|
||||
const UNIT_PER_PIXEL = 30
|
||||
|
||||
var coord : Vector2i
|
||||
var size : Vector2i
|
||||
var planet : Planet
|
||||
var wall_threshold = 0.4
|
||||
var noise_image : Image
|
||||
var entity_generated : bool
|
||||
|
||||
const CHUNK_TEXTURE_SCALE : float = 3.0
|
||||
const DEFAULT_CHUNK_BACKGROUND_MATERIAL : ShaderMaterial = preload("res://stages/terrain/planet/resources/materials/default_chunk_material.tres")
|
||||
|
||||
const LOOT_NUMBER : Array[int] = [2,3,4]
|
||||
const LOOT_ITEM_NUMBER : Array[int] = [1,2]
|
||||
|
||||
var chunk_background_material
|
||||
|
||||
func _init(
|
||||
_coord : Vector2i,
|
||||
_size : Vector2i,
|
||||
_planet : Planet,
|
||||
_entity_generated = false
|
||||
):
|
||||
coord = _coord
|
||||
size = _size
|
||||
planet = _planet
|
||||
entity_generated = _entity_generated
|
||||
|
||||
func _ready():
|
||||
noise_image = generate_noise()
|
||||
generate_background_sprite()
|
||||
global_position = coord * size
|
||||
generate_walls()
|
||||
if not entity_generated:
|
||||
generate_loot()
|
||||
|
||||
func generate_noise() -> Image:
|
||||
var image_size = Vector2i(
|
||||
roundi(float(size.x) / UNIT_PER_PIXEL),
|
||||
roundi(float(size.y) / UNIT_PER_PIXEL)
|
||||
)
|
||||
var noise: FastNoiseLite = FastNoiseLite.new()
|
||||
noise.seed = planet.data.planet_seed
|
||||
noise.noise_type = FastNoiseLite.TYPE_SIMPLEX_SMOOTH
|
||||
noise.frequency = 0.05
|
||||
noise.fractal_weighted_strength = 1.0
|
||||
noise.offset = Vector3(
|
||||
image_size.x * coord.x,
|
||||
image_size.y * coord.y,
|
||||
1
|
||||
)
|
||||
|
||||
var image = noise.get_image(
|
||||
image_size.x,
|
||||
image_size.y,
|
||||
1.0,
|
||||
)
|
||||
|
||||
return image
|
||||
|
||||
func generate_background_sprite() -> Polygon2D:
|
||||
var sprite :Polygon2D = generate_polygon_sprite()
|
||||
|
||||
sprite.texture = ImageTexture.create_from_image(noise_image)
|
||||
|
||||
var background_material = DEFAULT_CHUNK_BACKGROUND_MATERIAL.duplicate_deep()
|
||||
|
||||
background_material.set_shader_parameter("data_texture", ImageTexture.create_from_image(noise_image))
|
||||
background_material.set_shader_parameter("data_texture_size", size)
|
||||
background_material.set_shader_parameter("data_texture_threshold", wall_threshold)
|
||||
background_material.set_shader_parameter("texture_scale", CHUNK_TEXTURE_SCALE)
|
||||
|
||||
sprite.material = background_material
|
||||
|
||||
return sprite
|
||||
|
||||
func generate_polygon_sprite() -> Polygon2D:
|
||||
var sprite = Polygon2D.new()
|
||||
sprite.polygon = PackedVector2Array([
|
||||
Vector2(0,0),
|
||||
Vector2(size.x, 0),
|
||||
Vector2(size.x, size.y),
|
||||
Vector2(0, size.y),
|
||||
])
|
||||
|
||||
sprite.z_index = -100
|
||||
|
||||
add_child(sprite)
|
||||
|
||||
return sprite
|
||||
|
||||
func generate_walls():
|
||||
var static_body = StaticBody2D.new()
|
||||
add_child(static_body)
|
||||
var wall_resolution_factor = 25
|
||||
|
||||
for x in range(1, size.x, wall_resolution_factor):
|
||||
for y in range(1, size.y, wall_resolution_factor):
|
||||
if is_wall(Vector2(x, y)):
|
||||
var new_collision_shape = CollisionShape2D.new()
|
||||
new_collision_shape.shape = CircleShape2D.new()
|
||||
new_collision_shape.shape.radius = wall_resolution_factor / 2.
|
||||
static_body.add_child(new_collision_shape)
|
||||
new_collision_shape.global_position = Vector2i(x, y) + coord * size + Vector2i.ONE * 5
|
||||
|
||||
func generate_loot(number : int = LOOT_NUMBER.pick_random()):
|
||||
for i in range(number):
|
||||
var loot = UndergroundLoot.new()
|
||||
for j in range(LOOT_ITEM_NUMBER.pick_random()):
|
||||
loot.loot.append(
|
||||
Seed.new(GameInfo.game_data.unlocked_plant_types.pick_random())
|
||||
)
|
||||
|
||||
|
||||
var max_placement_try = 10
|
||||
var valid_coord = false
|
||||
while max_placement_try > 0 and not valid_coord:
|
||||
var random_position = Vector2(
|
||||
randf_range(0, size.x),
|
||||
randf_range(0, size.y)
|
||||
)
|
||||
if not is_wall(random_position):
|
||||
planet.add_entity(loot, random_position + Vector2(coord * size))
|
||||
valid_coord = true
|
||||
else :
|
||||
max_placement_try -= 1
|
||||
|
||||
func get_pixel_point(point : Vector2) -> Vector2i:
|
||||
var vec : Vector2 = Vector2(point) / UNIT_PER_PIXEL - Vector2.ONE
|
||||
return Vector2i(
|
||||
roundi(vec.x + 0.5),
|
||||
roundi(vec.y + 0.5)
|
||||
)
|
||||
|
||||
|
||||
func is_wall(game_point : Vector2) -> bool:
|
||||
var pixel_point = get_pixel_point(game_point)
|
||||
return noise_image.get_pixel(pixel_point.x, pixel_point.y).r < wall_threshold
|
||||
1
stages/terrain/planet/scripts/chunk.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://d2ixbaa2uqlv4
|
||||
108
stages/terrain/planet/scripts/garden.gd
Normal file
@@ -0,0 +1,108 @@
|
||||
extends Node2D
|
||||
class_name Garden
|
||||
|
||||
const GARDEN_TEXTURE_SCALE : float = 3.0
|
||||
|
||||
var contamination_material : ShaderMaterial = preload("res://stages/terrain/planet/resources/materials/ground_contamination.tres")
|
||||
|
||||
var contamination_sprite : Polygon2D
|
||||
var contamination_texture : Texture2D
|
||||
var decontamination_surface : float
|
||||
|
||||
var plants : Array[Plant]
|
||||
var planet_data : PlanetData
|
||||
|
||||
var size = PlanetData.DEFAULT_GARDEN_SIZE
|
||||
|
||||
func _init(_planet_data : PlanetData, _initial_plants : Array[Plant] = []):
|
||||
planet_data = _planet_data
|
||||
plants = _initial_plants
|
||||
|
||||
func _ready():
|
||||
contamination_sprite = generate_contamination_terrain_sprite()
|
||||
decontamination_surface = planet_data.get_decontamination_surface()
|
||||
|
||||
for p in plants:
|
||||
p.harvested.connect(_on_plant_harvested)
|
||||
p.state_changed.connect(_on_plant_state_changed)
|
||||
update_garden_score()
|
||||
|
||||
func generate_contamination_terrain_sprite() -> Polygon2D:
|
||||
if not planet_data.garden_contamination:
|
||||
planet_data.generate_default_contamination()
|
||||
|
||||
var sprite :Polygon2D = generate_polygon_sprite(size, 1)
|
||||
|
||||
contamination_texture = ImageTexture.create_from_image(planet_data.garden_contamination.image)
|
||||
|
||||
contamination_material.set_shader_parameter("data_texture", contamination_texture)
|
||||
contamination_material.set_shader_parameter("data_texture_size", size)
|
||||
contamination_material.set_shader_parameter("texture_scale", GARDEN_TEXTURE_SCALE)
|
||||
|
||||
sprite.material = contamination_material
|
||||
|
||||
return sprite
|
||||
|
||||
func get_score():
|
||||
var score = 0
|
||||
for p in plants:
|
||||
score += p.calculate_plant_score()
|
||||
return score
|
||||
|
||||
func plant(
|
||||
type : PlantType,
|
||||
plant_mutations : Array[PlantMutation] = []
|
||||
) -> Plant:
|
||||
var new_plant = Plant.new(
|
||||
type,
|
||||
plant_mutations
|
||||
)
|
||||
|
||||
plants.append(new_plant)
|
||||
new_plant.harvested.connect(_on_plant_harvested)
|
||||
new_plant.state_changed.connect(_on_plant_state_changed)
|
||||
update_garden_score()
|
||||
return new_plant
|
||||
|
||||
func _on_plant_state_changed(_p: Plant):
|
||||
update_garden_score()
|
||||
|
||||
func _on_plant_harvested(p: Plant):
|
||||
remove_plant(p)
|
||||
|
||||
func remove_plant(p: Plant):
|
||||
var id = plants.find(p)
|
||||
if id >= 0:
|
||||
plants.remove_at(id)
|
||||
update_garden_score()
|
||||
|
||||
|
||||
func update_garden_score():
|
||||
planet_data.garden_score = get_score()
|
||||
|
||||
func impact_contamination(impact_position : Vector2, impact_radius : int, contamination : bool = false):
|
||||
planet_data.impact_contamination(impact_position, impact_radius, 0. if contamination else 1.)
|
||||
if contamination_texture:
|
||||
contamination_texture.update(planet_data.garden_contamination.image)
|
||||
|
||||
func generate_polygon_sprite(s : Vector2 = size, order : int = 0) -> Polygon2D:
|
||||
var sprite = Polygon2D.new()
|
||||
sprite.polygon = PackedVector2Array([
|
||||
Vector2(0,0),
|
||||
Vector2(s.x, 0),
|
||||
Vector2(s.x, s.y),
|
||||
Vector2(0, s.y),
|
||||
])
|
||||
|
||||
sprite.z_index = -100 + order
|
||||
|
||||
add_child(sprite)
|
||||
|
||||
return sprite
|
||||
|
||||
|
||||
func is_in_garden(point : Vector2) -> bool:
|
||||
return planet_data.is_in_garden(point)
|
||||
|
||||
func is_there_contamination(point : Vector2) -> bool:
|
||||
return planet_data.get_contamination(point) < 0.5
|
||||
1
stages/terrain/planet/scripts/garden.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dpgtjhjgfqquj
|
||||
@@ -1,80 +1,51 @@
|
||||
extends Terrain
|
||||
class_name Planet
|
||||
|
||||
signal planet_updated(planet : Planet)
|
||||
signal day_limit_exceed(planet : Planet)
|
||||
signal pass_day_started(planet : Planet)
|
||||
signal pass_day_proceeded(planet : Planet)
|
||||
signal pass_day_ended(planet : Planet)
|
||||
signal quota_reward_asked(planet : Planet, item1 : Item, item2 : Item)
|
||||
signal new_quota_started(planet : Planet)
|
||||
|
||||
const PASS_DAY_ANIMATION_TIME : float = 1.5
|
||||
const DEFAULT_DAY_LIMIT : int = 7
|
||||
const PLANET_TEXTURE_SCALE : float = 5.0
|
||||
const OBJECTIVE_MAX_LEVEL : int = 10
|
||||
const OBJECTIVE_MIN_ANGLE_DIFF = PI/2
|
||||
const OBJECTIVE_FIRST_DISTANCE = 200
|
||||
const OBJECTIVE_BETWEEN_DISTANCE = 50
|
||||
|
||||
@export_group("Loot")
|
||||
@export var first_loot_number : int = 3
|
||||
@export var loot_number : Array[int] = [0,1,2]
|
||||
@export var loot_item_number : Array[int] = [1,2]
|
||||
|
||||
@export_group("Textures")
|
||||
@export var background_texture : Texture2D
|
||||
@export var contamination_material : ShaderMaterial
|
||||
|
||||
var background_sprite : Polygon2D
|
||||
var contamination_sprite : Polygon2D
|
||||
var decontamination_surface : float
|
||||
var garden_score : int
|
||||
|
||||
@onready var objective_scene : PackedScene = preload("res://entities/objectives/objective.tscn")
|
||||
var terrain_size = Vector2.ONE * 1000 :
|
||||
set(v):
|
||||
terrain_size = v
|
||||
if border_limit:
|
||||
border_limit.queue_free()
|
||||
border_limit = create_border_limit()
|
||||
|
||||
@onready var border_limit : StaticBody2D = create_border_limit()
|
||||
|
||||
var planet_data : PlanetData
|
||||
var data : PlanetData
|
||||
|
||||
var contamination_texture : ImageTexture
|
||||
var day : int = 1
|
||||
var day_limit = DEFAULT_DAY_LIMIT
|
||||
var days_on_last_quota : int = 0
|
||||
var last_quota : float = 0
|
||||
var next_quota : float
|
||||
var garden : Garden = null
|
||||
|
||||
var generated_chunks_objects : Array[Vector2i] = []
|
||||
|
||||
func _ready():
|
||||
planet_data = GameInfo.game_data.current_planet_data if GameInfo.game_data.current_planet_data else PlanetData.new()
|
||||
data = GameInfo.game_data.current_planet_data
|
||||
|
||||
terrain_size = planet_data.base_size
|
||||
entity_container.position = terrain_size/2
|
||||
entity_container.position = PlanetData.DEFAULT_GARDEN_SIZE/2
|
||||
load_entities(data.entities_saved_data)
|
||||
|
||||
background_sprite = generate_background_sprite()
|
||||
contamination_sprite = generate_contamination_terrain_sprite()
|
||||
decontamination_surface = planet_data.get_decontamination_surface()
|
||||
GameInfo.game_data.current_planet_data_updated.connect(
|
||||
func (surface):
|
||||
if surface:
|
||||
decontamination_surface = surface
|
||||
)
|
||||
var plants : Array[Plant] = []
|
||||
for e in entity_container.get_children():
|
||||
if e is Plant:
|
||||
plants.append(e)
|
||||
|
||||
garden_score = get_garden_score()
|
||||
garden = Garden.new(data, plants)
|
||||
add_child(garden)
|
||||
|
||||
next_quota = planet_data.get_quota()
|
||||
days_on_last_quota = day
|
||||
generate_first_entities()
|
||||
|
||||
generate_loot(first_loot_number)
|
||||
# generate_objectives()
|
||||
planet_updated.emit(self)
|
||||
|
||||
new_quota_started.emit(self)
|
||||
if player:
|
||||
generate_near_chunks(player)
|
||||
|
||||
func _process(_d):
|
||||
if player:
|
||||
generate_near_chunks(player)
|
||||
|
||||
# queue_redraw()
|
||||
|
||||
@@ -87,90 +58,47 @@ func _ready():
|
||||
# draw_circle(
|
||||
# point,
|
||||
# factor/10,
|
||||
# Color.BLUE if is_there_contamination(point) else Color.RED,
|
||||
# Color.BLUE if garden.is_there_contamination(point) else Color.RED,
|
||||
# true
|
||||
# )
|
||||
|
||||
#region ------------------ Generation ------------------
|
||||
|
||||
func instantiate_entity(s: PackedScene, entity_position : Vector2):
|
||||
var entity = s.instantiate() as Node2D
|
||||
func generate_first_entities():
|
||||
if not (Vector2i.ZERO in data.generated_chunk_entities):
|
||||
# Generate shovel
|
||||
drop_item(Shovel.new(), PlanetData.DEFAULT_GARDEN_SIZE/2 + Vector2(0, 100))
|
||||
|
||||
add_entity(entity)
|
||||
# Generate first loots
|
||||
generate_loot(first_loot_number)
|
||||
data.generated_chunk_entities.append(Vector2i.ZERO)
|
||||
|
||||
entity.global_position = entity_position
|
||||
func generate_near_chunks(p : Player):
|
||||
var player_chunk_coord = Vector2i(
|
||||
floor(p.global_position.x / PlanetData.DEFAULT_GARDEN_SIZE.x),
|
||||
floor(p.global_position.y / PlanetData.DEFAULT_GARDEN_SIZE.y)
|
||||
)
|
||||
|
||||
func instantiate_machine(m_type : MachineType, level, machine_position : Vector2):
|
||||
var machine = m_type.scene.instantiate() as Machine
|
||||
machine.setup_machine_info(m_type, level)
|
||||
for x in [-1, 0, 1]:
|
||||
for y in [-1, 0, 1]:
|
||||
var coord = Vector2i(x,y) + player_chunk_coord
|
||||
if coord != Vector2i.ZERO and generated_chunks_objects.find(coord) == -1:
|
||||
generate_chunk(coord)
|
||||
|
||||
add_entity(machine)
|
||||
func generate_chunk(coord : Vector2i):
|
||||
if generated_chunks_objects.find(coord) == -1:
|
||||
generated_chunks_objects.append(coord)
|
||||
var new_chunk = Chunk.new(
|
||||
coord,
|
||||
PlanetData.DEFAULT_GARDEN_SIZE,
|
||||
self,
|
||||
(data.generated_chunk_entities.find(coord) != -1)
|
||||
)
|
||||
add_child(new_chunk)
|
||||
data.generated_chunk_entities.append(coord)
|
||||
|
||||
machine.global_position = machine_position
|
||||
|
||||
func generate_polygon_sprite(order : int = 0) -> Polygon2D:
|
||||
var sprite = Polygon2D.new()
|
||||
var size = terrain_size
|
||||
sprite.polygon = PackedVector2Array([
|
||||
Vector2(0,0),
|
||||
Vector2(size.x, 0),
|
||||
Vector2(size.x, size.y),
|
||||
Vector2(0, size.y),
|
||||
])
|
||||
|
||||
sprite.z_index = -100 + order
|
||||
|
||||
add_child(sprite)
|
||||
|
||||
return sprite
|
||||
|
||||
func generate_background_sprite() -> Polygon2D:
|
||||
var sprite : Polygon2D = generate_polygon_sprite(0)
|
||||
|
||||
sprite.texture = background_texture
|
||||
sprite.texture_repeat = CanvasItem.TEXTURE_REPEAT_ENABLED
|
||||
sprite.texture_scale = Vector2.ONE * PLANET_TEXTURE_SCALE
|
||||
|
||||
return sprite
|
||||
|
||||
func generate_contamination_terrain_sprite() -> Polygon2D:
|
||||
if not planet_data.contamination:
|
||||
planet_data.generate_default_contamination()
|
||||
|
||||
var sprite :Polygon2D = generate_polygon_sprite(1)
|
||||
|
||||
contamination_texture = ImageTexture.create_from_image(planet_data.contamination.image)
|
||||
|
||||
contamination_material.set_shader_parameter("data_texture", contamination_texture)
|
||||
contamination_material.set_shader_parameter("data_texture_size", terrain_size)
|
||||
contamination_material.set_shader_parameter("texture_scale", PLANET_TEXTURE_SCALE)
|
||||
|
||||
sprite.material = contamination_material
|
||||
|
||||
return sprite
|
||||
|
||||
func create_border_limit() -> StaticBody2D:
|
||||
var static_body = StaticBody2D.new()
|
||||
var static_body_collision = CollisionPolygon2D.new()
|
||||
|
||||
add_child(static_body)
|
||||
static_body.add_child(static_body_collision)
|
||||
|
||||
var size = terrain_size
|
||||
static_body_collision.polygon = PackedVector2Array([
|
||||
Vector2(0,0),
|
||||
Vector2(0, size.y),
|
||||
Vector2(size.x, size.y),
|
||||
Vector2(size.x, 0),
|
||||
Vector2(0,0),
|
||||
Vector2(-BORDER_WIDTH, -BORDER_WIDTH),
|
||||
Vector2(size.x + BORDER_WIDTH, -BORDER_WIDTH),
|
||||
Vector2(size.x + BORDER_WIDTH, size.y + BORDER_WIDTH),
|
||||
Vector2(- BORDER_WIDTH, size.y + BORDER_WIDTH),
|
||||
Vector2(-BORDER_WIDTH, -BORDER_WIDTH)
|
||||
])
|
||||
|
||||
return static_body
|
||||
func save():
|
||||
data.entities_saved_data = save_entities()
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -181,30 +109,11 @@ func plant(
|
||||
plant_position : Vector2,
|
||||
plant_mutations : Array[PlantMutation] = []
|
||||
) -> bool:
|
||||
if is_there_contamination(plant_position):
|
||||
return false
|
||||
|
||||
var new_plant = Plant.new(
|
||||
type,
|
||||
self,
|
||||
plant_mutations
|
||||
)
|
||||
add_entity(new_plant)
|
||||
new_plant.global_position = plant_position
|
||||
garden_score = get_garden_score()
|
||||
return true
|
||||
|
||||
func impact_contamination(impact_position : Vector2, impact_radius : int, contamination : bool = false):
|
||||
planet_data.impact_contamination(impact_position, impact_radius, 0. if contamination else 1.)
|
||||
if contamination_texture:
|
||||
contamination_texture.update(planet_data.contamination.image)
|
||||
planet_updated.emit(self)
|
||||
|
||||
func is_in_base(point : Vector2) -> bool:
|
||||
return planet_data.is_in_base(point)
|
||||
|
||||
func is_there_contamination(point : Vector2) -> bool:
|
||||
return planet_data.get_contamination(point) < 0.5
|
||||
if garden.is_in_garden(plant_position):
|
||||
var new_plant = garden.plant(type, plant_mutations)
|
||||
add_entity(new_plant, plant_position)
|
||||
return true
|
||||
return false
|
||||
|
||||
func pass_day():
|
||||
for e : Node2D in entity_container.get_children():
|
||||
@@ -213,9 +122,9 @@ func pass_day():
|
||||
pass_day_started.emit(self)
|
||||
await get_tree().create_timer(PASS_DAY_ANIMATION_TIME/2.).timeout
|
||||
|
||||
generate_loot()
|
||||
pass_day_proceeded.emit(self)
|
||||
day += 1
|
||||
data.day += 1
|
||||
data.quota_days -= 1
|
||||
for e : Node2D in entity_container.get_children():
|
||||
if e.has_method("_pass_day"):
|
||||
e._pass_day()
|
||||
@@ -226,16 +135,15 @@ func pass_day():
|
||||
if e.has_method("_end_pass_day"):
|
||||
e._end_pass_day()
|
||||
|
||||
garden_score = get_garden_score()
|
||||
if garden_score >= next_quota:
|
||||
if data.garden_score >= data.get_quota_score():
|
||||
reach_quota()
|
||||
|
||||
if get_quota_remaining_days() <= 0:
|
||||
if data.quota_days <= 0:
|
||||
day_limit_exceed.emit(self)
|
||||
|
||||
planet_updated.emit(self)
|
||||
save()
|
||||
|
||||
func generate_loot(number : int = loot_number.pick_random()):
|
||||
func generate_loot(number : int):
|
||||
for i in range(number):
|
||||
var loot = UndergroundLoot.new()
|
||||
for j in range(loot_item_number.pick_random()):
|
||||
@@ -243,47 +151,19 @@ func generate_loot(number : int = loot_number.pick_random()):
|
||||
Seed.new(GameInfo.game_data.unlocked_plant_types.pick_random())
|
||||
)
|
||||
|
||||
add_entity(loot)
|
||||
|
||||
var loot_random_range = UndergroundLoot.LOOTED_ITEM_RANDOM_RANGE
|
||||
|
||||
loot.global_position = Vector2(
|
||||
randf_range(loot_random_range, terrain_size.x - loot_random_range),
|
||||
randf_range(loot_random_range, terrain_size.y - loot_random_range)
|
||||
|
||||
add_entity(
|
||||
loot,
|
||||
Vector2(
|
||||
randf_range(loot_random_range, garden.size.x),
|
||||
randf_range(loot_random_range, garden.size.y)
|
||||
)
|
||||
)
|
||||
|
||||
func generate_objectives():
|
||||
var last_objective_angle = 10
|
||||
for i in range(OBJECTIVE_MAX_LEVEL):
|
||||
var objective_rewards : Array[ObjectiveReward] = planet_data.generate_objective_rewards(i)
|
||||
|
||||
for objective_reward in objective_rewards:
|
||||
var objective_angle = randf_range(0, PI*2)
|
||||
while abs(objective_angle - last_objective_angle) < OBJECTIVE_MIN_ANGLE_DIFF:
|
||||
objective_angle = randf_range(0, PI*2)
|
||||
|
||||
last_objective_angle = objective_angle
|
||||
|
||||
generate_objective(
|
||||
OBJECTIVE_FIRST_DISTANCE + OBJECTIVE_BETWEEN_DISTANCE * i,
|
||||
objective_angle,
|
||||
objective_reward,
|
||||
)
|
||||
|
||||
func generate_objective(distance : int, angle : float, reward : ObjectiveReward):
|
||||
var objective : Objective = objective_scene.instantiate() as Objective
|
||||
add_entity(objective)
|
||||
objective.reward = reward
|
||||
|
||||
objective.position = Vector2.ONE.rotated(angle) * distance
|
||||
|
||||
func reach_quota():
|
||||
planet_data.quota_number += 1
|
||||
last_quota = next_quota
|
||||
next_quota = planet_data.get_quota(planet_data.quota_number)
|
||||
days_on_last_quota = day
|
||||
|
||||
new_quota_started.emit(self)
|
||||
data.quota += 1
|
||||
data.quota_days = data.get_quota_duration()
|
||||
|
||||
func ask_quota_reward():
|
||||
quota_reward_asked.emit(
|
||||
@@ -294,30 +174,10 @@ func ask_quota_reward():
|
||||
|
||||
func generate_quota_reward() -> Item:
|
||||
var random_level = randi_range(
|
||||
max(planet_data.quota_number - 1, 1),
|
||||
min(planet_data.quota_number, Machine.MAX_MACHINE_LEVEL),
|
||||
max(data.quota - 1, 1),
|
||||
min(data.quota, Machine.MAX_MACHINE_LEVEL),
|
||||
)
|
||||
var random_machine_type = GameInfo.game_data.unlocked_machines.pick_random()
|
||||
return Blueprint.new(random_machine_type, random_level)
|
||||
|
||||
func get_garden_score():
|
||||
var score = 0
|
||||
for e in entity_container.get_children():
|
||||
if e is Plant:
|
||||
score += e.calculate_plant_score()
|
||||
return score
|
||||
|
||||
func update_garden_score():
|
||||
garden_score = get_garden_score()
|
||||
|
||||
func choose_quota_reward(item : Item):
|
||||
drop_item(item, player.global_position, 100)
|
||||
if decontamination_surface >= next_quota:
|
||||
reach_quota()
|
||||
else :
|
||||
new_quota_started.emit(self)
|
||||
|
||||
func get_quota_remaining_days():
|
||||
return DEFAULT_DAY_LIMIT - (day - days_on_last_quota)
|
||||
|
||||
#endregion
|
||||
|
||||
109
stages/terrain/planet/scripts/planet_data.gd
Normal file
@@ -0,0 +1,109 @@
|
||||
extends Resource
|
||||
class_name PlanetData
|
||||
|
||||
signal new_quota_started(planet_data : PlanetData)
|
||||
signal contamination_updated(decontamination_surface : float)
|
||||
signal updated(planet_data : PlanetData)
|
||||
|
||||
const MAX_DEFAULT_CONTAMINATION_ZONE_SURFACE = 3000
|
||||
const DEFAULT_GARDEN_SIZE = Vector2(1500,1500)
|
||||
|
||||
@export var garden_size : Vector2 = Vector2(2000,2000)
|
||||
@export var garden_contamination : TerrainData
|
||||
@export var quota : int = 0 :
|
||||
set(v):
|
||||
quota = v
|
||||
is_quota_announced = false
|
||||
new_quota_started.emit(self)
|
||||
@export var is_quota_announced : bool = false
|
||||
@export var garden_score : int = 0 :
|
||||
set(v):
|
||||
garden_score = v
|
||||
updated.emit(self)
|
||||
@export var day : int = 1
|
||||
@export var planet_seed : int
|
||||
@export var quota_days : int = get_quota_duration() :
|
||||
set(v):
|
||||
quota_days = v
|
||||
updated.emit(self)
|
||||
@export var entities_saved_data : Array[EntityData] = []
|
||||
@export var generated_chunk_entities : Array[Vector2i]
|
||||
@export var tutorial_step : int = 0
|
||||
|
||||
func _init(_base_size : Vector2 = DEFAULT_GARDEN_SIZE):
|
||||
planet_seed = randi()
|
||||
garden_size = _base_size
|
||||
garden_contamination = TerrainData.new(garden_size)
|
||||
garden_contamination.draw_random_zone(
|
||||
MAX_DEFAULT_CONTAMINATION_ZONE_SURFACE,
|
||||
garden_size/2,
|
||||
planet_seed
|
||||
)
|
||||
contamination_updated.emit(get_decontamination_surface())
|
||||
|
||||
|
||||
func impact_contamination(position : Vector2, impact_radius : float, to_value : float = 1.):
|
||||
garden_contamination.draw_circle(
|
||||
position,
|
||||
impact_radius,
|
||||
to_value
|
||||
)
|
||||
contamination_updated.emit(get_decontamination_surface())
|
||||
|
||||
func is_in_garden(point):
|
||||
return (
|
||||
point.x > 0
|
||||
and point.y > 0
|
||||
and point.x < garden_size.x
|
||||
and point.y < garden_size.y)
|
||||
|
||||
func get_contamination(point : Vector2) -> float:
|
||||
return garden_contamination.get_value(point)
|
||||
|
||||
func get_decontamination_coverage() -> float:
|
||||
return garden_contamination.get_value_coverage()
|
||||
|
||||
func get_decontamination_surface() -> float:
|
||||
return garden_contamination.get_value_surface()
|
||||
|
||||
#region ------------------ Objectives ------------------
|
||||
func generate_objective_rewards(level = 0) -> Array[ObjectiveReward]:
|
||||
var amount = level + 1
|
||||
|
||||
var possible_objective_rewards_path : Array[ObjectiveReward] = [
|
||||
LootRandomSeedsReward.new(randi_range(4+level, 6+level))
|
||||
]
|
||||
|
||||
var objectives_reward : Array[ObjectiveReward] = []
|
||||
|
||||
var i = 0
|
||||
while i < amount and len(possible_objective_rewards_path) > 0:
|
||||
var r = possible_objective_rewards_path.pick_random()
|
||||
possible_objective_rewards_path.erase(r)
|
||||
objectives_reward.append(r)
|
||||
i += 1
|
||||
|
||||
return objectives_reward
|
||||
|
||||
#endregion
|
||||
|
||||
#region ------------------ Quotas ------------------
|
||||
func get_quota_score(q = quota) -> int:
|
||||
var first_quotas = [
|
||||
4,
|
||||
10,
|
||||
20,
|
||||
40,
|
||||
80,
|
||||
]
|
||||
|
||||
if quota >= len(first_quotas):
|
||||
return pow(q, 3)
|
||||
else:
|
||||
return first_quotas[q]
|
||||
|
||||
func get_quota_duration(_q = quota) -> int:
|
||||
return 7
|
||||
|
||||
#endregion
|
||||
|
||||
1
stages/terrain/planet/scripts/planet_data.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cx30nvq8b34lj
|
||||
105
stages/terrain/planet/scripts/terrain_data.gd
Normal file
@@ -0,0 +1,105 @@
|
||||
extends Resource
|
||||
class_name TerrainData
|
||||
|
||||
const UNIT_PER_PIXEL = 30
|
||||
|
||||
@export var image : Image
|
||||
@export var image_size : Vector2i
|
||||
|
||||
func _init(terrain_size : Vector2):
|
||||
image_size = terrain_size / UNIT_PER_PIXEL
|
||||
image = Image.create(
|
||||
image_size.x,
|
||||
image_size.y,
|
||||
false,
|
||||
Image.Format.FORMAT_L8
|
||||
)
|
||||
|
||||
func draw_random_zone(
|
||||
zone_max_surface : float,
|
||||
zone_position : Vector2i,
|
||||
random_seed : int,
|
||||
):
|
||||
var noise: Noise = FastNoiseLite.new()
|
||||
noise.seed = random_seed
|
||||
noise.noise_type = FastNoiseLite.TYPE_CELLULAR
|
||||
noise.frequency = 0.3
|
||||
|
||||
var noise_image_size : Vector2i = Vector2i.ONE * (image_size)
|
||||
var noise_image_center = noise_image_size / 2
|
||||
|
||||
var noise_image = noise.get_image(
|
||||
noise_image_size.x,
|
||||
noise_image_size.y,
|
||||
1.0,
|
||||
)
|
||||
|
||||
ImageTools.flatten(noise_image, 0.5)
|
||||
|
||||
ImageTools.draw_circle(
|
||||
noise_image,
|
||||
noise_image_center,
|
||||
80/UNIT_PER_PIXEL,
|
||||
Color.WHITE,
|
||||
)
|
||||
|
||||
var random_step = 1
|
||||
var zone_radius = noise_image_size.x - random_step
|
||||
while get_value_surface(noise_image) > zone_max_surface:
|
||||
zone_radius -= random_step
|
||||
ImageTools.draw_circle(
|
||||
noise_image,
|
||||
noise_image_center,
|
||||
zone_radius,
|
||||
Color.BLACK,
|
||||
true
|
||||
)
|
||||
|
||||
image.blit_rect(
|
||||
noise_image,
|
||||
Rect2i(
|
||||
Vector2i.ZERO,
|
||||
noise_image_size
|
||||
),
|
||||
Vector2i(zone_position / UNIT_PER_PIXEL) - noise_image_size/2
|
||||
)
|
||||
|
||||
func draw_circle(position : Vector2, impact_radius : float, to_value : float = 1.):
|
||||
ImageTools.draw_circle(
|
||||
image,
|
||||
position / UNIT_PER_PIXEL,
|
||||
roundi(impact_radius / UNIT_PER_PIXEL),
|
||||
Color(1., 1., 1., to_value)
|
||||
)
|
||||
|
||||
func is_in_image(pixel_point : Vector2i):
|
||||
return (
|
||||
pixel_point.x > 0
|
||||
and pixel_point.y > 0
|
||||
and pixel_point.x < image.get_width()
|
||||
and pixel_point.y < image.get_height())
|
||||
|
||||
func is_in_terrain(point : Vector2):
|
||||
return is_in_image(get_pixel_point(point))
|
||||
|
||||
func get_value(point : Vector2) -> float:
|
||||
var pixel_point : Vector2i = get_pixel_point(point)
|
||||
if (is_in_image(pixel_point)):
|
||||
return image.get_pixel(
|
||||
pixel_point.x,
|
||||
pixel_point.y
|
||||
).r
|
||||
return 0
|
||||
|
||||
func get_value_coverage(i : Image = image) -> float:
|
||||
return ImageTools.get_color_coverage(i)
|
||||
|
||||
func get_value_surface(i : Image = image) -> float:
|
||||
return float(ImageTools.get_color_pixel_count(i)) * UNIT_PER_PIXEL
|
||||
|
||||
func get_pixel_point(point : Vector2) -> Vector2i:
|
||||
var vec : Vector2 = Vector2(point) / UNIT_PER_PIXEL - Vector2.ONE
|
||||
return Vector2i(
|
||||
roundi(vec.x + 0.5),
|
||||
roundi(vec.y + 0.5)
|
||||
)
|
||||
1
stages/terrain/planet/scripts/terrain_data.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://we5pyyr1n06v
|
||||
@@ -9,17 +9,43 @@ var player : Player
|
||||
|
||||
@onready var entity_container : Node2D = create_entity_container()
|
||||
|
||||
func add_entity(e : Node2D, container : Node2D = entity_container):
|
||||
if e.get_parent():
|
||||
e.get_parent().remove_child(e)
|
||||
func instantiate_entity(s: PackedScene, entity_position : Vector2):
|
||||
var entity = s.instantiate() as Node2D
|
||||
|
||||
if "terrain" in e:
|
||||
e.terrain = self
|
||||
add_entity(entity, entity_position)
|
||||
|
||||
if e is Player:
|
||||
player = e
|
||||
entity.global_position = entity_position
|
||||
|
||||
container.add_child(e)
|
||||
func add_entity(entity : Node2D, entity_global_position : Vector2 = Vector2.ZERO, container : Node2D = entity_container):
|
||||
if entity.get_parent():
|
||||
if entity.get_parent().get_parent() is Terrain:
|
||||
entity.get_parent().get_parent().remove_entity(entity)
|
||||
else:
|
||||
entity.get_parent().remove_child(entity)
|
||||
|
||||
if "terrain" in entity:
|
||||
entity.terrain = self
|
||||
|
||||
if entity is Player:
|
||||
player = entity
|
||||
|
||||
container.add_child(entity)
|
||||
entity.global_position = entity_global_position
|
||||
|
||||
func save_entities() -> Array[EntityData]:
|
||||
var saved_entities_data : Array[EntityData] = []
|
||||
for e in entity_container.get_children():
|
||||
if e is Entity:
|
||||
var saved_data : EntityData = e.save()
|
||||
if saved_data:
|
||||
saved_entities_data.append(saved_data)
|
||||
return saved_entities_data
|
||||
|
||||
func load_entities(saved_entities_data : Array[EntityData]):
|
||||
for save_data in saved_entities_data:
|
||||
var entity = save_data.load()
|
||||
if entity:
|
||||
add_entity(entity, save_data.position)
|
||||
|
||||
func remove_entity(e : Node2D, container : Node2D = entity_container):
|
||||
if e.get_parent() == entity_container:
|
||||
@@ -33,14 +59,17 @@ func create_entity_container() -> Node2D:
|
||||
|
||||
if import_entities_from_node:
|
||||
for child in import_entities_from_node.get_children():
|
||||
add_entity(child, container)
|
||||
add_entity(
|
||||
child,
|
||||
child.global_position + (container.global_position - import_entities_from_node.global_position),
|
||||
container
|
||||
)
|
||||
|
||||
return container
|
||||
|
||||
func drop_item(item: Item, item_position : Vector2, random_displacement_factor = 0) -> ItemObject:
|
||||
var item_object = ItemObject.new(item)
|
||||
add_entity(item_object)
|
||||
item_object.global_position = item_position
|
||||
add_entity(item_object, item_position)
|
||||
|
||||
if random_displacement_factor:
|
||||
var displacement_direction = randf_range(0,2*PI)
|
||||
|
||||
7
stages/terrain/truck/scripts/truck_data.gd
Normal file
@@ -0,0 +1,7 @@
|
||||
extends Resource
|
||||
class_name TruckData
|
||||
|
||||
@export var rewards : Array[Reward] = []
|
||||
@export var rewarded_times : int = 0
|
||||
@export var compost_containing_seeds : Array[int] = []
|
||||
@export var entities_saved_data : Array[EntityData] = []
|
||||
1
stages/terrain/truck/scripts/truck_data.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dyx17r0phlodb
|
||||
@@ -1,53 +1,69 @@
|
||||
extends Terrain
|
||||
class_name TruckInterior
|
||||
|
||||
const PLANET_RUN_PATH = "res://stages/planet_run/planet_run.tscn"
|
||||
|
||||
@export var composts : Array[Compost]
|
||||
var rewarded_times = 0
|
||||
signal player_exited(player : Player)
|
||||
|
||||
@onready var spawn_position : Node2D = %SpawnPosition
|
||||
@onready var camera : Camera = %Camera
|
||||
@onready var data : TruckData = GameInfo.game_data.truck_data
|
||||
|
||||
func _on_exit_interacted(p: Player):
|
||||
player_exited.emit(p)
|
||||
func _on_exit_interacted(_p : Player):
|
||||
data.entities_saved_data = save_entities()
|
||||
get_tree().change_scene_to_file(PLANET_RUN_PATH)
|
||||
|
||||
func _ready():
|
||||
for c in composts:
|
||||
c.reward = generate_reward()
|
||||
c.rewarded.connect(_on_compost_rewarded)
|
||||
load_entities(data.entities_saved_data)
|
||||
while len(data.compost_containing_seeds) < len(composts):
|
||||
data.compost_containing_seeds.append(0)
|
||||
for i in range(len(composts)):
|
||||
var compost = composts[i]
|
||||
compost.containing_seed = data.compost_containing_seeds[i]
|
||||
compost.filled.connect(func (c: Compost): data.compost_containing_seeds[i] = c.containing_seed)
|
||||
|
||||
if i < len(data.rewards):
|
||||
compost.reward = data.rewards[i]
|
||||
else:
|
||||
var new_reward = generate_reward()
|
||||
compost.reward = new_reward
|
||||
data.rewards.append(new_reward)
|
||||
compost.rewarded.connect(_on_compost_rewarded)
|
||||
|
||||
func _on_compost_rewarded(c: Compost):
|
||||
rewarded_times += 1
|
||||
c.reward = generate_reward()
|
||||
data.rewarded_times += 1
|
||||
c.reward = generate_reward()
|
||||
|
||||
func get_compost_rewards() -> Array[Compost.Reward]:
|
||||
var rewards : Array[Compost.Reward] = []
|
||||
for c in composts:
|
||||
if c.reward:
|
||||
rewards.append(c.reward)
|
||||
return rewards
|
||||
func get_compost_rewards() -> Array[Reward]:
|
||||
var rewards : Array[Reward] = []
|
||||
for c in composts:
|
||||
if c.reward:
|
||||
rewards.append(c.reward)
|
||||
return rewards
|
||||
|
||||
func get_random_reward_cost() -> int:
|
||||
return randi_range(1 + rewarded_times * 2, 2 + rewarded_times * 2)
|
||||
return randi_range(1 + data.rewarded_times * 2, 2 + data.rewarded_times * 2)
|
||||
|
||||
func get_possible_rewards() -> Array[Compost.Reward]:
|
||||
return [
|
||||
Compost.UpgradeMaxEnergyReward.new(get_random_reward_cost() + 5),
|
||||
Compost.UpgradeMaxInventoryReward.new(get_random_reward_cost()),
|
||||
Compost.GiveItemReward.new(
|
||||
get_random_reward_cost(),
|
||||
Blueprint.new(preload("res://entities/interactables/machines/solar_pannel/solar_pannel.tres"))
|
||||
),
|
||||
Compost.GiveItemReward.new(
|
||||
get_random_reward_cost(),
|
||||
Knife.new()
|
||||
),
|
||||
Compost.GiveItemReward.new(
|
||||
get_random_reward_cost(),
|
||||
Trowel.new()
|
||||
)
|
||||
]
|
||||
func get_possible_rewards() -> Array[Reward]:
|
||||
return [
|
||||
UpgradeMaxEnergyReward.new(get_random_reward_cost() + 2),
|
||||
UpgradeMaxInventoryReward.new(get_random_reward_cost()),
|
||||
GiveItemReward.new(
|
||||
get_random_reward_cost(),
|
||||
Blueprint.new(preload("res://entities/interactables/machines/solar_pannel/solar_pannel.tres"))
|
||||
),
|
||||
GiveItemReward.new(
|
||||
get_random_reward_cost(),
|
||||
Knife.new()
|
||||
),
|
||||
GiveItemReward.new(
|
||||
get_random_reward_cost(),
|
||||
Trowel.new()
|
||||
)
|
||||
]
|
||||
|
||||
func generate_reward() -> Compost.Reward:
|
||||
return get_possible_rewards().pick_random()
|
||||
|
||||
func generate_reward() -> Reward:
|
||||
var max_tries = 3
|
||||
var reward = get_possible_rewards().pick_random()
|
||||
while get_compost_rewards().map(func(r): return r.desc()).find(reward.desc()) != -1 and max_tries > 0:
|
||||
max_tries -= 1
|
||||
reward = get_possible_rewards().pick_random()
|
||||
return reward
|
||||
|
||||
26
stages/terrain/truck/truck.tscn
Normal file
@@ -0,0 +1,26 @@
|
||||
[gd_scene load_steps=5 format=3 uid="uid://biwkti5cir5ut"]
|
||||
|
||||
[ext_resource type="PackedScene" uid="uid://ceplumcunebag" path="res://stages/terrain/truck/truck_interior.tscn" id="1_ycq4y"]
|
||||
[ext_resource type="Script" uid="uid://d1nsr56bh1a1y" path="res://entities/camera/scripts/camera.gd" id="2_063c3"]
|
||||
[ext_resource type="PackedScene" uid="uid://12nak7amd1uq" path="res://gui/game/game_gui.tscn" id="2_dw1sv"]
|
||||
[ext_resource type="PackedScene" uid="uid://bgvbgeq46wee2" path="res://entities/player/player.tscn" id="5_dw1sv"]
|
||||
|
||||
[node name="Truck" type="Node2D"]
|
||||
|
||||
[node name="CanvasLayer" type="CanvasLayer" parent="."]
|
||||
|
||||
[node name="GameGui" parent="CanvasLayer" instance=ExtResource("2_dw1sv")]
|
||||
|
||||
[node name="TruckInterior" parent="." node_paths=PackedStringArray("import_entities_from_node") instance=ExtResource("1_ycq4y")]
|
||||
position = Vector2(0, 0)
|
||||
import_entities_from_node = NodePath("../Entities")
|
||||
|
||||
[node name="Camera" type="Camera2D" parent="."]
|
||||
position = Vector2(385, 343)
|
||||
script = ExtResource("2_063c3")
|
||||
metadata/_custom_type_script = "uid://d1nsr56bh1a1y"
|
||||
|
||||
[node name="Entities" type="Node2D" parent="."]
|
||||
|
||||
[node name="Player" parent="Entities" instance=ExtResource("5_dw1sv")]
|
||||
position = Vector2(51, 492)
|
||||
@@ -1,10 +1,9 @@
|
||||
[gd_scene load_steps=8 format=3 uid="uid://ceplumcunebag"]
|
||||
[gd_scene load_steps=7 format=3 uid="uid://ceplumcunebag"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://d2p7h0aga85tn" path="res://stages/terrain/truck/assets/sprite/truck_interior.png" id="1_5c5ey"]
|
||||
[ext_resource type="Script" uid="uid://d0gmkwebxdptk" path="res://stages/terrain/truck/scripts/truck_interior.gd" id="1_fk6sc"]
|
||||
[ext_resource type="Script" uid="uid://dyprcd68fjstf" path="res://entities/interactables/scripts/interactable.gd" id="3_fk6sc"]
|
||||
[ext_resource type="Texture2D" uid="uid://dex283rx00fjb" path="res://common/icons/logout.svg" id="3_v18jm"]
|
||||
[ext_resource type="Script" uid="uid://d1nsr56bh1a1y" path="res://entities/camera/scripts/camera.gd" id="4_5di8w"]
|
||||
[ext_resource type="PackedScene" uid="uid://p2dkmy6xs31c" path="res://entities/interactables/truck/compost/compost.tscn" id="6_b7823"]
|
||||
|
||||
[sub_resource type="CapsuleShape2D" id="CapsuleShape2D_wi5be"]
|
||||
@@ -54,13 +53,6 @@ texture = ExtResource("3_v18jm")
|
||||
position = Vector2(9.026497, 81.2384)
|
||||
shape = SubResource("CapsuleShape2D_wi5be")
|
||||
|
||||
[node name="Camera" type="Camera2D" parent="."]
|
||||
unique_name_in_owner = true
|
||||
position = Vector2(316, 340)
|
||||
zoom = Vector2(1.18, 1.18)
|
||||
script = ExtResource("4_5di8w")
|
||||
metadata/_custom_type_script = "uid://d1nsr56bh1a1y"
|
||||
|
||||
[node name="Compost" parent="." instance=ExtResource("6_b7823")]
|
||||
position = Vector2(358, 357)
|
||||
|
||||
|
||||