Many changes
Handle it
This commit is contained in:
parent
bf09402bc5
commit
214e0aa5e0
366 changed files with 24353 additions and 2096 deletions
63
player/abilities/ability.gd
Normal file
63
player/abilities/ability.gd
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
class_name Ability extends Node2D
|
||||
|
||||
@export var cooldown: float = 5.0
|
||||
@export var effect_duration: float = 3.0
|
||||
|
||||
var modifiers: Array = []
|
||||
var can_activate: bool = true
|
||||
var cooldown_timer: Timer
|
||||
var effect_timer: Timer
|
||||
var is_active: bool = false
|
||||
|
||||
func _ready():
|
||||
cooldown_timer = Timer.new()
|
||||
add_child(cooldown_timer)
|
||||
cooldown_timer.one_shot = true
|
||||
cooldown_timer.connect("timeout", _on_cooldown_timeout)
|
||||
|
||||
effect_timer = Timer.new()
|
||||
add_child(effect_timer)
|
||||
effect_timer.one_shot = true
|
||||
effect_timer.connect("timeout", _on_effect_timeout)
|
||||
|
||||
func activate():
|
||||
if !can_activate:
|
||||
return
|
||||
|
||||
# Apply ability effects
|
||||
_start_ability()
|
||||
|
||||
# Apply modifiers to the ability
|
||||
for modifier in modifiers:
|
||||
modifier.modify_ability(self)
|
||||
|
||||
is_active = true
|
||||
can_activate = false
|
||||
effect_timer.start(effect_duration)
|
||||
|
||||
func add_modifier(modifier: Modifier):
|
||||
modifiers.append(modifier)
|
||||
modifier.on_equip(self)
|
||||
|
||||
func remove_modifier(modifier_id: String):
|
||||
for i in range(modifiers.size()):
|
||||
if modifiers[i].id == modifier_id:
|
||||
modifiers[i].on_unequip(self)
|
||||
modifiers.remove_at(i)
|
||||
break
|
||||
|
||||
# Override in child classes
|
||||
func _start_ability():
|
||||
pass
|
||||
|
||||
# Override in child classes
|
||||
func _end_ability():
|
||||
pass
|
||||
|
||||
func _on_effect_timeout():
|
||||
is_active = false
|
||||
_end_ability()
|
||||
cooldown_timer.start(cooldown)
|
||||
|
||||
func _on_cooldown_timeout():
|
||||
can_activate = true
|
||||
1
player/abilities/ability.gd.uid
Normal file
1
player/abilities/ability.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://hhd27rd8ii8j
|
||||
23
player/abilities/ice_field.gd
Normal file
23
player/abilities/ice_field.gd
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
class_name IceFieldAbility extends Ability
|
||||
|
||||
@export var field_radius: float = 150.0
|
||||
@export var damage_per_second: float = 5.0
|
||||
@export var slow_amount: float = 0.5
|
||||
|
||||
var field_instance: Node2D
|
||||
|
||||
func _init():
|
||||
cooldown = 10.0
|
||||
effect_duration = 6.0
|
||||
|
||||
func _start_ability():
|
||||
field_instance = preload("scenes/ice_field.tscn").instantiate()
|
||||
field_instance.global_position = global_position
|
||||
field_instance.radius = field_radius
|
||||
field_instance.damage = damage_per_second
|
||||
field_instance.slow = slow_amount
|
||||
get_tree().root.add_child(field_instance)
|
||||
|
||||
func _end_ability():
|
||||
if is_instance_valid(field_instance):
|
||||
field_instance.queue_free()
|
||||
1
player/abilities/ice_field.gd.uid
Normal file
1
player/abilities/ice_field.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://cs28213tcth26
|
||||
8
player/abilities/scenes/ice_field.tscn
Normal file
8
player/abilities/scenes/ice_field.tscn
Normal file
|
|
@ -0,0 +1,8 @@
|
|||
[gd_scene load_steps=2 format=3 uid="uid://btymtl71y0hx7"]
|
||||
|
||||
[sub_resource type="ImageTexture" id="ImageTexture_6kos1"]
|
||||
|
||||
[node name="IceField" type="Node2D"]
|
||||
|
||||
[node name="Sprite2D" type="Sprite2D" parent="."]
|
||||
texture = SubResource("ImageTexture_6kos1")
|
||||
13
player/modifiers/fire_rate_additive.gd
Normal file
13
player/modifiers/fire_rate_additive.gd
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
class_name FireRateAdditive extends Modifier
|
||||
|
||||
@export var fire_rate_bonus: float = 1.0 # +1 shot per second
|
||||
|
||||
func _init():
|
||||
id = "fire_rate_additive"
|
||||
display_name = "Rapid Fire"
|
||||
description = "Increases fire rate by %0.1f shots per second" % fire_rate_bonus
|
||||
modifier_type = ModifierType.ADDITIVE
|
||||
|
||||
func apply_stats_modification(final_stats: Dictionary, base_stats: Dictionary) -> void:
|
||||
if final_stats.has("fire_rate"):
|
||||
final_stats.fire_rate += fire_rate_bonus
|
||||
1
player/modifiers/fire_rate_additive.gd.uid
Normal file
1
player/modifiers/fire_rate_additive.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://cqamoc42g8sam
|
||||
13
player/modifiers/fire_rate_multiplicative.gd
Normal file
13
player/modifiers/fire_rate_multiplicative.gd
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
class_name FireRateMultiplicative extends Modifier
|
||||
|
||||
@export var fire_rate_multiplier: float = 1.2 # 20% faster firing
|
||||
|
||||
func _init():
|
||||
id = "fire_rate_multiplicative"
|
||||
display_name = "Frenzy"
|
||||
description = "Increases fire rate by %d%%" % ((fire_rate_multiplier - 1.0) * 100)
|
||||
modifier_type = ModifierType.MULTIPLICATIVE
|
||||
|
||||
func apply_stats_modification(final_stats: Dictionary, base_stats: Dictionary) -> void:
|
||||
if final_stats.has("fire_rate"):
|
||||
final_stats.fire_rate *= fire_rate_multiplier
|
||||
1
player/modifiers/fire_rate_multiplicative.gd.uid
Normal file
1
player/modifiers/fire_rate_multiplicative.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://bbqp2rhogkicu
|
||||
31
player/modifiers/modifier.gd
Normal file
31
player/modifiers/modifier.gd
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
class_name Modifier extends Resource
|
||||
|
||||
enum ModifierType {
|
||||
ADDITIVE, # Simply adds values (e.g., +5 damage)
|
||||
MULTIPLICATIVE, # Multiplies by a percentage (e.g., 20% more damage)
|
||||
OVERRIDE, # Completely replaces the value
|
||||
CONDITIONAL # Applies under certain conditions
|
||||
}
|
||||
|
||||
@export var id: String
|
||||
@export var display_name: String
|
||||
@export var description: String
|
||||
@export var icon: Texture
|
||||
@export var rarity: int
|
||||
@export var modifier_type: ModifierType = ModifierType.ADDITIVE
|
||||
@export var priority: int = 0 # Higher priority modifiers apply first
|
||||
|
||||
# Called when the modifier is added to a weapon or ability
|
||||
func on_equip(_owner) -> void:
|
||||
pass
|
||||
|
||||
# Called when the modifier is removed
|
||||
func on_unequip(_owner) -> void:
|
||||
pass
|
||||
|
||||
# Override in child classes for specific modification logic
|
||||
func modify_projectile(_projectile) -> void:
|
||||
pass
|
||||
|
||||
func modify_ability(_ability) -> void:
|
||||
pass
|
||||
1
player/modifiers/modifier.gd.uid
Normal file
1
player/modifiers/modifier.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://c2vpdeqk0vvrg
|
||||
18
player/modifiers/piercing.gd
Normal file
18
player/modifiers/piercing.gd
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
class_name PiercingModifier extends Modifier
|
||||
|
||||
@export var pierce_count: int = 2
|
||||
|
||||
func _init():
|
||||
id = "piercing"
|
||||
display_name = "Piercing Shot"
|
||||
description = "Projectiles pass through %d enemies" % pierce_count
|
||||
|
||||
func modify_projectile(projectile):
|
||||
projectile.pierce_count = pierce_count
|
||||
projectile.connect("on_hit", _on_projectile_hit)
|
||||
|
||||
func _on_projectile_hit(projectile, _target):
|
||||
projectile.pierce_count -= 1
|
||||
if projectile.pierce_count <= 0:
|
||||
projectile.pierce_count = 0
|
||||
projectile.set_piercing(false)
|
||||
1
player/modifiers/piercing.gd.uid
Normal file
1
player/modifiers/piercing.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://b60nonvh7ml2o
|
||||
25
player/modifiers/projectile_size_additive.gd
Normal file
25
player/modifiers/projectile_size_additive.gd
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
class_name ProjectileSizeAdditive extends Modifier
|
||||
|
||||
@export var size_increase: float = 0.5 # +50% bigger
|
||||
|
||||
func _init():
|
||||
id = "size_additive"
|
||||
display_name = "Enlarged Projectiles"
|
||||
description = "Increases projectile size by %d%%" % (size_increase * 100)
|
||||
modifier_type = ModifierType.ADDITIVE
|
||||
|
||||
func apply_stats_modification(final_stats: Dictionary, base_stats: Dictionary) -> void:
|
||||
if final_stats.has("projectile_size"):
|
||||
final_stats.projectile_size += size_increase
|
||||
|
||||
func modify_projectile(projectile) -> void:
|
||||
# This will be called when the projectile is created
|
||||
# Scale is often handled in the recalculate_stats method, but we can also add visual effects here
|
||||
projectile.connect("on_spawned", _on_projectile_spawned)
|
||||
|
||||
func _on_projectile_spawned(projectile):
|
||||
# Add a trail effect for larger projectiles
|
||||
if projectile.scale.x > 1.2:
|
||||
pass
|
||||
#var trail = preload("res://scenes/projectile_trail.tscn").instantiate()
|
||||
#projectile.add_child(trail)
|
||||
1
player/modifiers/projectile_size_additive.gd.uid
Normal file
1
player/modifiers/projectile_size_additive.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://hsl3es4bcvqf
|
||||
14
player/modifiers/projectile_size_multiplicative.gd
Normal file
14
player/modifiers/projectile_size_multiplicative.gd
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
class_name ProjectileSizeMultiplicative extends Modifier
|
||||
|
||||
@export var size_multiplier: float = 1.5 # 50% bigger
|
||||
|
||||
func _init():
|
||||
id = "size_multiplicative"
|
||||
display_name = "Giant Projectiles"
|
||||
description = "Multiplies projectile size by %0.1fx" % size_multiplier
|
||||
modifier_type = ModifierType.MULTIPLICATIVE
|
||||
priority = 10 # Higher priority than the additive version
|
||||
|
||||
func apply_stats_modification(final_stats: Dictionary, base_stats: Dictionary) -> void:
|
||||
if final_stats.has("projectile_size"):
|
||||
final_stats.projectile_size *= size_multiplier
|
||||
1
player/modifiers/projectile_size_multiplicative.gd.uid
Normal file
1
player/modifiers/projectile_size_multiplicative.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://bvfir8srnaraa
|
||||
558
player/player.tscn
Normal file
558
player/player.tscn
Normal file
|
|
@ -0,0 +1,558 @@
|
|||
[gd_scene load_steps=82 format=3 uid="uid://bo5aw2cad3akl"]
|
||||
|
||||
[ext_resource type="Script" uid="uid://bq038uo4cm6nv" path="res://player/scripts/player.gd" id="1_oul6g"]
|
||||
[ext_resource type="Texture2D" uid="uid://dqgq2c1h6yk3k" path="res://assets/sprites/characters/pink/Pink_Monster_Attack1_4.png" id="2_yllr7"]
|
||||
[ext_resource type="Texture2D" uid="uid://dinwwco5v2km5" path="res://assets/sprites/characters/pink/Pink_Monster_Attack2_6.png" id="3_kb6p2"]
|
||||
[ext_resource type="Texture2D" uid="uid://bx6nst3hqsww0" path="res://assets/sprites/characters/pink/Pink_Monster_Climb_4.png" id="4_wodsf"]
|
||||
[ext_resource type="Texture2D" uid="uid://0muqa26ngic7" path="res://assets/sprites/characters/pink/Pink_Monster_Death_8.png" id="5_32hag"]
|
||||
[ext_resource type="Texture2D" uid="uid://nyfqe1b4k8sx" path="res://assets/sprites/characters/pink/Pink_Monster_Hurt_4.png" id="6_tqiix"]
|
||||
[ext_resource type="Texture2D" uid="uid://b6ihjsu8qhm2x" path="res://assets/sprites/characters/pink/Pink_Monster_Idle_4.png" id="7_e7oew"]
|
||||
[ext_resource type="Texture2D" uid="uid://hnw46ye6vusn" path="res://assets/sprites/characters/pink/Pink_Monster_Jump_8.png" id="8_c35mf"]
|
||||
[ext_resource type="Texture2D" uid="uid://dun0f0rkhaew5" path="res://assets/sprites/characters/pink/Pink_Monster_Push_6.png" id="9_65viv"]
|
||||
[ext_resource type="Texture2D" uid="uid://cx2x6p0dnnm6y" path="res://assets/sprites/characters/pink/Pink_Monster_Run_6.png" id="10_x7c3f"]
|
||||
[ext_resource type="Texture2D" uid="uid://538sc3bsdell" path="res://assets/sprites/characters/pink/Pink_Monster_Throw_4.png" id="11_bjvpn"]
|
||||
[ext_resource type="Texture2D" uid="uid://efnfh4mf0ia2" path="res://assets/sprites/characters/pink/Pink_Monster_Walk_6.png" id="12_s7qer"]
|
||||
[ext_resource type="Texture2D" uid="uid://cyfq0x0h2qeof" path="res://assets/sprites/characters/pink/Pink_Monster_Walk+Attack_6.png" id="13_g4c7l"]
|
||||
|
||||
[sub_resource type="CircleShape2D" id="CircleShape2D_rkbax"]
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_knn7v"]
|
||||
atlas = ExtResource("2_yllr7")
|
||||
region = Rect2(0, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_7pqkx"]
|
||||
atlas = ExtResource("2_yllr7")
|
||||
region = Rect2(32, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_uw77l"]
|
||||
atlas = ExtResource("2_yllr7")
|
||||
region = Rect2(64, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_rptt4"]
|
||||
atlas = ExtResource("2_yllr7")
|
||||
region = Rect2(96, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_r7pn3"]
|
||||
atlas = ExtResource("3_kb6p2")
|
||||
region = Rect2(0, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_b8hi5"]
|
||||
atlas = ExtResource("3_kb6p2")
|
||||
region = Rect2(32, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_2uvqg"]
|
||||
atlas = ExtResource("3_kb6p2")
|
||||
region = Rect2(64, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_1s1yo"]
|
||||
atlas = ExtResource("3_kb6p2")
|
||||
region = Rect2(96, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_5ejfk"]
|
||||
atlas = ExtResource("3_kb6p2")
|
||||
region = Rect2(128, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_jd2rm"]
|
||||
atlas = ExtResource("3_kb6p2")
|
||||
region = Rect2(160, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_q28gw"]
|
||||
atlas = ExtResource("4_wodsf")
|
||||
region = Rect2(0, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_ge24q"]
|
||||
atlas = ExtResource("4_wodsf")
|
||||
region = Rect2(32, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_pnw6m"]
|
||||
atlas = ExtResource("4_wodsf")
|
||||
region = Rect2(64, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_1so5t"]
|
||||
atlas = ExtResource("4_wodsf")
|
||||
region = Rect2(96, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_55jnj"]
|
||||
atlas = ExtResource("5_32hag")
|
||||
region = Rect2(0, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_dx5ib"]
|
||||
atlas = ExtResource("5_32hag")
|
||||
region = Rect2(32, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_a2xo5"]
|
||||
atlas = ExtResource("5_32hag")
|
||||
region = Rect2(64, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_art4l"]
|
||||
atlas = ExtResource("5_32hag")
|
||||
region = Rect2(96, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_fjxoa"]
|
||||
atlas = ExtResource("5_32hag")
|
||||
region = Rect2(128, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_gswnw"]
|
||||
atlas = ExtResource("5_32hag")
|
||||
region = Rect2(160, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_xcnuv"]
|
||||
atlas = ExtResource("5_32hag")
|
||||
region = Rect2(192, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_j55il"]
|
||||
atlas = ExtResource("5_32hag")
|
||||
region = Rect2(224, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_hjies"]
|
||||
atlas = ExtResource("6_tqiix")
|
||||
region = Rect2(0, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_mmwog"]
|
||||
atlas = ExtResource("6_tqiix")
|
||||
region = Rect2(32, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_8pxes"]
|
||||
atlas = ExtResource("6_tqiix")
|
||||
region = Rect2(64, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_fmu53"]
|
||||
atlas = ExtResource("6_tqiix")
|
||||
region = Rect2(96, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_w7j2h"]
|
||||
atlas = ExtResource("7_e7oew")
|
||||
region = Rect2(0, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_n0b8q"]
|
||||
atlas = ExtResource("7_e7oew")
|
||||
region = Rect2(32, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_jfgyi"]
|
||||
atlas = ExtResource("7_e7oew")
|
||||
region = Rect2(64, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_237xx"]
|
||||
atlas = ExtResource("7_e7oew")
|
||||
region = Rect2(96, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_wpyo2"]
|
||||
atlas = ExtResource("8_c35mf")
|
||||
region = Rect2(0, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_7crtr"]
|
||||
atlas = ExtResource("8_c35mf")
|
||||
region = Rect2(32, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_vgvch"]
|
||||
atlas = ExtResource("8_c35mf")
|
||||
region = Rect2(64, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_a1u5o"]
|
||||
atlas = ExtResource("8_c35mf")
|
||||
region = Rect2(96, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_3dxkp"]
|
||||
atlas = ExtResource("8_c35mf")
|
||||
region = Rect2(128, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_6wior"]
|
||||
atlas = ExtResource("8_c35mf")
|
||||
region = Rect2(160, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_p5tca"]
|
||||
atlas = ExtResource("8_c35mf")
|
||||
region = Rect2(192, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_jbx34"]
|
||||
atlas = ExtResource("8_c35mf")
|
||||
region = Rect2(224, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_s3g0c"]
|
||||
atlas = ExtResource("9_65viv")
|
||||
region = Rect2(0, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_35wys"]
|
||||
atlas = ExtResource("9_65viv")
|
||||
region = Rect2(32, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_pjwc4"]
|
||||
atlas = ExtResource("9_65viv")
|
||||
region = Rect2(64, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_or4qq"]
|
||||
atlas = ExtResource("9_65viv")
|
||||
region = Rect2(96, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_hggc2"]
|
||||
atlas = ExtResource("9_65viv")
|
||||
region = Rect2(128, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_b2j0d"]
|
||||
atlas = ExtResource("9_65viv")
|
||||
region = Rect2(160, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_7l6ig"]
|
||||
atlas = ExtResource("10_x7c3f")
|
||||
region = Rect2(0, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_j3r50"]
|
||||
atlas = ExtResource("10_x7c3f")
|
||||
region = Rect2(32, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_utr5e"]
|
||||
atlas = ExtResource("10_x7c3f")
|
||||
region = Rect2(64, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_kewli"]
|
||||
atlas = ExtResource("10_x7c3f")
|
||||
region = Rect2(96, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_do7qw"]
|
||||
atlas = ExtResource("10_x7c3f")
|
||||
region = Rect2(128, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_2h6tc"]
|
||||
atlas = ExtResource("10_x7c3f")
|
||||
region = Rect2(160, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_8rogd"]
|
||||
atlas = ExtResource("11_bjvpn")
|
||||
region = Rect2(0, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_48p26"]
|
||||
atlas = ExtResource("11_bjvpn")
|
||||
region = Rect2(32, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_anp34"]
|
||||
atlas = ExtResource("11_bjvpn")
|
||||
region = Rect2(64, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_jdjat"]
|
||||
atlas = ExtResource("11_bjvpn")
|
||||
region = Rect2(96, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_j420s"]
|
||||
atlas = ExtResource("12_s7qer")
|
||||
region = Rect2(0, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_kcq4v"]
|
||||
atlas = ExtResource("12_s7qer")
|
||||
region = Rect2(32, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_qavcc"]
|
||||
atlas = ExtResource("12_s7qer")
|
||||
region = Rect2(64, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_bd26m"]
|
||||
atlas = ExtResource("12_s7qer")
|
||||
region = Rect2(96, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_lufic"]
|
||||
atlas = ExtResource("12_s7qer")
|
||||
region = Rect2(128, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_nxclr"]
|
||||
atlas = ExtResource("12_s7qer")
|
||||
region = Rect2(160, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_onxu2"]
|
||||
atlas = ExtResource("13_g4c7l")
|
||||
region = Rect2(0, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_gci7n"]
|
||||
atlas = ExtResource("13_g4c7l")
|
||||
region = Rect2(32, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_tcwf7"]
|
||||
atlas = ExtResource("13_g4c7l")
|
||||
region = Rect2(64, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_20bc7"]
|
||||
atlas = ExtResource("13_g4c7l")
|
||||
region = Rect2(96, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_jfgxe"]
|
||||
atlas = ExtResource("13_g4c7l")
|
||||
region = Rect2(128, 0, 32, 32)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_yg0n1"]
|
||||
atlas = ExtResource("13_g4c7l")
|
||||
region = Rect2(160, 0, 32, 32)
|
||||
|
||||
[sub_resource type="SpriteFrames" id="SpriteFrames_qjt2w"]
|
||||
animations = [{
|
||||
"frames": [{
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_knn7v")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_7pqkx")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_uw77l")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_rptt4")
|
||||
}],
|
||||
"loop": true,
|
||||
"name": &"attack_1",
|
||||
"speed": 5.0
|
||||
}, {
|
||||
"frames": [{
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_r7pn3")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_b8hi5")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_2uvqg")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_1s1yo")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_5ejfk")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_jd2rm")
|
||||
}],
|
||||
"loop": true,
|
||||
"name": &"attack_2",
|
||||
"speed": 5.0
|
||||
}, {
|
||||
"frames": [{
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_q28gw")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_ge24q")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_pnw6m")
|
||||
}, {
|
||||
"duration": 1.0,
|
||||
"texture": SubResource("AtlasTexture_1so5t")
|
||||
}],
|
||||
"loop": true,
|
||||
"name": &"climb",
|
||||
"speed": 5.0
|
||||
}, {
|
||||
"frames": [{
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_55jnj")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_dx5ib")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_a2xo5")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_art4l")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_fjxoa")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_gswnw")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_xcnuv")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_j55il")
|
||||
}],
|
||||
"loop": true,
|
||||
"name": &"death",
|
||||
"speed": 5.0
|
||||
}, {
|
||||
"frames": [{
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_hjies")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_mmwog")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_8pxes")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_fmu53")
|
||||
}],
|
||||
"loop": true,
|
||||
"name": &"hurt",
|
||||
"speed": 5.0
|
||||
}, {
|
||||
"frames": [{
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_w7j2h")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_n0b8q")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_jfgyi")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_237xx")
|
||||
}],
|
||||
"loop": true,
|
||||
"name": &"idle",
|
||||
"speed": 5.0
|
||||
}, {
|
||||
"frames": [{
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_wpyo2")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_7crtr")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_vgvch")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_a1u5o")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_3dxkp")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_6wior")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_p5tca")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_jbx34")
|
||||
}],
|
||||
"loop": true,
|
||||
"name": &"jump",
|
||||
"speed": 5.0
|
||||
}, {
|
||||
"frames": [{
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_s3g0c")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_35wys")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_pjwc4")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_or4qq")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_hggc2")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_b2j0d")
|
||||
}],
|
||||
"loop": true,
|
||||
"name": &"push",
|
||||
"speed": 5.0
|
||||
}, {
|
||||
"frames": [{
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_7l6ig")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_j3r50")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_utr5e")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_kewli")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_do7qw")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_2h6tc")
|
||||
}],
|
||||
"loop": true,
|
||||
"name": &"run",
|
||||
"speed": 5.0
|
||||
}, {
|
||||
"frames": [{
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_8rogd")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_48p26")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_anp34")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_jdjat")
|
||||
}],
|
||||
"loop": true,
|
||||
"name": &"throw",
|
||||
"speed": 5.0
|
||||
}, {
|
||||
"frames": [{
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_j420s")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_kcq4v")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_qavcc")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_bd26m")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_lufic")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_nxclr")
|
||||
}],
|
||||
"loop": true,
|
||||
"name": &"walk",
|
||||
"speed": 5.0
|
||||
}, {
|
||||
"frames": [{
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_onxu2")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_gci7n")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_tcwf7")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_20bc7")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_jfgxe")
|
||||
}, {
|
||||
"duration": 0.5,
|
||||
"texture": SubResource("AtlasTexture_yg0n1")
|
||||
}],
|
||||
"loop": true,
|
||||
"name": &"walk_attack",
|
||||
"speed": 5.0
|
||||
}]
|
||||
|
||||
[node name="Player" type="CharacterBody2D"]
|
||||
collision_mask = 14
|
||||
script = ExtResource("1_oul6g")
|
||||
|
||||
[node name="PlayerCollision" type="CollisionShape2D" parent="."]
|
||||
position = Vector2(0, 7)
|
||||
shape = SubResource("CircleShape2D_rkbax")
|
||||
|
||||
[node name="PlayerSprite" type="AnimatedSprite2D" parent="."]
|
||||
sprite_frames = SubResource("SpriteFrames_qjt2w")
|
||||
animation = &"attack_2"
|
||||
frame_progress = 0.752485
|
||||
|
||||
[node name="Camera2D" type="Camera2D" parent="."]
|
||||
zoom = Vector2(2, 2)
|
||||
84
player/scripts/modifier_management.gd
Normal file
84
player/scripts/modifier_management.gd
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
class_name ModifierManager extends Node
|
||||
|
||||
signal modifier_added(modifier)
|
||||
signal modifier_removed(modifier)
|
||||
signal stats_updated()
|
||||
|
||||
# Stores all active modifiers
|
||||
var modifiers: Array[Modifier] = []
|
||||
|
||||
# Base stats (before modifiers)
|
||||
var base_stats: Dictionary = {}
|
||||
|
||||
# Final calculated stats
|
||||
var final_stats: Dictionary = {}
|
||||
|
||||
func _init(initial_base_stats: Dictionary = {}):
|
||||
base_stats = initial_base_stats.duplicate()
|
||||
final_stats = initial_base_stats.duplicate()
|
||||
|
||||
func add_modifier(modifier: Modifier) -> void:
|
||||
modifiers.append(modifier)
|
||||
modifier.on_equip(get_parent())
|
||||
emit_signal("modifier_added", modifier)
|
||||
recalculate_stats()
|
||||
|
||||
func remove_modifier(modifier_id: String) -> void:
|
||||
for i in range(modifiers.size()):
|
||||
if modifiers[i].id == modifier_id:
|
||||
var modifier = modifiers[i]
|
||||
modifier.on_unequip(get_parent())
|
||||
modifiers.remove_at(i)
|
||||
emit_signal("modifier_removed", modifier)
|
||||
recalculate_stats()
|
||||
break
|
||||
|
||||
func recalculate_stats() -> void:
|
||||
# Reset stats to base values
|
||||
final_stats = base_stats.duplicate()
|
||||
|
||||
# Sort modifiers by priority
|
||||
modifiers.sort_custom(func(a, b): return a.priority > b.priority)
|
||||
|
||||
# First pass: Apply OVERRIDE modifiers (highest priority first)
|
||||
for modifier in modifiers:
|
||||
if modifier.modifier_type == Modifier.ModifierType.OVERRIDE:
|
||||
_apply_modifier_stats(modifier)
|
||||
|
||||
# Second pass: Apply ADDITIVE modifiers
|
||||
for modifier in modifiers:
|
||||
if modifier.modifier_type == Modifier.ModifierType.ADDITIVE:
|
||||
_apply_modifier_stats(modifier)
|
||||
|
||||
# Third pass: Apply MULTIPLICATIVE modifiers
|
||||
for modifier in modifiers:
|
||||
if modifier.modifier_type == Modifier.ModifierType.MULTIPLICATIVE:
|
||||
_apply_modifier_stats(modifier)
|
||||
|
||||
# Last pass: Apply CONDITIONAL modifiers
|
||||
for modifier in modifiers:
|
||||
if modifier.modifier_type == Modifier.ModifierType.CONDITIONAL:
|
||||
_apply_modifier_stats(modifier)
|
||||
|
||||
# Apply caps and floors to stats
|
||||
_apply_stat_limits()
|
||||
|
||||
emit_signal("stats_updated")
|
||||
|
||||
func _apply_modifier_stats(modifier: Modifier) -> void:
|
||||
if modifier.has_method("apply_stats_modification"):
|
||||
modifier.apply_stats_modification(final_stats, base_stats)
|
||||
|
||||
func _apply_stat_limits() -> void:
|
||||
# Example: Cap fire rate
|
||||
if final_stats.has("fire_rate"):
|
||||
final_stats.fire_rate = min(final_stats.fire_rate, 20.0) # Max 20 shots per second
|
||||
final_stats.fire_rate = max(final_stats.fire_rate, 0.5) # Min 0.5 shots per second
|
||||
|
||||
# Example: Cap projectile size
|
||||
if final_stats.has("projectile_size"):
|
||||
final_stats.projectile_size = min(final_stats.projectile_size, 5.0) # Max 5x normal size
|
||||
final_stats.projectile_size = max(final_stats.projectile_size, 0.2) # Min 0.2x normal size
|
||||
|
||||
func get_stat(stat_name: String, default_value = 0):
|
||||
return final_stats.get(stat_name, default_value)
|
||||
1
player/scripts/modifier_management.gd.uid
Normal file
1
player/scripts/modifier_management.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://cvklefr50qhfb
|
||||
1
player/scripts/movement.gd.uid
Normal file
1
player/scripts/movement.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://bw6kcdfiq3ugv
|
||||
47
player/scripts/player.gd
Normal file
47
player/scripts/player.gd
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
extends CharacterBody2D
|
||||
|
||||
@export var speed = 200
|
||||
@export var weapon: RangedWeapon
|
||||
@export var special_ability: Ability
|
||||
@export var movement: PlayerMovement
|
||||
|
||||
# Last direction for idle state
|
||||
var last_direction = Vector2.DOWN
|
||||
|
||||
@onready var animated_sprite = $PlayerSprite
|
||||
|
||||
func _ready():
|
||||
weapon = RangedWeapon.new()
|
||||
Log.pr("Weapon", weapon)
|
||||
|
||||
# Initialize the movement resource with references
|
||||
if movement:
|
||||
movement.player = self
|
||||
movement.animated_sprite = animated_sprite
|
||||
movement.last_direction = Vector2.DOWN # Default direction
|
||||
else:
|
||||
# Create a new resource instance if none was assigned in the editor
|
||||
movement = PlayerMovement.new()
|
||||
movement.player = self
|
||||
movement.animated_sprite = animated_sprite
|
||||
|
||||
Log.pr("Adding projectile size additive modifier")
|
||||
weapon.add_modifier(ProjectileSizeAdditive.new())
|
||||
Log.pr(weapon.stats.get_stat("projectile_size")) # Size is now 1.0 + 0.5 = 1.5
|
||||
# Size is now 1.0 + 0.5 = 1.5
|
||||
|
||||
# Add the multiplicative size modifier (1.5x multiplier)
|
||||
Log.pr("Adding projectile size multiplicative modifier")
|
||||
weapon.add_modifier(ProjectileSizeMultiplicative.new())
|
||||
Log.pr(weapon.stats.get_stat("projectile_size"))
|
||||
# Size is now 1.5 * 1.5 = 2.25
|
||||
|
||||
# Add another additive size modifier (+0.7 or 70% increase)
|
||||
Log.pr("Adding another projectile size additive modifier", 0.7)
|
||||
var another_size_mod = ProjectileSizeAdditive.new()
|
||||
another_size_mod.size_increase = 0.7
|
||||
weapon.add_modifier(another_size_mod)
|
||||
Log.pr(weapon.stats.get_stat("projectile_size"))
|
||||
|
||||
func _physics_process(delta):
|
||||
movement.process(delta)
|
||||
1
player/scripts/player.gd.uid
Normal file
1
player/scripts/player.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://bq038uo4cm6nv
|
||||
48
player/scripts/player_movement.gd
Normal file
48
player/scripts/player_movement.gd
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
# PlayerMovement.gd
|
||||
extends Resource
|
||||
class_name PlayerMovement
|
||||
|
||||
var player: CharacterBody2D
|
||||
var animated_sprite: AnimatedSprite2D
|
||||
var speed: float = 300.0
|
||||
var last_direction: Vector2 = Vector2.ZERO
|
||||
|
||||
func process(_delta):
|
||||
# Get input direction
|
||||
var direction = Vector2.ZERO
|
||||
|
||||
if Input.is_action_pressed("move_right"):
|
||||
direction.x += 1
|
||||
if Input.is_action_pressed("move_left"):
|
||||
direction.x -= 1
|
||||
if Input.is_action_pressed("move_down"):
|
||||
direction.y += 1
|
||||
if Input.is_action_pressed("move_up"):
|
||||
direction.y -= 1
|
||||
|
||||
# Normalize the direction
|
||||
if direction.length() > 0:
|
||||
direction = direction.normalized()
|
||||
last_direction = direction
|
||||
|
||||
# Set velocity
|
||||
player.velocity = direction * speed
|
||||
|
||||
# Move the character
|
||||
player.move_and_slide()
|
||||
|
||||
# Update animation
|
||||
update_animation(direction)
|
||||
|
||||
func update_animation(direction):
|
||||
var anim_name = "idle" # Default animation
|
||||
|
||||
if direction == Vector2.ZERO:
|
||||
# Character is idle
|
||||
anim_name = "idle"
|
||||
else:
|
||||
# Character is moving
|
||||
anim_name = "walk"
|
||||
|
||||
if animated_sprite.animation != anim_name:
|
||||
animated_sprite.play(anim_name)
|
||||
1
player/scripts/player_movement.gd.uid
Normal file
1
player/scripts/player_movement.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://b3wtxr3udscoa
|
||||
85
player/weapons/ranged_weapon.gd
Normal file
85
player/weapons/ranged_weapon.gd
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
class_name RangedWeapon extends Node2D
|
||||
|
||||
signal projectile_spawned(projectile)
|
||||
|
||||
@export var projectile_scene: PackedScene
|
||||
|
||||
# Base stats - will be modified by modifiers
|
||||
var base_stats = {
|
||||
"damage": 10.0,
|
||||
"fire_rate": 2.0, # Shots per second
|
||||
"projectile_speed": 500.0,
|
||||
"projectile_size": 1.0,
|
||||
"projectile_lifetime": 5.0,
|
||||
"max_pierce": 0
|
||||
}
|
||||
|
||||
# Components
|
||||
var stats: ModifierManager
|
||||
var can_fire: bool = true
|
||||
var fire_timer: Timer
|
||||
|
||||
func _init() -> void:
|
||||
stats = ModifierManager.new(base_stats)
|
||||
Log.pr(stats)
|
||||
add_child(stats)
|
||||
|
||||
func _ready():
|
||||
# Connect to stats updated signal
|
||||
stats.connect("stats_updated", _on_stats_updated)
|
||||
|
||||
# Setup fire timer
|
||||
fire_timer = Timer.new()
|
||||
add_child(fire_timer)
|
||||
fire_timer.one_shot = true
|
||||
fire_timer.connect("timeout", _on_fire_timer_timeout)
|
||||
|
||||
# Initial update
|
||||
_on_stats_updated()
|
||||
|
||||
func fire(direction: Vector2):
|
||||
if !can_fire:
|
||||
return
|
||||
|
||||
_spawn_projectile(global_position, direction)
|
||||
|
||||
can_fire = false
|
||||
fire_timer.start(1.0 / stats.get_stat("fire_rate"))
|
||||
|
||||
func _spawn_projectile(spawn_position: Vector2, spawn_direction: Vector2):
|
||||
var projectile = projectile_scene.instantiate()
|
||||
projectile.global_position = spawn_position
|
||||
projectile.direction = spawn_direction
|
||||
|
||||
# Apply stats to projectile
|
||||
projectile.speed = stats.get_stat("projectile_speed")
|
||||
projectile.damage = stats.get_stat("damage")
|
||||
projectile.lifetime = stats.get_stat("projectile_lifetime")
|
||||
projectile.pierce_count = stats.get_stat("max_pierce")
|
||||
projectile.source_weapon = self
|
||||
|
||||
# Apply size (scale)
|
||||
var size = stats.get_stat("projectile_size")
|
||||
projectile.scale = Vector2(size, size)
|
||||
|
||||
# Allow modifiers to directly modify the projectile
|
||||
for modifier in stats.modifiers:
|
||||
modifier.modify_projectile(projectile)
|
||||
|
||||
get_tree().root.add_child(projectile)
|
||||
projectile.emit_signal("on_spawned", projectile)
|
||||
emit_signal("projectile_spawned", projectile)
|
||||
|
||||
func add_modifier(modifier: Modifier):
|
||||
stats.add_modifier(modifier)
|
||||
|
||||
func remove_modifier(modifier_id: String):
|
||||
stats.remove_modifier(modifier_id)
|
||||
|
||||
func _on_stats_updated():
|
||||
# Update any visual components based on new stats
|
||||
# For example, if weapon appearance changes based on damage/fire rate
|
||||
pass
|
||||
|
||||
func _on_fire_timer_timeout():
|
||||
can_fire = true
|
||||
1
player/weapons/ranged_weapon.gd.uid
Normal file
1
player/weapons/ranged_weapon.gd.uid
Normal file
|
|
@ -0,0 +1 @@
|
|||
uid://dcenqdci4hjes
|
||||
Loading…
Add table
Add a link
Reference in a new issue