diff --git a/src/Actor/Actor.gd b/src/Actor/Actor.gd index abf36847..1bb423f5 100644 --- a/src/Actor/Actor.gd +++ b/src/Actor/Actor.gd @@ -5,13 +5,13 @@ class_name Actor const DAMAGE_NUMBER = preload("res://src/Effect/EnemyDamageNumber.tscn") const FLOOR_NORMAL: = Vector2.UP -var gravity := 300.0 var acceleration = 50 var ground_cof = 0.2 var air_cof = 0.05 var dead = false var is_in_water = false: set = set_is_in_water +var do_bubbles = true var home := Vector2(0, 0) var rng = RandomNumberGenerator.new() @@ -20,6 +20,8 @@ var rng = RandomNumberGenerator.new() @export var speed: = Vector2(150, 350) @export var editor_hidden = true +@onready var gravity := water_gravity if is_in_water else base_gravity + @onready var world = get_tree().get_root().get_node("World") func set_is_in_water(val): diff --git a/src/Actor/Enemy/Billy.tscn b/src/Actor/Enemy/Billy.tscn index 36094d96..33487f0b 100644 --- a/src/Actor/Enemy/Billy.tscn +++ b/src/Actor/Enemy/Billy.tscn @@ -139,7 +139,6 @@ collision_layer = 2 collision_mask = 520 floor_max_angle = 1.0471976 script = ExtResource("1") -debug = true editor_hidden = false [node name="CollisionShape2D" type="CollisionShape2D" parent="." unique_id=1482682800] diff --git a/src/Actor/Enemy/Enemy.gd b/src/Actor/Enemy/Enemy.gd index 516f413a..d588e571 100644 --- a/src/Actor/Enemy/Enemy.gd +++ b/src/Actor/Enemy/Enemy.gd @@ -177,7 +177,9 @@ func set_damagenum(damage): func die(quietly = false): if dead: return dead = true - f.pc().enemies_touching.erase(self) + + if (f.pc()): + f.pc().enemies_touching.erase(self) if !quietly: am.play(die_sound, self) do_death_routine() diff --git a/src/Actor/Enemy/Fish.gd b/src/Actor/Enemy/Fish.gd new file mode 100644 index 00000000..bc9f5fb4 --- /dev/null +++ b/src/Actor/Enemy/Fish.gd @@ -0,0 +1,239 @@ +extends Enemy + +const PATH_LINE = preload("res://src/Utility/PathLine.tscn") + +var move_dir = Vector2.LEFT +@export var swim_dir_x = -1: set = on_swim_dir_x_changed +@export var jump_height: int = 6: set = on_jump_height_changed +var normal_damage = 1 +var attack_damage = 4 + +@onready var start_pos = global_position +var jump_pos: Vector2 = global_position + +@export var can_move_x = true +@export var x_min = -3: set = on_x_min_changed +@export var x_max = 3: set = on_x_max_changed + +@onready var ap: AnimationPlayer = get_node("AnimationPlayer") +@onready var rc: RayCast2D = get_node("RayCast2D") + +@onready var BONK: PackedScene = preload("res://src/Effect/BonkParticle.tscn") +var did_bonk: bool = false + +func setup(): + change_state("idle") + do_bubbles = false + if debug: print("ready fish") + speed = Vector2(20, 150) + hp = 3 + damage_on_contact = normal_damage + update_path_lines() + +func on_swim_dir_x_changed(new): + swim_dir_x = new + if (get_node_or_null("Sprite2D")): + $Sprite2D.scale.x = new + move_dir.x = new + +func on_jump_height_changed(new): + if (get_node_or_null("RayCast2D")): + $RayCast2D.target_position.y = -new * 16 + jump_height = new + update_path_lines() + +func on_x_min_changed(new): + x_min = new + update_path_lines() + +func on_x_max_changed(new): + x_max = new + update_path_lines() + +func bonk(): + if (did_bonk or get_slide_collision_count() == 0): + return + + var slide_collision: KinematicCollision2D = get_last_slide_collision() + var bonk_effect = BONK.instantiate() + #print("Fish bonked ", slide_collision.get_normal()) + bonk_effect.normal = slide_collision.get_normal() + bonk_effect.global_position.x = global_position.x + bonk_effect.global_position.y = global_position.y + 7.0 + w.get_node("Front").add_child(bonk_effect) + did_bonk = true + +func calc_velocity(dir, _do_gravity = true, _do_acceleration = true, _do_friction = true) -> Vector2: + match state: + "idle", "swim": + var out = velocity + + out.x = speed.x * dir.x + + return out + "attack": + var out = velocity + + out.y += gravity * get_physics_process_delta_time() + if dir.y < 0: + out.y = speed.y * dir.y + elif is_on_ceiling() and !did_bonk: + out.y = 0 + + return out + "fall": + var out = velocity + if (is_on_ceiling() and !did_bonk): + out.y = 0 + else: + out.y += gravity * get_physics_process_delta_time() + + return out + return Vector2.ZERO + + +#region STATES +#region Idle +func enter_idle(_prev_state: String): + motion_mode = CharacterBody2D.MOTION_MODE_FLOATING + if can_move_x: + change_state("swim") + else: + get_parent().get_parent().get_node("AnimationPlayer").play("Idle") + + +func do_idle(): + velocity = calc_velocity(move_dir) + move_and_slide() + + var collision = get_node("RayCast2D").get_collider() + if collision != null: + if (collision is not TileMapLayer and collision.get_collision_layer_value(1)): + if (abs(collision.global_position.x - rc.global_position.x) <= 1): + if (debug): print("fish got target") + change_state("attack") + return +#endregion + +#region Swim +func enter_swim(_prev_state: String, _arg: Dictionary = {}): + motion_mode = CharacterBody2D.MOTION_MODE_FLOATING + move_dir.x = swim_dir_x + ap.play("Idle") + +func exit_swim(_next_state: String, _arg: Dictionary = {}): + move_dir = Vector2.ZERO + velocity = Vector2.ZERO + +func do_swim(): + var collision = rc.get_collider() + if collision != null: + if (collision is not TileMapLayer and collision.get_collision_layer_value(1)): + if (abs(collision.global_position.x - rc.global_position.x) <= 1): #Prevent the fish target just the side of player hitbox + if debug: print("fish got target") + change_state("attack") + return + + if is_on_wall() and (move_and_collide(Vector2.RIGHT, true) or move_and_collide(Vector2.LEFT, true)): + swim_dir_x = -swim_dir_x + else: + if global_position.x < start_pos.x + x_min * 16: + swim_dir_x = 1 + if global_position.x > start_pos.x + x_max * 16: + swim_dir_x = -1 + + velocity = calc_velocity(move_dir) + move_and_slide() +#endregion + +#region Attack +func enter_attack(_prev_state: String): + damage_on_contact = attack_damage + motion_mode = CharacterBody2D.MOTION_MODE_GROUNDED + jump_pos = global_position + ap.play("Target") + did_bonk = false + + await ap.animation_finished + move_dir = Vector2.UP + +func do_attack(): + if position.y <= jump_pos.y - jump_height * 16 + speed.y * 0.3 or is_on_ceiling(): + if (is_on_ceiling()): + bonk() + change_state("fall") + return + + velocity = calc_velocity(move_dir) + move_and_slide() +#endregion + +func exit_attack(_prev_state): + damage_on_contact = normal_damage + +#region Fall +func exit_fall(_next_state: String): + velocity = Vector2.ZERO + +func do_fall(): + if (velocity.y > 0): + if (ap.current_animation != "Fall"): + ap.play("Fall") + else: + if (ap.current_animation != "Rise"): + ap.play("Rise") + + if (is_on_ceiling()): + bonk() + + if !(global_position.y >= jump_pos.y - 5 or is_on_floor()): + velocity = calc_velocity(move_dir) + move_and_slide() + else: + #var tween = get_tree().create_tween() + #tween.tween_property(main, "position", Vector2(main.position.x, main.start_pos.y), 0.8).set_trans(Tween.TRANS_BACK).set_ease(Tween.EASE_OUT) + #await tween.finished + var collision: KinematicCollision2D = move_and_collide(jump_pos - global_position) + if (collision): + global_position += collision.get_travel() + else: + global_position.y = jump_pos.y + if (can_move_x): + change_state("swim") + else: + change_state("idle") + return + +#endregion +#endregion + +func update_path_lines(): + #if Engine.editor_hint or debug: + if !(debug or Engine.is_editor_hint()): + return + for c in get_children(): + if c.name == "VPath" or c.name == "HPath": c.free() + + var vline = PATH_LINE.instantiate() + vline.name = "VPath" + vline.default_color = Color.LIGHT_GREEN + if Engine.is_editor_hint(): + vline.add_point(Vector2.ZERO) + vline.add_point(Vector2(0, jump_height * -16)) + elif debug and world: + vline.add_point(global_position) + vline.add_point(global_position + Vector2(0, jump_height * -16)) + add_child(vline) + move_child(vline, 0) + + var hline = PATH_LINE.instantiate() + hline.name = "HPath" + hline.default_color = Color.RED + if Engine.is_editor_hint(): + hline.add_point(Vector2(x_min * 16, -4)) + hline.add_point(Vector2(x_max * 16, -4)) + elif debug and world: + hline.add_point(global_position + Vector2(x_min * 16, -4)) + hline.add_point(global_position + Vector2(x_max * 16, -4)) + add_child(hline) + move_child(hline, 0) diff --git a/src/Actor/Enemy/Fish.gd.uid b/src/Actor/Enemy/Fish.gd.uid new file mode 100644 index 00000000..a42440a9 --- /dev/null +++ b/src/Actor/Enemy/Fish.gd.uid @@ -0,0 +1 @@ +uid://bugags3jgh55c diff --git a/src/Actor/Enemy/Fish.tscn b/src/Actor/Enemy/Fish.tscn new file mode 100644 index 00000000..194910f7 --- /dev/null +++ b/src/Actor/Enemy/Fish.tscn @@ -0,0 +1,514 @@ +[gd_scene format=3 uid="uid://bcw46w7o0xwu3"] + +[ext_resource type="Texture2D" uid="uid://bbu1jyosea4de" path="res://assets/Actor/Enemy/Fish.png" id="1"] +[ext_resource type="Script" uid="uid://bugags3jgh55c" path="res://src/Actor/Enemy/Fish.gd" id="2"] + +[sub_resource type="RectangleShape2D" id="5"] +size = Vector2(10, 5) + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_yyuli"] +size = Vector2(12, 10) + +[sub_resource type="RectangleShape2D" id="RectangleShape2D_vcisb"] +size = Vector2(10, 5) + +[sub_resource type="Animation" id="1"] +resource_name = "Fall" +length = 0.1 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Sprite2D:frame") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [12] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("CollisionShape2D:position") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [Vector2(-0.5, -8)] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Hurtbox/CollisionShape2D:position") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [Vector2(-0.5, -8)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Hitbox/CollisionShape2D:position") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [Vector2(-0.5, -8)] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("CollisionShape2D:rotation") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [1.5707963267948966] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Hurtbox/CollisionShape2D:rotation") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [1.5707963267948966] +} +tracks/6/type = "value" +tracks/6/imported = false +tracks/6/enabled = true +tracks/6/path = NodePath("Hitbox/CollisionShape2D:rotation") +tracks/6/interp = 1 +tracks/6/loop_wrap = true +tracks/6/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [1.5707963267948966] +} + +[sub_resource type="Animation" id="2"] +resource_name = "Idle" +length = 0.4 +loop_mode = 1 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Sprite2D:frame") +tracks/0/interp = 1 +tracks/0/loop_wrap = false +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.3), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [0, 3] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("CollisionShape2D:position") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [Vector2(0, -7.5)] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Hurtbox/CollisionShape2D:position") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [Vector2(0, -7.5)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Hitbox/CollisionShape2D:position") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [Vector2(0, -7.5)] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("CollisionShape2D:rotation") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [0.0] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Hurtbox/CollisionShape2D:rotation") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [0.0] +} +tracks/6/type = "value" +tracks/6/imported = false +tracks/6/enabled = true +tracks/6/path = NodePath("Hitbox/CollisionShape2D:rotation") +tracks/6/interp = 1 +tracks/6/loop_wrap = true +tracks/6/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [0.0] +} + +[sub_resource type="Animation" id="Animation_vcisb"] +length = 0.001 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("CollisionShape2D:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [Vector2(0, -7.5)] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("Hurtbox/CollisionShape2D:position") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [Vector2(0, -7.5)] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Hitbox/CollisionShape2D:position") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [Vector2(0, -7.5)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("CollisionShape2D:rotation") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [0.0] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("Hurtbox/CollisionShape2D:rotation") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [0.0] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Hitbox/CollisionShape2D:rotation") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [0.0] +} +tracks/6/type = "value" +tracks/6/imported = false +tracks/6/enabled = true +tracks/6/path = NodePath("Sprite2D:frame") +tracks/6/interp = 1 +tracks/6/loop_wrap = false +tracks/6/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 0, +"values": [0] +} + +[sub_resource type="Animation" id="3"] +resource_name = "Rise" +length = 0.1 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Sprite2D:frame") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [8] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("CollisionShape2D:position") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [Vector2(-0.5, -8)] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Hurtbox/CollisionShape2D:position") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [Vector2(-0.5, -8)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Hitbox/CollisionShape2D:position") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [Vector2(-0.5, -8)] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("CollisionShape2D:rotation") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [1.5707963267948966] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Hurtbox/CollisionShape2D:rotation") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [1.5707963267948966] +} +tracks/6/type = "value" +tracks/6/imported = false +tracks/6/enabled = true +tracks/6/path = NodePath("Hitbox/CollisionShape2D:rotation") +tracks/6/interp = 1 +tracks/6/loop_wrap = true +tracks/6/keys = { +"times": PackedFloat32Array(0), +"transitions": PackedFloat32Array(1), +"update": 1, +"values": [1.5707963267948966] +} + +[sub_resource type="Animation" id="4"] +resource_name = "Target" +length = 0.2 +step = 0.025 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Sprite2D:frame") +tracks/0/interp = 1 +tracks/0/loop_wrap = false +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.05, 0.1, 0.15), +"transitions": PackedFloat32Array(1, 1, 1, 1), +"update": 1, +"values": [4, 5, 6, 7] +} +tracks/1/type = "value" +tracks/1/imported = false +tracks/1/enabled = true +tracks/1/path = NodePath("CollisionShape2D:position") +tracks/1/interp = 1 +tracks/1/loop_wrap = true +tracks/1/keys = { +"times": PackedFloat32Array(0, 0.05, 0.1), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [Vector2(0, -7.5), Vector2(0, -8), Vector2(-0.5, -7.5)] +} +tracks/2/type = "value" +tracks/2/imported = false +tracks/2/enabled = true +tracks/2/path = NodePath("Hurtbox/CollisionShape2D:position") +tracks/2/interp = 1 +tracks/2/loop_wrap = true +tracks/2/keys = { +"times": PackedFloat32Array(0, 0.05, 0.10000001), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [Vector2(0, -7.5), Vector2(0, -8), Vector2(-0.5, -7.5)] +} +tracks/3/type = "value" +tracks/3/imported = false +tracks/3/enabled = true +tracks/3/path = NodePath("Hitbox/CollisionShape2D:position") +tracks/3/interp = 1 +tracks/3/loop_wrap = true +tracks/3/keys = { +"times": PackedFloat32Array(0, 0.05, 0.10000001), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [Vector2(0, -7.5), Vector2(0, -8), Vector2(-0.5, -7.5)] +} +tracks/4/type = "value" +tracks/4/imported = false +tracks/4/enabled = true +tracks/4/path = NodePath("CollisionShape2D:rotation") +tracks/4/interp = 1 +tracks/4/loop_wrap = true +tracks/4/keys = { +"times": PackedFloat32Array(0, 0.05, 0.1), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [0.0, 0.7853981633974483, 1.5707963267948966] +} +tracks/5/type = "value" +tracks/5/imported = false +tracks/5/enabled = true +tracks/5/path = NodePath("Hurtbox/CollisionShape2D:rotation") +tracks/5/interp = 1 +tracks/5/loop_wrap = true +tracks/5/keys = { +"times": PackedFloat32Array(0, 0.05, 0.1), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [0.0, 0.7853982, 1.5707963267948966] +} +tracks/6/type = "value" +tracks/6/imported = false +tracks/6/enabled = true +tracks/6/path = NodePath("Hitbox/CollisionShape2D:rotation") +tracks/6/interp = 1 +tracks/6/loop_wrap = true +tracks/6/keys = { +"times": PackedFloat32Array(0, 0.05, 0.1), +"transitions": PackedFloat32Array(1, 1, 1), +"update": 1, +"values": [0.0, 0.7853982, 1.5707963267948966] +} + +[sub_resource type="AnimationLibrary" id="AnimationLibrary_3s1p6"] +_data = { +&"Fall": SubResource("1"), +&"Idle": SubResource("2"), +&"RESET": SubResource("Animation_vcisb"), +&"Rise": SubResource("3"), +&"Target": SubResource("4") +} + +[node name="Fish" type="CharacterBody2D" unique_id=1312856769 groups=["Actors", "Enemies", "Entities"]] +collision_layer = 2 +collision_mask = 8 +motion_mode = 1 +slide_on_ceiling = false +wall_min_slide_angle = 3.1415927 +floor_snap_length = 0.0 +script = ExtResource("2") +speed = Vector2(20, 150) +editor_hidden = false + +[node name="CollisionShape2D" type="CollisionShape2D" parent="." unique_id=1208749473] +position = Vector2(0, -7.5) +shape = SubResource("5") + +[node name="Hurtbox" type="Area2D" parent="." unique_id=434285087] +collision_layer = 131072 +collision_mask = 0 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Hurtbox" unique_id=569733112] +position = Vector2(0, -7.5) +shape = SubResource("RectangleShape2D_yyuli") +debug_color = Color(0, 1, 0, 0.235294) + +[node name="Hitbox" type="Area2D" parent="." unique_id=430236071] +collision_layer = 262144 +collision_mask = 65536 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Hitbox" unique_id=2082591926] +position = Vector2(0, -7.5) +shape = SubResource("RectangleShape2D_vcisb") +debug_color = Color(1, 0, 0, 0.235294) + +[node name="Sprite2D" type="Sprite2D" parent="." unique_id=971659152] +position = Vector2(0, -8) +scale = Vector2(-1, 1) +texture = ExtResource("1") +hframes = 4 +vframes = 4 + +[node name="AnimationPlayer" type="AnimationPlayer" parent="." unique_id=335076207] +libraries/ = SubResource("AnimationLibrary_3s1p6") + +[node name="RayCast2D" type="RayCast2D" parent="." unique_id=583405653] +target_position = Vector2(0, -96) +collision_mask = 9 +collide_with_areas = true + +[connection signal="area_entered" from="Hitbox" to="." method="_on_hitbox_area_entered"] +[connection signal="area_exited" from="Hitbox" to="." method="_on_hitbox_area_exited"] diff --git a/src/Actor/Enemy/Outdated/Fish/Fish.gd b/src/Actor/Enemy/Outdated/Fish/Fish.gd deleted file mode 100644 index dfa88cf0..00000000 --- a/src/Actor/Enemy/Outdated/Fish/Fish.gd +++ /dev/null @@ -1,80 +0,0 @@ -@tool -extends Enemy - - -const PATH_LINE = preload("res://src/Utility/PathLine.tscn") - - -var move_dir = Vector2.LEFT -@export var swim_dir_x = -1: set = on_swim_dir_x_changed -@export var jump_height: int = 6: set = on_jump_height_changed -@onready var start_pos = position -var jump_pos - -@export var can_move_x = true -@export var x_min = -3: set = on_x_min_changed -@export var x_max = 3: set = on_x_max_changed - - -func _ready(): - if debug: print("ready fish") - speed = Vector2(20,150) - damage_on_contact = 1 - update_path_lines() - - -func _physics_process(_delta): - if not Engine.is_editor_hint(): - gravity = 300.0 if not is_in_water else 150.0 - - -func on_swim_dir_x_changed(new): - swim_dir_x = new - $Sprite2D.scale.x = new - move_dir.x = new - -func on_jump_height_changed(new): - jump_height = new - jump_pos = Vector2(position.x, position.y + new * -16) - update_path_lines() - -func on_x_min_changed(new): - x_min = new - update_path_lines() - -func on_x_max_changed(new): - x_max = new - update_path_lines() - -func update_path_lines(): - #if Engine.editor_hint or debug: - for c in get_children(): - if c.name == "VPath" or c.name == "HPath": c.free() - - var vline = PATH_LINE.instantiate() - vline.name = "VPath" - vline.default_color = Color.LIGHT_GREEN - if Engine.is_editor_hint(): - vline.add_point(Vector2.ZERO) - vline.add_point(Vector2(0, jump_height * -16)) - add_child(vline) - move_child(vline, 0) - elif debug and world: - vline.add_point(position) - vline.add_point(jump_pos) - world.front.add_child(vline) - - $RayCast2D.target_position = Vector2(0, jump_height * -16) - - var hline = PATH_LINE.instantiate() - hline.name = "HPath" - hline.default_color = Color.RED - if Engine.is_editor_hint(): - hline.add_point(Vector2(x_min * 16,0)) - hline.add_point(Vector2(x_max * 16,0)) - add_child(hline) - move_child(hline, 0) - elif debug and world: - hline.add_point(position + Vector2(x_min * 16,0)) - hline.add_point(position + Vector2(x_max * 16,0)) - world.front.add_child(hline) diff --git a/src/Actor/Enemy/Outdated/Fish/Fish.tscn b/src/Actor/Enemy/Outdated/Fish/Fish.tscn deleted file mode 100644 index 56378554..00000000 --- a/src/Actor/Enemy/Outdated/Fish/Fish.tscn +++ /dev/null @@ -1,146 +0,0 @@ -[gd_scene load_steps=15 format=3 uid="uid://crtxny1yjnkmi"] - -[ext_resource type="Texture2D" uid="uid://bbu1jyosea4de" path="res://assets/Actor/Enemy/Fish.png" id="1"] -[ext_resource type="Script" uid="uid://ddxy1osfjb432" path="res://src/Actor/Enemy/Outdated/Fish/Fish.gd" id="2"] -[ext_resource type="Script" uid="uid://f3j1idg16dr0" path="res://src/Actor/Enemy/Outdated/Fish/Idle.gd" id="3"] -[ext_resource type="Script" uid="uid://5si1ouivktcq" path="res://src/Actor/Enemy/Outdated/Fish/Attack.gd" id="4"] -[ext_resource type="Theme" uid="uid://45e84j2sj7w0" path="res://src/UI/Theme/LaputaTheme.tres" id="5"] -[ext_resource type="Script" uid="uid://cdevxkqwx005a" path="res://src/Actor/Enemy/Outdated/Fish/Fall.gd" id="6"] -[ext_resource type="Script" uid="uid://bat4sn1l7tdkt" path="res://src/Actor/Enemy/Outdated/Fish/Swim.gd" id="7"] -[ext_resource type="PackedScene" uid="uid://qmvnhwivhm4j" path="res://src/Utility/StateMachine.tscn" id="8"] - -[sub_resource type="RectangleShape2D" id="5"] -size = Vector2(4, 4) - -[sub_resource type="Animation" id="1"] -resource_name = "Fall" -length = 0.1 -loop_mode = 1 -tracks/0/type = "value" -tracks/0/imported = false -tracks/0/enabled = true -tracks/0/path = NodePath("Sprite2D:frame") -tracks/0/interp = 1 -tracks/0/loop_wrap = false -tracks/0/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 0, -"values": [12] -} - -[sub_resource type="Animation" id="2"] -resource_name = "Idle" -length = 0.4 -loop_mode = 1 -tracks/0/type = "value" -tracks/0/imported = false -tracks/0/enabled = true -tracks/0/path = NodePath("Sprite2D:frame") -tracks/0/interp = 1 -tracks/0/loop_wrap = false -tracks/0/keys = { -"times": PackedFloat32Array(0, 0.3), -"transitions": PackedFloat32Array(1, 1), -"update": 0, -"values": [0, 3] -} - -[sub_resource type="Animation" id="3"] -resource_name = "Rise" -length = 0.1 -loop_mode = 1 -tracks/0/type = "value" -tracks/0/imported = false -tracks/0/enabled = true -tracks/0/path = NodePath("Sprite2D:frame") -tracks/0/interp = 1 -tracks/0/loop_wrap = false -tracks/0/keys = { -"times": PackedFloat32Array(0), -"transitions": PackedFloat32Array(1), -"update": 0, -"values": [8] -} - -[sub_resource type="Animation" id="4"] -resource_name = "Target" -length = 0.2 -tracks/0/type = "value" -tracks/0/imported = false -tracks/0/enabled = true -tracks/0/path = NodePath("Sprite2D:frame") -tracks/0/interp = 1 -tracks/0/loop_wrap = false -tracks/0/keys = { -"times": PackedFloat32Array(0, 0.2), -"transitions": PackedFloat32Array(1, 1), -"update": 0, -"values": [4, 7] -} - -[sub_resource type="AnimationLibrary" id="AnimationLibrary_3s1p6"] -_data = { -&"Fall": SubResource("1"), -&"Idle": SubResource("2"), -&"Rise": SubResource("3"), -&"Target": SubResource("4") -} - -[node name="Fish" type="CharacterBody2D" groups=["Actors", "Enemies", "Entities"]] -collision_layer = 2 -collision_mask = 8 -script = ExtResource("2") -id = "0.5" -speed = Vector2(20, 150) - -[node name="CollisionShape2D" type="CollisionShape2D" parent="."] -shape = SubResource("5") - -[node name="Sprite2D" type="Sprite2D" parent="."] -scale = Vector2(-1, 1) -texture = ExtResource("1") -hframes = 4 -vframes = 4 -frame = 12 - -[node name="AnimationPlayer" type="AnimationPlayer" parent="."] -libraries = { -"": SubResource("AnimationLibrary_3s1p6") -} - -[node name="RayCast2D" type="RayCast2D" parent="."] -target_position = Vector2(0, -96) -collision_mask = 9 -collide_with_areas = true - -[node name="StateMachine" parent="." instance=ExtResource("8")] -start_state = NodePath("Idle") - -[node name="Label" type="Label" parent="StateMachine"] -offset_left = -16.0 -offset_top = -16.0 -offset_right = 16.0 -theme = ExtResource("5") - -[node name="Idle" type="Node" parent="StateMachine"] -script = ExtResource("3") - -[node name="Swim" type="Node" parent="StateMachine"] -script = ExtResource("7") - -[node name="Attack" type="Node" parent="StateMachine"] -script = ExtResource("4") - -[node name="Fall" type="Node" parent="StateMachine"] -script = ExtResource("6") - -[node name="Tween" type="Tween" parent="StateMachine/Fall"] -_import_path = NodePath("") -unique_name_in_owner = false -process_mode = 0 -process_priority = 0 -process_physics_priority = 0 -process_thread_group = 0 -editor_description = "" -script = null diff --git a/src/Player/Player.gd b/src/Player/Player.gd index 3228c559..c20738d2 100644 --- a/src/Player/Player.gd +++ b/src/Player/Player.gd @@ -40,6 +40,7 @@ var forbid_crouching = false var is_in_water = false var is_in_coyote = false var dead = false +var do_bubbles = true @export var controller_id: int = 0 diff --git a/src/Trigger/Water.gd b/src/Trigger/Water.gd index d55b21f9..4a287e19 100644 --- a/src/Trigger/Water.gd +++ b/src/Trigger/Water.gd @@ -23,14 +23,14 @@ func _on_Water_body_entered(body): target.velocity *= velocity_dropoff do_bubbles = false if !body.get_collision_layer_value(1): - if target.just_spawned: + if $GraceTimer.time_left > 0.0: if (!splash_targets.has(target)): splash_targets.append(target) active_bodies.append(target) if not target.is_in_water: target.is_in_water = true - if do_bubbles: + if do_bubbles && target.do_bubbles: var be = BUBBLEEMITTER.instantiate() bubble_emitters[target] = be target.call_deferred("add_child", be) @@ -56,7 +56,7 @@ func _on_Water_body_exited(body): if not get_overlap(body): target.is_in_water = false - if do_bubbles and bubble_emitters.has(target): + if do_bubbles && bubble_emitters.has(target): bubble_emitters[target].queue_free() bubble_emitters.erase(target) await get_tree().physics_frame diff --git a/src/Trigger/Water.tscn b/src/Trigger/Water.tscn index 64417a70..b80ef5a9 100644 --- a/src/Trigger/Water.tscn +++ b/src/Trigger/Water.tscn @@ -1,19 +1,24 @@ -[gd_scene load_steps=3 format=3 uid="uid://xce0p5v08dn2"] +[gd_scene format=3 uid="uid://xce0p5v08dn2"] [ext_resource type="Script" uid="uid://b7n2ctrbbq4kn" path="res://src/Trigger/Water.gd" id="1"] [sub_resource type="RectangleShape2D" id="1"] size = Vector2(16, 16) -[node name="Water" type="Area2D" groups=["Triggers"]] +[node name="Water" type="Area2D" unique_id=1352829104 groups=["Triggers"]] collision_layer = 1048576 collision_mask = 7315 script = ExtResource("1") color = Color(0, 0, 0.701961, 1) -[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +[node name="CollisionShape2D" type="CollisionShape2D" parent="." unique_id=1012661956] position = Vector2(8, 8) shape = SubResource("1") +[node name="GraceTimer" type="Timer" parent="." unique_id=712103786] +wait_time = 0.2 +one_shot = true +autostart = true + [connection signal="body_entered" from="." to="." method="_on_Water_body_entered"] [connection signal="body_exited" from="." to="." method="_on_Water_body_exited"] diff --git a/src/Utility/PathLine.tscn b/src/Utility/PathLine.tscn index 1a2c90fb..7c7f82a1 100644 --- a/src/Utility/PathLine.tscn +++ b/src/Utility/PathLine.tscn @@ -1,6 +1,7 @@ [gd_scene format=3 uid="uid://ctxje1wg3ojk7"] -[node name="PathLine" type="Line2D"] +[node name="PathLine" type="Line2D" unique_id=1318880159] +top_level = true width = 0.5 default_color = Color(0.976471, 0.811765, 0.247059, 1) antialiased = true