Compare commits
5 Commits
f53d91a9eb
...
2bd83504f2
Author | SHA1 | Date | |
---|---|---|---|
2bd83504f2
|
|||
3f21aef4eb
|
|||
6fff2dd9a3
|
|||
0dada63709
|
|||
d862974747
|
BIN
assets/sprites/puddle_1.aseprite
(Stored with Git LFS)
Normal file
BIN
assets/sprites/puddle_1.aseprite
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/sprites/puddle_1.png
(Stored with Git LFS)
Normal file
BIN
assets/sprites/puddle_1.png
(Stored with Git LFS)
Normal file
Binary file not shown.
34
assets/sprites/puddle_1.png.import
Normal file
34
assets/sprites/puddle_1.png.import
Normal file
@@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://c5t4it4if0s6g"
|
||||
path="res://.godot/imported/puddle_1.png-28d62b8b3cc5647c5219303699bcce62.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/sprites/puddle_1.png"
|
||||
dest_files=["res://.godot/imported/puddle_1.png-28d62b8b3cc5647c5219303699bcce62.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
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/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
|
BIN
assets/sprites/small_bleed_icon.aseprite
(Stored with Git LFS)
Normal file
BIN
assets/sprites/small_bleed_icon.aseprite
(Stored with Git LFS)
Normal file
Binary file not shown.
BIN
assets/sprites/small_bleed_icon.png
(Stored with Git LFS)
Normal file
BIN
assets/sprites/small_bleed_icon.png
(Stored with Git LFS)
Normal file
Binary file not shown.
34
assets/sprites/small_bleed_icon.png.import
Normal file
34
assets/sprites/small_bleed_icon.png.import
Normal file
@@ -0,0 +1,34 @@
|
||||
[remap]
|
||||
|
||||
importer="texture"
|
||||
type="CompressedTexture2D"
|
||||
uid="uid://c856sh6vk5lqa"
|
||||
path="res://.godot/imported/small_bleed_icon.png-472f2c7cb608bb835a947b6c2d78acf7.ctex"
|
||||
metadata={
|
||||
"vram_texture": false
|
||||
}
|
||||
|
||||
[deps]
|
||||
|
||||
source_file="res://assets/sprites/small_bleed_icon.png"
|
||||
dest_files=["res://.godot/imported/small_bleed_icon.png-472f2c7cb608bb835a947b6c2d78acf7.ctex"]
|
||||
|
||||
[params]
|
||||
|
||||
compress/mode=0
|
||||
compress/high_quality=false
|
||||
compress/lossy_quality=0.7
|
||||
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/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
|
@@ -3,7 +3,7 @@
|
||||
name="Linux"
|
||||
platform="Linux"
|
||||
runnable=true
|
||||
advanced_options=false
|
||||
advanced_options=true
|
||||
dedicated_server=false
|
||||
custom_features=""
|
||||
export_filter="all_resources"
|
||||
|
7
scenes/enemies/effects/enemy_effect_base.gd
Normal file
7
scenes/enemies/effects/enemy_effect_base.gd
Normal file
@@ -0,0 +1,7 @@
|
||||
class_name EnemyEffectBase
|
||||
extends Resource
|
||||
|
||||
var enemy: EnemyBase
|
||||
|
||||
func apply(enemy: EnemyBase) -> void:
|
||||
push_error("%s does not implement apply" % self)
|
1
scenes/enemies/effects/enemy_effect_base.gd.uid
Normal file
1
scenes/enemies/effects/enemy_effect_base.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://dg3yshxb4vdiu
|
30
scenes/enemies/effects/enemy_effect_bleed.gd
Normal file
30
scenes/enemies/effects/enemy_effect_bleed.gd
Normal file
@@ -0,0 +1,30 @@
|
||||
class_name EnemyEffectBleed
|
||||
extends EnemyEffectBase
|
||||
|
||||
var damage: float
|
||||
var duration: float
|
||||
var tick_rate: float = 1.0
|
||||
|
||||
var _timer: Timer
|
||||
var _remaining_ticks: int = 5
|
||||
var _enemy: EnemyBase
|
||||
|
||||
const PUDDLE = preload("res://scenes/puddle.tscn")
|
||||
|
||||
func _init(enemy: EnemyBase, bleed_damage: float, duration: float):
|
||||
damage = bleed_damage
|
||||
_timer = Timer.new()
|
||||
|
||||
func apply(enemy: EnemyBase) -> void:
|
||||
enemy.effects.append(self)
|
||||
while _remaining_ticks > 0:
|
||||
enemy.take_damage(damage, false)
|
||||
_remaining_ticks -= 1
|
||||
await enemy.get_tree().create_timer(1.0, false, true, false).timeout
|
||||
var p = PUDDLE.instantiate()
|
||||
enemy.get_parent().add_child(p)
|
||||
p.global_position = enemy.global_position
|
||||
enemy.effects.erase(self)
|
||||
|
||||
static func _is_bleeding(enemy: EnemyBase) -> bool:
|
||||
return false
|
1
scenes/enemies/effects/enemy_effect_bleed.gd.uid
Normal file
1
scenes/enemies/effects/enemy_effect_bleed.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://b2ptwltm211t3
|
@@ -17,7 +17,9 @@ var modifiers: Array[EnemyMod] = []
|
||||
@onready var collision_shape_2d: CollisionShape2D = $CollisionShape2D
|
||||
@onready var shape_cast_2d: ShapeCast2D = $ShapeCast2D
|
||||
@onready var sprite_2d: Sprite2D = $Sprite2D
|
||||
@onready var label: Label = $Label
|
||||
@onready var label: Label = $HBoxContainer/Label
|
||||
@onready var effect_container: HBoxContainer = $HBoxContainer/EffectContainer
|
||||
|
||||
|
||||
var player: Player
|
||||
var enemy_name: String
|
||||
@@ -26,9 +28,11 @@ var god_mode: bool = false
|
||||
var is_dead: bool = false
|
||||
var health: float
|
||||
|
||||
var effects: Array[EnemyEffectBase]
|
||||
|
||||
var _path_update_timer: float = 0.0
|
||||
var _compute_cache: KeyedCache = KeyedCache.new()
|
||||
|
||||
var _effects_visible = []
|
||||
|
||||
func _ready() -> void:
|
||||
enemy_name = _gen_name()
|
||||
@@ -63,6 +67,15 @@ func _find_player():
|
||||
func _gen_name() -> String:
|
||||
return "Unnamed enemy"
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
for effect in effects:
|
||||
if effect in _effects_visible:
|
||||
continue
|
||||
var effect_sprite = Sprite2D.new()
|
||||
effect_sprite.texture = preload("res://assets/sprites/small_bleed_icon.png")
|
||||
effect_container.add_child(effect_sprite)
|
||||
_effects_visible.append(effect)
|
||||
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
if not target:
|
||||
|
@@ -72,7 +72,7 @@ texture = SubResource("PlaceholderTexture2D_pkqou")
|
||||
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
|
||||
shape = SubResource("CircleShape2D_satqt")
|
||||
|
||||
[node name="TargetCast" type="RayCast2D" parent="." groups=["damagable", "enemy"]]
|
||||
[node name="TargetCast" type="RayCast2D" parent="."]
|
||||
enabled = false
|
||||
|
||||
[node name="AnimationPlayer" type="AnimationPlayer" parent="."]
|
||||
@@ -90,20 +90,25 @@ wait_time = 0.5
|
||||
shape = SubResource("CircleShape2D_pkqou")
|
||||
max_results = 2
|
||||
|
||||
[node name="Label" type="Label" parent="."]
|
||||
anchors_preset = 7
|
||||
[node name="HBoxContainer" type="HBoxContainer" parent="."]
|
||||
anchors_preset = 8
|
||||
anchor_left = 0.5
|
||||
anchor_top = 1.0
|
||||
anchor_top = 0.5
|
||||
anchor_right = 0.5
|
||||
anchor_bottom = 1.0
|
||||
offset_left = -85.5
|
||||
offset_top = 5.0
|
||||
offset_right = 85.5
|
||||
offset_bottom = 28.0
|
||||
anchor_bottom = 0.5
|
||||
offset_left = -53.0
|
||||
offset_right = 53.0
|
||||
offset_bottom = 40.0
|
||||
grow_horizontal = 2
|
||||
grow_vertical = 0
|
||||
grow_vertical = 2
|
||||
|
||||
[node name="EffectContainer" type="HBoxContainer" parent="HBoxContainer"]
|
||||
layout_mode = 2
|
||||
size_flags_vertical = 4
|
||||
|
||||
[node name="Label" type="Label" parent="HBoxContainer"]
|
||||
layout_mode = 2
|
||||
theme_override_font_sizes/font_size = 9
|
||||
text = "Unnamed the Adjective"
|
||||
horizontal_alignment = 1
|
||||
|
||||
[connection signal="animation_finished" from="AnimationPlayer" to="." method="_on_animation_player_animation_finished"]
|
||||
|
@@ -20,16 +20,16 @@ script = ExtResource("1_jyhfs")
|
||||
zoom = Vector2(2, 2)
|
||||
process_callback = 0
|
||||
|
||||
[node name="Player" parent="." node_paths=PackedStringArray("camera", "main_ui") instance=ExtResource("2_0wfyh")]
|
||||
position = Vector2(1057, 798)
|
||||
camera = NodePath("../MainCamera")
|
||||
main_ui = NodePath("../MainUI")
|
||||
|
||||
[node name="EnemyManager" parent="." node_paths=PackedStringArray("target", "camera") instance=ExtResource("5_tbgi4")]
|
||||
spawn_rate = 1.5
|
||||
target = NodePath("../Player")
|
||||
camera = NodePath("../MainCamera")
|
||||
|
||||
[node name="Player" parent="." node_paths=PackedStringArray("camera", "main_ui") instance=ExtResource("2_0wfyh")]
|
||||
position = Vector2(1057, 798)
|
||||
camera = NodePath("../MainCamera")
|
||||
main_ui = NodePath("../MainUI")
|
||||
|
||||
[node name="PickupMagnet" parent="." instance=ExtResource("6_tefeu")]
|
||||
position = Vector2(1697, 414)
|
||||
|
||||
|
@@ -115,4 +115,3 @@ func _on_set_spawn_rate(val: float):
|
||||
timer.stop()
|
||||
timer.wait_time = 1.0 / val
|
||||
timer.start()
|
||||
print_debug("spawn_rate: %s" % timer.wait_time)
|
||||
|
@@ -29,11 +29,7 @@ func _ready() -> void:
|
||||
if not weapon:
|
||||
weapon = WEAPON_SWORD.instantiate()
|
||||
add_child(weapon)
|
||||
var mod = WeaponModBase.new()
|
||||
mod.mod_property = "attack_damage"
|
||||
mod.mod_value = 10.0
|
||||
mod.mod_type = WeaponModBase.ModType.ADDITIVE
|
||||
weapon.add_mod(mod)
|
||||
|
||||
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
|
21
scenes/puddle.gd
Normal file
21
scenes/puddle.gd
Normal file
@@ -0,0 +1,21 @@
|
||||
class_name Puddle
|
||||
extends Node2D
|
||||
|
||||
@export var color: Color = Color.CRIMSON
|
||||
@onready var base: Sprite2D = $Base
|
||||
|
||||
func _ready() -> void:
|
||||
var player: Player = get_tree().get_first_node_in_group(GlobalConst.GROUP_PLAYER)
|
||||
var shader = preload("res://assets/shaders/base_color_tint.gdshader")
|
||||
var shader_material: ShaderMaterial
|
||||
shader_material = ShaderMaterial.new()
|
||||
shader_material.set_shader_parameter("base_color", color)
|
||||
shader_material.shader = shader
|
||||
base.material = shader_material
|
||||
match randi() % 4:
|
||||
1:
|
||||
rotation_degrees = 90
|
||||
2:
|
||||
rotation_degrees = 180
|
||||
3:
|
||||
rotation_degrees = -90
|
1
scenes/puddle.gd.uid
Normal file
1
scenes/puddle.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cds5aqq2mqmpe
|
34
scenes/puddle.tscn
Normal file
34
scenes/puddle.tscn
Normal file
@@ -0,0 +1,34 @@
|
||||
[gd_scene load_steps=8 format=3 uid="uid://dcka1mmlgeoj7"]
|
||||
|
||||
[ext_resource type="Shader" uid="uid://cf48pgfl308o3" path="res://assets/shaders/base_color_tint.gdshader" id="1_qlq6d"]
|
||||
[ext_resource type="Script" uid="uid://cds5aqq2mqmpe" path="res://scenes/puddle.gd" id="1_s8xbh"]
|
||||
[ext_resource type="Texture2D" uid="uid://c5t4it4if0s6g" path="res://assets/sprites/puddle_1.png" id="2_s8xbh"]
|
||||
|
||||
[sub_resource type="ShaderMaterial" id="ShaderMaterial_i64cl"]
|
||||
shader = ExtResource("1_qlq6d")
|
||||
shader_parameter/base_color = Color(1, 0.2, 0.2, 1)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_h42jt"]
|
||||
atlas = ExtResource("2_s8xbh")
|
||||
region = Rect2(0, 0, 16, 13)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_16dvh"]
|
||||
atlas = ExtResource("2_s8xbh")
|
||||
region = Rect2(32, 0, 16, 13)
|
||||
|
||||
[sub_resource type="AtlasTexture" id="AtlasTexture_5nuq4"]
|
||||
atlas = ExtResource("2_s8xbh")
|
||||
region = Rect2(16, 0, 16, 13)
|
||||
|
||||
[node name="Puddle" type="Node2D"]
|
||||
script = ExtResource("1_s8xbh")
|
||||
|
||||
[node name="Base" type="Sprite2D" parent="."]
|
||||
material = SubResource("ShaderMaterial_i64cl")
|
||||
texture = SubResource("AtlasTexture_h42jt")
|
||||
|
||||
[node name="Highlights" type="Sprite2D" parent="."]
|
||||
texture = SubResource("AtlasTexture_16dvh")
|
||||
|
||||
[node name="Shading" type="Sprite2D" parent="."]
|
||||
texture = SubResource("AtlasTexture_5nuq4")
|
@@ -4,6 +4,8 @@ extends Node2D
|
||||
enum WeaponTag {
|
||||
CAN_RETURN,
|
||||
CAN_BLEED,
|
||||
CAN_CHAIN,
|
||||
CAN_FORK,
|
||||
}
|
||||
|
||||
@export var attack_cd: float
|
||||
@@ -12,11 +14,19 @@ enum WeaponTag {
|
||||
@export var attack_duration: float
|
||||
@export var attack_range: float
|
||||
@export var attack_crit_chance: float = 0.05
|
||||
@export var return_chance: float = 0.0
|
||||
@export var bleed_chance: float = 0.0
|
||||
@export var bleed_duration: float = 5.0
|
||||
@export var chain_chance: float = 0.0
|
||||
@export var tags: Array[String] = []
|
||||
@export var modifiers: Array[WeaponModBase] = []
|
||||
|
||||
@onready var active_cd_timer: Timer = $ActiveCDTimer
|
||||
|
||||
var _player: Player
|
||||
|
||||
func _ready() -> void:
|
||||
_player = get_tree().get_first_node_in_group(GlobalConst.GROUP_PLAYER)
|
||||
|
||||
func _on_attack_cd_timer_timeout() -> void:
|
||||
do_attack()
|
||||
@@ -76,3 +86,19 @@ func has_property(key: String) -> bool:
|
||||
if prop.name == key:
|
||||
return true
|
||||
return false
|
||||
|
||||
func did_crit() -> bool:
|
||||
var weapon_crit = get_calculated("attack_crit_chance")
|
||||
var player_crit = _player.player_stats.get_final("crit_chance", _player.modifiers)
|
||||
|
||||
return randf() >= 1 - weapon_crit + player_crit
|
||||
|
||||
func did_bleed() -> bool:
|
||||
return randf() >= 1 - bleed_chance
|
||||
|
||||
func base_damage() -> Array[Variant]:
|
||||
var damage = get_calculated("attack_damage")
|
||||
var is_crit := did_crit()
|
||||
if is_crit:
|
||||
damage *= _player.player_stats.get_final("crit_multiplier", _player.modifiers)
|
||||
return [damage, is_crit]
|
||||
|
@@ -8,13 +8,14 @@ const WEAPON_SWORD_PROJECTILE = preload("res://scenes/weapons/weapon_sword_proje
|
||||
|
||||
signal projectile_hit(projectile: WeaponSwordProjectile, enemy: EnemyBase)
|
||||
|
||||
var _player: Player
|
||||
|
||||
|
||||
|
||||
func _ready() -> void:
|
||||
bleed_chance = 0.2
|
||||
targeting_range_shape.shape.radius = attack_range
|
||||
projectile_hit.connect(_on_projectile_hit)
|
||||
_player = get_tree().get_first_node_in_group(GlobalConst.GROUP_PLAYER)
|
||||
super._ready()
|
||||
|
||||
|
||||
func do_attack() -> void:
|
||||
@@ -44,13 +45,13 @@ func _do_active() -> void:
|
||||
|
||||
|
||||
func deal_damage(enemy: EnemyBase, damage_mult: float):
|
||||
var weapon_crit = get_calculated("attack_crit_chance")
|
||||
var player_crit = _player.player_stats.get_final("crit_chance", _player.modifiers)
|
||||
var damage = get_calculated("attack_damage")
|
||||
var is_crit = randf() >= 1 - weapon_crit + player_crit
|
||||
if is_crit:
|
||||
damage *= _player.player_stats.get_final("crit_multiplier", _player.modifiers)
|
||||
enemy.take_damage(damage * damage_mult, is_crit)
|
||||
var damage_and_crit = base_damage()
|
||||
# TODO: Fix crit value
|
||||
enemy.take_damage(damage_and_crit[0], damage_and_crit[1])
|
||||
|
||||
if did_bleed():
|
||||
var bleed = EnemyEffectBleed.new(enemy, damage_and_crit[0], bleed_duration)
|
||||
bleed.apply(enemy)
|
||||
|
||||
|
||||
func _on_projectile_hit(projectile: WeaponSwordProjectile, enemy: EnemyBase, damage_mult: float):
|
||||
|
@@ -5,6 +5,7 @@ extends Node2D
|
||||
@export var range: float = 200.0
|
||||
@export var target: Node2D
|
||||
@export var damage_mult: float = 1.0
|
||||
@export var bleed_chance: float = 0.2
|
||||
@export var on_hit_sig: Signal
|
||||
|
||||
var _direction: Vector2
|
||||
|
Reference in New Issue
Block a user