diff --git a/items/consumables/bow/bow.gd b/items/consumables/bow/bow.gd index 5df10a8..60948ee 100644 --- a/items/consumables/bow/bow.gd +++ b/items/consumables/bow/bow.gd @@ -1,18 +1,21 @@ extends ActiveItem @export var cooldown = 0.3 @export var arrow_scene : PackedScene - + func actually_collect(): player.set_cooldown(cooldown) - func activate(): player.activate_cooldown() + + # Spawn an arrow on activation var arrow : Area2D = arrow_scene.instantiate() get_tree().get_root().add_child(arrow) arrow.position = player.position arrow.rotation = player.rotation arrow.direction = player.earth_aligner.global_from_local(Vector2(player.facing, 0)) + + # Make sure the arrow sprite faces the right direction if(player.facing == -1): arrow.get_node("Sprite2D").scale.x = - arrow.get_node("Sprite2D").scale.x $SoundBowRelease.play() diff --git a/items/consumables/heal_item/heal_item.gd b/items/consumables/heal_item/heal_item.gd index c7eee45..d4d63cf 100644 --- a/items/consumables/heal_item/heal_item.gd +++ b/items/consumables/heal_item/heal_item.gd @@ -3,6 +3,6 @@ extends Item func collect() -> bool: if(player.current_hp < player.max_hp): - player.current_hp = min(player.max_hp, player.current_hp + heal_amount) + player.current_hp += heal_amount return true return false diff --git a/items/consumables/horizontal_dash/horizontal_dash.gd b/items/consumables/horizontal_dash/horizontal_dash.gd index 134f3c4..dd314ce 100644 --- a/items/consumables/horizontal_dash/horizontal_dash.gd +++ b/items/consumables/horizontal_dash/horizontal_dash.gd @@ -6,22 +6,26 @@ var dash_dir func _process(delta: float) -> void: super(delta) + # While the dash is active, move the player in the + # (absolute!) direction fixed at the start of the dash if dash_timer != null and dash_timer.time_left > 0: player.reset_to_velocity = player.earth_aligner.local_from_global(dash_dir) - func actually_collect(): player.set_cooldown(cooldown) func activate(): $DashSound.play() player.activate_cooldown() - player.air_jumps_current = min(player.air_jumps_current + 1, player.air_jumps_max) + # The dash refills one air jump if possible and provides iframes. + player.air_jumps_current += 1 dash_timer = get_tree().create_timer(dash_time) dash_dir = player.earth_aligner.global_from_local(Vector2.RIGHT * player.facing * 1600) player.inv_time = max(player.inv_time, dash_time) func remove(reset_player_active = true): + # If the item is removed during the dash, clear the active item slot, + # but only remove the item from the scene afterwards. if(dash_timer != null): if reset_player_active: player.active_item = null diff --git a/items/consumables/updash/updash.gd b/items/consumables/updash/updash.gd index d250d3c..52c4c61 100644 --- a/items/consumables/updash/updash.gd +++ b/items/consumables/updash/updash.gd @@ -8,12 +8,15 @@ func actually_collect(): func activate(): $UpdashSound.play() player.activate_cooldown() + # Drop the player for a moment, then boost upwards. player.reset_to_velocity = Vector2(0,1) timer = get_tree().create_timer(0.1) await timer.timeout player.reset_to_velocity = Vector2(0, -2400) func remove(reset_player_active = true): + # If the item is removed during the dash startup, clear the active item slot, + # but only remove the item from the scene afterwards. if reset_player_active: player.active_item = null if timer != null and timer.time_left > 0: diff --git a/items/generic/active_item.gd b/items/generic/active_item.gd index 93af34e..3b14c80 100644 --- a/items/generic/active_item.gd +++ b/items/generic/active_item.gd @@ -7,22 +7,28 @@ class_name ActiveItem extends Item @export var uses = 1: set(new_uses): uses = new_uses - if active_item_uses != null: - while active_item_uses.get_children().size() > uses: - active_item_uses.remove_child(active_item_uses.get_child(0)) - if uses_left_icon != null: - while active_item_uses.get_children().size() < uses: - active_item_uses.add_child(uses_left_icon.instantiate()) + refresh_uses_ui() +func refresh_uses_ui(): + # Set the amount and type of child nodes active_item_uses has according to num_uses. + if active_item_uses != null: + while active_item_uses.get_children().size() > uses: + active_item_uses.remove_child(active_item_uses.get_child(0)) + if uses_left_icon != null: + while active_item_uses.get_children().size() < uses: + active_item_uses.add_child(uses_left_icon.instantiate()) + +# Called when the active item is touched. It will only be collected if +# the player has space, in which case actually_collect() is called. func collect() -> bool: if (player.active_item == null or (player.active_item.item_name == item_name and player.active_item.uses < uses)): player.active_item = self uses = uses actually_collect() - return true return false +# Intended to be overridden by item classes. func actually_collect(): pass @@ -33,9 +39,11 @@ func trigger_activation(): if uses == 0: remove() +# Intended to be overridden by item classes. func activate(): - assert(false) + pass +# When removed, also removes the reference from the player and removes the uses. func remove(reset_player_active = true): if player.active_item == self: uses = 0 diff --git a/items/generic/item.gd b/items/generic/item.gd index 02b699a..3c3bff4 100644 --- a/items/generic/item.gd +++ b/items/generic/item.gd @@ -6,6 +6,8 @@ var collected = false func _process(_delta: float) -> void: if(is_instance_valid(player) and overlaps_body(player)): + # Attempt to collect the item. If successful, play the collect animation + # and attach the item to the player. if(self.has_method("collect") and collect()): set_deferred("monitoring", false) set_deferred("monitorable", false) @@ -13,10 +15,12 @@ func _process(_delta: float) -> void: collect_animation() collected = true +# Placeholder for a proper animation. func collect_animation(): self.visible = false if self.has_node("AudioStreamPlayer2D"): $AudioStreamPlayer2D.play() +# Intended to be overridden by item classes. func collect(): push_error("Please specify item collection behavior") return false diff --git a/items/rare_items/healthup/healthup.gd b/items/rare_items/healthup/healthup.gd index ac890d0..fadc2e2 100644 --- a/items/rare_items/healthup/healthup.gd +++ b/items/rare_items/healthup/healthup.gd @@ -4,5 +4,5 @@ extends Item func collect() -> bool: player.max_hp += max_health_increase - player.current_hp = min(player.max_hp, player.current_hp + heal_amount) + player.current_hp += max_health_increase return true diff --git a/items/unique_items/backslash/backslash.gd b/items/unique_items/backslash/backslash.gd index a3c674b..520a11c 100644 --- a/items/unique_items/backslash/backslash.gd +++ b/items/unique_items/backslash/backslash.gd @@ -3,6 +3,7 @@ extends Item @export var sword : PackedScene func collect() -> bool: + # Give the player a new sword facing towards th back. var sword_instance = sword.instantiate() player.add_child(sword_instance) sword_instance.facing_mult = -1 diff --git a/player/player.gd b/player/player.gd index aa51915..5c442a6 100644 --- a/player/player.gd +++ b/player/player.gd @@ -22,7 +22,9 @@ var base_hspeed = 150.0; var ground_jump_strength = 1400; var air_jump_strength = 1100; var air_jumps_max = 1; -var air_jumps_current = 1; +var air_jumps_current = 1: + set(air_jumps_new): + air_jumps_current = min(air_jumps_new, air_jumps_max) # HP and Iframes signal health_changed(new_health : int) @@ -31,11 +33,19 @@ signal player_died var current_hp = 5: set(new_hp): - current_hp = new_hp - health_changed.emit(current_hp) + new_hp = min(new_hp, max_hp) + if new_hp <= 0: + new_hp = 0 + die() + if new_hp != current_hp: + health_changed.emit(current_hp) + current_hp = new_hp @export var max_hp = 5: set(new_max_hp): max_hp = new_max_hp + if max_hp <= 0: + max_hp = 0 + die() max_hp_changed.emit(max_hp) var hit_invulnerability = 0.8 var inv_time = 0; @@ -185,8 +195,6 @@ func hurt(dmg: int, dir: Vector2 = Vector2.ZERO): if Status.affects("Vulnerable", self): dmg += 1 $AudioStreamPlayer2D.play() current_hp -= dmg - if(current_hp <= 0): - die() inv_time = hit_invulnerability reset_to_velocity = Vector2(-sign(earth_aligner.local_from_global(dir).x)*knockback_strength, -damage_knockup) return true