diff --git a/Globals/EventBus.gd b/Globals/EventBus.gd index 7370470..7789707 100644 --- a/Globals/EventBus.gd +++ b/Globals/EventBus.gd @@ -3,16 +3,13 @@ extends Node #Emitter : TowerButton.gd #Subscriber : World.gd -signal tower_selected(tower : PackedScene) +signal tower_selected(towerType : Tower.TYPES) #Emitter : #Subscriber : signal tower_builded(tower : Tower) -#Emitter : gui.gd -#Subscriber : PlayerManager.gd -signal tower_to_build(packed_tower : PackedScene) #Emitter : UpgradeButton.gd #Subscriber : tower.gd @@ -62,6 +59,10 @@ signal money_spent(_value : int) #Subscriber : cube.gd signal player_has_won() +#Emitter : WaveManger.gd +#Subscriber : cube.gd +signal player_defeated() + #Emitter : PlayerManager.gd #Subscriber : game_menu.gd signal open_shop() diff --git a/Levels/level_1.tres b/Levels/level_1.tres new file mode 100644 index 0000000..fee81cb --- /dev/null +++ b/Levels/level_1.tres @@ -0,0 +1,82 @@ +[gd_resource type="Resource" script_class="Level" load_steps=15 format=3 uid="uid://ob41fnhkjr3o"] + +[ext_resource type="Script" uid="uid://cuhq6u67cbbqm" path="res://Scripts/Level.gd" id="1_ftl6b"] +[ext_resource type="Script" uid="uid://chu8s12rtdeqx" path="res://Scripts/Wave.gd" id="2_457yt"] +[ext_resource type="Script" uid="uid://blxx3vs2wnfet" path="res://Scripts/Troop.gd" id="3_ub8wd"] +[ext_resource type="PackedScene" uid="uid://dknt1oiyei5e5" path="res://enemies/enemy-a.tscn" id="4_ujs1b"] + +[sub_resource type="Resource" id="Resource_5q243"] +script = ExtResource("3_ub8wd") +enemy = ExtResource("4_ujs1b") +number_to_spawn = 1 +spawn_delay = 0.0 +metadata/_custom_type_script = "uid://blxx3vs2wnfet" + +[sub_resource type="Resource" id="Resource_ps5n4"] +script = ExtResource("3_ub8wd") +enemy = ExtResource("4_ujs1b") +number_to_spawn = 1 +spawn_delay = 3.0 +metadata/_custom_type_script = "uid://blxx3vs2wnfet" + +[sub_resource type="Resource" id="Resource_qfjse"] +script = ExtResource("3_ub8wd") +enemy = ExtResource("4_ujs1b") +number_to_spawn = 1 +spawn_delay = 3.0 +metadata/_custom_type_script = "uid://blxx3vs2wnfet" + +[sub_resource type="Resource" id="Resource_m6gub"] +script = ExtResource("2_457yt") +troops = Array[ExtResource("3_ub8wd")]([SubResource("Resource_5q243"), SubResource("Resource_ps5n4"), SubResource("Resource_qfjse")]) +wait_time_before_launch_wave = 4.0 +wait_for_enemy_kills = true +metadata/_custom_type_script = "uid://chu8s12rtdeqx" + +[sub_resource type="Resource" id="Resource_1mxdl"] +script = ExtResource("3_ub8wd") +enemy = ExtResource("4_ujs1b") +number_to_spawn = 1 +spawn_delay = 0.0 +metadata/_custom_type_script = "uid://blxx3vs2wnfet" + +[sub_resource type="Resource" id="Resource_87wss"] +script = ExtResource("3_ub8wd") +enemy = ExtResource("4_ujs1b") +number_to_spawn = 1 +spawn_delay = 3.0 +metadata/_custom_type_script = "uid://blxx3vs2wnfet" + +[sub_resource type="Resource" id="Resource_457yt"] +script = ExtResource("2_457yt") +troops = Array[ExtResource("3_ub8wd")]([SubResource("Resource_1mxdl"), SubResource("Resource_87wss")]) +wait_time_before_launch_wave = 5.0 +wait_for_enemy_kills = true +metadata/_custom_type_script = "uid://chu8s12rtdeqx" + +[sub_resource type="Resource" id="Resource_ftl6b"] +script = ExtResource("3_ub8wd") +enemy = ExtResource("4_ujs1b") +number_to_spawn = 1 +spawn_delay = 1.0 +metadata/_custom_type_script = "uid://blxx3vs2wnfet" + +[sub_resource type="Resource" id="Resource_ub8wd"] +script = ExtResource("3_ub8wd") +enemy = ExtResource("4_ujs1b") +number_to_spawn = 1 +spawn_delay = 1.0 +metadata/_custom_type_script = "uid://blxx3vs2wnfet" + +[sub_resource type="Resource" id="Resource_ujs1b"] +script = ExtResource("2_457yt") +troops = Array[ExtResource("3_ub8wd")]([SubResource("Resource_ftl6b"), SubResource("Resource_ub8wd")]) +wait_time_before_launch_wave = 3.0 +wait_for_enemy_kills = true +metadata/_custom_type_script = "uid://chu8s12rtdeqx" + +[resource] +script = ExtResource("1_ftl6b") +waves = Array[ExtResource("2_457yt")]([SubResource("Resource_m6gub"), SubResource("Resource_457yt"), SubResource("Resource_ujs1b")]) +auto_start = false +metadata/_custom_type_script = "uid://cuhq6u67cbbqm" diff --git a/Levels/level_2.tres b/Levels/level_2.tres new file mode 100644 index 0000000..6f1ca2e --- /dev/null +++ b/Levels/level_2.tres @@ -0,0 +1,82 @@ +[gd_resource type="Resource" script_class="Level" load_steps=17 format=3 uid="uid://cbgaiaaleyf6j"] + +[ext_resource type="Script" uid="uid://cuhq6u67cbbqm" path="res://Scripts/Level.gd" id="1_c4t4w"] +[ext_resource type="Script" uid="uid://chu8s12rtdeqx" path="res://Scripts/Wave.gd" id="2_2ji0m"] +[ext_resource type="Script" uid="uid://blxx3vs2wnfet" path="res://Scripts/Troop.gd" id="3_y8rub"] +[ext_resource type="PackedScene" uid="uid://dknt1oiyei5e5" path="res://enemies/enemy-a.tscn" id="4_nj0jn"] + +[sub_resource type="Resource" id="Resource_cm6sg"] +script = ExtResource("2_2ji0m") +troops = Array[ExtResource("3_y8rub")]([]) +wait_time_before_launch_wave = 3.0 +wait_for_enemy_kills = true + +[sub_resource type="Resource" id="Resource_ps5n4"] +script = ExtResource("3_y8rub") +enemy = ExtResource("4_nj0jn") +number_to_spawn = 7 +spawn_delay = 3.0 +metadata/_custom_type_script = "uid://blxx3vs2wnfet" + +[sub_resource type="Resource" id="Resource_qeljc"] +script = ExtResource("3_y8rub") +enemy = ExtResource("4_nj0jn") +number_to_spawn = 1 +spawn_delay = 1.0 + +[sub_resource type="Resource" id="Resource_1p7sg"] +script = ExtResource("3_y8rub") +enemy = ExtResource("4_nj0jn") +number_to_spawn = 1 +spawn_delay = 0.0 + +[sub_resource type="Resource" id="Resource_y8rub"] +script = ExtResource("3_y8rub") +enemy = ExtResource("4_nj0jn") +number_to_spawn = 1 +spawn_delay = 0.0 + +[sub_resource type="Resource" id="Resource_w0brl"] +script = ExtResource("3_y8rub") +number_to_spawn = 1 +spawn_delay = 1.0 + +[sub_resource type="Resource" id="Resource_c4t4w"] +script = ExtResource("2_2ji0m") +troops = Array[ExtResource("3_y8rub")]([SubResource("Resource_ps5n4"), SubResource("Resource_qeljc"), SubResource("Resource_1p7sg"), SubResource("Resource_y8rub"), SubResource("Resource_w0brl")]) +wait_time_before_launch_wave = 3.8 +wait_for_enemy_kills = true +metadata/_custom_type_script = "uid://chu8s12rtdeqx" + +[sub_resource type="Resource" id="Resource_2ji0m"] +script = ExtResource("3_y8rub") +number_to_spawn = 1 +spawn_delay = 1.0 + +[sub_resource type="Resource" id="Resource_nj0jn"] +script = ExtResource("3_y8rub") +number_to_spawn = 1 +spawn_delay = 1.0 + +[sub_resource type="Resource" id="Resource_s83h5"] +script = ExtResource("2_2ji0m") +troops = Array[ExtResource("3_y8rub")]([SubResource("Resource_2ji0m"), SubResource("Resource_nj0jn")]) +wait_time_before_launch_wave = 3.6 +wait_for_enemy_kills = true + +[sub_resource type="Resource" id="Resource_833nr"] +script = ExtResource("3_y8rub") +number_to_spawn = 1 +spawn_delay = 1.0 + +[sub_resource type="Resource" id="Resource_xgtww"] +script = ExtResource("2_2ji0m") +troops = Array[ExtResource("3_y8rub")]([SubResource("Resource_833nr")]) +wait_time_before_launch_wave = 7.0 +wait_for_enemy_kills = true + +[resource] +script = ExtResource("1_c4t4w") +waves = Array[ExtResource("2_2ji0m")]([SubResource("Resource_cm6sg"), SubResource("Resource_c4t4w"), SubResource("Resource_s83h5"), SubResource("Resource_xgtww")]) +auto_start = false +metadata/_custom_type_script = "uid://cuhq6u67cbbqm" diff --git a/Levels/world.tscn b/Levels/world.tscn index 30bd59d..48c1da3 100644 --- a/Levels/world.tscn +++ b/Levels/world.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=28 format=3 uid="uid://ky0uewndeuwv"] +[gd_scene load_steps=21 format=3 uid="uid://ky0uewndeuwv"] [ext_resource type="Script" uid="uid://qqid42jkpkmv" path="res://Levels/world.gd" id="1_fj7yv"] [ext_resource type="PackedScene" uid="uid://d1f6m15niwgt" path="res://Tiles/tile.tscn" id="3_aqk2v"] @@ -7,10 +7,7 @@ [ext_resource type="PackedScene" uid="uid://do7gm1gjhu1t5" path="res://Tiles/road.tscn" id="4_036b0"] [ext_resource type="Script" uid="uid://tpon511km4al" path="res://Scripts/WaveManager.gd" id="5_036b0"] [ext_resource type="PackedScene" uid="uid://dpjfo15otkfru" path="res://Tiles/cube.tscn" id="5_wse8f"] -[ext_resource type="Script" uid="uid://chu8s12rtdeqx" path="res://Scripts/Wave.gd" id="6_gbfbk"] -[ext_resource type="Resource" uid="uid://dkbuy7fetnihs" path="res://Waves/wave_1.tres" id="7_ioo17"] -[ext_resource type="Script" uid="uid://blxx3vs2wnfet" path="res://Scripts/Troop.gd" id="10_oyb16"] -[ext_resource type="PackedScene" uid="uid://dknt1oiyei5e5" path="res://enemies/enemy-a.tscn" id="11_43wwi"] +[ext_resource type="Resource" uid="uid://ob41fnhkjr3o" path="res://Levels/level_1.tres" id="8_44brb"] [ext_resource type="PackedScene" uid="uid://c54881eookjth" path="res://Assets/Meshes/SM_B26.glb" id="12_44brb"] [ext_resource type="PackedScene" uid="uid://p6a6rb7sgeqd" path="res://UI/gui.tscn" id="12_ikoig"] [ext_resource type="Script" uid="uid://xkk2pxkrwsq8" path="res://bullet_container.gd" id="12_k3n1d"] @@ -65,34 +62,6 @@ _data = { } point_count = 2 -[sub_resource type="Resource" id="Resource_1mf3x"] -script = ExtResource("10_oyb16") -enemy = ExtResource("11_43wwi") -number_to_spawn = 2 -spawn_delay = 0.0 -metadata/_custom_type_script = "uid://blxx3vs2wnfet" - -[sub_resource type="Resource" id="Resource_3i3vq"] -script = ExtResource("10_oyb16") -enemy = ExtResource("11_43wwi") -number_to_spawn = 1 -spawn_delay = 1.0 -metadata/_custom_type_script = "uid://blxx3vs2wnfet" - -[sub_resource type="Resource" id="Resource_qdqr3"] -script = ExtResource("10_oyb16") -enemy = ExtResource("11_43wwi") -number_to_spawn = 1 -spawn_delay = 1.0 -metadata/_custom_type_script = "uid://blxx3vs2wnfet" - -[sub_resource type="Resource" id="Resource_gtojq"] -script = ExtResource("6_gbfbk") -troops = Array[ExtResource("10_oyb16")]([SubResource("Resource_1mf3x"), SubResource("Resource_3i3vq"), SubResource("Resource_qdqr3")]) -wait_time_before_launch_wave = 5 -wait_for_enemy_kills = true -metadata/_custom_type_script = "uid://chu8s12rtdeqx" - [sub_resource type="Environment" id="Environment_036b0"] background_mode = 1 background_color = Color(0.924338, 0.849272, 0.847318, 1) @@ -249,7 +218,7 @@ transform = Transform3D(1.5, 0, 0, 0, 1.5, 0, 0, 0, 1.5, 10.1496, 0.209118, 0.49 transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0) curve = SubResource("Curve3D_aqk2v") script = ExtResource("5_036b0") -waves = Array[ExtResource("6_gbfbk")]([ExtResource("7_ioo17"), SubResource("Resource_gtojq")]) +level = ExtResource("8_44brb") [node name="WaveTimer" type="Timer" parent="WaveManager"] one_shot = true @@ -289,6 +258,3 @@ transform = Transform3D(-0.0471892, 0, 1.99944, 0, 2, 0, -1.99944, 0, -0.0471892 transform = Transform3D(1.08365, 0, 1.68098, 0, 2, 0, -1.68098, 0, 1.08365, 1.44235, 0, 4.63481) [node name="Towers" type="Node3D" parent="."] - -[connection signal="timeout" from="WaveManager/WaveTimer" to="WaveManager" method="_on_wave_timer_timeout"] -[connection signal="timeout" from="WaveManager/TroopTimer" to="WaveManager" method="_on_troop_timer_timeout"] diff --git a/Scripts/Level.gd b/Scripts/Level.gd new file mode 100644 index 0000000..c92d219 --- /dev/null +++ b/Scripts/Level.gd @@ -0,0 +1,5 @@ +extends Resource +class_name Level + +@export var waves : Array[Wave] +@export var auto_start : bool = false diff --git a/Scripts/Level.gd.uid b/Scripts/Level.gd.uid new file mode 100644 index 0000000..d28e344 --- /dev/null +++ b/Scripts/Level.gd.uid @@ -0,0 +1 @@ +uid://cuhq6u67cbbqm diff --git a/Scripts/PlayerManager.gd b/Scripts/PlayerManager.gd index 15b215b..958453a 100644 --- a/Scripts/PlayerManager.gd +++ b/Scripts/PlayerManager.gd @@ -1,44 +1,23 @@ extends Node3D - class_name PlayerManager -enum STATE {IDLE,PLACING} -var _state = STATE.IDLE -#TODO Get rid of tower_blueprint -@onready var tower_blueprint : PackedScene +const towerListResource := preload("res://Towers/towers.tres") + +enum STATE { IDLE, PLACING } +var _state := STATE.IDLE @onready var selected_tower : Tower = null +var selected_tower_type : Tower.TYPES = Tower.TYPES.NONE @onready var cam : Camera3D = $"../Camera3D" @onready var the_cube : TheCube = %TheCube @onready var selection_icon : Sprite3D = $Sprite3DSelection -@onready var towers : Array[Tower] - -var tower_count : int = 0: - set(value): - tower_count = value - EventBus.tower_count_changed.emit(tower_count) - - -var team_in_action : Array[Tower]: - set(value): - team_in_action = value - EventBus.team_in_action_changed.emit(team_in_action) - - -var team_in_rest : Array[Tower]: - set(value): - team_in_rest = value - EventBus.team_in_rest_changed.emit(team_in_rest) - -var target_tower : Tower - +var towers : Dictionary var selected_collider : CollisionObject3D func _ready() -> void: - EventBus.tower_selected.connect(_on_EventBus_tower_selected) - EventBus.tower_to_build.connect(_on_EventBus_tower_to_build) + EventBus.tower_selected.connect(selectTower) #$AnimationPlayer.play("arrow_bobbing") func _process(delta: float) -> void: @@ -59,8 +38,9 @@ func _process(delta: float) -> void: quit_placing() EventBus.close_shop.emit() - if target_tower: - send_to_rest() + if selected_collider is Tower: + selected_collider.is_rest = true + emitTeamChanges() func handle_player_controls() -> void: var space_state : PhysicsDirectSpaceState3D = get_world_3d().direct_space_state @@ -78,112 +58,98 @@ func handle_player_controls() -> void: selected_collider = null return - var collider : CollisionObject3D = ray_result.get("collider") - selected_collider = collider + selected_collider = ray_result.get("collider") visible = true - selection_icon.visible = false - global_position = collider.global_position + selection_icon.visible = false + global_position = selected_collider.global_position global_position += Vector3(0.0,0.02,0.0) - if selected_collider is Tower: - target_tower = collider - else: - target_tower = null - if _state == STATE.PLACING: - tower_to_place.sprite.modulate = "ff4545c8" #If the tower can't be placed he is red - selection_icon.visible = false + selected_tower.sprite.modulate = "ff4545c8" #If the tower can't be placed he is red + selection_icon.visible = false if selected_collider is BuildTile: #if we are placing a tower, hide the selector model - tower_to_place.sprite.modulate = "61ff45c8" #If the tower can be placed he is green + selected_tower.sprite.modulate = "61ff45c8" #If the tower can be placed he is green -var tower_to_place : Tower #It is freed in the build_tower() func place_tower() -> void: _state = STATE.PLACING - tower_to_place = tower_blueprint.instantiate() - add_child(tower_to_place) - tower_to_place.can_shoot = false - tower_to_place.collision_layer = 0 - tower_to_place.sprite.modulate = "ffffffc8" - tower_to_place.show_price_tag() + + selected_tower = towerListResource.getTowerSceneById(selected_tower_type).instantiate() + towers.set(selected_tower_type, selected_tower) + add_child(selected_tower) + selected_tower.can_shoot = false + selected_tower.collision_layer = 0 + selected_tower.show_price_tag() func quit_placing() -> void: _state = STATE.IDLE - tower_to_place.queue_free() # Refactoriser ce code func build_tower() -> void: - if tower_blueprint == null: + if !visible || !selected_tower: return - if !visible: - return - - var temp_tower : Tower = tower_blueprint.instantiate() - - - #Move existing tower - for tower : Tower in team_in_action: - if tower.tower_name == temp_tower.tower_name: - move_tower() - return - - #Send to action a resting tower - for tower : Tower in team_in_rest: - if tower.tower_name == temp_tower.tower_name: - move_tower() - send_to_action() - return - - #Build Tower - if temp_tower.price < the_cube.money: + if not selected_tower.builded && selected_tower.price > the_cube.money: #Can't build print("Too costly") return - else : - #Can build - quit_placing() #Destroy the tower placeholder - EventBus.money_spent.emit(temp_tower.price) - tower_count += 1 - $"../Towers".add_child(temp_tower) - EventBus.tower_builded.emit(temp_tower) - towers.append(temp_tower) - tower_blueprint == null - selected_tower = temp_tower - send_to_action() - move_tower() + if selected_tower.is_rest: + if not selected_tower.builded: + #Build Tower + EventBus.money_spent.emit(selected_tower.price) + selected_tower.can_shoot = true + selected_tower.collision_layer = 3 + selected_tower.sprite.modulate = "ffffffff" + selected_tower.hide_price_tag() + selected_tower.builded = true + EventBus.tower_builded.emit(selected_tower) + remove_child(selected_tower) + $"../Towers".add_child(selected_tower) + quit_placing() + selected_tower.is_rest = false + print(selected_tower.tower_type) + move_tower() + emitTeamChanges() + + +func selectTower(towerType : Tower.TYPES): + if selected_tower && not selected_tower.builded: + selected_tower.visible = false + + if towerType == selected_tower_type: + selected_tower = null + selected_tower_type = Tower.TYPES.NONE + _state = STATE.IDLE + return + + selected_tower_type = towerType + if towers.has(towerType): + _state = STATE.IDLE + selected_tower = towers.get(towerType) + selected_tower.visible = true + else: + place_tower() func move_tower(): selected_tower.global_position = global_position -func send_to_rest(): - team_in_action.erase(selected_tower) - team_in_rest.append(selected_tower) - selected_tower.is_rest = true +func emitTeamChanges() -> void: + var team_in_action : int = 0 + var team_in_rest : int = 0 + var tower_count : int = 0 + for towerType in towers: + var tower : Tower = towers[towerType] + if tower.builded: + tower_count += 1 + if tower.is_rest: + team_in_rest += 1 + else: + team_in_action += 1 + EventBus.team_in_action_changed.emit(team_in_action) - - -func send_to_action(): - team_in_rest.erase(selected_tower) - team_in_action.append(selected_tower) - selected_tower.is_rest = false - EventBus.team_in_action_changed.emit(team_in_action) - - -func _on_EventBus_tower_selected(tower : PackedScene): - # TODO: Remove tower_blueprint - print("pouette") - # tower_blueprint = tower - -# TODO: Utile ? -func _on_cube_icon_pressed() -> void: - pass - #open_shop() - -func _on_EventBus_tower_to_build(packed_tower : PackedScene) -> void: - tower_blueprint = packed_tower - place_tower() + EventBus.team_in_rest_changed.emit(team_in_rest) + EventBus.tower_count_changed.emit(tower_count) diff --git a/Scripts/Wave.gd b/Scripts/Wave.gd index 17d51e3..088601b 100644 --- a/Scripts/Wave.gd +++ b/Scripts/Wave.gd @@ -2,5 +2,5 @@ extends Resource class_name Wave @export var troops : Array[Troop] -@export var wait_time_before_launch_wave : int = 3 +@export var wait_time_before_launch_wave : float = 3 @export var wait_for_enemy_kills : bool = true diff --git a/Scripts/WaveManager.gd b/Scripts/WaveManager.gd index 3911e29..1f2e0f0 100644 --- a/Scripts/WaveManager.gd +++ b/Scripts/WaveManager.gd @@ -1,40 +1,50 @@ extends Path3D class_name WaveManager -@export var waves : Array[Wave] +@export var level : Level var current_wave : Wave var current_troop : Troop var enemies_to_spawn : int = 0 var wave_on_going : bool = false -var game_has_start : bool = false + +@onready var waveTimer := $WaveTimer +@onready var troopTimer := $TroopTimer + + +func _ready() -> void: + troopTimer.timeout.connect(spawn_troop) + EventBus.player_defeated.connect(clearLevel) func _process(delta: float) -> void: - if GameManager.wave > 0: + if GameManager.wave > 0 || level.auto_start: spawn_manager() func spawn_next_wave() -> void: - if waves.is_empty(): + if level.waves.is_empty(): EventBus.player_has_won.emit() return - current_wave = waves.pop_front() + current_wave = level.waves.pop_front() GameManager.wave += 1 - $WaveTimer.start(current_wave.wait_time_before_launch_wave) + waveTimer.start(current_wave.wait_time_before_launch_wave) func spawn_troop() -> void: for n in current_troop.number_to_spawn: - var tempEnemy = current_troop.enemy.instantiate() - add_child(tempEnemy) + add_child(current_troop.enemy.instantiate()) GameManager.enemies_alive += 1 func spawn_manager() -> void: #Send next troop - if !$WaveTimer.is_stopped() || !$TroopTimer.is_stopped(): + if !waveTimer.is_stopped() || !troopTimer.is_stopped(): + return + + if !current_wave: + spawn_next_wave() return if !current_wave.troops.is_empty(): @@ -42,8 +52,7 @@ func spawn_manager() -> void: if (current_troop.spawn_delay == 0): spawn_troop() else: - $TroopTimer.wait_time = current_troop.spawn_delay - $TroopTimer.start() + troopTimer.start(current_troop.spawn_delay) wave_on_going = true if GameManager.enemies_alive == 0 && current_wave.troops.is_empty(): @@ -53,8 +62,5 @@ func spawn_manager() -> void: spawn_next_wave() -func _on_wave_timer_timeout() -> void: - pass - -func _on_troop_timer_timeout() -> void: - spawn_troop() +func clearLevel() -> void: + queue_free() diff --git a/Tiles/cube.gd b/Tiles/cube.gd index 59d6fb9..661fa3f 100644 --- a/Tiles/cube.gd +++ b/Tiles/cube.gd @@ -37,6 +37,7 @@ func win(): func death(): + EventBus.player_defeated.emit() Transition.goto("res://UI/defeat_screen.tscn") func _on_EventBus_money_received(money_received : int): diff --git a/Towers/aline.gd b/Towers/Aline/aline.gd similarity index 100% rename from Towers/aline.gd rename to Towers/Aline/aline.gd diff --git a/Towers/aline.gd.uid b/Towers/Aline/aline.gd.uid similarity index 100% rename from Towers/aline.gd.uid rename to Towers/Aline/aline.gd.uid diff --git a/Towers/aline.tscn b/Towers/Aline/aline.tscn similarity index 63% rename from Towers/aline.tscn rename to Towers/Aline/aline.tscn index 14d3542..a33785b 100644 --- a/Towers/aline.tscn +++ b/Towers/Aline/aline.tscn @@ -1,13 +1,17 @@ -[gd_scene load_steps=4 format=3 uid="uid://btmhe8ah6eexf"] +[gd_scene load_steps=5 format=3 uid="uid://ck1qryleu80s"] [ext_resource type="PackedScene" uid="uid://trg7ag3dqr2l" path="res://Towers/tower.tscn" id="1_gvvig"] -[ext_resource type="Script" uid="uid://16hafh01iv" path="res://Towers/aline.gd" id="2_6sjqq"] +[ext_resource type="Script" uid="uid://16hafh01iv" path="res://Towers/Aline/aline.gd" id="2_6sjqq"] +[ext_resource type="Texture2D" uid="uid://cob1lydkirn20" path="res://Assets/Icones/raccoon-head.svg" id="3_6h033"] [ext_resource type="Script" uid="uid://bg0x4egeu17qb" path="res://Scripts/Upgrades/TowerUpgrade.gd" id="3_p2nb1"] [node name="Aline" instance=ExtResource("1_gvvig")] script = ExtResource("2_6sjqq") -icone = null +tower_name = "Aline" +tower_type = 2 +icone = ExtResource("3_6h033") bio = "" +price = 150 bullet_damage = 1 tower_shop = Array[ExtResource("3_p2nb1")]([]) diff --git a/Towers/pierre.gd b/Towers/Pierre/pierre.gd similarity index 100% rename from Towers/pierre.gd rename to Towers/Pierre/pierre.gd diff --git a/Towers/pierre.gd.uid b/Towers/Pierre/pierre.gd.uid similarity index 100% rename from Towers/pierre.gd.uid rename to Towers/Pierre/pierre.gd.uid diff --git a/Towers/Pierre/pierre.tscn b/Towers/Pierre/pierre.tscn new file mode 100644 index 0000000..fae25ca --- /dev/null +++ b/Towers/Pierre/pierre.tscn @@ -0,0 +1,20 @@ +[gd_scene load_steps=4 format=3 uid="uid://bj6srer7ghf7p"] + +[ext_resource type="PackedScene" uid="uid://trg7ag3dqr2l" path="res://Towers/tower.tscn" id="1_7f7qx"] +[ext_resource type="Script" uid="uid://q4o384wv3ijj" path="res://Towers/Pierre/pierre.gd" id="1_v16mf"] +[ext_resource type="Texture2D" uid="uid://bb4wihq1n1wm7" path="res://Assets/Icones/labrador-head.svg" id="3_odfqx"] + +[node name="Pierre" instance=ExtResource("1_7f7qx")] +script = ExtResource("1_v16mf") +tower_name = null +tower_type = 1 +icone = ExtResource("3_odfqx") +bio = null +price = null +bullet_damage = null +action_cooldown = null +max_energy = null +energy_regen = null +energy_cost = null +buttonTooltip = null +tower_shop = null diff --git a/Towers/TowerListResource.gd b/Towers/TowerListResource.gd new file mode 100644 index 0000000..7b629e9 --- /dev/null +++ b/Towers/TowerListResource.gd @@ -0,0 +1,23 @@ +@tool +extends Resource +class_name TowerListResource + +@export var towers : Array[TowerResource] : set = towersHasChanged + +func getTowerSceneById(towerType : Tower.TYPES) -> PackedScene : + var towerIndex := towers.find_custom(func(towerResource): return towerResource.towerType == towerType) + return towers[towerIndex].towerScene + + +func towersHasChanged(value : Array) -> void: + if not Engine.is_editor_hint(): + return + + if value.back() == null: + value.pop_back() + value.append(TowerResource.new()) + towers = value + for towerResource in towers: + if not towerResource.changed.is_connected(emit_changed): + towerResource.changed.connect(emit_changed) + emit_changed() diff --git a/Towers/TowerListResource.gd.uid b/Towers/TowerListResource.gd.uid new file mode 100644 index 0000000..961ffbd --- /dev/null +++ b/Towers/TowerListResource.gd.uid @@ -0,0 +1 @@ +uid://clm4xbebbeqgj diff --git a/Towers/TowerResource.gd b/Towers/TowerResource.gd new file mode 100644 index 0000000..a1b4fc3 --- /dev/null +++ b/Towers/TowerResource.gd @@ -0,0 +1,14 @@ +@tool +extends Resource +class_name TowerResource + +@export var towerScene : PackedScene : set = towerSceneHasChanged +var towerType : Tower.TYPES + +func towerSceneHasChanged(value) -> void : + towerScene = value + if value: + var tower : Tower = towerScene.instantiate() + towerType = tower.tower_type + tower.queue_free() + emit_changed() diff --git a/Towers/TowerResource.gd.uid b/Towers/TowerResource.gd.uid new file mode 100644 index 0000000..165996a --- /dev/null +++ b/Towers/TowerResource.gd.uid @@ -0,0 +1 @@ +uid://lvkeejppvv2c diff --git a/Towers/pierre.tscn b/Towers/pierre.tscn deleted file mode 100644 index 7d97f81..0000000 --- a/Towers/pierre.tscn +++ /dev/null @@ -1,15 +0,0 @@ -[gd_scene load_steps=4 format=3 uid="uid://bj6srer7ghf7p"] - -[ext_resource type="PackedScene" uid="uid://trg7ag3dqr2l" path="res://Towers/tower.tscn" id="1_7f7qx"] -[ext_resource type="Script" uid="uid://q4o384wv3ijj" path="res://Towers/pierre.gd" id="1_v16mf"] -[ext_resource type="Script" uid="uid://bg0x4egeu17qb" path="res://Scripts/Upgrades/TowerUpgrade.gd" id="3_v16mf"] - -[node name="Pierre" instance=ExtResource("1_7f7qx")] -script = ExtResource("1_v16mf") -icone = null -bio = "" -bullet_damage = 1 -tower_shop = Array[ExtResource("3_v16mf")]([]) - -[node name="EnergyBar3D" parent="." index="7"] -visible = true diff --git a/Towers/tower-b.tscn b/Towers/tower-b.tscn deleted file mode 100644 index c645eed..0000000 --- a/Towers/tower-b.tscn +++ /dev/null @@ -1,47 +0,0 @@ -[gd_scene load_steps=5 format=3 uid="uid://dp846r4jscm5p"] - -[ext_resource type="Script" uid="uid://8kpvuurr5h5n" path="res://Towers/tower.gd" id="1_pb6ru"] -[ext_resource type="Texture2D" uid="uid://315k07rsgf6t" path="res://Assets/Characters/Female1.png" id="2_pb6ru"] - -[sub_resource type="BoxShape3D" id="BoxShape3D_egfuc"] -size = Vector3(1, 0.1, 1) - -[sub_resource type="SphereShape3D" id="SphereShape3D_pajr1"] -radius = 3.0 - -[node name="Tower" type="StaticBody3D"] -collision_layer = 4 -collision_mask = 4 -script = ExtResource("1_pb6ru") -tower_name = "Aline" - -[node name="CollisionShape3D" type="CollisionShape3D" parent="."] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.00914001, 0) -shape = SubResource("BoxShape3D_egfuc") - -[node name="Range" type="Area3D" parent="."] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.923584, 0) - -[node name="CollisionShape3D" type="CollisionShape3D" parent="Range"] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.475708, 0) -shape = SubResource("SphereShape3D_pajr1") - -[node name="Aim" type="Marker3D" parent="."] -transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.02026, 0) - -[node name="BulletContainer" type="Node" parent="."] - -[node name="Cooldown" type="Timer" parent="."] -wait_time = 1.5 - -[node name="Sprite3D" type="Sprite3D" parent="."] -transform = Transform3D(3.5, 0, 0, 0, 3.5, 0, 0, 0, 3.5, 0, 0.515442, 0) -billboard = 2 -texture = ExtResource("2_pb6ru") -hframes = 8 -vframes = 12 -frame = 75 - -[connection signal="body_entered" from="Range" to="." method="_on_range_body_entered"] -[connection signal="body_exited" from="Range" to="." method="_on_range_body_exited"] -[connection signal="timeout" from="Cooldown" to="." method="_on_cooldown_timeout"] diff --git a/Towers/tower.gd b/Towers/tower.gd index c96b08b..0cca62a 100644 --- a/Towers/tower.gd +++ b/Towers/tower.gd @@ -1,8 +1,11 @@ extends StaticBody3D class_name Tower +enum TYPES { NONE, PIERRE, ALINE, MAXENCE, VICTORIA, EVAN, ALEX } + var bullet : PackedScene = preload("res://Bullets/bullet.tscn") @export var tower_name : String = "Pierre" +@export var tower_type : TYPES @export var icone : Texture2D @export var bio : String @@ -21,6 +24,11 @@ var bullet : PackedScene = preload("res://Bullets/bullet.tscn") max_energy = value @export var energy_regen : float = 10.0 @export var energy_cost : float = 50.0 + +@export_group("Button") +@export var buttonTooltip : String + + @onready var energy_bar : EnergyBar3D = $EnergyBar3D @onready var sprite : Sprite3D = $Sprite3D @@ -38,8 +46,9 @@ var current_targets : Array = [] var current : CharacterBody3D var can_shoot : bool = true var is_exhausted : bool = false +var builded : bool = false -var is_rest : bool = false: +var is_rest : bool = true: set(value): is_rest = value if value: diff --git a/Towers/tower.tscn b/Towers/tower.tscn index ea4341e..6e971bc 100644 --- a/Towers/tower.tscn +++ b/Towers/tower.tscn @@ -57,7 +57,6 @@ frame = 75 [node name="EnergyBar3D" parent="." instance=ExtResource("3_pajr1")] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.44473, 0) -visible = false [node name="PriceTag" type="Label3D" parent="."] transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1.06776, 0) diff --git a/Towers/towers.tres b/Towers/towers.tres new file mode 100644 index 0000000..f9d01f4 --- /dev/null +++ b/Towers/towers.tres @@ -0,0 +1,20 @@ +[gd_resource type="Resource" script_class="TowerListResource" load_steps=7 format=3 uid="uid://jd8bdhpyl0pw"] + +[ext_resource type="Script" uid="uid://clm4xbebbeqgj" path="res://Towers/TowerListResource.gd" id="1_yjmnm"] +[ext_resource type="Script" uid="uid://lvkeejppvv2c" path="res://Towers/TowerResource.gd" id="2_mwakf"] +[ext_resource type="PackedScene" uid="uid://bj6srer7ghf7p" path="res://Towers/Pierre/pierre.tscn" id="3_mwakf"] +[ext_resource type="PackedScene" uid="uid://ck1qryleu80s" path="res://Towers/Aline/aline.tscn" id="4_mwakf"] + +[sub_resource type="Resource" id="Resource_mwakf"] +script = ExtResource("2_mwakf") +towerScene = ExtResource("3_mwakf") +metadata/_custom_type_script = "uid://lvkeejppvv2c" + +[sub_resource type="Resource" id="Resource_dlgx8"] +script = ExtResource("2_mwakf") +towerScene = ExtResource("4_mwakf") +metadata/_custom_type_script = "uid://lvkeejppvv2c" + +[resource] +script = ExtResource("1_yjmnm") +towers = Array[ExtResource("2_mwakf")]([SubResource("Resource_mwakf"), SubResource("Resource_dlgx8")]) diff --git a/UI/PierreEnergyMenuProgressBar.gd b/UI/PierreEnergyMenuProgressBar.gd deleted file mode 100644 index 27b013f..0000000 --- a/UI/PierreEnergyMenuProgressBar.gd +++ /dev/null @@ -1,9 +0,0 @@ -extends ProgressBar - -func _init() -> void: - #font_outline_color = Color.YELLOW - EventBus.energy_has_changed.connect(changeEnergy) - -func changeEnergy(tower : Tower) -> void: - if tower is Pierre: - value = tower.energy diff --git a/UI/PierreEnergyMenuProgressBar.gd.uid b/UI/PierreEnergyMenuProgressBar.gd.uid deleted file mode 100644 index 88fb1ff..0000000 --- a/UI/PierreEnergyMenuProgressBar.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://igvr34eaqta diff --git a/UI/gui.gd b/UI/gui.gd index c7eaeb6..dda1809 100644 --- a/UI/gui.gd +++ b/UI/gui.gd @@ -1,9 +1,18 @@ +@tool extends Control -@onready var player_manager : PlayerManager = $"../../PlayerManager" +const BUTTON_QTY = 12 + +const towerButton := preload("res://UI/tower_button.tscn") +var towerListResource := preload("res://Towers/towers.tres") + +@onready var buttonContainer = $HBoxContainer/ControlPanelBase/MarginContainer/GridContainer func _ready() -> void: - pass + addTowerButtonNodes() + if Engine.is_editor_hint(): + towerListResource.changed.connect(addTowerButtonNodes) + func _on_button_cube_pressed() -> void: pass # Replace with function body. @@ -16,26 +25,26 @@ func _on_button_quit_level_pressed() -> void: func _on_button_quit_game_pressed() -> void: get_tree().quit() +func addTowerButtonNodes() -> void: + for node in buttonContainer.get_children(): + if node.has_meta("dynamicButton"): + node.queue_free() -func _on_button_pierre_pressed() -> void: - var can_build = true - for tower in player_manager.towers: - if tower is Pierre: - can_build = false - player_manager.selected_tower = tower #If can't build, tower is selected + for towerResource in towerListResource.towers: + if !towerResource || towerResource.towerType == Tower.TYPES.NONE: + continue - if can_build: #If Pierre is not builded then build it ! - print("can build !") - EventBus.tower_to_build.emit(load("res://Towers/pierre.tscn")) + var towerBtn := towerButton.instantiate() + var tower : Tower = towerResource.towerScene.instantiate() + towerBtn.towerType = tower.tower_type + towerBtn.tooltip_text = tower.name + towerBtn.setButtonTexture(tower.icone) + towerBtn.set_meta("dynamicButton", true) + tower.queue_free() + buttonContainer.add_child(towerBtn) - -func _on_button_aline_pressed() -> void: - var can_build = true - for tower in player_manager.towers: - if tower is Pierre: - can_build = false - player_manager.selected_tower = tower #If can't build, tower is selected - - if can_build: #If Pierre is not builded then build it ! - print("can build !") - EventBus.tower_to_build.emit(load("res://Towers/aline.tscn")) + for i in BUTTON_QTY - towerListResource.towers.size(): + var placeholderBtn := Button.new() + placeholderBtn.set_meta("dynamicButton", true) + placeholderBtn.custom_minimum_size = Vector2(80, 80) + buttonContainer.add_child(placeholderBtn) diff --git a/UI/gui.tscn b/UI/gui.tscn index 623002e..86c17be 100644 --- a/UI/gui.tscn +++ b/UI/gui.tscn @@ -1,4 +1,4 @@ -[gd_scene load_steps=23 format=3 uid="uid://p6a6rb7sgeqd"] +[gd_scene load_steps=15 format=3 uid="uid://p6a6rb7sgeqd"] [ext_resource type="Script" uid="uid://d2x8oy4os7ysn" path="res://UI/label_money.gd" id="1_cwd3r"] [ext_resource type="Script" uid="uid://c350dletl5pde" path="res://UI/label_tower_in_cube.gd" id="2_6ujs1"] @@ -9,14 +9,7 @@ [ext_resource type="Texture2D" uid="uid://csl43eb7qjhe4" path="res://Assets/Icones/dog-house.svg" id="7_fffne"] [ext_resource type="Texture2D" uid="uid://dfnf26suc8yb6" path="res://Assets/Icones/sideswipe.svg" id="8_ay13l"] [ext_resource type="Texture2D" uid="uid://dootdihg7gkoj" path="res://Assets/Icones/exit-door.svg" id="8_decjp"] -[ext_resource type="Texture2D" uid="uid://bb4wihq1n1wm7" path="res://Assets/Icones/labrador-head.svg" id="9_decjp"] [ext_resource type="Texture2D" uid="uid://b4m5ejfdrm8s0" path="res://Assets/Icones/power-button.svg" id="9_reygo"] -[ext_resource type="Texture2D" uid="uid://cob1lydkirn20" path="res://Assets/Icones/raccoon-head.svg" id="10_reygo"] -[ext_resource type="Texture2D" uid="uid://boxdrq4nrq7hv" path="res://Assets/Icones/flamingo.svg" id="11_76b7g"] -[ext_resource type="Script" uid="uid://igvr34eaqta" path="res://UI/PierreEnergyMenuProgressBar.gd" id="12_decjp"] -[ext_resource type="Texture2D" uid="uid://m6jwakrus50v" path="res://Assets/Icones/sea-star.svg" id="12_ih1k6"] -[ext_resource type="Texture2D" uid="uid://dwwgho6f8f4kj" path="res://Assets/Icones/penguin.svg" id="13_ryolu"] -[ext_resource type="Texture2D" uid="uid://c4ir6y45pchpl" path="res://Assets/Icones/seahorse.svg" id="14_hndjt"] [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_h4fn5"] bg_color = Color(0.933333, 0.933333, 0.933333, 1) @@ -31,9 +24,6 @@ bg_color = Color(0.727498, 0.222072, 0.249347, 1) [sub_resource type="StyleBoxFlat" id="StyleBoxFlat_3lugd"] bg_color = Color(0.933333, 0.933333, 0.933333, 1) -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_decjp"] -bg_color = Color(1, 0.878431, 0, 1) - [node name="GUI" type="Control"] layout_mode = 3 anchors_preset = 15 @@ -209,144 +199,6 @@ grow_vertical = 2 texture = ExtResource("8_ay13l") expand_mode = 1 -[node name="ButtonPierre" type="Button" parent="HBoxContainer/ControlPanelBase/MarginContainer/GridContainer"] -custom_minimum_size = Vector2(80, 80) -layout_mode = 2 -tooltip_text = "Sélectionner Pierre" -mouse_default_cursor_shape = 2 - -[node name="TextureRect" type="TextureRect" parent="HBoxContainer/ControlPanelBase/MarginContainer/GridContainer/ButtonPierre"] -layout_mode = 1 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -texture = ExtResource("9_decjp") -expand_mode = 1 - -[node name="ProgressBar" type="ProgressBar" parent="HBoxContainer/ControlPanelBase/MarginContainer/GridContainer/ButtonPierre"] -layout_mode = 0 -offset_left = 1.0 -offset_top = 71.0 -offset_right = 79.0 -offset_bottom = 78.0 -mouse_filter = 1 -theme_override_styles/fill = SubResource("StyleBoxFlat_decjp") -show_percentage = false -script = ExtResource("12_decjp") - -[node name="ButtonAline" type="Button" parent="HBoxContainer/ControlPanelBase/MarginContainer/GridContainer"] -custom_minimum_size = Vector2(80, 80) -layout_mode = 2 -tooltip_text = "Sélectionner Aline" -mouse_default_cursor_shape = 2 - -[node name="TextureRect" type="TextureRect" parent="HBoxContainer/ControlPanelBase/MarginContainer/GridContainer/ButtonAline"] -layout_mode = 1 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -texture = ExtResource("10_reygo") -expand_mode = 1 - -[node name="ButtonMaxence" type="Button" parent="HBoxContainer/ControlPanelBase/MarginContainer/GridContainer"] -custom_minimum_size = Vector2(80, 80) -layout_mode = 2 -tooltip_text = "Sélectionner Maxence" -mouse_default_cursor_shape = 2 - -[node name="TextureRect" type="TextureRect" parent="HBoxContainer/ControlPanelBase/MarginContainer/GridContainer/ButtonMaxence"] -layout_mode = 1 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -texture = ExtResource("11_76b7g") -expand_mode = 1 - -[node name="ButtonVictoria" type="Button" parent="HBoxContainer/ControlPanelBase/MarginContainer/GridContainer"] -custom_minimum_size = Vector2(80, 80) -layout_mode = 2 -tooltip_text = "Sélectionner Victoria" -mouse_default_cursor_shape = 2 - -[node name="TextureRect" type="TextureRect" parent="HBoxContainer/ControlPanelBase/MarginContainer/GridContainer/ButtonVictoria"] -layout_mode = 2 -offset_right = 80.0 -offset_bottom = 80.0 -grow_horizontal = 2 -grow_vertical = 2 -texture = ExtResource("12_ih1k6") -expand_mode = 1 - -[node name="ButtonEvan" type="Button" parent="HBoxContainer/ControlPanelBase/MarginContainer/GridContainer"] -custom_minimum_size = Vector2(80, 80) -layout_mode = 2 -tooltip_text = "Sélectionner Evan" -mouse_default_cursor_shape = 2 - -[node name="TextureRect" type="TextureRect" parent="HBoxContainer/ControlPanelBase/MarginContainer/GridContainer/ButtonEvan"] -layout_mode = 1 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -texture = ExtResource("13_ryolu") -expand_mode = 1 - -[node name="ButtonAlex" type="Button" parent="HBoxContainer/ControlPanelBase/MarginContainer/GridContainer"] -custom_minimum_size = Vector2(80, 80) -layout_mode = 2 -tooltip_text = "Sélectionner Alex" -mouse_default_cursor_shape = 2 - -[node name="TextureRect" type="TextureRect" parent="HBoxContainer/ControlPanelBase/MarginContainer/GridContainer/ButtonAlex"] -layout_mode = 1 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -texture = ExtResource("14_hndjt") -expand_mode = 1 - -[node name="Button11" type="Button" parent="HBoxContainer/ControlPanelBase/MarginContainer/GridContainer"] -custom_minimum_size = Vector2(80, 80) -layout_mode = 2 -mouse_default_cursor_shape = 2 - -[node name="Button12" type="Button" parent="HBoxContainer/ControlPanelBase/MarginContainer/GridContainer"] -custom_minimum_size = Vector2(80, 80) -layout_mode = 2 -mouse_default_cursor_shape = 2 - -[node name="Button13" type="Button" parent="HBoxContainer/ControlPanelBase/MarginContainer/GridContainer"] -custom_minimum_size = Vector2(80, 80) -layout_mode = 2 -mouse_default_cursor_shape = 2 - -[node name="Button14" type="Button" parent="HBoxContainer/ControlPanelBase/MarginContainer/GridContainer"] -custom_minimum_size = Vector2(80, 80) -layout_mode = 2 -mouse_default_cursor_shape = 2 - -[node name="Button15" type="Button" parent="HBoxContainer/ControlPanelBase/MarginContainer/GridContainer"] -custom_minimum_size = Vector2(80, 80) -layout_mode = 2 -mouse_default_cursor_shape = 2 - -[node name="Button16" type="Button" parent="HBoxContainer/ControlPanelBase/MarginContainer/GridContainer"] -custom_minimum_size = Vector2(80, 80) -layout_mode = 2 -mouse_default_cursor_shape = 2 - [connection signal="pressed" from="HBoxContainer/ControlPanelBase/MarginContainer/GridContainer/ButtonCube" to="." method="_on_button_cube_pressed"] [connection signal="pressed" from="HBoxContainer/ControlPanelBase/MarginContainer/GridContainer/ButtonQuitLevel" to="." method="_on_button_quit_level_pressed"] [connection signal="pressed" from="HBoxContainer/ControlPanelBase/MarginContainer/GridContainer/ButtonQuitGame" to="." method="_on_button_quit_game_pressed"] -[connection signal="pressed" from="HBoxContainer/ControlPanelBase/MarginContainer/GridContainer/ButtonPierre" to="." method="_on_button_pierre_pressed"] -[connection signal="pressed" from="HBoxContainer/ControlPanelBase/MarginContainer/GridContainer/ButtonAline" to="." method="_on_button_aline_pressed"] diff --git a/UI/shop_panel.tscn b/UI/shop_panel.tscn deleted file mode 100644 index b3789d7..0000000 --- a/UI/shop_panel.tscn +++ /dev/null @@ -1,49 +0,0 @@ -[gd_scene load_steps=3 format=3 uid="uid://he31g7f3ru1c"] - -[ext_resource type="PackedScene" uid="uid://bqpeu50pgsdfk" path="res://UI/tower_button.tscn" id="1_txsyf"] - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_oxe32"] -bg_color = Color(0.921569, 0.890196, 0.415686, 1) - -[node name="ShopPanel" type="Panel"] -custom_minimum_size = Vector2(300, 0) -anchors_preset = 11 -anchor_left = 1.0 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 0 -grow_vertical = 2 - -[node name="VBoxContainer" type="VBoxContainer" parent="."] -layout_mode = 1 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 - -[node name="PierreButton" parent="VBoxContainer" instance=ExtResource("1_txsyf")] -layout_mode = 2 - -[node name="EnergyBar" type="ProgressBar" parent="VBoxContainer/PierreButton"] -custom_minimum_size = Vector2(0, 5) -layout_mode = 1 -anchors_preset = 12 -anchor_top = 1.0 -anchor_right = 1.0 -anchor_bottom = 1.0 -offset_top = -4.0 -grow_horizontal = 2 -grow_vertical = 0 -theme_override_styles/fill = SubResource("StyleBoxFlat_oxe32") -show_percentage = false - -[node name="MarginContainer" type="MarginContainer" parent="VBoxContainer"] -layout_mode = 2 -size_flags_vertical = 3 - -[node name="CancelButton" type="Button" parent="VBoxContainer"] -custom_minimum_size = Vector2(0, 50) -layout_mode = 2 -text = "Cancel -" diff --git a/UI/tower_button.gd b/UI/tower_button.gd index 8336f8a..0f25c35 100644 --- a/UI/tower_button.gd +++ b/UI/tower_button.gd @@ -1,8 +1,20 @@ +@tool extends Button class_name TowerButton -@export var tower : PackedScene -#var tower_in_game : Tower +var towerType : Tower.TYPES -func _on_pressed() -> void: - EventBus.tower_selected.emit(tower, self) +func _ready() -> void: + #font_outline_color = Color.YELLOW + if not Engine.is_editor_hint(): + pressed.connect(EventBus.tower_selected.emit.bind(towerType)) + EventBus.energy_has_changed.connect(changeEnergy) + + +func changeEnergy(tower : Tower) -> void: + if tower.tower_type == towerType: + $ProgressBar.value = tower.energy + + +func setButtonTexture(texture : Texture2D) -> void: + $TextureRect.texture = texture diff --git a/UI/tower_button.tscn b/UI/tower_button.tscn index 543ff2f..75e06e7 100644 --- a/UI/tower_button.tscn +++ b/UI/tower_button.tscn @@ -1,25 +1,34 @@ -[gd_scene load_steps=4 format=3 uid="uid://bqpeu50pgsdfk"] +[gd_scene load_steps=3 format=3 uid="uid://dqb5o8w7u50hc"] -[ext_resource type="Texture2D" uid="uid://dqyhhvxpwtpsy" path="res://Assets/Emotes/emote_star.png" id="1_88p3s"] -[ext_resource type="Script" uid="uid://dyhtr6g7kd1g2" path="res://UI/tower_button.gd" id="1_i47ne"] -[ext_resource type="PackedScene" uid="uid://trg7ag3dqr2l" path="res://Towers/tower.tscn" id="2_4qiv5"] +[ext_resource type="Script" uid="uid://dyhtr6g7kd1g2" path="res://UI/tower_button.gd" id="1_3542o"] + +[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_decjp"] +bg_color = Color(1, 0.878431, 0, 1) [node name="TowerButton" type="Button"] -custom_minimum_size = Vector2(300, 50) -text = "Pierre -250 Trucs" -script = ExtResource("1_i47ne") -tower = ExtResource("2_4qiv5") +custom_minimum_size = Vector2(80, 80) +offset_right = 80.0 +offset_bottom = 80.0 +tooltip_text = "Sélectionner Pierre" +mouse_default_cursor_shape = 2 +script = ExtResource("1_3542o") +metadata/_custom_type_script = "uid://dyhtr6g7kd1g2" [node name="TextureRect" type="TextureRect" parent="."] layout_mode = 1 -anchors_preset = 4 -anchor_top = 0.5 -anchor_bottom = 0.5 -offset_top = -20.0 -offset_right = 40.0 -offset_bottom = 20.0 +anchors_preset = 15 +anchor_right = 1.0 +anchor_bottom = 1.0 +grow_horizontal = 2 grow_vertical = 2 -texture = ExtResource("1_88p3s") +expand_mode = 1 -[connection signal="pressed" from="." to="." method="_on_pressed"] +[node name="ProgressBar" type="ProgressBar" parent="."] +layout_mode = 0 +offset_left = 1.0 +offset_top = 71.0 +offset_right = 79.0 +offset_bottom = 78.0 +mouse_filter = 1 +theme_override_styles/fill = SubResource("StyleBoxFlat_decjp") +show_percentage = false diff --git a/UI/ui.tscn b/UI/ui.tscn deleted file mode 100644 index 85a7885..0000000 --- a/UI/ui.tscn +++ /dev/null @@ -1,14 +0,0 @@ -[gd_scene load_steps=2 format=3 uid="uid://dbx8ow3v45k4k"] - -[ext_resource type="PackedScene" uid="uid://he31g7f3ru1c" path="res://UI/shop_panel.tscn" id="1_2fwl4"] - -[node name="UI" type="Control"] -layout_mode = 3 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 - -[node name="ShopPanel" parent="." instance=ExtResource("1_2fwl4")] -layout_mode = 1 diff --git a/Waves/wave_1.tres b/Waves/wave_1.tres deleted file mode 100644 index e49c9d9..0000000 --- a/Waves/wave_1.tres +++ /dev/null @@ -1,33 +0,0 @@ -[gd_resource type="Resource" script_class="Wave" load_steps=7 format=3 uid="uid://dkbuy7fetnihs"] - -[ext_resource type="Script" uid="uid://chu8s12rtdeqx" path="res://Scripts/Wave.gd" id="1_bubg8"] -[ext_resource type="Script" uid="uid://blxx3vs2wnfet" path="res://Scripts/Troop.gd" id="2_mn2od"] -[ext_resource type="PackedScene" uid="uid://dknt1oiyei5e5" path="res://enemies/enemy-a.tscn" id="3_40llc"] - -[sub_resource type="Resource" id="Resource_1mf3x"] -script = ExtResource("2_mn2od") -enemy = ExtResource("3_40llc") -number_to_spawn = 2 -spawn_delay = 1.0 -metadata/_custom_type_script = "uid://blxx3vs2wnfet" - -[sub_resource type="Resource" id="Resource_3i3vq"] -script = ExtResource("2_mn2od") -enemy = ExtResource("3_40llc") -number_to_spawn = 1 -spawn_delay = 3.0 -metadata/_custom_type_script = "uid://blxx3vs2wnfet" - -[sub_resource type="Resource" id="Resource_qdqr3"] -script = ExtResource("2_mn2od") -enemy = ExtResource("3_40llc") -number_to_spawn = 1 -spawn_delay = 1.0 -metadata/_custom_type_script = "uid://blxx3vs2wnfet" - -[resource] -script = ExtResource("1_bubg8") -troops = Array[ExtResource("2_mn2od")]([SubResource("Resource_1mf3x"), SubResource("Resource_3i3vq"), SubResource("Resource_qdqr3")]) -wait_time_before_launch_wave = 5 -wait_for_enemy_kills = true -metadata/_custom_type_script = "uid://chu8s12rtdeqx" diff --git a/addons/LevelEditor/Draggable.gd b/addons/LevelEditor/Draggable.gd new file mode 100644 index 0000000..61510e1 --- /dev/null +++ b/addons/LevelEditor/Draggable.gd @@ -0,0 +1 @@ +extends Node diff --git a/addons/LevelEditor/Draggable.gd.uid b/addons/LevelEditor/Draggable.gd.uid new file mode 100644 index 0000000..2c4138e --- /dev/null +++ b/addons/LevelEditor/Draggable.gd.uid @@ -0,0 +1 @@ +uid://dno7nph2s6ad0 diff --git a/addons/LevelEditor/LevelEditor.gd b/addons/LevelEditor/LevelEditor.gd new file mode 100644 index 0000000..e5e1911 --- /dev/null +++ b/addons/LevelEditor/LevelEditor.gd @@ -0,0 +1,32 @@ +@tool +extends EditorPlugin + +# Replace this value with a PascalCase autoload name, as per the GDScript style guide. +#const AUTOLOAD_NAME = "LevelEditorAutoload" +const ui = preload("res://addons/LevelEditor/wave_maker.tscn") + +var main_panel_instance + +func _enter_tree(): + main_panel_instance = ui.instantiate() + # Add the main panel to the editor's main viewport. + EditorInterface.get_editor_main_screen().add_child(main_panel_instance) + # Hide the main panel. Very much required. + _make_visible(false) + + +func _has_main_screen(): + return true + + +func _make_visible(visible): + if main_panel_instance: + main_panel_instance.visible = visible + + +func _get_plugin_name(): + return "Level Editor" + + +func _get_plugin_icon(): + return EditorInterface.get_editor_theme().get_icon("Node", "EditorIcons") diff --git a/addons/LevelEditor/LevelEditor.gd.uid b/addons/LevelEditor/LevelEditor.gd.uid new file mode 100644 index 0000000..e1d9cb0 --- /dev/null +++ b/addons/LevelEditor/LevelEditor.gd.uid @@ -0,0 +1 @@ +uid://ppf3jmjydns0 diff --git a/addons/LevelEditor/UI/CustomLineEdit.gd b/addons/LevelEditor/UI/CustomLineEdit.gd new file mode 100644 index 0000000..69edbdf --- /dev/null +++ b/addons/LevelEditor/UI/CustomLineEdit.gd @@ -0,0 +1,51 @@ +@tool +extends LineEdit + +class_name CustomLineEdit + +enum TYPE { INT, TEXT, FLOAT } + +@export var inputType : TYPE +@export var step : float = 1 +var oldValue : String = "" + +var value: + get: + return getTypedValue(text) + +func _init() -> void: + text_changed.connect(valueUpdated) + + +func _input(event : InputEvent) -> void: + if !has_focus() || event is not InputEventKey || !event.pressed: + return + + processKeyInput(event) + + +func processKeyInput(event : InputEventKey) -> void: + if inputType in [TYPE.INT, TYPE.FLOAT]: + if event.keycode == KEY_UP: + text = str(getTypedValue(str(value + step))) + valueUpdated(text) + elif event.keycode == KEY_DOWN: + text = str(getTypedValue(str(value - step))) + valueUpdated(text) + + +func valueUpdated(newText : String) -> void: + valueHasChanged.emit(value) + + +func setValue(value) -> void: + text = str(getTypedValue(str(value))) + + +func getTypedValue(valueToType: String): + match inputType: + TYPE.INT: return int(valueToType) + TYPE.FLOAT: return float(valueToType) + _: return valueToType + +signal valueHasChanged(newValue) diff --git a/addons/LevelEditor/UI/CustomLineEdit.gd.uid b/addons/LevelEditor/UI/CustomLineEdit.gd.uid new file mode 100644 index 0000000..740a6f2 --- /dev/null +++ b/addons/LevelEditor/UI/CustomLineEdit.gd.uid @@ -0,0 +1 @@ +uid://bpv75ucqoy446 diff --git a/addons/LevelEditor/UI/CustomOptionButton.gd b/addons/LevelEditor/UI/CustomOptionButton.gd new file mode 100644 index 0000000..a5fdbe7 --- /dev/null +++ b/addons/LevelEditor/UI/CustomOptionButton.gd @@ -0,0 +1,47 @@ +@tool +extends OptionButton +class_name CustomOptionButton + +@export_dir var resourcePath : String +@export var regexPattern : String +@export var reloadOnOpen : bool = false + +var selectedValue : String + +func _ready() -> void: + loadData(true) + item_selected.connect(itemHasBeenSelected) + pressed.connect(loadData) + allow_reselect = true + +func loadData(force : bool = false) -> void: + if !force && !reloadOnOpen: + return + + var regex := RegEx.create_from_string(regexPattern) + var dir := DirAccess.open(resourcePath) + clear() + for file in dir.get_files(): + var fileMatch := regex.search(file) + if fileMatch: + add_item(fileMatch.strings[1]) + if selectedValue == fileMatch.strings[1]: + selected = item_count - 1 + + if !selectedValue && item_count > 0: + selected = 0 + +func itemHasBeenSelected(index : int) -> void: + if selectedValue != get_item_text(index): + selectedValue = get_item_text(index) + onValueChanged.emit(selectedValue) + + +func selectItemByName(name : String) -> void: + for i in item_count: + if get_item_text(i) == name: + selected = i + return + + +signal onValueChanged(value : String) diff --git a/addons/LevelEditor/UI/CustomOptionButton.gd.uid b/addons/LevelEditor/UI/CustomOptionButton.gd.uid new file mode 100644 index 0000000..690e15b --- /dev/null +++ b/addons/LevelEditor/UI/CustomOptionButton.gd.uid @@ -0,0 +1 @@ +uid://b47p2u458hsn0 diff --git a/addons/LevelEditor/UI/baseLabel.tres b/addons/LevelEditor/UI/baseLabel.tres new file mode 100644 index 0000000..9de60ce --- /dev/null +++ b/addons/LevelEditor/UI/baseLabel.tres @@ -0,0 +1,7 @@ +[gd_resource type="LabelSettings" load_steps=2 format=3 uid="uid://s1lfc81j20la"] + +[ext_resource type="FontFile" uid="uid://dv7ow5e7jj355" path="res://Assets/Fonts/Grandstander/static/Grandstander-Light.ttf" id="1_r6cgw"] + +[resource] +font = ExtResource("1_r6cgw") +font_size = 24 diff --git a/addons/LevelEditor/UI/theme.tres b/addons/LevelEditor/UI/theme.tres new file mode 100644 index 0000000..c698a00 --- /dev/null +++ b/addons/LevelEditor/UI/theme.tres @@ -0,0 +1,4 @@ +[gd_resource type="Theme" format=3 uid="uid://bvji8e8p2d72y"] + +[resource] +default_font_size = 20 diff --git a/addons/LevelEditor/UI/troopLabel.tres b/addons/LevelEditor/UI/troopLabel.tres new file mode 100644 index 0000000..1c450a9 --- /dev/null +++ b/addons/LevelEditor/UI/troopLabel.tres @@ -0,0 +1,7 @@ +[gd_resource type="LabelSettings" load_steps=2 format=3 uid="uid://bee458c1kc0j7"] + +[ext_resource type="FontFile" uid="uid://ctmfgwv1dwdyg" path="res://Assets/Fonts/Grandstander/static/Grandstander-BoldItalic.ttf" id="1_kyxue"] + +[resource] +font = ExtResource("1_kyxue") +font_size = 24 diff --git a/addons/LevelEditor/UI/waveLabel.tres b/addons/LevelEditor/UI/waveLabel.tres new file mode 100644 index 0000000..1d5577e --- /dev/null +++ b/addons/LevelEditor/UI/waveLabel.tres @@ -0,0 +1,7 @@ +[gd_resource type="LabelSettings" load_steps=2 format=3 uid="uid://cafoo04y1t31t"] + +[ext_resource type="FontFile" uid="uid://byqqml5g6dwil" path="res://Assets/Fonts/Grandstander/static/Grandstander-BlackItalic.ttf" id="1_m52f8"] + +[resource] +font = ExtResource("1_m52f8") +font_size = 32 diff --git a/addons/LevelEditor/WaveMaker.gd b/addons/LevelEditor/WaveMaker.gd new file mode 100644 index 0000000..e051793 --- /dev/null +++ b/addons/LevelEditor/WaveMaker.gd @@ -0,0 +1,243 @@ +@tool +extends Control + +const LEVEL_PATH : String = "res://Levels" +const LEVEL_NAME_PATERN : String = "level_{id}.tres" +const LEVEL_NAME_PATH_PATERN : String = LEVEL_PATH + "/{name}.tres" + +const ENEMY_PATH : String = "res://enemies" +const ENEMY_REGEX_PATERN : String = "(enemy.*)\\.tscn" + +const BASE_LABEL_SETTINGS = preload("res://addons/LevelEditor/UI/baseLabel.tres") +const WAVE_LABEL_SETTINGS = preload("res://addons/LevelEditor/UI/waveLabel.tres") +const TROOP_LABEL_SETTINGS = preload("res://addons/LevelEditor/UI/troopLabel.tres") + +const space_multiplicator : int = 10 +enum DIRECTION { UP, DOWN, TOP, LEFT, VERTICAL, HORIZONTAL} + + +@onready var autoLaunchLevel := $VBoxContainer2/ButtonContainer2/AutoLaunchLevel +@onready var waitForKill := $VBoxContainer2/ButtonContainer4/WaitForKill +@onready var levelSelect := $VBoxContainer2/HBoxContainer/LevelSelect +@onready var waveTabContainer := $VBoxContainer2/ScrollContainer/WaveContainer +@onready var waveTimerInput := $VBoxContainer2/ButtonContainer3/WaveTimer +var level : Level +var currentWave : int = -1 + + +func _input(event: InputEvent) -> void: + if !has_focus() || event is not InputEventKey || !event.pressed: + return + + if event.keycode == KEY_RIGHT && waveTabContainer.get_tab_count() > waveTabContainer.current_tab: + waveTabContainer.current_tab += 1 + elif event.keycode == KEY_LEFT && waveTabContainer.current_tab > 0: + waveTabContainer.current_tab -= 1 + + +func buildTree() -> void: + if !level: + return + + autoLaunchLevel.button_pressed = level.auto_start + for i in level.waves.size(): + var troopContainer := VBoxContainer.new() + waitForKill.button_pressed = level.waves[i].wait_for_enemy_kills + buildWave(level.waves[i], troopContainer) + waveTabContainer.add_child(troopContainer) + waveTabContainer.set_tab_title(i, "Vague N°" + str(i + 1)) + + +func buildWave(wave : Wave, troopContainer : VBoxContainer) -> void: + for i in wave.troops.size(): + var troop : Troop = wave.troops[i] + + if i > 0 && !troopContainer.get_child(troopContainer.get_child_count() - 1).has_meta("troop_group") \ + || troop.spawn_delay > 0: + troopContainer.add_child(HSeparator.new()) + + if troop.spawn_delay: + var timeSeparator := buildInputLabel( + func(newValue): + troop.spawn_delay = newValue + if newValue == 0: + cleanAndBuildMenu(), + troop.spawn_delay, + CustomLineEdit.TYPE.FLOAT, + "sec." + ) + troopContainer.add_child(timeSeparator) + + var nodeToAppend : BoxContainer = troopContainer + if i < wave.troops.size() -1 && wave.troops[i + 1].spawn_delay == 0: + if i == 0 || !troopContainer.get_child(troopContainer.get_child_count() - 1).has_meta("troop_group"): + nodeToAppend = HBoxContainer.new() + nodeToAppend.size_flags_horizontal = Control.SIZE_SHRINK_CENTER + nodeToAppend.set_meta("troop_group", true) + troopContainer.add_child(nodeToAppend) + + if i > 0 && troop.spawn_delay == 0: + nodeToAppend = troopContainer.get_child(troopContainer.get_child_count() - 1) + nodeToAppend.add_child(VSeparator.new()) + + var ennemyContainer := VBoxContainer.new() + ennemyContainer.add_child(createSection("Troop N°" + str(i + 1), removeTroop.bind(troop, wave), TROOP_LABEL_SETTINGS)) + + if troop.spawn_delay == 0: + var button := Button.new() + button.text = "Séparer" + button.pressed.connect( + func(): + troop.spawn_delay = 1 + cleanAndBuildMenu() + ) + ennemyContainer.add_child(button) + + buildTroop(troop, ennemyContainer) + nodeToAppend.add_child(ennemyContainer) + + var addTroopBtn := Button.new() + addTroopBtn.text = "Ajouter une troupe" + addTroopBtn.pressed.connect(addTroop.bind(wave)) + troopContainer.add_child(addTroopBtn) + + + +func buildTroop(troop : Troop, ennemyContainer : VBoxContainer) -> void: + var qtyEdit := buildInputLabel( + func(newValue): troop.number_to_spawn = newValue, + troop.number_to_spawn, + CustomLineEdit.TYPE.INT, + "x" + ) + + var enemySelector := CustomOptionButton.new() + enemySelector.resourcePath = ENEMY_PATH + enemySelector.regexPattern = ENEMY_REGEX_PATERN + var regex = RegEx.create_from_string(ENEMY_REGEX_PATERN) + enemySelector.onValueChanged.connect(func(enemyFileName): addEnemy(troop, enemyFileName)) + if troop.enemy: + enemySelector.selectItemByName(regex.search(troop.enemy.resource_path).strings[0]) + + qtyEdit.add_child(enemySelector) + ennemyContainer.add_child(qtyEdit) + + +func buildInputLabel(updateCallback : Callable, delay : float, type : CustomLineEdit.TYPE, text : String = "") -> HBoxContainer: + var container := HBoxContainer.new() + container.size_flags_vertical = Control.SIZE_SHRINK_CENTER + container.alignment = BoxContainer.ALIGNMENT_CENTER + + var timeEdit := CustomLineEdit.new() + timeEdit.inputType = type + timeEdit.setValue(delay) + timeEdit.valueHasChanged.connect(updateCallback) + container.add_child(timeEdit) + + if text: + var label := Label.new() + label.text = text + label.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER + label.label_settings = BASE_LABEL_SETTINGS + container.add_child(label) + + return container + +func createSection(sectionName : String, BtnCallback : Callable, settings : LabelSettings = BASE_LABEL_SETTINGS) -> HSplitContainer : + var container := HSplitContainer.new() + + var label := Label.new() + label.text = sectionName + label.label_settings = settings + + var button := Button.new() + button.text = "Supprimer" + button.pressed.connect(BtnCallback) + + container.add_child(label) + container.add_child(button) + + return container + + +func cleanMenu() -> void: + if waveTabContainer.get_child_count() > 0: + for child in waveTabContainer.get_children(): + child.queue_free() + + +func removeWave() -> void: + level.waves.remove_at(currentWave) + waveTabContainer.get_child(currentWave).queue_free() + + +func addWave() -> void: + level.waves.append(Wave.new()) + cleanAndBuildMenu() + + +func changeWaveOrder(newPos : int) -> void: + var newWaveOrder : Array[Wave] + var waveToMove = level.waves[currentWave] + for i in level.waves.size(): + if i == 0 && newPos == 0: + newWaveOrder.append(waveToMove) + if i != currentWave: + newWaveOrder.append(level.waves[i]) + if i == newPos && newPos != 0: + newWaveOrder.append(waveToMove) + currentWave = newPos + level.waves = newWaveOrder + + + +func addTroop(toWave : Wave) -> void: + toWave.troops.append(Troop.new()) + cleanAndBuildMenu() + + +func addEnemy(toTroop : Troop, enemyResourcePath : String) -> void: + var enemy = load(enemyResourcePath) + toTroop.enemy = enemy + + +func removeTroop(troop : Troop, fromWave : Wave) -> void: + fromWave.troops.erase(troop) + cleanAndBuildMenu() + + +func selectLevel(levelName : String) -> void : + level = load(LEVEL_NAME_PATH_PATERN.format([["name", levelName]])) + + +func changeWaveCooldown(duration : float) -> void: + level.waves[currentWave].wait_time_before_launch_wave = duration + + +func tabFocusHaschanged(idx : int) -> void: + waveTimerInput.setValue(level.waves[idx].wait_time_before_launch_wave) + currentWave = idx + + +func cleanAndBuildMenu() -> void: + cleanMenu() + buildTree() + + +func _on_auto_launch_wave_toggled(toggled_on: bool) -> void: + level.auto_start = toggled_on + + +func _on_wait_for_kill_toggled(toggled_on: bool) -> void: + level.waves[currentWave].wait_for_enemy_kills = toggled_on + + +func _on_new_level_pressed() -> void: + level = Level.new() + levelSelect.add_item(LEVEL_NAME_PATERN.format([["id", levelSelect.item_count + 1]])) + levelSelect.select(levelSelect.item_count - 1) + _on_save_pressed() + + +func _on_save_pressed() -> void: + ResourceSaver.save(level, LEVEL_PATH + "/" + levelSelect.selectedValue, ResourceSaver.FLAG_BUNDLE_RESOURCES) diff --git a/addons/LevelEditor/WaveMaker.gd.uid b/addons/LevelEditor/WaveMaker.gd.uid new file mode 100644 index 0000000..26ef6d4 --- /dev/null +++ b/addons/LevelEditor/WaveMaker.gd.uid @@ -0,0 +1 @@ +uid://27y0jliv6ckx diff --git a/addons/LevelEditor/plugin.cfg b/addons/LevelEditor/plugin.cfg new file mode 100644 index 0000000..407f1c2 --- /dev/null +++ b/addons/LevelEditor/plugin.cfg @@ -0,0 +1,7 @@ +[plugin] + +name="LevelEditor" +description="" +author="Varylios" +version="0.3" +script="LevelEditor.gd" diff --git a/addons/LevelEditor/wave_maker.tscn b/addons/LevelEditor/wave_maker.tscn new file mode 100644 index 0000000..d2dcebd --- /dev/null +++ b/addons/LevelEditor/wave_maker.tscn @@ -0,0 +1,144 @@ +[gd_scene load_steps=4 format=3 uid="uid://dh24t8804isms"] + +[ext_resource type="Script" uid="uid://27y0jliv6ckx" path="res://addons/LevelEditor/WaveMaker.gd" id="1_usfft"] +[ext_resource type="Script" uid="uid://b47p2u458hsn0" path="res://addons/LevelEditor/UI/CustomOptionButton.gd" id="2_xjxpq"] +[ext_resource type="Script" uid="uid://bpv75ucqoy446" path="res://addons/LevelEditor/UI/CustomLineEdit.gd" id="3_qw7ts"] + +[node name="Menu" type="HBoxContainer"] +offset_right = 885.0 +offset_bottom = 574.0 +size_flags_horizontal = 3 +size_flags_vertical = 3 +script = ExtResource("1_usfft") + +[node name="MarginContainer" type="MarginContainer" parent="."] +custom_minimum_size = Vector2(20, 0) +layout_mode = 2 + +[node name="VBoxContainer2" type="VBoxContainer" parent="."] +layout_mode = 2 +size_flags_horizontal = 3 + +[node name="MarginContainer" type="MarginContainer" parent="VBoxContainer2"] +custom_minimum_size = Vector2(0, 20) +layout_mode = 2 + +[node name="HBoxContainer" type="HBoxContainer" parent="VBoxContainer2"] +layout_mode = 2 + +[node name="LevelSelect" type="OptionButton" parent="VBoxContainer2/HBoxContainer"] +layout_mode = 2 +selected = 0 +allow_reselect = true +item_count = 2 +popup/item_0/text = "level_1" +popup/item_0/id = 0 +popup/item_1/text = "level_2" +popup/item_1/id = 1 +script = ExtResource("2_xjxpq") +resourcePath = "res://Levels" +regexPattern = "(level_.*)\\.tres" +reloadOnOpen = true +metadata/_custom_type_script = "uid://b47p2u458hsn0" + +[node name="NewLevel" type="Button" parent="VBoxContainer2/HBoxContainer"] +layout_mode = 2 +text = "Nouveau Niveau" + +[node name="Show" type="Button" parent="VBoxContainer2/HBoxContainer"] +layout_mode = 2 +text = "Afficher" + +[node name="Clean" type="Button" parent="VBoxContainer2/HBoxContainer"] +layout_mode = 2 +text = "Effacer" + +[node name="Save" type="Button" parent="VBoxContainer2/HBoxContainer"] +layout_mode = 2 +text = "Sauvegarder" + +[node name="Test" type="Button" parent="VBoxContainer2/HBoxContainer"] +visible = false +layout_mode = 2 +text = "TESTER !!!!" + +[node name="ButtonContainer" type="HBoxContainer" parent="VBoxContainer2"] +layout_mode = 2 + +[node name="Add wave" type="Button" parent="VBoxContainer2/ButtonContainer"] +layout_mode = 2 +text = "Ajouter une vague" + +[node name="ButtonContainer2" type="HBoxContainer" parent="VBoxContainer2"] +layout_mode = 2 + +[node name="AutoLaunchLevel" type="CheckButton" parent="VBoxContainer2/ButtonContainer2"] +layout_mode = 2 + +[node name="Label" type="Label" parent="VBoxContainer2/ButtonContainer2"] +layout_mode = 2 +text = "Lancer le niveau auto. " + +[node name="MarginContainer2" type="MarginContainer" parent="VBoxContainer2/ButtonContainer2"] +custom_minimum_size = Vector2(20, 0) +layout_mode = 2 + +[node name="RemoveWave" type="Button" parent="VBoxContainer2/ButtonContainer2"] +layout_mode = 2 +text = "Suprimer la vague" + +[node name="ButtonContainer4" type="HBoxContainer" parent="VBoxContainer2"] +layout_mode = 2 + +[node name="WaitForKill" type="CheckButton" parent="VBoxContainer2/ButtonContainer4"] +layout_mode = 2 + +[node name="Label" type="Label" parent="VBoxContainer2/ButtonContainer4"] +layout_mode = 2 +text = "Attendre la mort des enemies pour lancer la vague suivante" + +[node name="ButtonContainer3" type="HBoxContainer" parent="VBoxContainer2"] +layout_mode = 2 + +[node name="WaveTimer" type="LineEdit" parent="VBoxContainer2/ButtonContainer3"] +custom_minimum_size = Vector2(55, 55) +layout_mode = 2 +script = ExtResource("3_qw7ts") +inputType = 2 +step = 0.2 +metadata/_custom_type_script = "uid://bpv75ucqoy446" + +[node name="MarginContainer" type="MarginContainer" parent="VBoxContainer2/ButtonContainer3"] +custom_minimum_size = Vector2(10, 0) +layout_mode = 2 + +[node name="Label" type="Label" parent="VBoxContainer2/ButtonContainer3"] +layout_mode = 2 +text = "Timer avant lancement de la vague" + +[node name="MarginContainer2" type="MarginContainer" parent="VBoxContainer2"] +custom_minimum_size = Vector2(0, 30) +layout_mode = 2 + +[node name="ScrollContainer" type="ScrollContainer" parent="VBoxContainer2"] +layout_mode = 2 +size_flags_vertical = 3 + +[node name="WaveContainer" type="TabContainer" parent="VBoxContainer2/ScrollContainer"] +layout_mode = 2 +size_flags_vertical = 3 +clip_tabs = false +drag_to_rearrange_enabled = true + +[connection signal="onValueChanged" from="VBoxContainer2/HBoxContainer/LevelSelect" to="." method="selectLevel"] +[connection signal="pressed" from="VBoxContainer2/HBoxContainer/NewLevel" to="." method="_on_new_level_pressed"] +[connection signal="pressed" from="VBoxContainer2/HBoxContainer/Show" to="." method="cleanAndBuildMenu"] +[connection signal="pressed" from="VBoxContainer2/HBoxContainer/Clean" to="." method="cleanMenu"] +[connection signal="pressed" from="VBoxContainer2/HBoxContainer/Save" to="." method="_on_save_pressed"] +[connection signal="pressed" from="VBoxContainer2/ButtonContainer/Add wave" to="." method="addWave"] +[connection signal="toggled" from="VBoxContainer2/ButtonContainer2/AutoLaunchLevel" to="." method="_on_auto_launch_wave_toggled"] +[connection signal="pressed" from="VBoxContainer2/ButtonContainer2/RemoveWave" to="." method="removeWave"] +[connection signal="toggled" from="VBoxContainer2/ButtonContainer4/WaitForKill" to="." method="_on_wait_for_kill_toggled"] +[connection signal="valueHasChanged" from="VBoxContainer2/ButtonContainer3/WaveTimer" to="." method="changeWaveCooldown"] +[connection signal="active_tab_rearranged" from="VBoxContainer2/ScrollContainer/WaveContainer" to="." method="changeWaveOrder"] +[connection signal="tab_changed" from="VBoxContainer2/ScrollContainer/WaveContainer" to="." method="tabFocusHaschanged"] diff --git a/addons/signal_lens/editor/signal_lens_editor_panel.gd b/addons/signal_lens/editor/signal_lens_editor_panel.gd index 1e5908c..fbda55e 100644 --- a/addons/signal_lens/editor/signal_lens_editor_panel.gd +++ b/addons/signal_lens/editor/signal_lens_editor_panel.gd @@ -17,7 +17,7 @@ const DEFAULT_EMISSION_DURATION: float = 1.0 ## TODO: This could be a user setting const DEFAULT_CONNECTION_OPACITY: float = 0.3 -## This enum is used to set up the graph node's ports +## This enum is used to set up the graph node's ports ## in a way that provides more legibility in the code enum Direction {LEFT, RIGHT} @@ -42,7 +42,7 @@ var block_new_inspections: bool = false ## If true, all incoming signal emissions will be drawn and won't fade out var keep_emissions: bool = false -## Multiplier that increases or decreases emission drawing speed +## Multiplier that increases or decreases emission drawing speed ## Acquired from slider in scene var emission_speed_multiplier: float = 1.0 @@ -61,10 +61,10 @@ var settings: Dictionary = { } # Scene references -@export var graph_edit: GraphEdit +@export var graph_edit: GraphEdit @export var logger_button: Button -@export var node_path_line_edit: LineEdit -@export var refresh_button: Button +@export var node_path_line_edit: LineEdit +@export var refresh_button: Button @export var options_button: MenuButton @onready var options_popup: PopupMenu = options_button.get_popup() @export var clear_button: Button @@ -96,7 +96,7 @@ func _ready() -> void: graph_edit.get_menu_hbox().hide() #graph_edit.get_menu_hbox().hide() repo_button.icon = EditorInterface.get_base_control().get_theme_icon("ExternalLink", "EditorIcons") - + @onready var repo_button: Button = $EditorPanel/MainButtonsContainer/HBoxContainer2/RepoButton @onready var panel_container: PanelContainer = $EditorPanel/PanelContainer @@ -143,13 +143,13 @@ func stop_session(): func assign_node_path(target_node: NodePath): # If locked button is toggled, don't change the current node if block_new_inspections: return - + # If incoming node is invalid, disable refreshing to avoid null nodes refresh_button.disabled = target_node.is_empty() - + # Assign incoming node as the current one current_node = target_node - + # Update line edit node_path_line_edit.text = current_node node_path_line_edit.caret_column = node_path_line_edit.text.length() @@ -167,7 +167,7 @@ func clear_graph(): clean_connection_activity() # Frees child nodes for child: Node in graph_edit.get_children(): - # This seems to be necessary as per Godot 4.3 + # This seems to be necessary as per Godot 4.3 # because this child, despite being internal, # is iterated in get_children() and if it is # destroyed, the editor crashed @@ -187,20 +187,20 @@ func clear_graph(): func draw_node_data(data: Array): # If lock button toggled on, don't draw incoming data if block_new_inspections: return - + # Clear graph to avoid drawing over old data clear_graph() logger.clear() - + # This line is super important to avoid random rendering errors # It seems we need to give a small breathing room for the graph edit # to fully cleanup, otherwise, artifacts from a previously rendered # graph edit may appear and mess up the new drawing await get_tree().create_timer(0.1).timeout - + # Retrieve the targeted node from the data array, which is always index 0 var target_node_name = data[0] - + # Handle root node inspection edge case if target_node_name == "Root": warning_text.show() @@ -211,19 +211,19 @@ func draw_node_data(data: Array): # Retrieve the targeted node signal data, which is always index 1 var target_node_signal_data: Array = data[1] - + # Create main node from which connections will be created # and add it to the graph var target_node: SignalLensGraphNode = create_node(target_node_name, "(Signals)") graph_edit.add_child(target_node) - + var current_signal_index = 0 - + # Start iterating signal by signal for signal_data in target_node_signal_data: # Check signal connections and skip not connected signals (based on settings) if settings[Options.HIDE_SIGNALS_WITHOUT_CONNECTIONS] and signal_data["callables"].size() == 0: continue - + # Check signal connections and skip if signal is built-in (based on settings) if settings[Options.HIDE_BUILT_IN_SIGNALS]: var class_signals: Array = [] @@ -231,13 +231,13 @@ func draw_node_data(data: Array): class_signals.append(class_signal["name"]) if signal_data["signal"] in class_signals: continue - + # Get the color based on the index so we can have the rainbow vibes var slot_color = get_slot_color(current_signal_index, target_node_signal_data.size()) - + # Create the slot button with the signal's name create_button_slot(signal_data["signal"], target_node, Direction.RIGHT, slot_color) - + # Start iterating each callable in the signal var callables_for_current_signal = signal_data["callables"] for callable_index in range(callables_for_current_signal.size()): @@ -306,8 +306,8 @@ func create_button_slot(button_text: String, parent_node: GraphNode, slot_direct parent_node.set_slot(signal_button.get_index(), slot_direction == Direction.LEFT, 0, slot_color, slot_direction == Direction.RIGHT, 0, slot_color) func get_slot_color(slot_index, signal_amount) -> Color: - var hue = float(slot_index) / float(signal_amount) - return Color.from_hsv(hue, 1.0, 0.5, connection_opacity) + var hue = float(slot_index) / float(signal_amount) + return Color.from_hsv(hue, 1.0, 0.5, connection_opacity) func clean_connection_activity(): for connection in graph_edit.get_connection_list(): @@ -331,13 +331,13 @@ func draw_signal_emission(data: Array): func pulse_connection(connection: Dictionary) -> void: if connection not in pulsing_connections: pulsing_connections.append(connection) - + var from_node = connection["from_node"] var from_port = connection["from_port"] var to_node = connection["to_node"] var to_port = connection["to_port"] - - if keep_emissions: + + if keep_emissions: graph_edit.set_connection_activity(from_node, from_port, to_node, to_port, 1.0) else: fade_out_connection(connection) @@ -349,11 +349,11 @@ func fade_out_connection(connection: Dictionary): var from_port = connection["from_port"] var to_node = connection["to_node"] var to_port = connection["to_port"] - + tween.tween_method( func(value): graph_edit.set_connection_activity(from_node, from_port, to_node, to_port, value), 1.0, 0.0, fade_out_duration ).set_trans(Tween.TRANS_QUAD).set_ease(Tween.EASE_IN) - + tween.tween_callback(func(): pulsing_connections.erase(connection)) func get_port_index_from_signal_name(signal_name: String): @@ -407,7 +407,7 @@ func _resize_panel(new_size: float): func _can_resize_panel() -> bool: # If user wants to resize panel on open if not ProjectSettings.get_setting("addons/Signal Lens/resize_panel_on_open"): return false - + # If editor dock reference has been acquired if not _editor_dock: return false return true @@ -417,7 +417,7 @@ func _on_visibility_changed() -> void: # Only resize bottom panel if both visible and visible in editor if visible and is_visible_in_tree(): _resize_panel(-ProjectSettings.get_setting("addons/Signal Lens/height_to_resize_to")) - else: + else: _resize_panel(_original_panel_size) func _open_project_settings(): @@ -517,12 +517,12 @@ func _on_keep_emissions_checkbox_toggled(toggled_on: bool) -> void: func _on_logger_button_toggled(toggled_on: bool) -> void: logger.visible = toggled_on - + func _on_options_index_pressed(option_index: int) -> void: if options_popup.is_item_checkable(option_index): settings[option_index] = not options_popup.is_item_checked(option_index) # Change state options_popup.set_item_checked(option_index, settings[option_index]) # Apply state - + if option_index in [Options.HIDE_SIGNALS_WITHOUT_CONNECTIONS, Options.HIDE_BUILT_IN_SIGNALS]: refresh_button.pressed.emit() elif option_index == Options.SHOW_GRAPH_TOOLBAR: diff --git a/game_menu.gd b/game_menu.gd deleted file mode 100644 index 3f0fae8..0000000 --- a/game_menu.gd +++ /dev/null @@ -1,30 +0,0 @@ -extends Control - -var selected_tower - -func _ready() -> void: - EventBus.tower_selected.connect(_on_EventBus_tower_selected) - EventBus.open_shop.connect(open_shop) - EventBus.close_shop.connect(close_shop) - -func open_shop(): - if visible: - close_shop() - return - - visible = true - -func close_shop(): - visible = false - -func _on_EventBus_tower_selected(tower : PackedScene): - selected_tower = tower - -func _on_button_return_desktop_pressed() -> void: - get_tree().quit() - -func _on_button_back_to_start_screen_pressed() -> void: - Transition.goto("res://UI/start_menu.tscn") - -func _on_button_continue_pressed() -> void: - visible = false diff --git a/game_menu.gd.uid b/game_menu.gd.uid deleted file mode 100644 index 353ccbb..0000000 --- a/game_menu.gd.uid +++ /dev/null @@ -1 +0,0 @@ -uid://jg5ny0u7buos diff --git a/game_menu.tscn b/game_menu.tscn deleted file mode 100644 index 6f6d9c1..0000000 --- a/game_menu.tscn +++ /dev/null @@ -1,393 +0,0 @@ -[gd_scene load_steps=12 format=3 uid="uid://djyye2otjju2d"] - -[ext_resource type="Theme" uid="uid://bbp4qcbwkeg7x" path="res://default_theme.tres" id="1_xxfb2"] -[ext_resource type="PackedScene" uid="uid://bqpeu50pgsdfk" path="res://UI/tower_button.tscn" id="2_qus6b"] -[ext_resource type="Script" uid="uid://jg5ny0u7buos" path="res://game_menu.gd" id="2_wr0q8"] -[ext_resource type="Texture2D" uid="uid://cs24awnya7o5p" path="res://Assets/VFX/start_menu_vignette.png" id="3_3rcmp"] -[ext_resource type="Texture2D" uid="uid://uptdcefxlv4c" path="res://Assets/Icones/ppdf_bio_image_placeholder_2.png" id="3_wr0q8"] -[ext_resource type="Script" uid="uid://tn3qdhcyaxsg" path="res://UI/upgrade_button.gd" id="4_3rcmp"] -[ext_resource type="Texture2D" uid="uid://dksohsrys0yy7" path="res://Assets/Icones/baby-face.svg" id="5_pbvm6"] - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_pbvm6"] -bg_color = Color(0.933333, 0.933333, 0.933333, 1) - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_yd342"] -bg_color = Color(0.2, 0.2, 0.2, 0.588235) - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_tklej"] -bg_color = Color(0.2, 0.2, 0.2, 0.588235) - -[sub_resource type="StyleBoxFlat" id="StyleBoxFlat_scae6"] -bg_color = Color(0.2, 0.2, 0.2, 0.588235) - -[node name="GameMenu" type="Control"] -layout_mode = 3 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -theme = ExtResource("1_xxfb2") -script = ExtResource("2_wr0q8") - -[node name="Background" type="Panel" parent="."] -layout_mode = 1 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -theme_override_styles/panel = SubResource("StyleBoxFlat_pbvm6") - -[node name="TextureRect" type="TextureRect" parent="Background"] -modulate = Color(1, 1, 1, 0.305882) -layout_mode = 1 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -texture = ExtResource("3_3rcmp") - -[node name="MenuHeader" type="HBoxContainer" parent="."] -layout_mode = 1 -offset_left = 304.0 -offset_right = 1918.0 -offset_bottom = 82.0 -alignment = 1 - -[node name="ButtonContinue" type="Button" parent="MenuHeader"] -layout_mode = 2 -size_flags_horizontal = 3 -text = "Continue" - -[node name="ButtonSettings" type="Button" parent="MenuHeader"] -layout_mode = 2 -size_flags_horizontal = 3 -text = "Settings" - -[node name="ButtonBackToStartScreen" type="Button" parent="MenuHeader"] -layout_mode = 2 -size_flags_horizontal = 3 -text = "Quitter partie" - -[node name="ButtonReturnDesktop" type="Button" parent="MenuHeader"] -layout_mode = 2 -size_flags_horizontal = 3 -text = "Retour bureau" - -[node name="ButtonMoney" type="Button" parent="MenuHeader"] -layout_mode = 2 -size_flags_horizontal = 3 -text = "Money" - -[node name="Towers" type="VBoxContainer" parent="."] -layout_mode = 1 -offset_right = 300.0 -offset_bottom = 722.0 - -[node name="ButtonCube" type="Button" parent="Towers"] -layout_mode = 2 -text = "Cube" - -[node name="TowerButtonPierre" parent="Towers" instance=ExtResource("2_qus6b")] -layout_mode = 2 - -[node name="TowerButtonAline" parent="Towers" instance=ExtResource("2_qus6b")] -visible = false -layout_mode = 2 - -[node name="TowerButtonMaxence" parent="Towers" instance=ExtResource("2_qus6b")] -visible = false -layout_mode = 2 - -[node name="TowerButtonAlex" parent="Towers" instance=ExtResource("2_qus6b")] -visible = false -layout_mode = 2 - -[node name="TowerButtonGeraldine" parent="Towers" instance=ExtResource("2_qus6b")] -visible = false -layout_mode = 2 - -[node name="CharacterSheet" type="Control" parent="."] -layout_mode = 1 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 - -[node name="TowerStats" type="Panel" parent="CharacterSheet"] -custom_minimum_size = Vector2(800, 512) -layout_mode = 0 -offset_left = 313.0 -offset_top = 86.0 -offset_right = 1113.0 -offset_bottom = 598.0 -theme_override_styles/panel = SubResource("StyleBoxFlat_yd342") - -[node name="MarginContainer2" type="MarginContainer" parent="CharacterSheet/TowerStats"] -layout_mode = 1 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -theme_override_constants/margin_left = 20 -theme_override_constants/margin_top = 20 -theme_override_constants/margin_right = 20 -theme_override_constants/margin_bottom = 20 - -[node name="HBoxContainer" type="HBoxContainer" parent="CharacterSheet/TowerStats/MarginContainer2"] -layout_mode = 2 - -[node name="VBoxContainer" type="VBoxContainer" parent="CharacterSheet/TowerStats/MarginContainer2/HBoxContainer"] -layout_mode = 2 -size_flags_horizontal = 3 - -[node name="LabelCharacterSheet" type="Label" parent="CharacterSheet/TowerStats/MarginContainer2/HBoxContainer/VBoxContainer"] -layout_mode = 2 -text = "Fiche Perso : -FRIANDISE" -horizontal_alignment = 1 - -[node name="MarginContainer" type="MarginContainer" parent="CharacterSheet/TowerStats/MarginContainer2/HBoxContainer/VBoxContainer"] -custom_minimum_size = Vector2(0, 40) -layout_mode = 2 - -[node name="StatDamage" type="HBoxContainer" parent="CharacterSheet/TowerStats/MarginContainer2/HBoxContainer/VBoxContainer"] -layout_mode = 2 - -[node name="NameStat" type="Label" parent="CharacterSheet/TowerStats/MarginContainer2/HBoxContainer/VBoxContainer/StatDamage"] -layout_mode = 2 -text = "Damage :" - -[node name="Stat" type="Label" parent="CharacterSheet/TowerStats/MarginContainer2/HBoxContainer/VBoxContainer/StatDamage"] -layout_mode = 2 -size_flags_horizontal = 3 -text = "0" -horizontal_alignment = 2 - -[node name="StatCooldown" type="HBoxContainer" parent="CharacterSheet/TowerStats/MarginContainer2/HBoxContainer/VBoxContainer"] -layout_mode = 2 - -[node name="NameStat" type="Label" parent="CharacterSheet/TowerStats/MarginContainer2/HBoxContainer/VBoxContainer/StatCooldown"] -layout_mode = 2 -text = "Cooldown :" - -[node name="Stat" type="Label" parent="CharacterSheet/TowerStats/MarginContainer2/HBoxContainer/VBoxContainer/StatCooldown"] -layout_mode = 2 -size_flags_horizontal = 3 -text = "0" -horizontal_alignment = 2 - -[node name="StatMaxEnergy" type="HBoxContainer" parent="CharacterSheet/TowerStats/MarginContainer2/HBoxContainer/VBoxContainer"] -layout_mode = 2 - -[node name="NameStat" type="Label" parent="CharacterSheet/TowerStats/MarginContainer2/HBoxContainer/VBoxContainer/StatMaxEnergy"] -layout_mode = 2 -text = "Max Energy :" - -[node name="Stat" type="Label" parent="CharacterSheet/TowerStats/MarginContainer2/HBoxContainer/VBoxContainer/StatMaxEnergy"] -layout_mode = 2 -size_flags_horizontal = 3 -text = "0" -horizontal_alignment = 2 - -[node name="StatRegen" type="HBoxContainer" parent="CharacterSheet/TowerStats/MarginContainer2/HBoxContainer/VBoxContainer"] -layout_mode = 2 - -[node name="NameStat" type="Label" parent="CharacterSheet/TowerStats/MarginContainer2/HBoxContainer/VBoxContainer/StatRegen"] -layout_mode = 2 -text = "Energy Regen :" - -[node name="Stat" type="Label" parent="CharacterSheet/TowerStats/MarginContainer2/HBoxContainer/VBoxContainer/StatRegen"] -layout_mode = 2 -size_flags_horizontal = 3 -text = "0" -horizontal_alignment = 2 - -[node name="MarginContainer" type="MarginContainer" parent="CharacterSheet/TowerStats/MarginContainer2/HBoxContainer"] -custom_minimum_size = Vector2(20, 0) -layout_mode = 2 - -[node name="Bio" type="VBoxContainer" parent="CharacterSheet/TowerStats/MarginContainer2/HBoxContainer"] -layout_mode = 2 - -[node name="BioImage" type="TextureRect" parent="CharacterSheet/TowerStats/MarginContainer2/HBoxContainer/Bio"] -custom_minimum_size = Vector2(300, 300) -layout_mode = 2 -texture = ExtResource("3_wr0q8") -expand_mode = 1 - -[node name="Label" type="Label" parent="CharacterSheet/TowerStats/MarginContainer2/HBoxContainer/Bio"] -custom_minimum_size = Vector2(300, 0) -layout_mode = 2 -size_flags_vertical = 3 -theme_override_font_sizes/font_size = 30 -text = "Aime se promener dans l'herbe et manger des framboises. Sa petite bouille la rend trop mignonne." -horizontal_alignment = 1 -autowrap_mode = 2 - -[node name="TowerUpgrades" type="Panel" parent="CharacterSheet"] -layout_mode = 1 -anchors_preset = 3 -anchor_left = 1.0 -anchor_top = 1.0 -anchor_right = 1.0 -anchor_bottom = 1.0 -offset_left = -786.0 -offset_top = -990.0 -offset_right = -19.0 -offset_bottom = -28.0 -grow_horizontal = 0 -grow_vertical = 0 -theme_override_styles/panel = SubResource("StyleBoxFlat_tklej") - -[node name="MarginContainer2" type="MarginContainer" parent="CharacterSheet/TowerUpgrades"] -layout_mode = 1 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -theme_override_constants/margin_left = 20 -theme_override_constants/margin_top = 20 -theme_override_constants/margin_right = 20 -theme_override_constants/margin_bottom = 20 - -[node name="VBoxContainer" type="VBoxContainer" parent="CharacterSheet/TowerUpgrades/MarginContainer2"] -layout_mode = 2 -theme_override_constants/separation = 10 - -[node name="Title" type="Label" parent="CharacterSheet/TowerUpgrades/MarginContainer2/VBoxContainer"] -layout_mode = 2 -text = "Boutique" -horizontal_alignment = 1 - -[node name="MarginContainer" type="MarginContainer" parent="CharacterSheet/TowerUpgrades/MarginContainer2/VBoxContainer"] -custom_minimum_size = Vector2(0, 40) -layout_mode = 2 - -[node name="UpgradeButton" type="Button" parent="CharacterSheet/TowerUpgrades/MarginContainer2/VBoxContainer"] -layout_mode = 2 -text = "Upgrade 1" -script = ExtResource("4_3rcmp") -metadata/_custom_type_script = "uid://tn3qdhcyaxsg" - -[node name="UpgradeButton2" type="Button" parent="CharacterSheet/TowerUpgrades/MarginContainer2/VBoxContainer"] -layout_mode = 2 -text = "Upgrade 2" -script = ExtResource("4_3rcmp") -metadata/_custom_type_script = "uid://tn3qdhcyaxsg" - -[node name="UpgradeButton3" type="Button" parent="CharacterSheet/TowerUpgrades/MarginContainer2/VBoxContainer"] -layout_mode = 2 -text = "Upgrade 3" -script = ExtResource("4_3rcmp") -metadata/_custom_type_script = "uid://tn3qdhcyaxsg" - -[node name="UpgradeButton4" type="Button" parent="CharacterSheet/TowerUpgrades/MarginContainer2/VBoxContainer"] -layout_mode = 2 -text = "Upgrade 4" -script = ExtResource("4_3rcmp") -metadata/_custom_type_script = "uid://tn3qdhcyaxsg" - -[node name="UpgradeButton5" type="Button" parent="CharacterSheet/TowerUpgrades/MarginContainer2/VBoxContainer"] -layout_mode = 2 -text = "Upgrade 5" -script = ExtResource("4_3rcmp") -metadata/_custom_type_script = "uid://tn3qdhcyaxsg" - -[node name="TowerSkills" type="Panel" parent="CharacterSheet"] -layout_mode = 1 -anchors_preset = 7 -anchor_left = 0.5 -anchor_top = 1.0 -anchor_right = 0.5 -anchor_bottom = 1.0 -offset_left = -646.0 -offset_top = -471.0 -offset_right = 153.0 -offset_bottom = -28.0 -grow_horizontal = 2 -grow_vertical = 0 -theme_override_styles/panel = SubResource("StyleBoxFlat_scae6") - -[node name="MarginContainer" type="MarginContainer" parent="CharacterSheet/TowerSkills"] -layout_mode = 1 -anchors_preset = 15 -anchor_right = 1.0 -anchor_bottom = 1.0 -grow_horizontal = 2 -grow_vertical = 2 -theme_override_constants/margin_left = 20 -theme_override_constants/margin_top = 20 -theme_override_constants/margin_right = 20 -theme_override_constants/margin_bottom = 20 - -[node name="VBoxContainer" type="VBoxContainer" parent="CharacterSheet/TowerSkills/MarginContainer"] -layout_mode = 2 - -[node name="Title" type="Label" parent="CharacterSheet/TowerSkills/MarginContainer/VBoxContainer"] -layout_mode = 2 -text = "Capacités" -horizontal_alignment = 1 - -[node name="MarginContainer" type="MarginContainer" parent="CharacterSheet/TowerSkills/MarginContainer/VBoxContainer"] -layout_mode = 2 - -[node name="SkillUI" type="HBoxContainer" parent="CharacterSheet/TowerSkills/MarginContainer/VBoxContainer"] -layout_mode = 2 - -[node name="Icone" type="TextureRect" parent="CharacterSheet/TowerSkills/MarginContainer/VBoxContainer/SkillUI"] -custom_minimum_size = Vector2(64, 64) -layout_mode = 2 -texture = ExtResource("5_pbvm6") -expand_mode = 1 - -[node name="MarginContainer" type="MarginContainer" parent="CharacterSheet/TowerSkills/MarginContainer/VBoxContainer/SkillUI"] -custom_minimum_size = Vector2(20, 0) -layout_mode = 2 - -[node name="Label" type="Label" parent="CharacterSheet/TowerSkills/MarginContainer/VBoxContainer/SkillUI"] -layout_mode = 2 -text = "Bonjour" - -[node name="SkillUI2" type="HBoxContainer" parent="CharacterSheet/TowerSkills/MarginContainer/VBoxContainer"] -layout_mode = 2 - -[node name="Icone" type="TextureRect" parent="CharacterSheet/TowerSkills/MarginContainer/VBoxContainer/SkillUI2"] -custom_minimum_size = Vector2(64, 64) -layout_mode = 2 -texture = ExtResource("5_pbvm6") -expand_mode = 1 - -[node name="MarginContainer" type="MarginContainer" parent="CharacterSheet/TowerSkills/MarginContainer/VBoxContainer/SkillUI2"] -custom_minimum_size = Vector2(20, 0) -layout_mode = 2 - -[node name="Label" type="Label" parent="CharacterSheet/TowerSkills/MarginContainer/VBoxContainer/SkillUI2"] -layout_mode = 2 -text = "Compliments" - -[node name="SkillUI3" type="HBoxContainer" parent="CharacterSheet/TowerSkills/MarginContainer/VBoxContainer"] -layout_mode = 2 - -[node name="Icone" type="TextureRect" parent="CharacterSheet/TowerSkills/MarginContainer/VBoxContainer/SkillUI3"] -custom_minimum_size = Vector2(64, 64) -layout_mode = 2 -texture = ExtResource("5_pbvm6") -expand_mode = 1 - -[node name="MarginContainer" type="MarginContainer" parent="CharacterSheet/TowerSkills/MarginContainer/VBoxContainer/SkillUI3"] -custom_minimum_size = Vector2(20, 0) -layout_mode = 2 - -[node name="Label" type="Label" parent="CharacterSheet/TowerSkills/MarginContainer/VBoxContainer/SkillUI3"] -layout_mode = 2 -text = "Cinéphile" - -[connection signal="pressed" from="MenuHeader/ButtonContinue" to="." method="_on_button_continue_pressed"] -[connection signal="pressed" from="MenuHeader/ButtonBackToStartScreen" to="." method="_on_button_back_to_start_screen_pressed"] -[connection signal="pressed" from="MenuHeader/ButtonReturnDesktop" to="." method="_on_button_return_desktop_pressed"] diff --git a/project.godot b/project.godot index f459e04..921a506 100644 --- a/project.godot +++ b/project.godot @@ -29,7 +29,7 @@ window/size/viewport_height=1080 [editor_plugins] -enabled=PackedStringArray("res://addons/signal_lens/plugin.cfg") +enabled=PackedStringArray("res://addons/LevelEditor/plugin.cfg", "res://addons/signal_lens/plugin.cfg") [file_customization]