Compare commits

...

74 commits

Author SHA1 Message Date
6dead4cc61 Added new Enemy Sprites 2025-10-23 10:07:55 +02:00
77464c39d7 Disabled Debug Cam 2025-10-22 14:09:43 +02:00
8ec8ea59ba Fixed water being cut off on the left 2025-10-22 13:27:21 +02:00
40a80801e7 Debug Cam 2025-10-22 13:22:15 +02:00
b2aa7b2907 Fixed a crash on building destruction 2025-10-22 13:09:12 +02:00
b4dbd50a8f Prevented natural spawn of vines 2025-10-22 03:31:05 +02:00
b75e6be470 Documented and refactored world scripts. 2025-10-22 03:29:21 +02:00
8ca085192d Documented and adjusted vine initialization 2025-10-22 03:04:15 +02:00
808ffb337e Journal no longer contains duplicates
Added some documentation to grid.gd
2025-10-22 02:23:16 +02:00
930d9e6d8e Removed initial load time 2025-10-22 02:04:12 +02:00
248b1915b6 Fixed vines spawning inactively at some point 2025-10-22 01:45:25 +02:00
1ea01c30d6 Fixed a crash in the boss fight 2025-10-21 17:54:43 +02:00
42ea2d3d75 Made vines spawn precisely at unique items 2025-10-21 16:07:22 +02:00
49d48da550 Fundamental adjustments and fixes for vine spawning 2025-10-21 16:06:16 +02:00
8786d30936 Fixed bug in offset calculation 2025-10-17 14:20:42 +02:00
8f2a1146f0 Restricted Petal Spawns to unique items 2025-10-17 12:57:41 +02:00
07b5114f23 Fixed a crash induced by lacking components of enemy hurtboxes 2025-10-17 12:54:05 +02:00
de06759514 Refactored and documented utils 2025-10-15 16:00:47 +02:00
cabc547b51 Refactored and documented UI code 2025-10-14 16:24:45 +02:00
5b880fa1ac Refactored trap code 2025-10-14 16:09:40 +02:00
0072a5e2e3 Documented status code 2025-10-14 15:57:23 +02:00
c2649a6032 Fixed "Play Again" not resetting the grid 2025-10-14 15:07:38 +02:00
14e7fc057f Refactored sword code 2025-10-14 15:05:34 +02:00
2a346363eb Minor refactor in player code 2025-10-14 14:45:39 +02:00
d9dae634ef Refactored player code and added quick access to cardinal directions to EarthALigner 2025-10-14 14:43:38 +02:00
20dea147ba Documented Item Spawn Code 2025-10-14 11:57:01 +02:00
a404950b92 Fixed error in HP display 2025-10-12 18:29:14 +02:00
b2c54a0e14 Refactored and documented item codes. 2025-10-12 18:26:36 +02:00
01ee8f051f Refactored and documented leech and segment code. 2025-10-12 17:59:43 +02:00
75194e1700 Refactored and documented boss spawner, destroy area and ghost 2025-10-12 17:17:09 +02:00
8c11ee3000 Refactored and documented boss code. 2025-10-11 20:02:47 +02:00
60e32002c1 Refactored and documented blob_big.gd 2025-10-11 19:44:05 +02:00
b3b6998e14 Refactoring of blob.gd 2025-10-11 19:37:25 +02:00
c558f31583 Some refactoring and documentation of the building code.
Removed empty background.gd.
2025-10-11 19:30:55 +02:00
28640e94c6 Fixed crash related to status effects 2025-10-11 19:06:46 +02:00
c33d892cf0 Active Vines now apply statusses 2025-10-11 18:22:15 +02:00
786444e789 Turned Grid into an autoload node. Made Buildings persist after death. 2025-10-11 17:36:43 +02:00
a042bb1282 Introduced Status Effects 2025-10-11 16:37:14 +02:00
2acc452f19 Added Vines to non-common item spawns 2025-10-11 12:47:24 +02:00
a1208fa8a4 Vine Spawns on Petal Interaction 2025-10-05 15:01:51 +02:00
d3a46ee779 Fixed vines overlapping with themselves after being extended around the whole planet 2025-10-03 18:21:46 +02:00
c2104f2d24 z_index fix 2025-10-03 17:11:36 +02:00
be1e8a658f Some code cleanup 2025-10-03 17:09:51 +02:00
8d642f694d First Growing Vine 2025-10-03 16:36:28 +02:00
f790694373 Fixed major oopsie 2025-10-03 11:33:13 +02:00
5e2ca5be83 File cleanup and addition of Buds and Vines, yet to obtain functionality 2025-10-03 11:31:45 +02:00
c73dd1dbd6 Building code cleanup 2025-10-03 11:30:45 +02:00
8e9f7723d9 Made Extra Jump unique
Fixed Boss getting stuck during slam
2025-10-02 19:37:56 +02:00
7687844ea6 Increased Health Spawnrate
Fixed Hit Knockback resetting vertical movement
2025-10-02 18:39:10 +02:00
7186482a3f Fixed Upslash + Backslash interaction 2025-10-02 18:31:42 +02:00
7451279024 Bug Fixes for updash and horizontal dash 2025-10-02 18:28:10 +02:00
e2ccf87792 Fixed a crash on item collection 2025-10-02 18:12:42 +02:00
f6d2c22e84 Removed Bow from common item pool (oopsie) 2025-10-02 18:01:55 +02:00
85f7d32f71 Added indicator for remaining uses of active item 2025-10-02 17:59:23 +02:00
697e5ad9e4 Fixed attack knockback for upslash and backslash 2025-10-02 15:26:45 +02:00
9b05276ad6 Attack Knockback + Controller Keybinds 2025-10-02 15:08:59 +02:00
2d2b63fd74 Fixed a bug desyncing weapon direction and weapon hitbox. Removed angle from FPS counter. 2025-10-02 14:06:25 +02:00
beb0b697ea Added color modulated background 2025-09-24 17:43:16 +02:00
8740b632a1 Added grass 2025-09-24 16:37:34 +02:00
f98c89ef94 Adjusted item sizes 2025-09-24 16:13:48 +02:00
e37c27a280 Fixed the build 2025-09-23 18:46:21 +02:00
0020947533 Added item journal 2025-09-23 17:40:50 +02:00
cf69b51ea8 Additional keybinds for WASD + Mouse Scheme 2025-09-23 15:52:33 +02:00
bd42aa7963 Proper Item Pool Handling 2025-09-23 15:50:34 +02:00
408fbb40e3 Modified Damage Behavior and Item Spawn Rate 2025-09-23 15:10:45 +02:00
a42d798490 Adjusted damage behavior against enemies 2025-09-23 13:36:19 +02:00
39df6cd554 Unlocked framerate 2025-09-23 12:36:15 +02:00
28a6e98d3d Adjusted Item Spawnrates + Boss HP 2025-09-23 12:20:33 +02:00
7265c16a2f Adjustments to horizontal dash 2025-09-22 17:42:23 +02:00
f9075777e8 Adjusted Player Hit iframes 2025-09-22 17:33:52 +02:00
39b825f572 Added ends to leeches 2025-09-22 17:32:54 +02:00
0b03dda8a3 Minor changes to draw order and ceiling height 2025-09-22 17:13:50 +02:00
561962cca9 Added Leech Sprite, fixed platform dropdown jank 2025-09-22 17:03:48 +02:00
88bd17c8c3 Smoothened Leeches + increased Player jump height 2025-09-22 15:39:58 +02:00
192 changed files with 2703 additions and 709 deletions

View file

@ -1,5 +0,0 @@
extends Node2D
#func _process(delta: float) -> void:
#for p : Parallax2D in get_children():
#p.scroll_offset += Vector2.RIGHT * 100 * delta * p.scroll_scale

View file

@ -1 +0,0 @@
uid://c6q1tgl7kag67

13
background/bg_image.gd Normal file
View file

@ -0,0 +1,13 @@
extends TextureRect
@export var colors : Array[Color] = [Color(0.3, 1, 1) * 0.7, Color(1, 0.6, 0.6) * 0.7, Color(1, 1, 1) * 0.7]
# Modulate the background with an interpolation of the colors in the list,
# depending on the players position on the earth.
func _process(_delta: float) -> void:
var index : int = floor((%Player.position.angle() + PI)/ TAU * colors.size())
var diff = (%Player.position.angle() + PI)/ TAU * colors.size() - index
self.modulate = linear_color_interpolation(colors[index], colors[(index + 1) % colors.size()], diff)
func linear_color_interpolation(c1 : Color, c2 : Color, t : float):
return c1 + (c2 - c1) * t

View file

@ -0,0 +1 @@
uid://gul4u5tw1vxk

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 6.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.9 KiB

After

Width:  |  Height:  |  Size: 6.7 KiB

View file

@ -2,7 +2,7 @@ class_name Building extends Node2D
@export var location : Vector2i # x is the angle, y is the height in the grid
@export var dimension : Vector2i = Vector2(2, 1) # same as above
@onready var grid : Grid = get_parent()
@export var blocks_area = true
var objects = []
var destroyed = false
@ -10,32 +10,14 @@ var destroyed = false
# make sure location is set before adding a building to the scene tree
# also make sure that the buildings are instantiated as children of the grid
func _ready() -> void:
assert(grid != null)
var angle = location.x * TAU / grid.num_collumns; # currently assumes anchor is bottom left
var height = grid.ground_radius + location.y * grid.cell_height;
position = height * Vector2.from_angle(angle)
global_position = Grid.get_world_position(location)
grid.buildings.append(self)
if blocks_area:
Grid.buildings.append(self)
await get_tree().create_timer(0.2).timeout
if get_node_or_null("EnemyList") != null:
var enemies = $EnemyList.get_children()
$EnemyList.reparent(get_tree().get_root().get_node("main"), false)
for enemy in enemies:
var oldpos = enemy.position;
enemy.position = get_world_position(oldpos)
if enemy is Platform or enemy is Trap or enemy is Item:
objects.append(enemy)
if "building" in enemy: enemy.building = self
if(enemy.has_method("init_at_horizontal_distortion")):
enemy.init_at_horizontal_distortion(enemy.position.length() / grid.ground_radius)
func get_world_position (local_position: Vector2) -> Vector2:
var height = grid.ground_radius + location.y * grid.cell_height - local_position.y
var angle = (location.x + local_position.x / grid.cell_height) * TAU / grid.num_collumns
return height * Vector2.from_angle(angle)
if get_node_or_null("ObjectList") != null:
var obj_list = $ObjectList
Grid.call_deferred("place_object_list", obj_list, self)
func overlaps(other : Building):
# heights don't overlap
@ -43,16 +25,17 @@ func overlaps(other : Building):
if location.y + dimension.y <= other.location.y: return false # other is above
# angles overlap. We can now assume heights overlap
var relative_other_loc = (other.location.x - location.x + grid.num_collumns) % grid.num_collumns
var relative_other_loc = (other.location.x - location.x + Grid.num_collumns) % Grid.num_collumns
if dimension.x > relative_other_loc: return true
if relative_other_loc + other.dimension.x > grid.num_collumns: return true
if relative_other_loc + other.dimension.x > Grid.num_collumns: return true
# If we get here, angles do not overlap
return false
func destroy():
if not destroyed:
grid.buildings.remove_at(grid.buildings.find(self))
# On destruction, the building is removed from the list and destroyed together with all its objects.
Grid.buildings.remove_at(Grid.buildings.find(self))
for object in objects:
if object != null and not ("collected" in object and object.collected):
object.queue_free()

View file

@ -31,36 +31,36 @@ texture = ExtResource("5_012sa")
script = ExtResource("4_505qw")
grid_offset = Vector2i(0, -1)
[node name="EnemyList" type="Node2D" parent="."]
[node name="ObjectList" type="Node2D" parent="."]
[node name="MorningStar" parent="EnemyList" instance=ExtResource("6_qwyfo")]
[node name="MorningStar" parent="ObjectList" instance=ExtResource("6_qwyfo")]
position = Vector2(238, -149)
[node name="Platform" parent="EnemyList" instance=ExtResource("8_evf2t")]
[node name="Platform" parent="ObjectList" instance=ExtResource("8_evf2t")]
visible = false
position = Vector2(75, -285)
position = Vector2(75, -295)
collision_layer = 41
[node name="Platform2" parent="EnemyList" instance=ExtResource("8_evf2t")]
[node name="Platform2" parent="ObjectList" instance=ExtResource("8_evf2t")]
visible = false
position = Vector2(225, -285)
position = Vector2(225, -295)
collision_layer = 41
[node name="Platform3" parent="EnemyList" instance=ExtResource("8_evf2t")]
[node name="Platform3" parent="ObjectList" instance=ExtResource("8_evf2t")]
visible = false
position = Vector2(375, -285)
position = Vector2(375, -295)
collision_layer = 41
[node name="Platform4" parent="EnemyList" instance=ExtResource("8_evf2t")]
[node name="Platform4" parent="ObjectList" instance=ExtResource("8_evf2t")]
visible = false
position = Vector2(525, -285)
position = Vector2(525, -295)
collision_layer = 41
[node name="Platform5" parent="EnemyList" instance=ExtResource("8_evf2t")]
[node name="Platform5" parent="ObjectList" instance=ExtResource("8_evf2t")]
position = Vector2(431, -150)
scale = Vector2(2.688, 3)
[node name="BearTrap" parent="EnemyList" instance=ExtResource("9_c7qov")]
[node name="BearTrap" parent="ObjectList" instance=ExtResource("9_c7qov")]
position = Vector2(270, -9)
[node name="DebugSprite" type="Sprite2D" parent="."]

View file

@ -31,36 +31,36 @@ texture = ExtResource("5_hu6aj")
script = ExtResource("4_2shqy")
grid_offset = Vector2i(0, -1)
[node name="EnemyList" type="Node2D" parent="."]
[node name="ObjectList" type="Node2D" parent="."]
[node name="Platform" parent="EnemyList" instance=ExtResource("8_y6yyb")]
[node name="Platform" parent="ObjectList" instance=ExtResource("8_y6yyb")]
visible = false
position = Vector2(75, -285)
position = Vector2(75, -295)
collision_layer = 41
[node name="Platform2" parent="EnemyList" instance=ExtResource("8_y6yyb")]
[node name="Platform2" parent="ObjectList" instance=ExtResource("8_y6yyb")]
visible = false
position = Vector2(225, -285)
position = Vector2(225, -295)
collision_layer = 41
[node name="Platform3" parent="EnemyList" instance=ExtResource("8_y6yyb")]
[node name="Platform3" parent="ObjectList" instance=ExtResource("8_y6yyb")]
visible = false
position = Vector2(375, -285)
position = Vector2(375, -295)
collision_layer = 41
[node name="Platform4" parent="EnemyList" instance=ExtResource("8_y6yyb")]
[node name="Platform4" parent="ObjectList" instance=ExtResource("8_y6yyb")]
visible = false
position = Vector2(525, -285)
position = Vector2(525, -295)
collision_layer = 41
[node name="Platform5" parent="EnemyList" instance=ExtResource("8_y6yyb")]
[node name="Platform5" parent="ObjectList" instance=ExtResource("8_y6yyb")]
position = Vector2(300, -150)
scale = Vector2(2.688, 3)
[node name="ItemSpawn" parent="EnemyList" instance=ExtResource("9_jmdjr")]
[node name="ItemSpawn" parent="ObjectList" instance=ExtResource("9_jmdjr")]
position = Vector2(300, -200)
[node name="Giant_Leech" parent="EnemyList" instance=ExtResource("8_r3b86")]
[node name="Giant_Leech" parent="ObjectList" instance=ExtResource("8_r3b86")]
position = Vector2(400, -340)
[node name="DebugSprite" type="Sprite2D" parent="."]

View file

@ -25,25 +25,25 @@ scale = Vector2(25, 25)
texture = ExtResource("3_uv7v8")
script = ExtResource("4_bl5jt")
[node name="EnemyList" type="Node2D" parent="."]
[node name="ObjectList" type="Node2D" parent="."]
[node name="Ghost" parent="EnemyList" instance=ExtResource("5_23fi7")]
[node name="Ghost" parent="ObjectList" instance=ExtResource("5_23fi7")]
position = Vector2(150, -300)
[node name="Platform" parent="EnemyList" instance=ExtResource("6_e6j05")]
[node name="Platform" parent="ObjectList" instance=ExtResource("6_e6j05")]
visible = false
position = Vector2(75, -585)
position = Vector2(75, -595)
collision_layer = 41
[node name="Platform2" parent="EnemyList" instance=ExtResource("6_e6j05")]
[node name="Platform2" parent="ObjectList" instance=ExtResource("6_e6j05")]
visible = false
position = Vector2(225, -585)
position = Vector2(225, -595)
collision_layer = 41
[node name="Platform3" parent="EnemyList" instance=ExtResource("6_e6j05")]
[node name="Platform3" parent="ObjectList" instance=ExtResource("6_e6j05")]
position = Vector2(290, -431)
[node name="Platform4" parent="EnemyList" instance=ExtResource("6_e6j05")]
[node name="Platform4" parent="ObjectList" instance=ExtResource("6_e6j05")]
position = Vector2(62, -184)
[node name="DebugSprite" type="Sprite2D" parent="."]

View file

@ -27,38 +27,38 @@ scale = Vector2(25, 25)
texture = ExtResource("3_elmbw")
script = ExtResource("4_1cnhw")
[node name="EnemyList" type="Node2D" parent="."]
[node name="ObjectList" type="Node2D" parent="."]
[node name="Ghost" parent="EnemyList" instance=ExtResource("5_rh5oo")]
[node name="Ghost" parent="ObjectList" instance=ExtResource("5_rh5oo")]
position = Vector2(-38, -481)
[node name="Platform" parent="EnemyList" instance=ExtResource("6_caaff")]
[node name="Platform" parent="ObjectList" instance=ExtResource("6_caaff")]
visible = false
position = Vector2(75, -585)
position = Vector2(75, -595)
collision_layer = 41
[node name="Platform2" parent="EnemyList" instance=ExtResource("6_caaff")]
[node name="Platform2" parent="ObjectList" instance=ExtResource("6_caaff")]
visible = false
position = Vector2(225, -585)
position = Vector2(225, -595)
collision_layer = 41
[node name="Platform3" parent="EnemyList" instance=ExtResource("6_caaff")]
[node name="Platform3" parent="ObjectList" instance=ExtResource("6_caaff")]
position = Vector2(5, -251)
[node name="Platform4" parent="EnemyList" instance=ExtResource("6_caaff")]
[node name="Platform4" parent="ObjectList" instance=ExtResource("6_caaff")]
position = Vector2(286, -138)
[node name="Platform5" parent="EnemyList" instance=ExtResource("6_caaff")]
[node name="Platform5" parent="ObjectList" instance=ExtResource("6_caaff")]
position = Vector2(269, -435)
scale = Vector2(2.49, 3.1)
[node name="ItemSpawn" parent="EnemyList" instance=ExtResource("7_elmbw")]
[node name="ItemSpawn" parent="ObjectList" instance=ExtResource("7_elmbw")]
position = Vector2(149, -645)
[node name="MorningStar" parent="EnemyList" instance=ExtResource("8_1cnhw")]
[node name="MorningStar" parent="ObjectList" instance=ExtResource("8_1cnhw")]
position = Vector2(39, -552)
[node name="Ghost2" parent="EnemyList" instance=ExtResource("5_rh5oo")]
[node name="Ghost2" parent="ObjectList" instance=ExtResource("5_rh5oo")]
position = Vector2(301, -39)
[node name="DebugSprite" type="Sprite2D" parent="."]

View file

@ -27,30 +27,30 @@ scale = Vector2(25, 25)
texture = ExtResource("3_0yjll")
script = ExtResource("4_ri5b7")
[node name="EnemyList" type="Node2D" parent="."]
[node name="ObjectList" type="Node2D" parent="."]
[node name="Platform" parent="EnemyList" instance=ExtResource("6_kom4b")]
[node name="Platform" parent="ObjectList" instance=ExtResource("6_kom4b")]
visible = false
position = Vector2(75, -585)
position = Vector2(75, -595)
collision_layer = 41
[node name="Platform2" parent="EnemyList" instance=ExtResource("6_kom4b")]
[node name="Platform2" parent="ObjectList" instance=ExtResource("6_kom4b")]
visible = false
position = Vector2(225, -585)
position = Vector2(225, -595)
collision_layer = 41
[node name="Platform5" parent="EnemyList" instance=ExtResource("6_kom4b")]
[node name="Platform5" parent="ObjectList" instance=ExtResource("6_kom4b")]
position = Vector2(85, -287)
scale = Vector2(2.49, 3.1)
[node name="ItemSpawn" parent="EnemyList" instance=ExtResource("7_sr858")]
[node name="ItemSpawn" parent="ObjectList" instance=ExtResource("7_sr858")]
position = Vector2(149, -645)
rarity_bonus = 2
rarity_bonus = 0.5
[node name="MorningStar" parent="EnemyList" instance=ExtResource("8_ta0fd")]
[node name="MorningStar" parent="ObjectList" instance=ExtResource("8_ta0fd")]
position = Vector2(39, -552)
[node name="BearTrap" parent="EnemyList" instance=ExtResource("8_pww4b")]
[node name="BearTrap" parent="ObjectList" instance=ExtResource("8_pww4b")]
position = Vector2(165, -7)
[node name="DebugSprite" type="Sprite2D" parent="."]

View file

@ -33,42 +33,42 @@ texture = ExtResource("5_pfkkr")
script = ExtResource("4_xr4t5")
grid_offset = Vector2i(0, -1)
[node name="EnemyList" type="Node2D" parent="."]
[node name="ObjectList" type="Node2D" parent="."]
[node name="MorningStar" parent="EnemyList" instance=ExtResource("5_xr4t5")]
[node name="MorningStar" parent="ObjectList" instance=ExtResource("5_xr4t5")]
position = Vector2(397, -3)
[node name="Ghost" parent="EnemyList" instance=ExtResource("7_35wcg")]
[node name="Ghost" parent="ObjectList" instance=ExtResource("7_35wcg")]
position = Vector2(118, -125)
[node name="Platform" parent="EnemyList" instance=ExtResource("8_sifiv")]
[node name="Platform" parent="ObjectList" instance=ExtResource("8_sifiv")]
visible = false
position = Vector2(75, -285)
position = Vector2(75, -295)
collision_layer = 41
[node name="Platform2" parent="EnemyList" instance=ExtResource("8_sifiv")]
[node name="Platform2" parent="ObjectList" instance=ExtResource("8_sifiv")]
visible = false
position = Vector2(225, -285)
position = Vector2(225, -295)
collision_layer = 41
[node name="Platform3" parent="EnemyList" instance=ExtResource("8_sifiv")]
[node name="Platform3" parent="ObjectList" instance=ExtResource("8_sifiv")]
visible = false
position = Vector2(375, -285)
position = Vector2(375, -295)
collision_layer = 41
[node name="Platform4" parent="EnemyList" instance=ExtResource("8_sifiv")]
[node name="Platform4" parent="ObjectList" instance=ExtResource("8_sifiv")]
visible = false
position = Vector2(525, -285)
position = Vector2(525, -295)
collision_layer = 41
[node name="Platform5" parent="EnemyList" instance=ExtResource("8_sifiv")]
[node name="Platform5" parent="ObjectList" instance=ExtResource("8_sifiv")]
position = Vector2(300, -150)
scale = Vector2(2.688, 3)
[node name="ItemSpawn" parent="EnemyList" instance=ExtResource("9_i1qmw")]
[node name="ItemSpawn" parent="ObjectList" instance=ExtResource("9_i1qmw")]
position = Vector2(300, -200)
[node name="Leech" parent="EnemyList" instance=ExtResource("10_ibnxs")]
[node name="Leech" parent="ObjectList" instance=ExtResource("10_ibnxs")]
position = Vector2(240, -340)
[node name="DebugSprite" type="Sprite2D" parent="."]

View file

@ -33,39 +33,39 @@ texture = ExtResource("5_v4fh6")
script = ExtResource("4_h84o2")
grid_offset = Vector2i(0, -1)
[node name="EnemyList" type="Node2D" parent="."]
[node name="ObjectList" type="Node2D" parent="."]
[node name="Platform" parent="EnemyList" instance=ExtResource("6_me65q")]
[node name="Platform" parent="ObjectList" instance=ExtResource("6_me65q")]
visible = false
position = Vector2(75, -285)
position = Vector2(75, -295)
collision_layer = 41
[node name="Platform2" parent="EnemyList" instance=ExtResource("6_me65q")]
[node name="Platform2" parent="ObjectList" instance=ExtResource("6_me65q")]
visible = false
position = Vector2(225, -285)
position = Vector2(225, -295)
collision_layer = 41
[node name="Platform3" parent="EnemyList" instance=ExtResource("6_me65q")]
[node name="Platform3" parent="ObjectList" instance=ExtResource("6_me65q")]
visible = false
position = Vector2(375, -285)
position = Vector2(375, -295)
collision_layer = 41
[node name="Platform4" parent="EnemyList" instance=ExtResource("6_me65q")]
[node name="Platform4" parent="ObjectList" instance=ExtResource("6_me65q")]
visible = false
position = Vector2(525, -285)
position = Vector2(525, -295)
collision_layer = 41
[node name="ItemSpawn" parent="EnemyList" instance=ExtResource("7_crruu")]
[node name="ItemSpawn" parent="ObjectList" instance=ExtResource("7_crruu")]
position = Vector2(137, -329)
rarity_bonus = 1
rarity_bonus = 0.25
[node name="BearTrap" parent="EnemyList" instance=ExtResource("8_fkxmk")]
[node name="BearTrap" parent="ObjectList" instance=ExtResource("8_fkxmk")]
position = Vector2(465, -301)
[node name="Ghost" parent="EnemyList" instance=ExtResource("9_6hrl3")]
[node name="Ghost" parent="ObjectList" instance=ExtResource("9_6hrl3")]
position = Vector2(301, -49)
[node name="Leech" parent="EnemyList" instance=ExtResource("10_7e5ul")]
[node name="Leech" parent="ObjectList" instance=ExtResource("10_7e5ul")]
position = Vector2(176, -340)
[node name="DebugSprite" type="Sprite2D" parent="."]

BIN
enemies/Elite.pdn Normal file

Binary file not shown.

BIN
enemies/Elite_Body.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

BIN
enemies/Elite_Head.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

View file

@ -1,26 +1,35 @@
extends Node2D
var moving = false
@onready var player = get_tree().get_root().get_node("main/Player")
@onready var target = player.position
var speed = 500
# The target is set on initialization and never updated.
@onready var target = player.position
var reached = false
signal target_reached
func _ready() -> void:
# Wait one second before firing
await get_tree().create_timer(1).timeout
moving = true
func _physics_process(delta: float) -> void:
func _process(delta: float) -> void:
# Fire towards the center of the cross
if moving:
position += (target - global_position).normalized().rotated(-get_parent().rotation) * speed * delta
# When reaching the center, inform parent node
if((global_position - target).length() < 40):
moving = false
if not reached:
target_reached.emit()
reached = true
# Damage the player on contact
if has_node("Area2D") and $Area2D.overlaps_body(player):
player.hurt(1, global_position-player.position)

View file

@ -5,7 +5,8 @@ var angular_speed = TAU/8
var lifetime = 5
var ready_blobs = 0
var num_blobs = 4
var num_blobs = 0
var particles_ended = false
@ -13,16 +14,20 @@ func _on_target_reached():
ready_blobs += 1
func _ready() -> void:
# Count those children that have a "target reached" signal and connect them.
for child in get_children():
if "target_reached" in child:
num_blobs += 1
child.connect("target_reached", _on_target_reached)
$SplashSound.play()
func _physics_process(delta: float) -> void:
func _process(delta: float) -> void:
# Once all child blobs have reached their target, start moving as one while slowly rotating.
if ready_blobs == num_blobs:
position += (player.position - position).normalized() * speed * delta
rotate(angular_speed * delta)
lifetime -= delta
# In the end, clear all child blobs, then the rest.
if lifetime < 0 and not particles_ended:
particles_ended = true
for child in get_children():

View file

@ -1,106 +1,124 @@
extends CharacterBody2D
@onready var earthaligner = $EarthAligner
@onready var player = get_tree().get_root().get_node("main/Player")
var moves = ["slam", "wave", "water_rise", "splash"]
@export var big_blob : PackedScene
@onready var water : Water = get_tree().get_root().get_node("main/Water")
@onready var next_move = choose_next_move()
# How often water has been risen.
var risen = 0
# Managing idle behavior between attacks.
var attack_ready = true
var idle_dir : Vector2 = Vector2.ZERO
var idle_dir_remaining = 0
var idle_move = true
var target_pos = Vector2.ZERO
var damage = 1
var dead = false
signal grounded
signal slam_step_finished
func choose_next_move() -> String:
if $EnemyHurtbox.hp < 2 * $EnemyHurtbox.max_hp / 3 and risen == 0:
# Water rises at 75% and 50% of remaining HP.
if $EnemyHurtbox.hp <= 3 * $EnemyHurtbox.max_hp / 4 and risen == 0:
risen += 1
return "water_rise"
if $EnemyHurtbox.hp < $EnemyHurtbox.max_hp / 3 and risen == 1:
if $EnemyHurtbox.hp <= $EnemyHurtbox.max_hp / 2 and risen == 1:
risen += 1
return "water_rise"
var pool = ["splash"]
if not (position.length() - water.radius < 300 and randf()<0.75):
# Heavily decrease slam probability if boss height is low.
if not (position.length() - water.radius < 450 and randf()<0.75):
pool.append("slam")
# Heavily decrease wave probability if player is very high up.
if not (player.position.length() > water.radius + 900 and randf()<0.75):
pool.append("wave")
return ["slam", "wave", "splash"].pick_random()
func _process(_delta: float) -> void:
if dead: return
if attack_ready:
attack_ready = false
call(choose_next_move())
func _physics_process(delta: float) -> void:
if dead: return
up_direction = earthaligner.global_from_local(Vector2.UP)
if attack_ready:
attack_ready = false
call(next_move)
next_move = choose_next_move()
up_direction = $EarthAligner.up
if(is_on_floor()):
grounded.emit()
if idle_move: move_idle(delta)
if($Hitbox.overlaps_body(player)):
player.hurt(damage, self.position - player.position)
move_and_slide()
func move_idle(delta : float):
# Pick a random target roughly above the player's head every 0.5 seconds.
idle_dir_remaining -= delta
if(idle_dir_remaining <= 0):
target_pos = player.position + player.earth_aligner.global_from_local(Vector2.UP) * 400
target_pos = player.position + player.get_node("EarthAligner").up * 400
target_pos += randf_range(0, max(200, (target_pos - global_position).length())*0.25) * Vector2.from_angle(randf_range(0,TAU))
idle_dir = (target_pos - global_position).normalized()* max(200, (target_pos - global_position).length()) * 0.4
idle_dir_remaining = 0.5
velocity = idle_dir
func slam():
# Move up, Slam Down, Repeat. Afterwards, linger for a moment.
# The slam destroys buildings.
idle_move = false
velocity = up_direction * 500
await get_tree().create_timer(0.6).timeout
damage = 2
velocity = up_direction * -1500
await grounded
$SoundSlam.play()
destroy_below()
await slam_step()
damage = 1
velocity = up_direction * 500
await get_tree().create_timer(0.3).timeout
damage = 2
velocity = up_direction * -1500
await grounded
$SoundSlam.play()
destroy_below()
damage = 1
await slam_step()
velocity = up_direction * 35
await get_tree().create_timer(3).timeout
idle_move = true
attack_ready = true
func slam_step():
# End a downslam after ground is reached or 1.5 seconds have passed.
# Then destroy buildings hit.
damage = 2
velocity = up_direction * -1500
grounded.connect(func(): slam_step_finished.emit())
get_tree().create_timer(1.5).timeout.connect(func(): slam_step_finished.emit())
await slam_step_finished
$SoundSlam.play()
destroy_below()
damage = 1
func destroy_below():
if dead: return
for body in $DestructionChecker.get_overlapping_bodies():
if(body.has_method("destroy")): body.destroy()
func wave():
var angle = atan2(player.position.y, player.position.x)
# Raise a wave from the water at the boundary of the screen and move it towards the center.
var angle = player.position.angle()
var dir = randi_range(0, 1) * 2 - 1
var speed = 3000/water.radius_base
water.create_tsunami(angle - speed * dir*TAU/30, dir, speed)
var speed = 3000 / water.radius_base
water.create_tsunami(angle - speed * dir * TAU/30, dir, speed)
await get_tree().create_timer(0.5).timeout
$Wave.play()
await get_tree().create_timer(3.5).timeout
attack_ready = true
func water_rise():
# Increase the water level by 1 room height.
water.rise_water()
await get_tree().create_timer(5).timeout
attack_ready = true
func splash():
# Form four small blobs around the player which merge into one.
var blob_instance = big_blob.instantiate()
get_tree().get_root().get_node("main").add_child(blob_instance)
blob_instance.position = player.position
@ -110,16 +128,17 @@ func splash():
func die():
# Clear everything else, then wait for Audio Players to make sure sounds are not cut off.
dead = true
for child in get_children():
if not child is AudioStreamPlayer2D:
child.queue_free()
$DeathSound.play()
await $DeathSound.finished
await get_tree().create_timer(3).timeout
await get_tree().create_timer(1).timeout
get_tree().change_scene_to_file("res://ui/victory_screen/victory_screen.tscn")
queue_free()
func _on_enemy_hurtbox_damage_taken(_damage, _dir) -> void:
func _on_enemy_hurtbox_damage_taken(_damage, _dir, _id) -> void:
if dead: return
$AudioStreamPlayer2D.play()

View file

@ -32,8 +32,9 @@ texture = ExtResource("3_opohk")
[node name="EnemyHurtbox" parent="." node_paths=PackedStringArray("canvasItem") instance=ExtResource("2_skx2t")]
collision_layer = 16
collision_mask = 32
max_hp = 600
max_hp = 800
canvasItem = NodePath("..")
id_block_time = 5.0
[node name="CollisionShape2D" type="CollisionShape2D" parent="EnemyHurtbox"]
rotation = 1.5708

View file

@ -6,7 +6,8 @@ func _ready() -> void:
pass
func _on_water_water_reached_max_height() -> void:
# The boss spawns once the water has risen to its maximum height.
var node = boss.instantiate()
add_sibling(node)
node.position = %Player.position + %Player.earth_aligner.local_from_global(Vector2.UP) * 1000;
node.position = %Player.position + %Player.get_node("EarthAligner").up * 1000;
queue_free()

View file

@ -1,4 +1,5 @@
extends Area2D
# Attach this to an object to make it destructible
func destroy():
get_parent().queue_free()

View file

@ -1,46 +1,53 @@
extends Area2D
@onready var earth_aligner = $EarthAligner
@onready var player : CharacterBody2D = get_tree().get_root().get_node_or_null("main/Player")
var target : CharacterBody2D
# Base stats
var speed = 100
var damage = 1
var player : CharacterBody2D
var target : CharacterBody2D
var current_knockback = Vector2.ZERO
var knockback_weight = 800
# Aggro range determines at which distance the ghost targets the player,
# Chase range determines at which distance the ghost stops pursuing the player.
var aggro_range = 900
var chase_range = 1400
var current_knockback = Vector2.ZERO
var knockback_weight = 800
func _ready() -> void:
player = get_tree().get_root().get_node_or_null("main/Player")
$AnimatedSprite2D.play("default")
func _physics_process(delta: float) -> void:
func _process(delta: float) -> void:
if !is_instance_valid(player):
return
var dist = (position - player.position).length()
# Set target based on aggression range and whether target is already set
if(dist > chase_range):
target = null
elif(target == null and dist <= aggro_range):
target = player
# Move towards the target at constant speed
if(target!=null):
var motion = -(position - target.position).normalized() * speed
self.position += motion * delta * min(1, dist/(motion.length()*delta))
# Process knockback
self.position += current_knockback * delta
current_knockback = current_knockback/pow(1.3, 60*delta)
if(self.overlaps_body(player)):
player.hurt(damage, self.global_position-player.global_position)
func _on_death():
# First free all other children, then wait for Death Sound to finish
for child in get_children():
if not child is AudioStreamPlayer2D:
child.queue_free()
await $AudioStreamPlayer2D.finished
await $HurtSound.finished
self.queue_free()
func _on_damage_taken(_damage : int, dir: Vector2):
func _on_damage_taken(_damage : int, dir: Vector2, _id):
current_knockback = - dir * knockback_weight
$AudioStreamPlayer2D.play()
$HurtSound.play()

View file

@ -28,7 +28,7 @@ animations = [{
}]
[node name="Ghost" type="Area2D"]
z_index = 1
z_index = 5
scale = Vector2(0.8, 0.8)
collision_layer = 0
collision_mask = 4
@ -37,6 +37,7 @@ script = ExtResource("1_6attn")
[node name="EnemyHurtbox" parent="." node_paths=PackedStringArray("canvasItem") instance=ExtResource("2_34o1m")]
max_hp = 50
canvasItem = NodePath("..")
id_block_time = 0.2
[node name="CollisionShape2D" type="CollisionShape2D" parent="EnemyHurtbox"]
scale = Vector2(6, 6)
@ -52,7 +53,7 @@ shape = SubResource("CircleShape2D_6attn")
[node name="EarthAligner" parent="." instance=ExtResource("3_obmiq")]
[node name="AudioStreamPlayer2D" type="AudioStreamPlayer2D" parent="."]
[node name="HurtSound" type="AudioStreamPlayer2D" parent="."]
stream = ExtResource("7_eqcb8")
volume_db = 15.0

View file

@ -1,23 +1,24 @@
[gd_scene load_steps=6 format=3 uid="uid://5nb7pf8g1ck"]
[gd_scene load_steps=7 format=3 uid="uid://5nb7pf8g1ck"]
[ext_resource type="Script" uid="uid://b70f2ylbb3btt" path="res://enemies/leech/leech.gd" id="1_wfsrb"]
[ext_resource type="PackedScene" uid="uid://cvoicwo2xnf7e" path="res://enemies/leech/segment.tscn" id="2_7ngsb"]
[ext_resource type="PackedScene" uid="uid://dn8qucrpq6k72" path="res://enemies/leech/segment_end.tscn" id="2_poqop"]
[ext_resource type="PackedScene" uid="uid://chs0u61f45nau" path="res://utils/earth_aligner.tscn" id="3_vk62e"]
[ext_resource type="AudioStream" uid="uid://co07360hqn6fk" path="res://sounds/686321__cjspellsfish__punch-land-soft.wav" id="4_ps8gx"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_cq6dk"]
size = Vector2(2, 24)
size = Vector2(2, 15)
[node name="Giant_Leech" type="Node2D"]
[node name="Giant_Leech" type="Area2D"]
scale = Vector2(1, 1.2)
script = ExtResource("1_wfsrb")
broadth = 400
hp = 180
max_hp = 180
[node name="Segments" type="Node2D" parent="."]
[node name="Segment0" parent="Segments" instance=ExtResource("2_7ngsb")]
scale = Vector2(2, 2)
[node name="SegmentEnd1" parent="Segments" instance=ExtResource("2_poqop")]
scale = Vector2(-2, -2)
[node name="Segment2" parent="Segments" instance=ExtResource("2_7ngsb")]
scale = Vector2(2, 2)
@ -43,24 +44,30 @@ scale = Vector2(2, 2)
[node name="Segment9" parent="Segments" instance=ExtResource("2_7ngsb")]
scale = Vector2(2, 2)
[node name="SegmentEnd2" parent="Segments" instance=ExtResource("2_poqop")]
scale = Vector2(2, 2)
[node name="EarthAligner" parent="." instance=ExtResource("3_vk62e")]
[node name="RayCast2D" type="Area2D" parent="."]
[node name="StepChecker" type="Area2D" parent="."]
position = Vector2(248, 31.2)
collision_layer = 0
collision_mask = 8
[node name="CollisionShape2D" type="CollisionShape2D" parent="RayCast2D"]
position = Vector2(0, 14.8)
[node name="CollisionShape2D" type="CollisionShape2D" parent="StepChecker"]
position = Vector2(0, 25)
shape = SubResource("RectangleShape2D_cq6dk")
[node name="RayCast2D2" type="Area2D" parent="."]
[node name="GroundSensor" type="Area2D" parent="."]
collision_layer = 0
collision_mask = 8
[node name="CollisionShape2D" type="CollisionShape2D" parent="RayCast2D2"]
position = Vector2(0, 14.8)
[node name="CollisionShape2D" type="CollisionShape2D" parent="GroundSensor"]
position = Vector2(0, 25)
shape = SubResource("RectangleShape2D_cq6dk")
[node name="AudioStreamPlayer2D" type="AudioStreamPlayer2D" parent="."]
stream = ExtResource("4_ps8gx")
[connection signal="damage_taken" from="." to="." method="_on_damage_taken"]
[connection signal="died" from="." to="." method="_on_death"]

View file

@ -1,65 +1,63 @@
extends Node2D
extends EnemyHurtbox
# The distance from one end to the other while standing
@export var broadth = 250
@export var move_dir = -1
@export var angular_speed = 0.25
@export var hp = 400
var move_dir = [-1, 1].pick_random()
const angular_speed = 0.25
# The angle from the base to the moving end
var angle = 0.0 if move_dir == 1 else PI
@onready var segments : Array[Node] = $Segments.get_children()
@onready var segment_count = segments.size()
var paused = false
var pause_time = 0.1
var iframes = 0.2
var iframe_time = 0
var dead = false
func _ready() -> void:
for segment in segments:
segment.segment_damaged.connect(hurt)
func _physics_process(delta: float) -> void:
func _process(delta: float) -> void:
if dead: return
iframe_time = max(0, iframe_time - delta)
if not paused:
angle -= TAU * delta * angular_speed * move_dir
if(angle > PI or angle < 0):
paused = true
await get_tree().create_timer(pause_time).timeout
paused = false
angle = fmod(angle + PI, PI)
var y = position.length()
var ratio = - move_dir * broadth / (2 * y)
var rot_angle = - 2 * asin(ratio)
position = position.rotated(rot_angle)
if dead:
return
if(move_dir == 1 and angle < 1 or move_dir == -1 and angle > PI - 1):
var y = position.length()
var ratio = - move_dir * broadth / (2 * y)
var rot_angle = - 2 * asin(ratio)
$RayCast2D.global_position = position.rotated(rot_angle)
$RayCast2D.rotation = rot_angle
if(move_dir == 1 and angle < 0.5 or move_dir == -1 and angle > PI - 0.5):
if(not $RayCast2D.has_overlapping_bodies()):
paused = true
await get_tree().create_timer(pause_time).timeout
paused = false
move_dir *= -1
if dead:
return
for i in range(segment_count):
var segment_pos_data = calculate_segment_location_and_rotation(i)
if not is_instance_valid(segments[i]):
get_tree().get_root().print_tree_pretty()
segments[i].position = segment_pos_data.position
segments[i].rotation = segment_pos_data.rotation
if not $RayCast2D2.has_overlapping_bodies():
position += 200 * delta * $EarthAligner.global_from_local(Vector2.DOWN)
# Fall slowly while not grounded
if not $GroundSensor.has_overlapping_bodies():
position += 200 * delta * $EarthAligner.down
var y = position.length()
var ratio = - move_dir * broadth / (2 * y)
# Due to the curvature of the ground, the leech can not just prescribe a semicircle.
# 2 * rot_angle determines how much further than 180° the moving leg has to move.
# This agrees with the angle of the arc spanned by the leeches standing ends.
var rot_angle = - 2 * asin(ratio)
angle -= TAU * delta * angular_speed * move_dir
# Once the rotation has finished, the other leg is used as the leeches center.
# The leeches position has to be updated accordingly.
if(angle > PI + abs(rot_angle) / 2 or angle < - abs(rot_angle) / 2):
angle = fmod(angle + PI, PI)
position = position.rotated(rot_angle)
# StepChecker determines whether there is ground for the next step.
# Place the StepChecker on the side of the next step to be made.
if(move_dir == 1 and angle < 1 or move_dir == -1 and angle > PI - 1):
$StepChecker.global_position = position.rotated(rot_angle)
$StepChecker.rotation = rot_angle
# At some point of the movement, check whether there is ground to step on, turn around otherwise.
if(move_dir == 1 and angle < 0.5 or move_dir == -1 and angle > PI - 0.5):
if(not $StepChecker.has_overlapping_bodies()):
move_dir *= -1
# Update the position and rotation according to the end's position
for i in range(segment_count):
var segment_pos_data = calculate_segment_location_and_rotation(i)
if not is_instance_valid(segments[i]):
get_tree().get_root().print_tree_pretty()
segments[i].position = segment_pos_data.position
segments[i].rotation = segment_pos_data.rotation
func calculate_segment_location_and_rotation (i) -> Dictionary:
var aerial_end_location = Vector2.from_angle(-angle) * broadth
# Compute the gravicenter of the standing end, the moving end and the apex of the movement.
var gravicenter = (aerial_end_location + Vector2(0, -broadth) + Vector2.ZERO) / 3
# Compute the circle through the above gravicenter, the standing end and the moving end.
var ax = gravicenter.x
var ay = gravicenter.y
var bx = aerial_end_location.x
@ -69,36 +67,50 @@ func calculate_segment_location_and_rotation (i) -> Dictionary:
var d = 2 * (ax * (by - cy) + bx * (cy - ay) + cx * (ay - by))
var ux = ((ax * ax + ay * ay) * (by - cy) + (bx * bx + by * by) * (cy - ay) + (cx * cx + cy * cy) * (ay - by)) / d
var uy = ((ax * ax + ay * ay) * (cx - bx) + (bx * bx + by * by) * (ax - cx) + (cx * cx + cy * cy) * (bx - ax)) / d
var center = Vector2(ux, uy)
var radius = center.length()
var circum_center = Vector2(ux, uy)
var radius = circum_center.length()
# Determine the direction of the correct arc between the standing and the moving end
var switch_arc_dir = false
# When the moving end crosses above the standing end, the circumcenter jumps
# from one side of the leech to the other, reverting the direction of the arc
if ux < 0:
switch_arc_dir = !switch_arc_dir
if center.angle() > 1:
# For sufficiently large size of circum_center.angle() it can happen that
# the sign of the (circum_center - aerial_end_location).angle() flips while
# that of circum_center.angle() doesn't, which has to be counteracted.
if circum_center.angle() > 1:
switch_arc_dir = !switch_arc_dir
var angle1 = - PI + center.angle()
var angle2 = - PI + (center-aerial_end_location).angle()
var angle1 = - PI + circum_center.angle()
var angle2 = - PI + (circum_center - aerial_end_location).angle()
if(switch_arc_dir):
angle1 += TAU
if radius < 10000000:
return {"position": center + radius * Vector2.from_angle((i * angle1 + (segment_count - 1 - i) * angle2)/(segment_count - 1))
, "rotation": (i * angle1 + (segment_count - 1 - i) * angle2)/ (segment_count - 1) + PI/2}
else:
# In the edge case where the leech is almost a straight line, the circum_center
# and radius approach infty, leading to numerical errors producing flickering.
# This is ruled out by treating these cases as actual straight lines.
if radius > 1000000:
return {"position" : Vector2.UP * broadth * i / (segment_count - 1),
"rotation" : 3 * PI / 2}
# Otherwise, the segments are distributed regularly along the arc.
else:
var arc_angle = (i * angle1 + (segment_count - 1 - i) * angle2)/(segment_count - 1)
return {"position": circum_center + radius * Vector2.from_angle(arc_angle),
"rotation": arc_angle + sign(ux) * PI/2}
func hurt(damage : int, _dir):
if iframe_time <= 0:
hp -= damage
$AudioStreamPlayer2D.play()
if(hp<=0):
dead = true
for child in get_children():
if not child is AudioStreamPlayer2D:
child.queue_free()
await $AudioStreamPlayer2D.finished
queue_free()
else:
iframe_time = iframes
func _on_damage_taken(_damage, _dir, _id):
$AudioStreamPlayer2D.play()
func _on_death():
# Free all other children while waiting for the death sound to play.
dead = true
for child in get_children():
if not child is AudioStreamPlayer2D:
child.queue_free()
$AudioStreamPlayer2D.play()
await $AudioStreamPlayer2D.finished
queue_free()

View file

@ -1,6 +1,7 @@
[gd_scene load_steps=6 format=3 uid="uid://b62xcg0dd3vct"]
[gd_scene load_steps=7 format=3 uid="uid://b62xcg0dd3vct"]
[ext_resource type="Script" uid="uid://b70f2ylbb3btt" path="res://enemies/leech/leech.gd" id="1_6u582"]
[ext_resource type="PackedScene" uid="uid://dn8qucrpq6k72" path="res://enemies/leech/segment_end.tscn" id="2_i1r8c"]
[ext_resource type="PackedScene" uid="uid://cvoicwo2xnf7e" path="res://enemies/leech/segment.tscn" id="2_oqch2"]
[ext_resource type="PackedScene" uid="uid://chs0u61f45nau" path="res://utils/earth_aligner.tscn" id="3_0r7dp"]
[ext_resource type="AudioStream" uid="uid://co07360hqn6fk" path="res://sounds/686321__cjspellsfish__punch-land-soft.wav" id="4_b1m5t"]
@ -8,15 +9,17 @@
[sub_resource type="RectangleShape2D" id="RectangleShape2D_cq6dk"]
size = Vector2(2, 12)
[node name="Leech" type="Node2D"]
[node name="Leech" type="Area2D"]
scale = Vector2(1, 1.2)
script = ExtResource("1_6u582")
broadth = 200
hp = 80
max_hp = 80
[node name="Segments" type="Node2D" parent="."]
[node name="Segment0" parent="Segments" instance=ExtResource("2_oqch2")]
[node name="SegmentEnd1" parent="Segments" instance=ExtResource("2_i1r8c")]
rotation = 3.1415927
scale = Vector2(-1, -1)
[node name="Segment2" parent="Segments" instance=ExtResource("2_oqch2")]
@ -32,27 +35,30 @@ hp = 80
[node name="Segment8" parent="Segments" instance=ExtResource("2_oqch2")]
[node name="Segment9" parent="Segments" instance=ExtResource("2_oqch2")]
[node name="SegmentEnd2" parent="Segments" instance=ExtResource("2_i1r8c")]
[node name="EarthAligner" parent="." instance=ExtResource("3_0r7dp")]
[node name="RayCast2D" type="Area2D" parent="."]
[node name="StepChecker" type="Area2D" parent="."]
position = Vector2(248, 31.2)
collision_layer = 0
collision_mask = 8
[node name="CollisionShape2D" type="CollisionShape2D" parent="RayCast2D"]
[node name="CollisionShape2D" type="CollisionShape2D" parent="StepChecker"]
position = Vector2(0, 14.8)
shape = SubResource("RectangleShape2D_cq6dk")
[node name="RayCast2D2" type="Area2D" parent="."]
[node name="GroundSensor" type="Area2D" parent="."]
collision_layer = 0
collision_mask = 8
[node name="CollisionShape2D" type="CollisionShape2D" parent="RayCast2D2"]
[node name="CollisionShape2D" type="CollisionShape2D" parent="GroundSensor"]
position = Vector2(0, 8.8)
shape = SubResource("RectangleShape2D_cq6dk")
[node name="AudioStreamPlayer2D" type="AudioStreamPlayer2D" parent="."]
stream = ExtResource("4_b1m5t")
volume_db = 15.0
[connection signal="damage_taken" from="." to="." method="_on_damage_taken"]
[connection signal="died" from="." to="." method="_on_death"]

View file

@ -0,0 +1,61 @@
[gd_scene load_steps=7 format=3 uid="uid://b62xcg0dd3vct"]
[ext_resource type="Script" uid="uid://b70f2ylbb3btt" path="res://enemies/leech/leech.gd" id="1_6u582"]
[ext_resource type="PackedScene" uid="uid://dn8qucrpq6k72" path="res://enemies/leech/segment_end.tscn" id="2_i1r8c"]
[ext_resource type="PackedScene" uid="uid://cvoicwo2xnf7e" path="res://enemies/leech/segment.tscn" id="2_oqch2"]
[ext_resource type="PackedScene" uid="uid://chs0u61f45nau" path="res://utils/earth_aligner.tscn" id="3_0r7dp"]
[ext_resource type="AudioStream" uid="uid://co07360hqn6fk" path="res://sounds/686321__cjspellsfish__punch-land-soft.wav" id="4_b1m5t"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_cq6dk"]
size = Vector2(2, 12)
[node name="Leech" type="Node2D"]
scale = Vector2(1, 1.2)
script = ExtResource("1_6u582")
broadth = 200
max_hp = 80
[node name="Segments" type="Node2D" parent="."]
[node name="SegmentEnd1" parent="Segments" instance=ExtResource("2_i1r8c")]
rotation = 3.1415927
scale = Vector2(-1, -1)
[node name="Segment2" parent="Segments" instance=ExtResource("2_oqch2")]
[node name="Segment3" parent="Segments" instance=ExtResource("2_oqch2")]
[node name="Segment4" parent="Segments" instance=ExtResource("2_oqch2")]
[node name="Segment5" parent="Segments" instance=ExtResource("2_oqch2")]
[node name="Segment6" parent="Segments" instance=ExtResource("2_oqch2")]
[node name="Segment7" parent="Segments" instance=ExtResource("2_oqch2")]
[node name="Segment8" parent="Segments" instance=ExtResource("2_oqch2")]
[node name="SegmentEnd2" parent="Segments" instance=ExtResource("2_i1r8c")]
[node name="EarthAligner" parent="." instance=ExtResource("3_0r7dp")]
[node name="RayCast2D" type="Area2D" parent="."]
position = Vector2(248, 31.2)
collision_layer = 0
collision_mask = 8
[node name="CollisionShape2D" type="CollisionShape2D" parent="RayCast2D"]
position = Vector2(0, 14.8)
shape = SubResource("RectangleShape2D_cq6dk")
[node name="RayCast2D2" type="Area2D" parent="."]
collision_layer = 0
collision_mask = 8
[node name="CollisionShape2D" type="CollisionShape2D" parent="RayCast2D2"]
position = Vector2(0, 8.8)
shape = SubResource("RectangleShape2D_cq6dk")
[node name="AudioStreamPlayer2D" type="AudioStreamPlayer2D" parent="."]
stream = ExtResource("4_b1m5t")
volume_db = 15.0

View file

@ -0,0 +1,61 @@
[gd_scene load_steps=7 format=3 uid="uid://b62xcg0dd3vct"]
[ext_resource type="Script" uid="uid://b70f2ylbb3btt" path="res://enemies/leech/leech.gd" id="1_6u582"]
[ext_resource type="PackedScene" uid="uid://dn8qucrpq6k72" path="res://enemies/leech/segment_end.tscn" id="2_i1r8c"]
[ext_resource type="PackedScene" uid="uid://cvoicwo2xnf7e" path="res://enemies/leech/segment.tscn" id="2_oqch2"]
[ext_resource type="PackedScene" uid="uid://chs0u61f45nau" path="res://utils/earth_aligner.tscn" id="3_0r7dp"]
[ext_resource type="AudioStream" uid="uid://co07360hqn6fk" path="res://sounds/686321__cjspellsfish__punch-land-soft.wav" id="4_b1m5t"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_cq6dk"]
size = Vector2(2, 12)
[node name="Leech" type="Node2D"]
scale = Vector2(1, 1.2)
script = ExtResource("1_6u582")
broadth = 200
max_hp = 80
[node name="Segments" type="Node2D" parent="."]
[node name="SegmentEnd1" parent="Segments" instance=ExtResource("2_i1r8c")]
rotation = 3.1415927
scale = Vector2(-1, -1)
[node name="Segment2" parent="Segments" instance=ExtResource("2_oqch2")]
[node name="Segment3" parent="Segments" instance=ExtResource("2_oqch2")]
[node name="Segment4" parent="Segments" instance=ExtResource("2_oqch2")]
[node name="Segment5" parent="Segments" instance=ExtResource("2_oqch2")]
[node name="Segment6" parent="Segments" instance=ExtResource("2_oqch2")]
[node name="Segment7" parent="Segments" instance=ExtResource("2_oqch2")]
[node name="Segment8" parent="Segments" instance=ExtResource("2_oqch2")]
[node name="SegmentEnd2" parent="Segments" instance=ExtResource("2_i1r8c")]
[node name="EarthAligner" parent="." instance=ExtResource("3_0r7dp")]
[node name="RayCast2D" type="Area2D" parent="."]
position = Vector2(248, 31.2)
collision_layer = 0
collision_mask = 8
[node name="CollisionShape2D" type="CollisionShape2D" parent="RayCast2D"]
position = Vector2(0, 14.8)
shape = SubResource("RectangleShape2D_cq6dk")
[node name="RayCast2D2" type="Area2D" parent="."]
collision_layer = 0
collision_mask = 8
[node name="CollisionShape2D" type="CollisionShape2D" parent="RayCast2D2"]
position = Vector2(0, 8.8)
shape = SubResource("RectangleShape2D_cq6dk")
[node name="AudioStreamPlayer2D" type="AudioStreamPlayer2D" parent="."]
stream = ExtResource("4_b1m5t")
volume_db = 15.0

View file

@ -0,0 +1,61 @@
[gd_scene load_steps=7 format=3 uid="uid://b62xcg0dd3vct"]
[ext_resource type="Script" uid="uid://b70f2ylbb3btt" path="res://enemies/leech/leech.gd" id="1_6u582"]
[ext_resource type="PackedScene" uid="uid://dn8qucrpq6k72" path="res://enemies/leech/segment_end.tscn" id="2_i1r8c"]
[ext_resource type="PackedScene" uid="uid://cvoicwo2xnf7e" path="res://enemies/leech/segment.tscn" id="2_oqch2"]
[ext_resource type="PackedScene" uid="uid://chs0u61f45nau" path="res://utils/earth_aligner.tscn" id="3_0r7dp"]
[ext_resource type="AudioStream" uid="uid://co07360hqn6fk" path="res://sounds/686321__cjspellsfish__punch-land-soft.wav" id="4_b1m5t"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_cq6dk"]
size = Vector2(2, 12)
[node name="Leech" type="Node2D"]
scale = Vector2(1, 1.2)
script = ExtResource("1_6u582")
broadth = 200
max_hp = 80
[node name="Segments" type="Node2D" parent="."]
[node name="SegmentEnd1" parent="Segments" instance=ExtResource("2_i1r8c")]
rotation = 3.1415927
scale = Vector2(-1, -1)
[node name="Segment2" parent="Segments" instance=ExtResource("2_oqch2")]
[node name="Segment3" parent="Segments" instance=ExtResource("2_oqch2")]
[node name="Segment4" parent="Segments" instance=ExtResource("2_oqch2")]
[node name="Segment5" parent="Segments" instance=ExtResource("2_oqch2")]
[node name="Segment6" parent="Segments" instance=ExtResource("2_oqch2")]
[node name="Segment7" parent="Segments" instance=ExtResource("2_oqch2")]
[node name="Segment8" parent="Segments" instance=ExtResource("2_oqch2")]
[node name="SegmentEnd2" parent="Segments" instance=ExtResource("2_i1r8c")]
[node name="EarthAligner" parent="." instance=ExtResource("3_0r7dp")]
[node name="RayCast2D" type="Area2D" parent="."]
position = Vector2(248, 31.2)
collision_layer = 0
collision_mask = 8
[node name="CollisionShape2D" type="CollisionShape2D" parent="RayCast2D"]
position = Vector2(0, 14.8)
shape = SubResource("RectangleShape2D_cq6dk")
[node name="RayCast2D2" type="Area2D" parent="."]
collision_layer = 0
collision_mask = 8
[node name="CollisionShape2D" type="CollisionShape2D" parent="RayCast2D2"]
position = Vector2(0, 8.8)
shape = SubResource("RectangleShape2D_cq6dk")
[node name="AudioStreamPlayer2D" type="AudioStreamPlayer2D" parent="."]
stream = ExtResource("4_b1m5t")
volume_db = 15.0

View file

@ -2,11 +2,10 @@ extends Area2D
@onready var player = get_tree().get_root().get_node_or_null("main/Player")
var damage = 1
signal segment_damaged
func _physics_process(_delta: float) -> void:
func _process(_delta: float) -> void:
if (player != null and overlaps_body(player)):
player.hurt(damage, self.global_position-player.global_position)
func _on_hurtbox_damaged(dmg : int, dir : Vector2):
segment_damaged.emit(dmg, dir)
# Forward taken damage to the parent leech.
func _on_hurtbox_damaged(dmg : int, dir : Vector2, id):
get_parent().get_parent().hurt(dmg, dir, id)

BIN
enemies/leech/segment.pdn Normal file

Binary file not shown.

BIN
enemies/leech/segment.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

View file

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://bx4w0yifutm7y"
path="res://.godot/imported/segment.png-cdd72fb07696c7bd21dcdf251ba1e79d.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://enemies/leech/segment.png"
dest_files=["res://.godot/imported/segment.png-cdd72fb07696c7bd21dcdf251ba1e79d.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

View file

@ -1,20 +1,22 @@
[gd_scene load_steps=5 format=3 uid="uid://cvoicwo2xnf7e"]
[ext_resource type="Script" uid="uid://b3q5khoqnnicx" path="res://enemies/leech/segment.gd" id="1_o43lr"]
[ext_resource type="Texture2D" uid="uid://cy70quh6k3s1j" path="res://icon.svg" id="2_sa5vt"]
[ext_resource type="Texture2D" uid="uid://bx4w0yifutm7y" path="res://enemies/leech/segment.png" id="2_jsq5k"]
[ext_resource type="PackedScene" uid="uid://mtfsdd4cdf3a" path="res://utils/enemy_hurtbox.tscn" id="3_sa5vt"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_fgt1l"]
[node name="Segment" type="Area2D"]
z_index = 4
collision_layer = 0
collision_mask = 4
script = ExtResource("1_o43lr")
[node name="Sprite2D" type="Sprite2D" parent="."]
modulate = Color(0.309804, 0.113725, 0, 1)
scale = Vector2(0.315, 0.16)
texture = ExtResource("2_sa5vt")
position = Vector2(-1.9073486e-06, 0)
rotation = 1.5707964
scale = Vector2(0.6233792, 0.6257627)
texture = ExtResource("2_jsq5k")
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
scale = Vector2(2, 1)
@ -24,8 +26,10 @@ shape = SubResource("RectangleShape2D_fgt1l")
collision_layer = 16
canvasItem = NodePath("..")
flashColor = Color(2.00392, 2.00392, 2.00392, 1)
id_block_time = 0.0
[node name="CollisionShape2D" type="CollisionShape2D" parent="EnemyHurtbox"]
visible = false
scale = Vector2(2, 1)
shape = SubResource("RectangleShape2D_fgt1l")

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

View file

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://03pv5447noi8"
path="res://.godot/imported/segment_end.png-3737d47c0764ba7974a4bc464eccda0b.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://enemies/leech/segment_end.png"
dest_files=["res://.godot/imported/segment_end.png-3737d47c0764ba7974a4bc464eccda0b.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

View file

@ -0,0 +1,35 @@
[gd_scene load_steps=5 format=3 uid="uid://dn8qucrpq6k72"]
[ext_resource type="Script" uid="uid://b3q5khoqnnicx" path="res://enemies/leech/segment.gd" id="1_tokuw"]
[ext_resource type="Texture2D" uid="uid://03pv5447noi8" path="res://enemies/leech/segment_end.png" id="2_tokuw"]
[ext_resource type="PackedScene" uid="uid://mtfsdd4cdf3a" path="res://utils/enemy_hurtbox.tscn" id="3_ws4kp"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_fgt1l"]
[node name="Segment" type="Area2D"]
z_index = 4
collision_layer = 0
collision_mask = 4
script = ExtResource("1_tokuw")
[node name="Sprite2D" type="Sprite2D" parent="."]
position = Vector2(-1.9073486e-06, 0)
rotation = 1.5707964
scale = Vector2(0.6233792, 0.6257627)
texture = ExtResource("2_tokuw")
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
scale = Vector2(2, 1)
shape = SubResource("RectangleShape2D_fgt1l")
[node name="EnemyHurtbox" parent="." node_paths=PackedStringArray("canvasItem") instance=ExtResource("3_ws4kp")]
collision_layer = 16
canvasItem = NodePath("..")
flashColor = Color(2.00392, 2.00392, 2.00392, 1)
[node name="CollisionShape2D" type="CollisionShape2D" parent="EnemyHurtbox"]
visible = false
scale = Vector2(2, 1)
shape = SubResource("RectangleShape2D_fgt1l")
[connection signal="damage_taken" from="EnemyHurtbox" to="." method="_on_hurtbox_damaged"]

View file

@ -18,6 +18,8 @@ dest_files=["res://.godot/imported/icon.svg-218a8f2b3041327d8a5756f3a245f83b.cte
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
@ -25,6 +27,10 @@ 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

View file

@ -1,19 +0,0 @@
class_name ActiveItem extends Item
@export var sprite : Texture2D
func collect() -> bool:
if (player.active_item == null):
player.active_item = self
actually_collect()
return true
return false
func actually_collect():
pass
func activate():
assert(false)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 770 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

View file

@ -1,21 +0,0 @@
extends ActiveItem
var cooldown = 1.5
var dash_time = 0.2
var dashing = 0
func _physics_process(delta: float) -> void:
super(delta)
if dashing > 0:
dashing -= delta
player.reset_to_velocity = Vector2.RIGHT * player.facing * 1600
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)
dashing = dash_time
player.inv_time = max(player.inv_time, dash_time)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

View file

@ -1,13 +0,0 @@
extends ActiveItem
var cooldown = 10
func actually_collect():
player.set_cooldown(cooldown)
func activate():
$UpdashSound.play()
player.activate_cooldown()
player.reset_to_velocity = Vector2(0,1)
await get_tree().create_timer(0.1).timeout
player.reset_to_velocity = Vector2(0, -2400)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.5 KiB

View file

@ -3,8 +3,9 @@ extends Area2D
var damage = 20
var direction = Vector2(1,0)
@export var speed = 2000
@onready var dmg_id = Global.next_dmg_id
func _physics_process(delta: float) -> void:
func _process(delta: float) -> void:
self.position += delta * speed * direction
for area in get_overlapping_areas():
area.hurt(damage, -3 * direction)
area.hurt(damage, -3 * direction, dmg_id)

Binary file not shown.

After

Width:  |  Height:  |  Size: 875 B

View file

@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://bavoghl2pxs83"
path="res://.godot/imported/arror.png-9ea2fbd842e6807dfd42e9ceed411fd2.ctex"
path="res://.godot/imported/arrow.png-2cffe6fabf19679230c231a1fd8a329e.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://items/active_items/bow/arror.png"
dest_files=["res://.godot/imported/arror.png-9ea2fbd842e6807dfd42e9ceed411fd2.ctex"]
source_file="res://items/consumables/bow/arrow.png"
dest_files=["res://.godot/imported/arrow.png-2cffe6fabf19679230c231a1fd8a329e.ctex"]
[params]

View file

@ -1,7 +1,7 @@
[gd_scene load_steps=4 format=3 uid="uid://dfva4dhflxglr"]
[ext_resource type="Script" uid="uid://bglrm0bb4nla" path="res://items/active_items/bow/arrow.gd" id="1_lxthq"]
[ext_resource type="Texture2D" uid="uid://bavoghl2pxs83" path="res://items/active_items/bow/arror.png" id="2_ilsew"]
[ext_resource type="Script" uid="uid://bglrm0bb4nla" path="res://items/consumables/bow/arrow.gd" id="1_lxthq"]
[ext_resource type="Texture2D" uid="uid://bavoghl2pxs83" path="res://items/consumables/bow/arrow.png" id="2_ilsew"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_tfcgf"]
size = Vector2(20, 5)

View file

@ -0,0 +1,9 @@
[gd_scene load_steps=2 format=3 uid="uid://bu3j6ambrybd2"]
[ext_resource type="Texture2D" uid="uid://bavoghl2pxs83" path="res://items/consumables/bow/arrow.png" id="1_7lvex"]
[node name="TextureRect" type="TextureRect"]
custom_minimum_size = Vector2(0, 3)
texture = ExtResource("1_7lvex")
expand_mode = 3
stretch_mode = 3

View file

@ -1,18 +1,21 @@
extends ActiveItem
@export var cooldown = 1
@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))
arrow.direction = player.get_node("EarthAligner").right * player.facing
# 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()

Binary file not shown.

After

Width:  |  Height:  |  Size: 967 B

View file

@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://d01h01le82gyh"
path="res://.godot/imported/bow.png-5c21d924e7ed46a9ae9ef92089b84a58.ctex"
path="res://.godot/imported/bow.png-7ca2f79a3aaf0404b0d2a5f64b2c7b38.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://items/active_items/bow/bow.png"
dest_files=["res://.godot/imported/bow.png-5c21d924e7ed46a9ae9ef92089b84a58.ctex"]
source_file="res://items/consumables/bow/bow.png"
dest_files=["res://.godot/imported/bow.png-7ca2f79a3aaf0404b0d2a5f64b2c7b38.ctex"]
[params]

View file

@ -1,11 +1,12 @@
[gd_scene load_steps=9 format=3 uid="uid://ddn025xnjngko"]
[gd_scene load_steps=10 format=3 uid="uid://ddn025xnjngko"]
[ext_resource type="Script" uid="uid://bkcip66at5sug" path="res://items/active_items/bow/bow.gd" id="1_xppub"]
[ext_resource type="PackedScene" uid="uid://dfva4dhflxglr" path="res://items/active_items/bow/arrow.tscn" id="2_0id2q"]
[ext_resource type="Texture2D" uid="uid://d01h01le82gyh" path="res://items/active_items/bow/bow.png" id="3_vkelq"]
[ext_resource type="Script" uid="uid://bkcip66at5sug" path="res://items/consumables/bow/bow.gd" id="1_xppub"]
[ext_resource type="PackedScene" uid="uid://dfva4dhflxglr" path="res://items/consumables/bow/arrow.tscn" id="2_0id2q"]
[ext_resource type="Texture2D" uid="uid://d01h01le82gyh" path="res://items/consumables/bow/bow.png" id="3_vkelq"]
[ext_resource type="PackedScene" uid="uid://chs0u61f45nau" path="res://utils/earth_aligner.tscn" id="4_0id2q"]
[ext_resource type="PackedScene" uid="uid://bu3j6ambrybd2" path="res://items/consumables/bow/arrow_icon.tscn" id="4_2dslu"]
[ext_resource type="AudioStream" uid="uid://bg1w0fyeyys2p" path="res://sounds/item-equip-6904.mp3" id="5_gfbg0"]
[ext_resource type="Texture2D" uid="uid://d4mrbgfl7jpqq" path="res://items/ItemShine.png" id="5_o1smo"]
[ext_resource type="Texture2D" uid="uid://d4mrbgfl7jpqq" path="res://items/generic/ItemShine.png" id="5_o1smo"]
[ext_resource type="AudioStream" uid="uid://10ljbd4djqgb" path="res://sounds/263675__porkmuncher__bow_release_cut.wav" id="7_o1smo"]
[sub_resource type="CircleShape2D" id="CircleShape2D_gllxn"]
@ -17,6 +18,10 @@ collision_mask = 4
script = ExtResource("1_xppub")
arrow_scene = ExtResource("2_0id2q")
sprite = ExtResource("3_vkelq")
uses_left_icon = ExtResource("4_2dslu")
uses = 5
icon = ExtResource("3_vkelq")
item_name = "Bow"
[node name="EarthAligner" parent="." instance=ExtResource("4_0id2q")]
@ -26,13 +31,12 @@ scale = Vector2(2.17, 3.5)
shape = SubResource("CircleShape2D_gllxn")
[node name="Sprite2D2" type="Sprite2D" parent="."]
modulate = Color(0.583047, 0.321422, 0.988413, 1)
position = Vector2(8, 2)
scale = Vector2(1.5, 1.5)
texture = ExtResource("5_o1smo")
[node name="Sprite2D" type="Sprite2D" parent="."]
scale = Vector2(0.7, 0.7)
scale = Vector2(1.4, 1.4)
texture = ExtResource("3_vkelq")
[node name="AudioStreamPlayer2D" type="AudioStreamPlayer2D" parent="."]

View file

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 928 B

View file

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://dog2yksitfgu1"
path="res://.godot/imported/heal_item.png-8a8830bfa8056f0430b6f7daf94a6634.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://items/consumables/heal_item/heal_item.png"
dest_files=["res://.godot/imported/heal_item.png-8a8830bfa8056f0430b6f7daf94a6634.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

View file

@ -1,15 +1,18 @@
[gd_scene load_steps=7 format=3 uid="uid://b00185vygcka1"]
[gd_scene load_steps=8 format=3 uid="uid://b00185vygcka1"]
[ext_resource type="Script" uid="uid://b43fudwi47qfd" path="res://items/immediate_items/heal_item/heal_item.gd" id="1_3vbv8"]
[ext_resource type="Script" uid="uid://b43fudwi47qfd" path="res://items/consumables/heal_item/heal_item.gd" id="1_3vbv8"]
[ext_resource type="Texture2D" uid="uid://dog2yksitfgu1" path="res://items/consumables/heal_item/heal_item.png" id="2_bqles"]
[ext_resource type="PackedScene" uid="uid://chs0u61f45nau" path="res://utils/earth_aligner.tscn" id="2_evqwq"]
[ext_resource type="Texture2D" uid="uid://djfc7sdc8wxp6" path="res://player/Heart_cut.png" id="3_fvuym"]
[ext_resource type="Texture2D" uid="uid://d4mrbgfl7jpqq" path="res://items/ItemShine.png" id="4_sr4am"]
[ext_resource type="Texture2D" uid="uid://d4mrbgfl7jpqq" path="res://items/generic/ItemShine.png" id="4_sr4am"]
[ext_resource type="AudioStream" uid="uid://b37akn7hmk2r3" path="res://sounds/471834__keshafilm__health-pickup.wav" id="5_1ujdq"]
[sub_resource type="CircleShape2D" id="CircleShape2D_hvhjo"]
[node name="HealItem" type="Area2D"]
script = ExtResource("1_3vbv8")
icon = ExtResource("2_bqles")
item_name = "HP +1"
[node name="EarthAligner" parent="." instance=ExtResource("2_evqwq")]
@ -18,7 +21,6 @@ scale = Vector2(2.4, 3.36)
shape = SubResource("CircleShape2D_hvhjo")
[node name="Sprite2D2" type="Sprite2D" parent="."]
position = Vector2(1, -1)
scale = Vector2(1.2, 1.2)
texture = ExtResource("4_sr4am")

View file

@ -0,0 +1,36 @@
extends ActiveItem
@export var cooldown = 0.2
var dash_time = 0.15
var dash_timer : SceneTreeTimer
var dash_velocity
var dash_speed = 1600
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.get_node("EarthAligner").local_from_global(dash_velocity)
func actually_collect():
player.set_cooldown(cooldown)
func activate():
$DashSound.play()
player.activate_cooldown()
# 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_velocity = player.get_node("EarthAligner").right * player.facing * dash_speed
player.get_node("IFrames").start(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
await dash_timer.timeout
super(false)
else:
super()

View file

@ -1,8 +1,8 @@
[gd_scene load_steps=8 format=3 uid="uid://dy17xhg1yrl0o"]
[ext_resource type="Script" uid="uid://jq326dmuaj22" path="res://items/active_items/horizontal_dash/horizontal_dash.gd" id="1_ktd5x"]
[ext_resource type="Texture2D" uid="uid://cnn3tadylge8y" path="res://items/active_items/horizontal_dash/horizontaldash.png" id="3_ktd5x"]
[ext_resource type="Texture2D" uid="uid://d4mrbgfl7jpqq" path="res://items/ItemShine.png" id="3_vqrqe"]
[ext_resource type="Script" uid="uid://jq326dmuaj22" path="res://items/consumables/horizontal_dash/horizontal_dash.gd" id="1_ktd5x"]
[ext_resource type="Texture2D" uid="uid://cnn3tadylge8y" path="res://items/consumables/horizontal_dash/horizontaldash.png" id="3_ktd5x"]
[ext_resource type="Texture2D" uid="uid://d4mrbgfl7jpqq" path="res://items/generic/ItemShine.png" id="3_vqrqe"]
[ext_resource type="PackedScene" uid="uid://chs0u61f45nau" path="res://utils/earth_aligner.tscn" id="4_gtuhj"]
[ext_resource type="AudioStream" uid="uid://bg1w0fyeyys2p" path="res://sounds/item-equip-6904.mp3" id="5_5y0ew"]
[ext_resource type="AudioStream" uid="uid://ds0yw3au0quae" path="res://sounds/whoosh.mp3" id="6_a6gm0"]
@ -14,6 +14,8 @@ radius = 12.6667
scale = Vector2(1.4, 1.4)
script = ExtResource("1_ktd5x")
sprite = ExtResource("3_ktd5x")
icon = ExtResource("3_ktd5x")
item_name = "Dash"
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
visible = false
@ -30,14 +32,13 @@ scale = Vector2(1, 4)
shape = SubResource("CircleShape2D_ktd5x")
[node name="Sprite2D2" type="Sprite2D" parent="."]
modulate = Color(0.725757, 0.519822, 5.77569e-07, 1)
position = Vector2(-2, 14)
scale = Vector2(1.2, 1.2)
texture = ExtResource("3_vqrqe")
[node name="Sprite2D" type="Sprite2D" parent="."]
position = Vector2(4.9999995, 12.999999)
scale = Vector2(0.8, 0.8)
scale = Vector2(1.6, 1.6)
texture = ExtResource("3_ktd5x")
[node name="EarthAligner" parent="." instance=ExtResource("4_gtuhj")]

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://cnn3tadylge8y"
path="res://.godot/imported/horizontaldash.png-3a6880e60346d9b8d19d47557212a382.ctex"
path="res://.godot/imported/horizontaldash.png-9fe6fddd3110882a6c56740b08ea51eb.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://items/active_items/horizontal_dash/horizontaldash.png"
dest_files=["res://.godot/imported/horizontaldash.png-3a6880e60346d9b8d19d47557212a382.ctex"]
source_file="res://items/consumables/horizontal_dash/horizontaldash.png"
dest_files=["res://.godot/imported/horizontaldash.png-9fe6fddd3110882a6c56740b08ea51eb.ctex"]
[params]

View file

@ -0,0 +1,24 @@
extends ActiveItem
var cooldown = 10
var timer : SceneTreeTimer
func actually_collect():
player.set_cooldown(cooldown)
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:
await timer.timeout
super(false)

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

View file

@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://dxcfkdhl4g24c"
path="res://.godot/imported/updash.png-ddc6856a4b101f20557ef85572ee190a.ctex"
path="res://.godot/imported/updash.png-6cf7335cc7a138df6d0425e524bb4bb8.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://items/active_items/updash/updash.png"
dest_files=["res://.godot/imported/updash.png-ddc6856a4b101f20557ef85572ee190a.ctex"]
source_file="res://items/consumables/updash/updash.png"
dest_files=["res://.godot/imported/updash.png-6cf7335cc7a138df6d0425e524bb4bb8.ctex"]
[params]

View file

@ -1,9 +1,9 @@
[gd_scene load_steps=8 format=3 uid="uid://ewe36lqcjojk"]
[ext_resource type="Script" uid="uid://bbwsc2a2hd0ow" path="res://items/active_items/updash/updash.gd" id="1_ghbl6"]
[ext_resource type="Texture2D" uid="uid://dxcfkdhl4g24c" path="res://items/active_items/updash/updash.png" id="3_a5yxq"]
[ext_resource type="Script" uid="uid://bbwsc2a2hd0ow" path="res://items/consumables/updash/updash.gd" id="1_ghbl6"]
[ext_resource type="Texture2D" uid="uid://dxcfkdhl4g24c" path="res://items/consumables/updash/updash.png" id="3_a5yxq"]
[ext_resource type="PackedScene" uid="uid://chs0u61f45nau" path="res://utils/earth_aligner.tscn" id="3_ktv3s"]
[ext_resource type="Texture2D" uid="uid://d4mrbgfl7jpqq" path="res://items/ItemShine.png" id="3_ssiqx"]
[ext_resource type="Texture2D" uid="uid://d4mrbgfl7jpqq" path="res://items/generic/ItemShine.png" id="3_ssiqx"]
[ext_resource type="AudioStream" uid="uid://bg1w0fyeyys2p" path="res://sounds/item-equip-6904.mp3" id="5_ssiqx"]
[ext_resource type="AudioStream" uid="uid://ds0yw3au0quae" path="res://sounds/whoosh.mp3" id="6_mbe12"]
@ -13,27 +13,26 @@ radius = 12.6667
[node name="Updash" type="Area2D"]
script = ExtResource("1_ghbl6")
sprite = ExtResource("3_a5yxq")
icon = ExtResource("3_a5yxq")
item_name = "Upward Boost"
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
visible = false
position = Vector2(0, 19)
scale = Vector2(3, 2)
scale = Vector2(3.3, 2.2)
shape = SubResource("CircleShape2D_ghbl6")
[node name="CollisionShape2D2" type="CollisionShape2D" parent="."]
visible = false
position = Vector2(0, -4)
scale = Vector2(1, 4)
scale = Vector2(1.1, 4.4)
shape = SubResource("CircleShape2D_ghbl6")
[node name="Sprite2D2" type="Sprite2D" parent="."]
modulate = Color(0.583047, 0.321422, 0.988413, 1)
position = Vector2(0, 15)
scale = Vector2(1.2, 1.2)
scale = Vector2(1.4, 1.4)
texture = ExtResource("3_ssiqx")
[node name="Sprite2D" type="Sprite2D" parent="."]
scale = Vector2(0.8, 0.8)
scale = Vector2(1.8, 1.8)
texture = ExtResource("3_a5yxq")
[node name="EarthAligner" parent="." instance=ExtResource("3_ktv3s")]

View file

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View file

@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://d4mrbgfl7jpqq"
path="res://.godot/imported/ItemShine.png-41425a3fac8f6530e2b2e4df0c180258.ctex"
path="res://.godot/imported/ItemShine.png-034066fd9fe20ff0370bbee7c72c08ef.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://items/ItemShine.png"
dest_files=["res://.godot/imported/ItemShine.png-41425a3fac8f6530e2b2e4df0c180258.ctex"]
source_file="res://items/generic/ItemShine.png"
dest_files=["res://.godot/imported/ItemShine.png-034066fd9fe20ff0370bbee7c72c08ef.ctex"]
[params]

View file

@ -0,0 +1,52 @@
class_name ActiveItem extends Item
@onready var active_item_uses = get_tree().get_root().get_node_or_null("main/UIOverlay/ActiveItemUses")
@export var sprite : Texture2D
@export var uses_left_icon : PackedScene
@export var uses = 1:
set(new_uses):
uses = new_uses
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
func trigger_activation():
activate()
if uses != -1:
uses -= 1
if uses == 0:
remove()
# Intended to be overridden by item classes.
func activate():
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
if reset_player_active:
player.active_item = null
self.queue_free()

View file

@ -1,9 +1,13 @@
class_name Item extends Area2D
@onready var player = get_tree().get_root().get_node_or_null("main/Player")
var collected = false
@export var icon : Texture2D
@export var item_name : String = ""
func _physics_process(_delta: float) -> void:
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)
@ -11,10 +15,12 @@ func _physics_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

View file

@ -0,0 +1,4 @@
class_name ItemPool extends Resource
@export var common : Array[PackedScene]
@export var rare : Array[PackedScene]
@export var unique : Array[PackedScene]

View file

@ -0,0 +1 @@
uid://bgbqefa6h7ckv

View file

@ -0,0 +1,18 @@
[gd_resource type="Resource" script_class="ItemPool" load_steps=11 format=3 uid="uid://m6yj45qvoecs"]
[ext_resource type="PackedScene" uid="uid://b00185vygcka1" path="res://items/consumables/heal_item/heal_item.tscn" id="1_rli0f"]
[ext_resource type="PackedScene" uid="uid://dy17xhg1yrl0o" path="res://items/consumables/horizontal_dash/horizontal_dash.tscn" id="2_g002j"]
[ext_resource type="PackedScene" uid="uid://ddn025xnjngko" path="res://items/consumables/bow/bow.tscn" id="3_vpswe"]
[ext_resource type="PackedScene" uid="uid://ewe36lqcjojk" path="res://items/consumables/updash/updash.tscn" id="4_jwi73"]
[ext_resource type="PackedScene" uid="uid://gwctb2xqsbj" path="res://items/rare_items/healthup/healthup.tscn" id="5_73uum"]
[ext_resource type="Script" uid="uid://bgbqefa6h7ckv" path="res://items/generic/item_pool.gd" id="6_rli0f"]
[ext_resource type="PackedScene" uid="uid://bbpf28ohayd8n" path="res://items/unique_items/backslash/backslash.tscn" id="7_k6eth"]
[ext_resource type="PackedScene" uid="uid://bpgo1djj8f1rg" path="res://items/unique_items/high_jump/high_jump.tscn" id="8_8cxou"]
[ext_resource type="PackedScene" uid="uid://bwtdls58ajair" path="res://items/unique_items/upslash/upslash.tscn" id="9_esvgx"]
[ext_resource type="PackedScene" uid="uid://wc7kgtomy6xm" path="res://items/unique_items/extrajump/extrajump.tscn" id="10_l52h1"]
[resource]
script = ExtResource("6_rli0f")
common = Array[PackedScene]([ExtResource("1_rli0f"), ExtResource("1_rli0f"), ExtResource("1_rli0f"), ExtResource("2_g002j"), ExtResource("3_vpswe"), ExtResource("4_jwi73")])
rare = Array[PackedScene]([ExtResource("5_73uum")])
unique = Array[PackedScene]([ExtResource("7_k6eth"), ExtResource("8_8cxou"), ExtResource("9_esvgx"), ExtResource("10_l52h1"), ExtResource("5_73uum"), ExtResource("5_73uum"), ExtResource("5_73uum")])

View file

@ -1,45 +1,55 @@
class_name ItemSpawn extends Node2D
@export var common_items : Array[PackedScene]
@export var rare_items : Array[PackedScene]
static var unique_items : Array[PackedScene] = []
static var item_pool = ResourceLoader.load("res://items/generic/item_pool.tres","",ResourceLoader.CACHE_MODE_IGNORE)
@export var rarity_bonus = 0
@export var rarity_bonus : float = 0
@export var guarantee_rare : bool = false
@export var unique_base_chance = .03
@export var rare_base_chance = .2
@export var unique_bonus_multiplier = .025
@export var rare_bonus_multiplier = .1
@export var unique_base_chance = 0.24
@export var rare_base_chance = 0
@export var unique_bonus_multiplier = .05
@export var rare_bonus_multiplier = 0
@export var spawn_petal = true
@export var petal_scene : PackedScene = ResourceLoader.load("res://vines_petals/petal.tscn")
var packed_item_scene : PackedScene
var remove_after_spawn = false
# Choose the item pool this spawn location draws from
func choose_pool() -> Array[PackedScene]:
spawn_petal = false
var unique_chance = unique_base_chance + unique_bonus_multiplier * rarity_bonus
var rare_chance = unique_base_chance + unique_bonus_multiplier * rarity_bonus
var rare_chance = rare_base_chance + rare_bonus_multiplier * rarity_bonus
var random = randf()
if random < unique_chance && unique_items.size() > 0:
if random < unique_chance && item_pool.unique.size() > 0:
# Unique items are removed from the pool when picked
remove_after_spawn = true
return unique_items
return item_pool.unique
elif random < unique_chance + rare_chance || guarantee_rare:
return rare_items
return common_items
return item_pool.rare
return item_pool.common
# Places a petal holding this item
func instantiate_petal(item):
var petal : Petal = petal_scene.instantiate()
get_parent().call_deferred("add_child", petal)
petal.item = item
petal.global_position = global_position
func _ready():
# Pick a random pool and a random item from it, then remove it if unique.
var pool = choose_pool()
var index = randi_range(0, pool.size() - 1)
var packed_scene : PackedScene = pool[index]
packed_item_scene = pool[index]
if remove_after_spawn:
unique_items.remove_at(index)
var object = packed_scene.instantiate()
item_pool.unique.remove_at(index)
# Place the item, possibly inside a petal
if packed_item_scene == null: return
var object = packed_item_scene.instantiate()
add_child.call_deferred(object)
object.reparent.call_deferred(get_parent())
static func refill_unique_item_pool():
unique_items = [
load("res://items/permanent_items/backslash.tscn"),
load("res://items/permanent_items/high_jump.tscn"),
load("res://items/permanent_items/upslash.tscn"),
load("res://items/active_items/horizontal_dash/horizontal_dash.tscn")
]
if spawn_petal: instantiate_petal(object)

View file

@ -1,19 +1,12 @@
[gd_scene load_steps=8 format=3 uid="uid://xj0of571aur1"]
[gd_scene load_steps=4 format=3 uid="uid://xj0of571aur1"]
[ext_resource type="Script" uid="uid://b8em61mqgdi58" path="res://items/generic/item_spawn.gd" id="1_ms6tn"]
[ext_resource type="PackedScene" uid="uid://b00185vygcka1" path="res://items/immediate_items/heal_item/heal_item.tscn" id="2_w6i8k"]
[ext_resource type="PackedScene" uid="uid://bhhhvaqhm3ctc" path="res://vines_petals/petal.tscn" id="2_5to52"]
[ext_resource type="PackedScene" uid="uid://chs0u61f45nau" path="res://utils/earth_aligner.tscn" id="3_5pwuf"]
[ext_resource type="PackedScene" uid="uid://gwctb2xqsbj" path="res://items/immediate_items/healthup/healthup.tscn" id="3_yi7ag"]
[ext_resource type="PackedScene" uid="uid://ddn025xnjngko" path="res://items/active_items/bow/bow.tscn" id="4_v0ua0"]
[ext_resource type="PackedScene" uid="uid://ewe36lqcjojk" path="res://items/active_items/updash/updash.tscn" id="5_uitgx"]
[ext_resource type="PackedScene" uid="uid://wc7kgtomy6xm" path="res://items/permanent_items/extrajump.tscn" id="6_xqgya"]
[node name="ItemSpawn" type="Node2D"]
script = ExtResource("1_ms6tn")
common_items = Array[PackedScene]([ExtResource("2_w6i8k")])
rare_items = Array[PackedScene]([ExtResource("4_v0ua0"), ExtResource("5_uitgx"), ExtResource("3_yi7ag"), ExtResource("6_xqgya")])
unique_base_chance = 0.1
rare_base_chance = 0.3
petal_scene = ExtResource("2_5to52")
metadata/_custom_type_script = "uid://b8em61mqgdi58"
[node name="EarthAligner" parent="." instance=ExtResource("3_5pwuf")]

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

View file

@ -1,6 +0,0 @@
extends Item
func collect():
player.jump_strength = 1500
$SoundCollect.play()
return true

Binary file not shown.

Before

Width:  |  Height:  |  Size: 705 B

View file

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 3 KiB

View file

@ -0,0 +1,40 @@
[remap]
importer="texture"
type="CompressedTexture2D"
uid="uid://cp4uia4l6j5nt"
path="res://.godot/imported/healthup.png-2c1ab3085e0e24d17f4f5b1fcfed814f.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://items/rare_items/healthup/healthup.png"
dest_files=["res://.godot/imported/healthup.png-2c1ab3085e0e24d17f4f5b1fcfed814f.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

View file

@ -1,16 +1,17 @@
[gd_scene load_steps=8 format=3 uid="uid://gwctb2xqsbj"]
[gd_scene load_steps=7 format=3 uid="uid://gwctb2xqsbj"]
[ext_resource type="Script" uid="uid://ce6fxbjarlvtk" path="res://items/immediate_items/healthup/healthup.gd" id="1_ivtxh"]
[ext_resource type="Script" uid="uid://ce6fxbjarlvtk" path="res://items/rare_items/healthup/healthup.gd" id="1_ivtxh"]
[ext_resource type="Texture2D" uid="uid://cp4uia4l6j5nt" path="res://items/rare_items/healthup/healthup.png" id="2_gb062"]
[ext_resource type="PackedScene" uid="uid://chs0u61f45nau" path="res://utils/earth_aligner.tscn" id="2_lolop"]
[ext_resource type="Texture2D" uid="uid://d4mrbgfl7jpqq" path="res://items/ItemShine.png" id="3_gb062"]
[ext_resource type="Texture2D" uid="uid://ctwu08w867gax" path="res://player/Heart_cut Grey.png" id="4_uq82b"]
[ext_resource type="Texture2D" uid="uid://djfc7sdc8wxp6" path="res://player/Heart_cut.png" id="5_m76tj"]
[ext_resource type="Texture2D" uid="uid://d4mrbgfl7jpqq" path="res://items/generic/ItemShine.png" id="3_gb062"]
[ext_resource type="AudioStream" uid="uid://b37akn7hmk2r3" path="res://sounds/471834__keshafilm__health-pickup.wav" id="6_uq82b"]
[sub_resource type="CircleShape2D" id="CircleShape2D_rlcnv"]
[node name="HealthUp" type="Area2D"]
script = ExtResource("1_ivtxh")
icon = ExtResource("2_gb062")
item_name = "Max HP +1"
[node name="EarthAligner" parent="." instance=ExtResource("2_lolop")]
@ -22,19 +23,13 @@ shape = SubResource("CircleShape2D_rlcnv")
[node name="Sprite2D2" type="Sprite2D" parent="."]
modulate = Color(0.583047, 0.321422, 0.988413, 1)
position = Vector2(1, -1)
scale = Vector2(1.2, 1.2)
scale = Vector2(1.4, 1.4)
texture = ExtResource("3_gb062")
[node name="Sprite2D3" type="Sprite2D" parent="."]
modulate = Color(1, 0.853464, 0.355128, 1)
position = Vector2(5, -3)
scale = Vector2(1.6, 1.6)
texture = ExtResource("4_uq82b")
[node name="Sprite2D" type="Sprite2D" parent="."]
position = Vector2(4, -3)
scale = Vector2(1.4, 1.4)
texture = ExtResource("5_m76tj")
scale = Vector2(1.5, 1.5)
texture = ExtResource("2_gb062")
[node name="AudioStreamPlayer2D" type="AudioStreamPlayer2D" parent="."]
stream = ExtResource("6_uq82b")

View file

@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View file

@ -3,15 +3,15 @@
importer="texture"
type="CompressedTexture2D"
uid="uid://c7mrm8uel7r36"
path="res://.godot/imported/backslash.png-149a372aa6b01851fbdc2c6a7a2e54db.ctex"
path="res://.godot/imported/backslash.png-d9537e0b7044cf5f7b1de9b329c0275d.ctex"
metadata={
"vram_texture": false
}
[deps]
source_file="res://items/permanent_items/backslash.png"
dest_files=["res://.godot/imported/backslash.png-149a372aa6b01851fbdc2c6a7a2e54db.ctex"]
source_file="res://items/unique_items/backslash/backslash.png"
dest_files=["res://.godot/imported/backslash.png-d9537e0b7044cf5f7b1de9b329c0275d.ctex"]
[params]

View file

@ -1,10 +1,10 @@
[gd_scene load_steps=8 format=3 uid="uid://bbpf28ohayd8n"]
[ext_resource type="Script" uid="uid://blg876atd71cg" path="res://items/permanent_items/backslash.gd" id="1_s4bdx"]
[ext_resource type="Script" uid="uid://blg876atd71cg" path="res://items/unique_items/backslash/backslash.gd" id="1_s4bdx"]
[ext_resource type="PackedScene" uid="uid://chs0u61f45nau" path="res://utils/earth_aligner.tscn" id="2_kiuxs"]
[ext_resource type="PackedScene" uid="uid://d3e3kuyeh6mr1" path="res://player/sword.tscn" id="2_u6vk4"]
[ext_resource type="Texture2D" uid="uid://d4mrbgfl7jpqq" path="res://items/ItemShine.png" id="4_legpc"]
[ext_resource type="Texture2D" uid="uid://c7mrm8uel7r36" path="res://items/permanent_items/backslash.png" id="5_qg660"]
[ext_resource type="Texture2D" uid="uid://d4mrbgfl7jpqq" path="res://items/generic/ItemShine.png" id="4_legpc"]
[ext_resource type="Texture2D" uid="uid://c7mrm8uel7r36" path="res://items/unique_items/backslash/backslash.png" id="5_qg660"]
[ext_resource type="AudioStream" uid="uid://pdd0sy3p4y0d" path="res://sounds/750240__universfield__coin-drop.mp3" id="6_qg660"]
[sub_resource type="CircleShape2D" id="CircleShape2D_hvhjo"]
@ -12,22 +12,23 @@
[node name="Backslash" type="Area2D"]
script = ExtResource("1_s4bdx")
sword = ExtResource("2_u6vk4")
icon = ExtResource("5_qg660")
item_name = "Second Blade"
[node name="EarthAligner" parent="." instance=ExtResource("2_kiuxs")]
[node name="CollisionShape2D" type="CollisionShape2D" parent="."]
visible = false
scale = Vector2(7, 7)
scale = Vector2(4, 4)
shape = SubResource("CircleShape2D_hvhjo")
[node name="Sprite2D2" type="Sprite2D" parent="."]
modulate = Color(0.725757, 0.519822, 5.77569e-07, 1)
scale = Vector2(2.5, 2.5)
scale = Vector2(1.4, 1.4)
texture = ExtResource("4_legpc")
[node name="Sprite2D" type="Sprite2D" parent="."]
position = Vector2(-3, -2)
scale = Vector2(1.2, 1.2)
scale = Vector2(1.6, 1.6)
texture = ExtResource("5_qg660")
[node name="AudioStreamPlayer2D" type="AudioStreamPlayer2D" parent="."]

Some files were not shown because too many files have changed in this diff Show more