210 lines
6.3 KiB
Plaintext
210 lines
6.3 KiB
Plaintext
[gd_scene load_steps=6 format=3 uid="uid://x4kv2y5f52cm"]
|
|
|
|
[ext_resource type="Texture2D" uid="uid://b3kjaw1hajc6s" path="res://assets/grille_seeds.png" id="1_n5onq"]
|
|
|
|
[sub_resource type="GDScript" id="GDScript_x3g5o"]
|
|
script/source = "class_name Plant
|
|
|
|
extends Node2D
|
|
|
|
enum PlantState { SAPLING, GROWN, DEAD}
|
|
|
|
signal grown
|
|
signal died
|
|
|
|
@onready var growing_timer: Timer = $Growing
|
|
@onready var need_checker: Timer = $NeedChecker
|
|
@onready var sapling_count_down: Timer = $SaplingCountDown
|
|
@onready var reproduction: Timer = $Reproduction
|
|
@onready var sprite_node: AnimatedSprite2D = $AnimatedSprite2D
|
|
|
|
const NEED_CHECK_PERIOD := 0.5
|
|
const SAPLING_LIFETIME_MULT := 2.0 # this multiplies the time to grow to tell the time it can stay as a sapling
|
|
const OFFSET_REPRODUCTION_PERCT_DIST := 0.5
|
|
|
|
var parameter: PlantType
|
|
var state := PlantState.SAPLING
|
|
var sapling_time_left: float
|
|
var can_grow := true
|
|
|
|
func init(plant_parameter: PlantType):
|
|
parameter = plant_parameter
|
|
sapling_count_down.start(SAPLING_LIFETIME_MULT * parameter.growing_time)
|
|
sprite_node.sprite_frames = parameter.sprite_frames
|
|
need_checker.start(NEED_CHECK_PERIOD)
|
|
|
|
|
|
func _on_need_checker_timeout() -> void:
|
|
can_grow = check_terrain_viability()
|
|
growing_timer.paused = not can_grow and state == PlantState.SAPLING
|
|
reproduction.paused = not can_grow
|
|
|
|
func check_terrain_viability() -> bool:
|
|
var water := GameTerrain.get_stat(position, GameTerrain.Stats.WATER)
|
|
if water < parameter.water_need[0] or water > parameter.water_need[1]:
|
|
return false
|
|
|
|
var fertility := GameTerrain.get_stat(position, GameTerrain.Stats.FERTILITY)
|
|
if fertility < parameter.fertility_need[0] or fertility > parameter.fertility_need[1]:
|
|
return false
|
|
|
|
var presence := GameTerrain.get_stat(position, GameTerrain.Stats.PRESENCE)
|
|
presence += GameTerrain.LEVELS_NUMBER / 2
|
|
if presence < parameter.presence_need[0] or presence > parameter.presence_need[1]:
|
|
return false
|
|
|
|
return true
|
|
|
|
|
|
func _on_growing_timeout() -> void:
|
|
if state == PlantState.SAPLING:
|
|
can_grow = check_terrain_viability()
|
|
if not can_grow:
|
|
growing_timer.start()
|
|
return
|
|
|
|
match state:
|
|
PlantState.SAPLING:
|
|
grow()
|
|
PlantState.GROWN:
|
|
die()
|
|
PlantState.DEAD:
|
|
remove()
|
|
|
|
|
|
func plant(new_position: Vector2):
|
|
position = new_position
|
|
state = PlantState.SAPLING
|
|
growing_timer.start(parameter.growing_time)
|
|
sprite_node.play(\"SAPLING\")
|
|
|
|
|
|
func grow():
|
|
if state != PlantState.SAPLING:
|
|
push_error(\"Tried to grow \" + parameter.type + \", but was not at sapling state\")
|
|
return
|
|
state = PlantState.GROWN
|
|
sapling_count_down.stop()
|
|
growing_timer.start(parameter.dying_time)
|
|
GameTerrain.modify_zone(position,
|
|
parameter.distance_prod,
|
|
GameTerrain.Stats.WATER,
|
|
parameter.water_prod)
|
|
GameTerrain.modify_zone(position,
|
|
parameter.distance_prod,
|
|
GameTerrain.Stats.FERTILITY,
|
|
parameter.fertility_prod)
|
|
GameTerrain.modify_zone(position,
|
|
parameter.distance_prod,
|
|
GameTerrain.Stats.PRESENCE,
|
|
parameter.presence_prod)
|
|
|
|
reproduction.start(parameter.dying_time / (parameter.offspring_per_lifetime + 1) + 0.1)
|
|
|
|
grown.emit()
|
|
sprite_node.play(\"GROWN\")
|
|
|
|
|
|
func die():
|
|
state = PlantState.DEAD
|
|
# remove alive prod and add dead prod
|
|
GameTerrain.modify_zone(position,
|
|
parameter.distance_prod,
|
|
GameTerrain.Stats.WATER,
|
|
-parameter.water_prod + parameter.dead_water_prod)
|
|
GameTerrain.modify_zone(position,
|
|
parameter.distance_prod,
|
|
GameTerrain.Stats.FERTILITY,
|
|
-parameter.fertility_prod + parameter.dead_fertility_prod)
|
|
GameTerrain.modify_zone(position,
|
|
parameter.distance_prod,
|
|
GameTerrain.Stats.PRESENCE,
|
|
-parameter.presence_prod)
|
|
growing_timer.start(parameter.dead_time)
|
|
died.emit()
|
|
sprite_node.play(\"DEAD\")
|
|
|
|
func remove(was_dead: bool = true):
|
|
if was_dead:
|
|
GameTerrain.modify_zone(position,
|
|
parameter.distance_prod,
|
|
GameTerrain.Stats.WATER,
|
|
-parameter.dead_water_prod)
|
|
GameTerrain.modify_zone(position,
|
|
parameter.distance_prod,
|
|
GameTerrain.Stats.FERTILITY,
|
|
-parameter.dead_fertility_prod)
|
|
queue_free()
|
|
|
|
|
|
func _on_sapling_count_down_timeout() -> void:
|
|
remove(false)
|
|
|
|
|
|
func _on_reproduction_timeout() -> void:
|
|
var min_dist := parameter.distance_prod - parameter.distance_prod * OFFSET_REPRODUCTION_PERCT_DIST
|
|
var max_dist := parameter.distance_prod + parameter.distance_prod * OFFSET_REPRODUCTION_PERCT_DIST
|
|
var plant_pos = position + (Vector2.RIGHT * randf_range(min_dist, max_dist)).rotated(randf_range(0, PI))
|
|
|
|
var space := get_world_2d().direct_space_state
|
|
var parameters = PhysicsPointQueryParameters2D.new()
|
|
parameters.position = plant_pos
|
|
parameters.collide_with_areas = true
|
|
parameters.collide_with_bodies = false
|
|
var result := space.intersect_point(parameters, 1)
|
|
if result.size() > 0:
|
|
return
|
|
|
|
var offspring = self.duplicate()
|
|
self.get_parent().add_child(offspring)
|
|
offspring.init(parameter)
|
|
offspring.plant(plant_pos)
|
|
"
|
|
|
|
[sub_resource type="AtlasTexture" id="AtlasTexture_5did5"]
|
|
atlas = ExtResource("1_n5onq")
|
|
region = Rect2(810, 540, 270, 270)
|
|
|
|
[sub_resource type="SpriteFrames" id="SpriteFrames_667un"]
|
|
animations = [{
|
|
"frames": [{
|
|
"duration": 1.0,
|
|
"texture": SubResource("AtlasTexture_5did5")
|
|
}],
|
|
"loop": true,
|
|
"name": &"SEED",
|
|
"speed": 5.0
|
|
}]
|
|
|
|
[sub_resource type="CircleShape2D" id="CircleShape2D_jksuk"]
|
|
radius = 36.0
|
|
|
|
[node name="Plant" type="Node2D"]
|
|
script = SubResource("GDScript_x3g5o")
|
|
|
|
[node name="Growing" type="Timer" parent="."]
|
|
one_shot = true
|
|
|
|
[node name="NeedChecker" type="Timer" parent="."]
|
|
|
|
[node name="SaplingCountDown" type="Timer" parent="."]
|
|
one_shot = true
|
|
|
|
[node name="Reproduction" type="Timer" parent="."]
|
|
|
|
[node name="AnimatedSprite2D" type="AnimatedSprite2D" parent="."]
|
|
scale = Vector2(0.2, 0.2)
|
|
sprite_frames = SubResource("SpriteFrames_667un")
|
|
animation = &"SEED"
|
|
offset = Vector2(0, -250)
|
|
|
|
[node name="Area2D" type="Area2D" parent="."]
|
|
|
|
[node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"]
|
|
shape = SubResource("CircleShape2D_jksuk")
|
|
|
|
[connection signal="timeout" from="Growing" to="." method="_on_growing_timeout"]
|
|
[connection signal="timeout" from="NeedChecker" to="." method="_on_need_checker_timeout"]
|
|
[connection signal="timeout" from="SaplingCountDown" to="." method="_on_sapling_count_down_timeout"]
|
|
[connection signal="timeout" from="Reproduction" to="." method="_on_reproduction_timeout"]
|