Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion scenes/game_elements/props/character_sight/character_sight.gd
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,16 @@ signal interact_area_changed
var is_looking_from_right: bool = false

## The area that the character is currently observing.
var interact_area: InteractArea
var interact_area: InteractArea:
set = _set_interact_area


func _set_interact_area(new_interact_area: InteractArea) -> void:
if interact_area:
interact_area.remove_observer(self)
interact_area = new_interact_area
if new_interact_area:
interact_area.add_observer(self)


func _ready() -> void:
Expand Down
26 changes: 26 additions & 0 deletions scenes/game_elements/props/interact_area/interact_area.gd
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@ extends Area2D
signal interaction_started(player: Player, from_right: bool)
signal interaction_ended

## Emitted when characters start or stop seeing this area for interaction.
signal observers_changed

const EXAMPLE_INTERACTION_FONT = preload("uid://c3bb7lmvdqc5e")
const EXAMPLE_INTERACTION_FONT_SIZE = 34

Expand All @@ -33,6 +36,13 @@ var interact_label_position: Vector2:
set_collision_layer_value(Enums.CollisionLayers.INTERACTABLE, not disabled)
@export var action: String = "Talk"

## Whether this area is being observed by one or more characters.
## That is, if a [CharacterSight] area is seeing this area for interaction.
var is_being_observed: bool:
get = _get_is_being_observed

var _observers: Array[CharacterSight] = []


func start_interaction(player: Player, from_right: bool) -> void:
interaction_started.emit(player, from_right)
Expand All @@ -46,6 +56,22 @@ func get_global_interact_label_position() -> Vector2:
return to_global(interact_label_position)


## A [CharacterSight] calls this when it starts seeing this area.
func add_observer(character_sight: CharacterSight) -> void:
_observers.append(character_sight)
observers_changed.emit()


## A [CharacterSight] calls this when it stops seeing this area.
func remove_observer(character_sight: CharacterSight) -> void:
_observers.erase(character_sight)
observers_changed.emit()


func _get_is_being_observed() -> bool:
return bool(_observers.size())


func _ready() -> void:
collision_layer = 0
collision_mask = 0
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# SPDX-FileCopyrightText: The Threadbare Authors
# SPDX-License-Identifier: MPL-2.0
~ start
[wave amp=25 freq=5]You got a new ability! [b]{{ability_name}}[/b][/wave]
=> END
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[remap]

importer="dialogue_manager"
importer_version=15
type="Resource"
uid="uid://cj0i5jwlv8idi"
path="res://.godot/imported/default_powerup.dialogue-7b4f95958377611890379db90e1904ef.tres"

[deps]

source_file="res://scenes/game_elements/props/powerup/components/default_powerup.dialogue"
dest_files=["res://.godot/imported/default_powerup.dialogue-7b4f95958377611890379db90e1904ef.tres"]

[params]

defaults=true
Git LFS file not shown
115 changes: 115 additions & 0 deletions scenes/game_elements/props/powerup/components/powerup.gd
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
# SPDX-FileCopyrightText: The Threadbare Authors
# SPDX-License-Identifier: MPL-2.0
@tool
extends Node2D
## A powerup that, when interacted, enables a player ability.
##
## By default it also displays a dialogue telling the player that an ability
## has been obtained.

## Emitted when this powerup is collected.
signal collected

## The player ability to enable.
@export var ability: Enums.PlayerAbilities = Enums.PlayerAbilities.ABILITY_A

## Name for the ability to display if using the default dialogue.
@export var ability_name: String

## Text to display in the label when the player gets close to interact with this powerup.
@export var interact_action: String:
set = _set_interact_action

## Asset of this powerup.
@export var sprite_frames: SpriteFrames:
set = _set_sprite_frames

## The powerup shines with this color through a shader.
@export var highlight_color: Color = Color.WHITE:
set = _set_highlight_color

## Dialogue to display when collecting the powerup.
@export var dialogue: DialogueResource = preload("uid://cj0i5jwlv8idi")

var _tween: Tween

@onready var interact_area: InteractArea = %InteractArea
@onready var highlight_effect: Sprite2D = %HighlightEffect
@onready var sprite: AnimatedSprite2D = %Sprite
@onready var interact_collision: CollisionShape2D = %InteractCollision
@onready var ground_collision: CollisionShape2D = %GroundCollision


func _set_interact_action(new_interact_action: String) -> void:
interact_action = new_interact_action
if is_node_ready():
interact_area.action = interact_action


func _set_sprite_frames(new_sprite_frames: SpriteFrames) -> void:
sprite_frames = new_sprite_frames
if is_node_ready():
sprite.sprite_frames = sprite_frames
sprite.play("default")


func _set_highlight_color(new_highlight_color: Color) -> void:
highlight_color = new_highlight_color
if is_node_ready():
highlight_effect.modulate = highlight_color


func _ready() -> void:
_set_interact_action(interact_action)
_set_sprite_frames(sprite_frames)
_set_highlight_color(highlight_color)
if Engine.is_editor_hint():
return
GameState.abilities_changed.connect(_on_abilities_changed)
_on_abilities_changed()


func _notification(what: int) -> void:
match what:
NOTIFICATION_EDITOR_PRE_SAVE:
# Since this is a tool script that plays the animations in the
# editor, reset the frame progress before saving the scene.
sprite.frame_progress = 0


func _on_abilities_changed() -> void:
var has_ability := GameState.has_ability(ability)
ground_collision.disabled = has_ability
interact_collision.disabled = has_ability
highlight_effect.visible = not has_ability
var alpha: float = 0.5 if has_ability else 1.0
sprite.modulate = Color(Color.WHITE, alpha)
_set_highlight_color(highlight_color)
var highlight_material := highlight_effect.material as ShaderMaterial
if highlight_material:
highlight_material.set_shader_parameter(&"width", 0.4)


func _on_interact_area_interaction_started(
_player: Player, _from_right: bool, source: InteractArea
) -> void:
if _tween:
_tween.kill()
_tween = create_tween()
_tween.tween_property(highlight_effect, "modulate", Color.WHITE, 0.5)
_tween.tween_property(highlight_effect, "material:shader_parameter/width", 1.0, 1.0)
await _tween.finished
if dialogue:
DialogueManager.show_dialogue_balloon(dialogue, "", [self])
await DialogueManager.dialogue_ended
source.end_interaction()
GameState.set_ability(ability, true)
collected.emit()


func _on_interact_area_observers_changed() -> void:
if _tween:
_tween.kill()
_tween = create_tween()
var width: float = 0.8 if interact_area.is_being_observed else 0.4
_tween.tween_property(highlight_effect, "material:shader_parameter/width", width, 1.0)
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
uid://bhmae3daygmqh
3 changes: 3 additions & 0 deletions scenes/game_elements/props/powerup/components/powerup.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
[remap]

importer="texture"
type="CompressedTexture2D"
uid="uid://dr1cdu5ien6jq"
path="res://.godot/imported/powerup.png-a4ee45e73209b83508bc25ff7865937f.ctex"
metadata={
"vram_texture": false
}

[deps]

source_file="res://scenes/game_elements/props/powerup/components/powerup.png"
dest_files=["res://.godot/imported/powerup.png-a4ee45e73209b83508bc25ff7865937f.ctex"]

[params]

compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
[remap]

importer="texture"
type="CompressedTexture2D"
uid="uid://bbo1nd3usbxnr"
path="res://.godot/imported/powerup_highlight.png-deef463ba3599bc39e64667d2828727c.ctex"
metadata={
"vram_texture": false
}

[deps]

source_file="res://scenes/game_elements/props/powerup/components/powerup_highlight.png"
dest_files=["res://.godot/imported/powerup_highlight.png-deef463ba3599bc39e64667d2828727c.ctex"]

[params]

compress/mode=0
compress/high_quality=false
compress/lossy_quality=0.7
compress/uastc_level=0
compress/rdo_quality_loss=0.0
compress/hdr_compression=1
compress/normal_map=0
compress/channel_pack=0
mipmaps/generate=false
mipmaps/limit=-1
roughness/mode=0
roughness/src_normal=""
process/channel_remap/red=0
process/channel_remap/green=1
process/channel_remap/blue=2
process/channel_remap/alpha=3
process/fix_alpha_border=true
process/premult_alpha=false
process/normal_map_invert_y=false
process/hdr_as_srgb=false
process/hdr_clamp_exposure=false
process/size_limit=0
detect_3d/compress_to=1
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* Ripple effect
*
* This shader expects the CanvasItem to be a gradient asset that goes from white to transparent.
* It adjusts the alpha to create a ripple effect of a certain width.
*
* SPDX-FileCopyrightText: The Threadbare Authors
* SPDX-License-Identifier: MPL-2.0
*/
shader_type canvas_item;
render_mode blend_add;

/**
* How smooth or sharp are the ripples.
*/
uniform float ease: hint_range(0.0, 2.0) = 2.0;

/**
* This is perceived as the amount of ripples.
*/
uniform float modulo_width: hint_range(0.0, 1.0) = 0.2;

/**
* The ripple width.
*/
uniform float width: hint_range(0.0, 1.0) = 0.4;

/**
* The ripple speed.
*/
uniform float speed: hint_range(0.0, 2.0) = 0.2;

void fragment() {
float sdf_alpha = mod(TIME * speed + COLOR.a, modulo_width);
float front_ease = smoothstep(0, ease, sdf_alpha);
float easeAmount = front_ease * modulo_width;
float brightness = COLOR.a - sdf_alpha + easeAmount;

COLOR.a = smoothstep(1.0 - width, width+(1.0 - width), brightness);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
uid://v56tvdvw22lj
Loading