diff --git a/addons/nezvers_library/autoload/InstanceManager.gd b/addons/nezvers_library/autoload/InstanceManager.gd new file mode 100644 index 00000000..a2dd7ef4 --- /dev/null +++ b/addons/nezvers_library/autoload/InstanceManager.gd @@ -0,0 +1,10 @@ +extends Node + +func instance(scene:PackedScene, parent_reference:ReferenceNodeResource, position:Vector2 = Vector2.ZERO)->void: + assert(scene != null) + assert(parent_reference != null) + assert(parent_reference.node != null) + var inst:Node = scene.instantiate() + if inst is CanvasItem || inst is Node3D: + inst.global_position = position + parent_reference.node.add_child(inst) diff --git a/project.godot b/project.godot index b53425b4..0285ad7c 100644 --- a/project.godot +++ b/project.godot @@ -23,6 +23,7 @@ buses/default_bus_layout="" SoundManager="*res://autoload/sound_manager.tscn" Music="*res://autoload/music.tscn" +InstanceManager="*res://addons/nezvers_library/autoload/InstanceManager.gd" [display] diff --git a/resources/DamageResource/shotgun_damage.tres b/resources/DamageResource/shotgun_damage.tres index bf5526c8..197eccc0 100644 --- a/resources/DamageResource/shotgun_damage.tres +++ b/resources/DamageResource/shotgun_damage.tres @@ -4,9 +4,12 @@ [resource] script = ExtResource("1_jwgv3") -value = 1.0 +value = 2.0 projectile_multiply = 1.0 critical_multiply = 1.5 critical_chance = 0.3 direction = Vector2(0, 0) kickback_strength = 0.0 +is_critical = false +hit_list = [] +total_damage = 0.0 diff --git a/resources/DamageResource/zombie_damage.tres b/resources/DamageResource/zombie_damage.tres index 2062dd2e..cdada8cd 100644 --- a/resources/DamageResource/zombie_damage.tres +++ b/resources/DamageResource/zombie_damage.tres @@ -7,6 +7,9 @@ script = ExtResource("1_ymdgu") value = 1.0 projectile_multiply = 1.0 critical_multiply = 1.5 -critical_chance = 0.3 +critical_chance = 0.0 direction = Vector2(0, 0) -kickback_strength = 0.0 +kickback_strength = 120.0 +is_critical = false +hit_list = [] +total_damage = 0.0 diff --git a/scenes/actors/player.tscn b/scenes/actors/player.tscn index ade1eca1..43a5a046 100644 --- a/scenes/actors/player.tscn +++ b/scenes/actors/player.tscn @@ -142,7 +142,7 @@ script = ExtResource("9_hpc12") projectile_parent_path = "../.." auto_instance_weapons = Array[PackedScene]([ExtResource("10_x7xjs"), ExtResource("11_nnusp"), ExtResource("12_gom0h")]) mover = NodePath("../MoverTopDown2D") -collision_mask = 5 +collision_mask = 4 [node name="Gun" parent="WeaponManager" index="0" node_paths=PackedStringArray("mover") instance=ExtResource("6_rnlhu")] collision_mask = 5 diff --git a/scenes/projectiles/bullet.tscn b/scenes/projectiles/bullet.tscn index 25328840..520c27ff 100644 --- a/scenes/projectiles/bullet.tscn +++ b/scenes/projectiles/bullet.tscn @@ -33,7 +33,7 @@ scale_curve = SubResource("CurveTexture_k2ccc") color_ramp = SubResource("GradientTexture1D_138ku") [node name="Bullet" instance=ExtResource("1_omfnw")] -self_remove = true +kickback_strength = 60.0 [node name="Shadow" type="Sprite2D" parent="." index="1"] modulate = Color(1, 0.983333, 0, 0.168627) diff --git a/scenes/projectiles/projectile.tscn b/scenes/projectiles/projectile.tscn index 070f6353..de6a2020 100644 --- a/scenes/projectiles/projectile.tscn +++ b/scenes/projectiles/projectile.tscn @@ -1,10 +1,13 @@ -[gd_scene load_steps=7 format=3 uid="uid://beifde6xst23w"] +[gd_scene load_steps=10 format=3 uid="uid://beifde6xst23w"] [ext_resource type="Script" path="res://scripts/weapon_system/projectile/Projectile2D.gd" id="1_8ha7j"] [ext_resource type="Texture2D" uid="uid://ciqkwwrhgebko" path="res://assets/images/projectile/bullet_0.png" id="2_7x3e8"] [ext_resource type="Script" path="res://scripts/damage/DamageSource.gd" id="2_dihsx"] [ext_resource type="Script" path="res://scripts/weapon_system/projectile/ProjectileRotation.gd" id="3_wuoxf"] [ext_resource type="Script" path="res://scripts/weapon_system/projectile/ProjectileImpact.gd" id="4_v8blt"] +[ext_resource type="Script" path="res://scripts/weapon_system/projectile/HitLimit.gd" id="6_pkcss"] +[ext_resource type="Resource" uid="uid://d16p36img8x6j" path="res://resources/ReferenceNodeResources/front_reference.tres" id="6_uars4"] +[ext_resource type="Script" path="res://scripts/weapon_system/projectile/ProjectileLifetime.gd" id="8_dsjh1"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_g4a7g"] size = Vector2(4, 2) @@ -13,7 +16,6 @@ size = Vector2(4, 2) script = ExtResource("1_8ha7j") speed = 120.0 axis_multiplier = Vector2(1, 0.5) -lifetime = 2.0 damage_source = NodePath("DamageSource") [node name="DamageSource" type="Area2D" parent="."] @@ -38,3 +40,14 @@ projectile = NodePath("..") script = ExtResource("4_v8blt") projectile = NodePath("..") damage_source = NodePath("../DamageSource") +impact_parent_reference = ExtResource("6_uars4") + +[node name="HitLimit" type="Node" parent="." node_paths=PackedStringArray("projectile", "damage_source")] +script = ExtResource("6_pkcss") +projectile = NodePath("..") +damage_source = NodePath("../DamageSource") + +[node name="ProjectileLifetime" type="Node" parent="." node_paths=PackedStringArray("projectile")] +script = ExtResource("8_dsjh1") +time = 2.0 +projectile = NodePath("..") diff --git a/scenes/projectiles/sword_projectile.tscn b/scenes/projectiles/sword_projectile.tscn index 3cc5aa45..dd9ff0d5 100644 --- a/scenes/projectiles/sword_projectile.tscn +++ b/scenes/projectiles/sword_projectile.tscn @@ -100,10 +100,8 @@ _data = { [node name="SwordProjectile" instance=ExtResource("1_3klw8")] speed = 150.0 -lifetime = 0.6 damage_multiply = 0.5 kickback_strength = 30.0 -self_remove = true [node name="CollisionShape2D" parent="DamageSource" index="0"] shape = SubResource("RectangleShape2D_asrea") @@ -132,3 +130,6 @@ autoplay = "slash" [node name="ProjectileImpact" parent="." index="4"] impact_scene = ExtResource("5_pxxe4") + +[node name="ProjectileLifetime" parent="." index="6"] +time = 0.6 diff --git a/scenes/projectiles/sword_slash.tscn b/scenes/projectiles/sword_slash.tscn index 0affd52a..f2835607 100644 --- a/scenes/projectiles/sword_slash.tscn +++ b/scenes/projectiles/sword_slash.tscn @@ -103,8 +103,6 @@ _data = { [node name="SwordSlash" instance=ExtResource("1_lwexf")] speed = 0.0 -lifetime = 0.27 -hit_limit = -1 destroy_collision_mask = 0 [node name="CollisionShape2D" parent="DamageSource" index="0"] @@ -145,3 +143,6 @@ script = ExtResource("7_n74ie") projectile = NodePath("..") projectile_spawner = NodePath("../ProjectileSpawner") start_projectile_scene = ExtResource("8_1el3x") + +[node name="ProjectileLifetime" parent="." index="8"] +time = 0.27 diff --git a/scenes/projectiles/zombie_slash.tscn b/scenes/projectiles/zombie_slash.tscn index 38e58ccd..e356a880 100644 --- a/scenes/projectiles/zombie_slash.tscn +++ b/scenes/projectiles/zombie_slash.tscn @@ -56,7 +56,6 @@ _data = { [node name="ZombieSlash" instance=ExtResource("1_5ra58")] speed = 0.0 -lifetime = 0.25 [node name="Sprite2D" parent="RotatedNode" index="0"] texture = ExtResource("2_eg08h") @@ -71,3 +70,9 @@ speed_scale = 2.0 [node name="ProjectileRotation" parent="." index="2"] enabled = false + +[node name="HitLimit" parent="." index="4"] +hit_limit = -1 + +[node name="ProjectileLifetime" parent="." index="5"] +time = 0.25 diff --git a/scripts/weapon_system/projectile/HitLimit.gd b/scripts/weapon_system/projectile/HitLimit.gd new file mode 100644 index 00000000..4e2684ad --- /dev/null +++ b/scripts/weapon_system/projectile/HitLimit.gd @@ -0,0 +1,21 @@ +class_name HitLimit +extends Node + +@export var projectile:Projectile2D +@export var damage_source:DamageSource +## Projectile is removed when reaching 0 +## Starting with negative has infinite count +@export var hit_limit:int = 1 + +func _ready()->void: + damage_source.hit.connect(on_hit) + damage_source.hit_solid.connect(projectile.prepare_exit) + +func on_hit()->void: + if hit_limit < 1: + return + hit_limit -= 1 + if hit_limit != 0: + return + + projectile.prepare_exit() diff --git a/scripts/weapon_system/projectile/Projectile2D.gd b/scripts/weapon_system/projectile/Projectile2D.gd index b895ede1..99040c9b 100644 --- a/scripts/weapon_system/projectile/Projectile2D.gd +++ b/scripts/weapon_system/projectile/Projectile2D.gd @@ -1,7 +1,7 @@ class_name Projectile2D extends Node2D -signal limit_reached +signal prepare_exit_event ## Travelling speed @export var speed:float @@ -9,18 +9,10 @@ signal limit_reached @export var direction: = Vector2.RIGHT ## Used to fake angled perspective @export var axis_multiplier:Vector2 = Vector2.ONE -## Remove after this time if above 0.0 -@export var lifetime:float = 0.0 ## Each projectile contribute to the total damage value with multiply - @export var damage_multiply:float = 1.0 ## Force pushing a damage receiver @export var kickback_strength:float = 120.0 -## Projectile is removed when reaching 0 -## Starting with negative has infinite count -@export var hit_limit:int = 1 -## Does it need queue_free self after hitting limit? -@export var self_remove:bool = false ## Holds information about damage stats and events @export var damage_resource:DamageResource @export_group("Damage Source") @@ -29,39 +21,33 @@ signal limit_reached @export_flags_2d_physics var destroy_collision_mask:int = 1 @export_flags_2d_physics var collision_mask:int -var is_limit_reached:bool = false func _ready()->void: # fill last values that projectile is controlling damage_resource.kickback_strength = kickback_strength damage_resource.projectile_multiply = damage_multiply + # TODO: remove references to damage_source to a separate node damage_source.collision_mask = Bitwise.append_flags(damage_source.collision_mask, collision_mask) damage_source.collision_mask = Bitwise.append_flags(damage_source.collision_mask, destroy_collision_mask) damage_source.damage_resource = damage_resource damage_source.hit.connect(on_hit) - damage_source.hit_solid.connect(remove) - direction *= Vector2.ONE / axis_multiplier direction = direction.normalized() - if lifetime > 0.0: - var tween:Tween = create_tween() # used as a timer - tween.tween_callback(remove).set_delay(lifetime) func _physics_process(delta:float)->void: global_position += speed * delta * direction * axis_multiplier func on_hit()->void: damage_resource.direction = direction - # TODO: this hit limit solution looks dumb - if is_limit_reached: - return - hit_limit -= 1 - if hit_limit == 0: - limit_reached.emit() - if self_remove: - remove() + + +func prepare_exit()->void: + set_physics_process(false) + damage_source.monitoring = false + prepare_exit_event.emit() + remove() ## created to call from Tween, Timer, AnimationPlayer or anything else func remove()->void: diff --git a/scripts/weapon_system/projectile/ProjectileImpact.gd b/scripts/weapon_system/projectile/ProjectileImpact.gd index 472a366e..5ab90c71 100644 --- a/scripts/weapon_system/projectile/ProjectileImpact.gd +++ b/scripts/weapon_system/projectile/ProjectileImpact.gd @@ -4,15 +4,15 @@ extends Node @export var projectile:Projectile2D @export var damage_source:DamageSource @export var impact_scene:PackedScene +@export var impact_parent_reference:ReferenceNodeResource func _ready()->void: if impact_scene == null: return + assert(impact_parent_reference != null) damage_source.hit.connect(spawn) + damage_source.hit_solid.connect(spawn) func spawn()->void: - var inst:Node2D = impact_scene.instantiate() - var parent:Node2D = projectile.get_parent() - parent.add_child(inst) - inst.global_position = projectile.global_position # TODO: some vfx might need rotation + InstanceManager.instance(impact_scene, impact_parent_reference, projectile.global_position) diff --git a/scripts/weapon_system/projectile/ProjectileLifetime.gd b/scripts/weapon_system/projectile/ProjectileLifetime.gd new file mode 100644 index 00000000..4732de78 --- /dev/null +++ b/scripts/weapon_system/projectile/ProjectileLifetime.gd @@ -0,0 +1,14 @@ +class_name ProjectileLifetime +extends Node + +@export var time:float = 1.0 +@export var projectile:Projectile2D + +func _ready()->void: + if !(time > 0.0): + return + var tween:Tween = create_tween() + tween.tween_callback(on_timeout).set_delay(time) + +func on_timeout()->void: + projectile.prepare_exit()