diff --git a/scenes/attacks/attack_sword.gd b/scenes/attacks/attack_sword.gd index 5da22be..31bf7e9 100644 --- a/scenes/attacks/attack_sword.gd +++ b/scenes/attacks/attack_sword.gd @@ -1,7 +1,7 @@ extends Node2D @export var default_attack_time: float = 0.5 -@export var default_damage: float = 5.0 +@export var player: Player = null @onready var trigger_area: Area2D = $TriggerArea @onready var trigger_collision: CollisionShape2D = $TriggerArea/TriggerCollision @@ -10,7 +10,7 @@ extends Node2D @onready var path_follow_2d: PathFollow2D = $AttackPath/PathFollow2D @onready var attack_area: Area2D = $AttackPath/PathFollow2D/Sprite2D/AttackArea -var damage: float +var base_damage: float = 5.0 var current_target: Node2D = null var current_progress: float = 0.0 var damaged_this_attack: Array = [] @@ -19,7 +19,6 @@ var is_attacking: bool = false func _ready() -> void: attack_path.visible = false - damage = default_damage func _process(delta: float) -> void: @@ -93,5 +92,11 @@ func _on_attack_area_body_entered(body: Node2D) -> void: if body in damaged_this_attack: return if body.is_in_group(GlobalConst.GROUP_ENEMY) and body.is_in_group(GlobalConst.GROUP_DAMAGEABLE): - body.take_damage(damage) + 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) diff --git a/scenes/damage_numbers.tscn b/scenes/damage_numbers.tscn index 1f40a68..cae14c3 100644 --- a/scenes/damage_numbers.tscn +++ b/scenes/damage_numbers.tscn @@ -2,21 +2,6 @@ [ext_resource type="Script" uid="uid://dri8n7vfnarub" path="res://scenes/damage_numbers.gd" id="1_bhj6t"] -[sub_resource type="Animation" id="Animation_ngvhj"] -resource_name = "normal_damage" -tracks/0/type = "value" -tracks/0/imported = false -tracks/0/enabled = true -tracks/0/path = NodePath("Control/Label:position") -tracks/0/interp = 1 -tracks/0/loop_wrap = true -tracks/0/keys = { -"times": PackedFloat32Array(0, 1), -"transitions": PackedFloat32Array(0.148651, 0.148651), -"update": 0, -"values": [Vector2(-9.5, -11.5), Vector2(-9, -82)] -} - [sub_resource type="Animation" id="Animation_bhj6t"] length = 0.001 tracks/0/type = "value" @@ -32,6 +17,21 @@ tracks/0/keys = { "values": [Vector2(0, -248)] } +[sub_resource type="Animation" id="Animation_ngvhj"] +resource_name = "normal_damage" +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Control/Label:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 1), +"transitions": PackedFloat32Array(0.148651, 0.148651), +"update": 0, +"values": [Vector2(-9.5, -11.5), Vector2(-9, -82)] +} + [sub_resource type="AnimationLibrary" id="AnimationLibrary_0otjp"] _data = { &"RESET": SubResource("Animation_bhj6t"), diff --git a/scenes/enemies/enemy.gd b/scenes/enemies/enemy.gd index 80cc49c..e9bede9 100644 --- a/scenes/enemies/enemy.gd +++ b/scenes/enemies/enemy.gd @@ -34,12 +34,13 @@ func _physics_process(delta: float) -> void: deal_damage() -func take_damage(value: float): +func take_damage(value: float, is_crit: bool = false): if god_mode: return health -= value var dm = preload("res://scenes/damage_numbers.tscn").instantiate() dm.damage_taken = value + dm.critical_damage = is_crit add_child(dm) if health <= 0: die() diff --git a/scenes/enemies/enemy.tscn b/scenes/enemies/enemy.tscn index f9a1cba..29354e6 100644 --- a/scenes/enemies/enemy.tscn +++ b/scenes/enemies/enemy.tscn @@ -45,23 +45,6 @@ tracks/2/keys = { "values": [Color(1, 1, 1, 1)] } -[sub_resource type="Animation" id="Animation_8e3ao"] -resource_name = "jump" -length = 0.7 -loop_mode = 1 -tracks/0/type = "value" -tracks/0/imported = false -tracks/0/enabled = true -tracks/0/path = NodePath("Sprite2D:position") -tracks/0/interp = 1 -tracks/0/loop_wrap = true -tracks/0/keys = { -"times": PackedFloat32Array(0, 0.3), -"transitions": PackedFloat32Array(1, 1), -"update": 0, -"values": [Vector2(0, 0), Vector2(0, -7)] -} - [sub_resource type="Animation" id="Animation_fcftc"] resource_name = "die" length = 2.0 @@ -90,6 +73,23 @@ tracks/1/keys = { "values": [Color(1, 1, 1, 1), Color(1, 1, 1, 1), Color(1, 1, 1, 0)] } +[sub_resource type="Animation" id="Animation_8e3ao"] +resource_name = "jump" +length = 0.7 +loop_mode = 1 +tracks/0/type = "value" +tracks/0/imported = false +tracks/0/enabled = true +tracks/0/path = NodePath("Sprite2D:position") +tracks/0/interp = 1 +tracks/0/loop_wrap = true +tracks/0/keys = { +"times": PackedFloat32Array(0, 0.3), +"transitions": PackedFloat32Array(1, 1), +"update": 0, +"values": [Vector2(0, 0), Vector2(0, -7)] +} + [sub_resource type="AnimationLibrary" id="AnimationLibrary_38ino"] _data = { &"RESET": SubResource("Animation_38ino"), diff --git a/scenes/player.gd b/scenes/player.gd index 0dce040..8fa53ca 100644 --- a/scenes/player.gd +++ b/scenes/player.gd @@ -1,15 +1,13 @@ +class_name Player extends CharacterBody2D @export var camera: Camera2D @export var main_ui: MainUI -@export var default_movement_speed: float = 200.0 -@export var default_max_health: float = 50.0 @onready var sprite_2d: Sprite2D = $Sprite2D -var movement_speed: float -var max_health: float -var health: float +var player_stats: PlayerStats = PlayerStats.new() +var modifiers: Array[PlayerStatsModifier] = [] var dead: bool = false var death_anim_done: bool = false var god_mode: bool = false @@ -17,9 +15,6 @@ var god_mode: bool = false func _ready() -> void: camera.position = global_position - movement_speed = default_movement_speed - max_health = default_max_health - health = max_health main_ui.player_ui.set_hp(100) GlobalConst.sig_debug_god_mode.connect(toggle_god_mode) @@ -28,7 +23,8 @@ func _physics_process(delta: float) -> void: if dead: return var input_direction = Input.get_vector("left", "right", "up", "down") - velocity = input_direction * movement_speed + var move_speed = player_stats.get_final("move_speed", modifiers) + velocity = input_direction * move_speed move_and_slide() @@ -42,14 +38,13 @@ func _process(delta: float) -> void: func take_damage(value: float) -> void: if dead or god_mode: return - health -= value - print_debug("player took damage. now has %s hp" % health) + player_stats.current_health -= value var dm = preload("res://scenes/damage_numbers.tscn").instantiate() dm.damage_taken = value dm.player_damage = false add_child(dm) - main_ui.player_ui.set_hp(health / max_health * 100) - if health <= 0: + main_ui.player_ui.set_hp((player_stats.current_health / player_stats.get_final("max_health", modifiers)) * 100) + if player_stats.current_health <= 0: die() diff --git a/scenes/player.tscn b/scenes/player.tscn index 507568f..5a068ef 100644 --- a/scenes/player.tscn +++ b/scenes/player.tscn @@ -19,4 +19,5 @@ region_rect = Rect2(0, 104, 16, 14) [node name="CollisionShape2D" type="CollisionShape2D" parent="."] shape = SubResource("CircleShape2D_3vyb7") -[node name="AttackSword" parent="." instance=ExtResource("3_qhqgy")] +[node name="AttackSword" parent="." node_paths=PackedStringArray("player") instance=ExtResource("3_qhqgy")] +player = NodePath("..") diff --git a/scenes/player_stats.gd b/scenes/player_stats.gd new file mode 100644 index 0000000..5f8cba8 --- /dev/null +++ b/scenes/player_stats.gd @@ -0,0 +1,28 @@ +class_name PlayerStats +extends Resource + +var max_health: float = 50.0 +var current_health: float = 50.0 +var current_xp: float = 0.0 +var current_level: int = 1 +var crit_chance: float = 0.05 +var crit_multiplier: float = 2.0 +var move_speed: float = 200.0 +var attack_damage: float = 1.0 + +func get_final(stat: String, modifiers: Array[PlayerStatsModifier]) -> Variant: + var base_value = get(stat) + var add = 0.0 + var mul = 1.0 + for mod in modifiers: + if mod.stat_name == stat: + if mod.type == PlayerStatsModifier.ModifierType.ADDITIVE: + add += mod.value + if mod.type == PlayerStatsModifier.ModifierType.ADDITIVE: + mul *= mod.value + if mod.type == PlayerStatsModifier.ModifierType.ABSOLUTE: + return mod.value + return (base_value + add) * mul + +func xp_required_for_level() -> float: + return 100 * (100*(1.5**(current_level-1))) diff --git a/scenes/player_stats.gd.uid b/scenes/player_stats.gd.uid new file mode 100644 index 0000000..7a8469a --- /dev/null +++ b/scenes/player_stats.gd.uid @@ -0,0 +1 @@ +uid://bcr7dywiutax7 diff --git a/scenes/player_stats_modifier.gd b/scenes/player_stats_modifier.gd new file mode 100644 index 0000000..4f419df --- /dev/null +++ b/scenes/player_stats_modifier.gd @@ -0,0 +1,8 @@ +class_name PlayerStatsModifier +extends Resource + +enum ModifierType { ADDITIVE, MULTIPLICATIVE, ABSOLUTE } + +var stat_name: String +var value: Variant +var type: ModifierType = ModifierType.ADDITIVE diff --git a/scenes/player_stats_modifier.gd.uid b/scenes/player_stats_modifier.gd.uid new file mode 100644 index 0000000..2ddd456 --- /dev/null +++ b/scenes/player_stats_modifier.gd.uid @@ -0,0 +1 @@ +uid://d3nkb530haufx