Compare commits
	
		
			2 Commits
		
	
	
		
			156da4898e
			...
			c8340efc95
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| c8340efc95 | |||
| 8bd7bfa406 | 
| @@ -18,6 +18,7 @@ const GROUP_DAMAGEABLE = "damagable" | ||||
| const GROUP_PLAYER = "player" | ||||
| const GROUP_XP_ORB = "xp_orb" | ||||
| const GROUP_PICKUP = "pickup" | ||||
| const GROUP_PROJ_MANAGER = "proj_manager" | ||||
|  | ||||
| enum ModRarity { LEGENDARY, EPIC, RARE, NORMAL } | ||||
|  | ||||
|   | ||||
| @@ -33,6 +33,7 @@ enemy="Group containing all enemies" | ||||
| damagable="Can be damaged using take_damage" | ||||
| xp_orb="Experience orbs" | ||||
| pickup="Items that can be picked up" | ||||
| proj_manager="Parent node for all projectiles" | ||||
|  | ||||
| [input] | ||||
|  | ||||
|   | ||||
| @@ -1,102 +0,0 @@ | ||||
| extends Node2D | ||||
|  | ||||
| @export var default_attack_time: float = 0.5 | ||||
| @export var player: Player = null | ||||
|  | ||||
| @onready var trigger_area: Area2D = $TriggerArea | ||||
| @onready var trigger_collision: CollisionShape2D = $TriggerArea/TriggerCollision | ||||
| @onready var timer: Timer = $Timer | ||||
| @onready var attack_path: Path2D = $AttackPath | ||||
| @onready var path_follow_2d: PathFollow2D = $AttackPath/PathFollow2D | ||||
| @onready var attack_area: Area2D = $AttackPath/PathFollow2D/Sprite2D/AttackArea | ||||
|  | ||||
| var base_damage: float = 5.0 | ||||
| var current_target: Node2D = null | ||||
| var current_progress: float = 0.0 | ||||
| var damaged_this_attack: Array = [] | ||||
| var is_attacking: bool = false | ||||
|  | ||||
|  | ||||
| func _ready() -> void: | ||||
| 	attack_path.visible = false | ||||
|  | ||||
|  | ||||
| func _process(delta: float) -> void: | ||||
| 	if timer.is_stopped() and current_progress == 0.0: | ||||
| 		timer.start() | ||||
| 	if current_progress > 0.95: | ||||
| 		reset_attack() | ||||
| 	if ( | ||||
| 		current_target | ||||
| 		and is_instance_valid(current_target) | ||||
| 		and not current_target.is_queued_for_deletion() | ||||
| 	): | ||||
| 		track_target(current_target) | ||||
| 		is_attacking = true | ||||
| 		attack_path.visible = true | ||||
|  | ||||
| 	if is_attacking: | ||||
| 		# Do attack animation | ||||
| 		current_progress += delta / default_attack_time | ||||
| 		current_progress = clampf(current_progress, 0.0, 1.0) | ||||
| 		path_follow_2d.progress_ratio = current_progress | ||||
|  | ||||
|  | ||||
| func reset_attack() -> void: | ||||
| 	current_target = null | ||||
| 	attack_path.visible = false | ||||
| 	current_progress = 0.0 | ||||
| 	damaged_this_attack = [] | ||||
| 	is_attacking = false | ||||
| 	position = Vector2.ZERO | ||||
| 	rotation = 0.0 | ||||
|  | ||||
|  | ||||
| func set_target(body: Node2D): | ||||
| 	current_target = body | ||||
| 	is_attacking = true | ||||
|  | ||||
|  | ||||
| func track_target(body: Node2D): | ||||
| 	var mid_distance = attack_path.curve.get_baked_length() / 2 | ||||
| 	var mid_point: Vector2 = attack_path.curve.sample_baked(mid_distance) | ||||
| 	var offset = body.global_position - to_global(mid_point) | ||||
|  | ||||
| 	var desired_dir = (body.global_position - to_global(mid_point)).normalized() | ||||
| 	var start_point_global = attack_path.to_global(attack_path.curve.sample_baked(0)) | ||||
| 	var end_point_global = attack_path.to_global( | ||||
| 		attack_path.curve.sample_baked(attack_path.curve.get_baked_length()) | ||||
| 	) | ||||
| 	var curve_dir = (start_point_global - end_point_global).normalized() | ||||
| 	var angle_diff = curve_dir.angle_to(desired_dir) | ||||
| 	if rotation == 0.0: | ||||
| 		rotation = curve_dir.angle_to(desired_dir) | ||||
| 	position += offset | ||||
|  | ||||
|  | ||||
| func _on_timer_timeout() -> void: | ||||
| 	if current_target: | ||||
| 		if trigger_area.has_overlapping_areas(): | ||||
| 			if current_target not in trigger_area.get_overlapping_bodies(): | ||||
| 				current_target = null | ||||
| 		return | ||||
| 	if trigger_area.has_overlapping_bodies(): | ||||
| 		for body in trigger_area.get_overlapping_bodies(): | ||||
| 			if body.is_in_group(GlobalConst.GROUP_ENEMY): | ||||
| 				set_target(body) | ||||
|  | ||||
|  | ||||
| func _on_attack_area_body_entered(body: Node2D) -> void: | ||||
| 	if not attack_path.visible: | ||||
| 		return | ||||
| 	if body in damaged_this_attack: | ||||
| 		return | ||||
| 	if body.is_in_group(GlobalConst.GROUP_ENEMY) and body.is_in_group(GlobalConst.GROUP_DAMAGEABLE): | ||||
| 		var crit_chance = player.player_stats.get_final("crit_chance", player.modifiers) | ||||
| 		var damage_dealt = base_damage | ||||
| 		var is_crit = randf() >= 1 - crit_chance | ||||
| 		if is_crit: | ||||
| 			damage_dealt *= player.player_stats.get_final("crit_multiplier", player.modifiers) | ||||
|  | ||||
| 		body.take_damage(damage_dealt, is_crit) | ||||
| 		damaged_this_attack.append(body) | ||||
| @@ -1 +0,0 @@ | ||||
| uid://db326gu8abue5 | ||||
| @@ -1,53 +0,0 @@ | ||||
| [gd_scene load_steps=6 format=3 uid="uid://cdojqe2m4kxx1"] | ||||
|  | ||||
| [ext_resource type="Texture2D" uid="uid://dycw7c3484dir" path="res://assets/sprites/sword.png" id="1_3fwwl"] | ||||
| [ext_resource type="Script" uid="uid://db326gu8abue5" path="res://scenes/attacks/attack_sword.gd" id="1_frsqi"] | ||||
|  | ||||
| [sub_resource type="Curve2D" id="Curve2D_frsqi"] | ||||
| bake_interval = 2.0 | ||||
| _data = { | ||||
| "points": PackedVector2Array(0, 0, 0, 0, 0, 0, 0, 0, 25, 10, 200, 0) | ||||
| } | ||||
| point_count = 2 | ||||
|  | ||||
| [sub_resource type="RectangleShape2D" id="RectangleShape2D_frsqi"] | ||||
| size = Vector2(13.9997, 46.999) | ||||
|  | ||||
| [sub_resource type="CircleShape2D" id="CircleShape2D_3fwwl"] | ||||
| radius = 267.002 | ||||
|  | ||||
| [node name="AttackSword" type="Node2D"] | ||||
| script = ExtResource("1_frsqi") | ||||
|  | ||||
| [node name="AttackPath" type="Path2D" parent="."] | ||||
| curve = SubResource("Curve2D_frsqi") | ||||
|  | ||||
| [node name="PathFollow2D" type="PathFollow2D" parent="AttackPath"] | ||||
| loop = false | ||||
|  | ||||
| [node name="Sprite2D" type="Sprite2D" parent="AttackPath/PathFollow2D"] | ||||
| position = Vector2(0.322462, -0.946582) | ||||
| rotation = 0.328329 | ||||
| texture = ExtResource("1_3fwwl") | ||||
|  | ||||
| [node name="AttackArea" type="Area2D" parent="AttackPath/PathFollow2D/Sprite2D"] | ||||
| collision_layer = 0 | ||||
| collision_mask = 2 | ||||
|  | ||||
| [node name="AttackCollision" type="CollisionShape2D" parent="AttackPath/PathFollow2D/Sprite2D/AttackArea"] | ||||
| position = Vector2(-0.0328934, -4.50646) | ||||
| shape = SubResource("RectangleShape2D_frsqi") | ||||
|  | ||||
| [node name="TriggerArea" type="Area2D" parent="."] | ||||
| visible = false | ||||
| collision_layer = 0 | ||||
| collision_mask = 2 | ||||
|  | ||||
| [node name="TriggerCollision" type="CollisionShape2D" parent="TriggerArea"] | ||||
| shape = SubResource("CircleShape2D_3fwwl") | ||||
|  | ||||
| [node name="Timer" type="Timer" parent="."] | ||||
| one_shot = true | ||||
|  | ||||
| [connection signal="body_entered" from="AttackPath/PathFollow2D/Sprite2D/AttackArea" to="." method="_on_attack_area_body_entered"] | ||||
| [connection signal="timeout" from="Timer" to="." method="_on_timer_timeout"] | ||||
| @@ -55,6 +55,7 @@ func do_movement(delta: float) -> void: | ||||
| 	else: | ||||
| 		_do_nav_agent_movement() | ||||
|  | ||||
|  | ||||
| func _has_direct_path(): | ||||
| 	target_cast.target_position = to_local(target.global_position) | ||||
| 	target_cast.enabled = true | ||||
|   | ||||
| @@ -14,6 +14,7 @@ func _process(delta: float) -> void: | ||||
| 	elapsed_time += delta | ||||
| 	main_ui.player_ui.set_elapsed_time(elapsed_time) | ||||
|  | ||||
|  | ||||
| func _unhandled_input(event: InputEvent) -> void: | ||||
| 	if event.is_action_pressed("ui_cancel"): | ||||
| 		main_ui.pause_ui.toggle_pause_ui() | ||||
|   | ||||
| @@ -1,4 +1,4 @@ | ||||
| [gd_scene load_steps=8 format=3 uid="uid://bjg50n7aab3ng"] | ||||
| [gd_scene load_steps=9 format=3 uid="uid://bjg50n7aab3ng"] | ||||
|  | ||||
| [ext_resource type="Script" uid="uid://brb4ssksmtq8k" path="res://scenes/main.gd" id="1_jyhfs"] | ||||
| [ext_resource type="PackedScene" uid="uid://4xha2nhf8fya" path="res://scenes/test_level.tscn" id="1_o5qli"] | ||||
| @@ -7,6 +7,7 @@ | ||||
| [ext_resource type="PackedScene" uid="uid://dy73qrxcgrwg3" path="res://scenes/managers/enemy_manager.tscn" id="5_tbgi4"] | ||||
| [ext_resource type="PackedScene" uid="uid://bbev8m5g0p3a3" path="res://scenes/pickups/pickup_magnet.tscn" id="6_tefeu"] | ||||
| [ext_resource type="PackedScene" uid="uid://cr8gj1dlloamp" path="res://scenes/pickups/pickup_hp.tscn" id="7_o6xl0"] | ||||
| [ext_resource type="PackedScene" uid="uid://c2o1lpm4pimpr" path="res://scenes/managers/projectile_manager.tscn" id="8_tipki"] | ||||
|  | ||||
| [node name="Main" type="Node2D"] | ||||
| script = ExtResource("1_jyhfs") | ||||
| @@ -32,3 +33,5 @@ position = Vector2(1697, 414) | ||||
|  | ||||
| [node name="PickupHP" parent="." instance=ExtResource("7_o6xl0")] | ||||
| position = Vector2(1678, 939) | ||||
|  | ||||
| [node name="ProjectileManager" parent="." instance=ExtResource("8_tipki")] | ||||
|   | ||||
| @@ -26,11 +26,13 @@ func _on_timer_timeout() -> void: | ||||
| 		new_enemy.target = target | ||||
| 		add_child(new_enemy) | ||||
|  | ||||
|  | ||||
| func _on_stop_spawning(val: bool): | ||||
| 	if val: | ||||
| 		timer.stop() | ||||
| 	elif timer.is_stopped(): | ||||
| 		timer.start() | ||||
|  | ||||
|  | ||||
| func _on_set_spawn_rate(val: float): | ||||
| 	timer.wait_time = 1 / val | ||||
|   | ||||
							
								
								
									
										3
									
								
								scenes/managers/projectile_manager.tscn
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								scenes/managers/projectile_manager.tscn
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,3 @@ | ||||
| [gd_scene format=3 uid="uid://c2o1lpm4pimpr"] | ||||
|  | ||||
| [node name="ProjectileManager" type="Node2D"] | ||||
| @@ -5,7 +5,6 @@ extends CharacterBody2D | ||||
| @export var main_ui: MainUI | ||||
|  | ||||
| @onready var sprite_2d: Sprite2D = $Sprite2D | ||||
| @onready var attack_sword: Node2D = $AttackSword | ||||
|  | ||||
| var player_stats: PlayerStats = PlayerStats.new() | ||||
| var modifiers: Array[PlayerStatsModifier] = [] | ||||
| @@ -61,7 +60,6 @@ func die(): | ||||
| 	dead = true | ||||
| 	remove_from_group("damagable") | ||||
| 	get_tree().call_group("enemy", "cheer") | ||||
| 	attack_sword.queue_free() | ||||
| 	GlobalConst.sig_stop_spawning.emit(true) | ||||
| 	sprite_2d.z_index += 10 | ||||
| 	get_taunted() | ||||
|   | ||||
| @@ -2,7 +2,7 @@ | ||||
|  | ||||
| [ext_resource type="Texture2D" uid="uid://5x5wimok8uw2" path="res://assets/sprites/roguelikeChar_transparent.png" id="1_3vyb7"] | ||||
| [ext_resource type="Script" uid="uid://cvqaxckx4num3" path="res://scenes/player.gd" id="1_g2els"] | ||||
| [ext_resource type="PackedScene" uid="uid://cdojqe2m4kxx1" path="res://scenes/attacks/attack_sword.tscn" id="3_qhqgy"] | ||||
| [ext_resource type="PackedScene" uid="uid://dfikvj27k01tu" path="res://scenes/weapons/weapon_sword.tscn" id="3_qhqgy"] | ||||
|  | ||||
| [sub_resource type="CircleShape2D" id="CircleShape2D_3vyb7"] | ||||
| radius = 8.0 | ||||
| @@ -22,9 +22,6 @@ region_rect = Rect2(0, 104, 16, 14) | ||||
| [node name="CollisionShape2D" type="CollisionShape2D" parent="."] | ||||
| shape = SubResource("CircleShape2D_3vyb7") | ||||
|  | ||||
| [node name="AttackSword" parent="." node_paths=PackedStringArray("player") instance=ExtResource("3_qhqgy")] | ||||
| player = NodePath("..") | ||||
|  | ||||
| [node name="PickupArea" type="Area2D" parent="."] | ||||
| collision_layer = 0 | ||||
| collision_mask = 24 | ||||
| @@ -33,4 +30,6 @@ monitorable = false | ||||
| [node name="CollisionShape2D" type="CollisionShape2D" parent="PickupArea"] | ||||
| shape = SubResource("CircleShape2D_qhqgy") | ||||
|  | ||||
| [node name="WeaponSword" parent="." instance=ExtResource("3_qhqgy")] | ||||
|  | ||||
| [connection signal="area_entered" from="PickupArea" to="." method="_on_pickup_area_area_entered"] | ||||
|   | ||||
							
								
								
									
										42
									
								
								scenes/weapons/weapon_base.gd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								scenes/weapons/weapon_base.gd
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| class_name WeaponBase | ||||
| extends Node2D | ||||
|  | ||||
| @export var attack_cd: float | ||||
| @export var attack_damage: float | ||||
| @export var attack_aoe: float | ||||
| @export var attack_duration: float | ||||
| @export var attack_range: float | ||||
|  | ||||
|  | ||||
| func _on_attack_cd_timer_timeout() -> void: | ||||
| 	do_attack() | ||||
|  | ||||
|  | ||||
| func do_attack() -> void: | ||||
| 	push_error("%s does not implement do_attack" % self) | ||||
|  | ||||
|  | ||||
| func find_target_in_radius() -> EnemyBase: | ||||
| 	var space_state: PhysicsDirectSpaceState2D = get_world_2d().direct_space_state | ||||
| 	var shape := CircleShape2D.new() | ||||
| 	shape.radius = attack_range | ||||
|  | ||||
| 	var query := PhysicsShapeQueryParameters2D.new() | ||||
| 	query.shape = shape | ||||
| 	query.transform = Transform2D(0, global_position) | ||||
| 	query.collision_mask = 2 | ||||
| 	query.collide_with_bodies = true | ||||
| 	var results := space_state.intersect_shape(query) | ||||
| 	if len(results) < 1: | ||||
| 		return null | ||||
| 	var closest: PhysicsBody2D = results[0]["collider"] | ||||
| 	for r in results: | ||||
| 		var c: PhysicsBody2D = r["collider"] | ||||
| 		if not c.is_in_group(GlobalConst.GROUP_ENEMY): | ||||
| 			continue | ||||
| 		if ( | ||||
| 			c.global_position.distance_to(global_position) | ||||
| 			< closest.global_position.distance_to(global_position) | ||||
| 		): | ||||
| 			closest = c | ||||
| 	return closest | ||||
							
								
								
									
										1
									
								
								scenes/weapons/weapon_base.gd.uid
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								scenes/weapons/weapon_base.gd.uid
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| uid://d6nwfhyethdw | ||||
							
								
								
									
										11
									
								
								scenes/weapons/weapon_base.tscn
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								scenes/weapons/weapon_base.tscn
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | ||||
| [gd_scene load_steps=2 format=3 uid="uid://i8mtky2req41"] | ||||
|  | ||||
| [ext_resource type="Script" uid="uid://d6nwfhyethdw" path="res://scenes/weapons/weapon_base.gd" id="1_v4xn6"] | ||||
|  | ||||
| [node name="WeaponBase" type="Node2D"] | ||||
| script = ExtResource("1_v4xn6") | ||||
|  | ||||
| [node name="AttackCDTimer" type="Timer" parent="."] | ||||
| autostart = true | ||||
|  | ||||
| [connection signal="timeout" from="AttackCDTimer" to="." method="_on_attack_cd_timer_timeout"] | ||||
							
								
								
									
										42
									
								
								scenes/weapons/weapon_sword.gd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								scenes/weapons/weapon_sword.gd
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,42 @@ | ||||
| class_name WeaponSword | ||||
| extends WeaponBase | ||||
|  | ||||
| const WEAPON_SWORD_PROJECTILE = preload("res://scenes/weapons/weapon_sword_projectile.tscn") | ||||
|  | ||||
| @onready var targeting_range: Area2D = $TargetingRange | ||||
| @onready var targeting_range_shape: CollisionShape2D = $TargetingRange/CollisionShape2D | ||||
|  | ||||
| signal projectile_hit(projectile: WeaponSwordProjectile, enemy: EnemyBase) | ||||
|  | ||||
| var _player: Player | ||||
|  | ||||
|  | ||||
| func _ready() -> void: | ||||
| 	targeting_range_shape.shape.radius = attack_range | ||||
| 	projectile_hit.connect(_on_projectile_hit) | ||||
| 	_player = get_tree().get_first_node_in_group(GlobalConst.GROUP_PLAYER) | ||||
|  | ||||
|  | ||||
| func do_attack() -> void: | ||||
| 	var target: EnemyBase = find_target_in_radius() | ||||
| 	if not target: | ||||
| 		return | ||||
|  | ||||
| 	var projectile = WEAPON_SWORD_PROJECTILE.instantiate() | ||||
| 	projectile.damage = attack_damage | ||||
| 	projectile.target = target | ||||
| 	projectile.on_hit_sig = projectile_hit | ||||
| 	add_child(projectile) | ||||
|  | ||||
|  | ||||
| func deal_damage(enemy: EnemyBase): | ||||
| 	var crit_chance = _player.player_stats.get_final("crit_chance", _player.modifiers) | ||||
| 	var damage_dealt = attack_damage | ||||
| 	var is_crit = randf() >= 1 - crit_chance | ||||
| 	if is_crit: | ||||
| 		damage_dealt *= _player.player_stats.get_final("crit_multiplier", _player.modifiers) | ||||
| 	enemy.take_damage(damage_dealt, is_crit) | ||||
|  | ||||
|  | ||||
| func _on_projectile_hit(projectile: WeaponSwordProjectile, enemy: EnemyBase): | ||||
| 	deal_damage(enemy) | ||||
							
								
								
									
										1
									
								
								scenes/weapons/weapon_sword.gd.uid
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								scenes/weapons/weapon_sword.gd.uid
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| uid://b072d866r4usq | ||||
							
								
								
									
										22
									
								
								scenes/weapons/weapon_sword.tscn
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								scenes/weapons/weapon_sword.tscn
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
| [gd_scene load_steps=4 format=3 uid="uid://dfikvj27k01tu"] | ||||
|  | ||||
| [ext_resource type="PackedScene" uid="uid://i8mtky2req41" path="res://scenes/weapons/weapon_base.tscn" id="1_2dti5"] | ||||
| [ext_resource type="Script" uid="uid://b072d866r4usq" path="res://scenes/weapons/weapon_sword.gd" id="2_ruf80"] | ||||
|  | ||||
| [sub_resource type="CircleShape2D" id="CircleShape2D_ruf80"] | ||||
|  | ||||
| [node name="WeaponSword" instance=ExtResource("1_2dti5")] | ||||
| script = ExtResource("2_ruf80") | ||||
| attack_cd = 1.0 | ||||
| attack_damage = 5.0 | ||||
| attack_aoe = 1.0 | ||||
| attack_duration = 1.0 | ||||
| attack_range = 150.0 | ||||
|  | ||||
| [node name="TargetingRange" type="Area2D" parent="." index="1"] | ||||
| collision_layer = 0 | ||||
| collision_mask = 2 | ||||
| monitorable = false | ||||
|  | ||||
| [node name="CollisionShape2D" type="CollisionShape2D" parent="TargetingRange" index="0"] | ||||
| shape = SubResource("CircleShape2D_ruf80") | ||||
							
								
								
									
										40
									
								
								scenes/weapons/weapon_sword_projectile.gd
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								scenes/weapons/weapon_sword_projectile.gd
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | ||||
| class_name WeaponSwordProjectile | ||||
| extends Node2D | ||||
|  | ||||
| @export var speed: float = 500.0 | ||||
| @export var range: float = 200.0 | ||||
| @export var target: Node2D | ||||
| @export var damage: float | ||||
| @export var on_hit_sig: Signal | ||||
|  | ||||
| var _direction: Vector2 | ||||
| var _traveled: float = 0.0 | ||||
| var _already_hit: Array[PhysicsBody2D] = [] | ||||
|  | ||||
|  | ||||
| func _ready() -> void: | ||||
| 	_direction = global_position.direction_to(target.global_position).normalized() | ||||
| 	_traveled = 0.0 | ||||
| 	rotation = _direction.angle() | ||||
| 	if _direction.x < 0: | ||||
| 		rotation += PI | ||||
| 	var proj_manager = get_tree().get_first_node_in_group(GlobalConst.GROUP_PROJ_MANAGER) | ||||
| 	if not proj_manager: | ||||
| 		return | ||||
| 	reparent(proj_manager, true) | ||||
|  | ||||
|  | ||||
| func _physics_process(delta: float) -> void: | ||||
| 	var step = _direction * speed * delta | ||||
| 	global_position += step | ||||
| 	_traveled += step.length() | ||||
|  | ||||
| 	if _traveled >= range: | ||||
| 		queue_free() | ||||
|  | ||||
|  | ||||
| func _on_area_2d_body_entered(body: Node2D) -> void: | ||||
| 	if body in _already_hit: | ||||
| 		return | ||||
| 	on_hit_sig.emit(self, body) | ||||
| 	_already_hit.append(body) | ||||
							
								
								
									
										1
									
								
								scenes/weapons/weapon_sword_projectile.gd.uid
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								scenes/weapons/weapon_sword_projectile.gd.uid
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| uid://c40iaqdubwl0p | ||||
							
								
								
									
										24
									
								
								scenes/weapons/weapon_sword_projectile.tscn
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								scenes/weapons/weapon_sword_projectile.tscn
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| [gd_scene load_steps=4 format=3 uid="uid://bv5f47x3ishmf"] | ||||
|  | ||||
| [ext_resource type="Script" uid="uid://c40iaqdubwl0p" path="res://scenes/weapons/weapon_sword_projectile.gd" id="1_asuu4"] | ||||
| [ext_resource type="Texture2D" uid="uid://dycw7c3484dir" path="res://assets/sprites/sword.png" id="2_pxap4"] | ||||
|  | ||||
| [sub_resource type="RectangleShape2D" id="RectangleShape2D_ygc1t"] | ||||
| size = Vector2(16, 46) | ||||
|  | ||||
| [node name="WeaponSwordProjectile" type="Node2D"] | ||||
| script = ExtResource("1_asuu4") | ||||
|  | ||||
| [node name="Sprite2D" type="Sprite2D" parent="."] | ||||
| texture = ExtResource("2_pxap4") | ||||
|  | ||||
| [node name="Area2D" type="Area2D" parent="."] | ||||
| collision_layer = 0 | ||||
| collision_mask = 2 | ||||
| monitorable = false | ||||
|  | ||||
| [node name="CollisionShape2D" type="CollisionShape2D" parent="Area2D"] | ||||
| position = Vector2(0, -5) | ||||
| shape = SubResource("RectangleShape2D_ygc1t") | ||||
|  | ||||
| [connection signal="body_entered" from="Area2D" to="." method="_on_area_2d_body_entered"] | ||||
		Reference in New Issue
	
	Block a user