mirror of
https://github.com/JHDev2006/Super-Mario-Bros.-Remastered-Public.git
synced 2025-10-22 15:38:14 +00:00
added the game
This commit is contained in:
29
Scripts/Classes/Entities/Enemies/Barrel.gd
Normal file
29
Scripts/Classes/Entities/Enemies/Barrel.gd
Normal file
@@ -0,0 +1,29 @@
|
||||
extends Enemy
|
||||
|
||||
const MOVE_SPEED := 30
|
||||
const BARREL_DESTRUCTION_PARTICLE = preload("res://Scenes/Prefabs/Particles/BarrelDestructionParticle.tscn")
|
||||
func _physics_process(delta: float) -> void:
|
||||
handle_movement(delta)
|
||||
|
||||
func handle_movement(delta: float) -> void:
|
||||
if is_on_wall() and is_on_floor() and get_wall_normal().x == -direction:
|
||||
die()
|
||||
|
||||
func die() -> void:
|
||||
destroy()
|
||||
|
||||
func die_from_object(_node: Node2D) -> void:
|
||||
destroy()
|
||||
|
||||
func summon_particle() -> void:
|
||||
var node = BARREL_DESTRUCTION_PARTICLE.instantiate()
|
||||
node.global_position = global_position - Vector2(0, 8)
|
||||
add_sibling(node)
|
||||
|
||||
func destroy() -> void:
|
||||
summon_particle()
|
||||
AudioManager.play_sfx("block_break", global_position)
|
||||
queue_free()
|
||||
|
||||
func bounce_up() -> void:
|
||||
velocity.y = -200
|
1
Scripts/Classes/Entities/Enemies/Barrel.gd.uid
Executable file
1
Scripts/Classes/Entities/Enemies/Barrel.gd.uid
Executable file
@@ -0,0 +1 @@
|
||||
uid://dkg8usmlrm1d3
|
10
Scripts/Classes/Entities/Enemies/BasicEnemy.gd
Executable file
10
Scripts/Classes/Entities/Enemies/BasicEnemy.gd
Executable file
@@ -0,0 +1,10 @@
|
||||
extends Enemy
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
handle_movement(delta)
|
||||
|
||||
func handle_movement(delta: float) -> void:
|
||||
apply_enemy_gravity(delta)
|
||||
if is_on_floor():
|
||||
velocity.x = lerpf(velocity.x, 0, delta * 10)
|
||||
move_and_slide()
|
1
Scripts/Classes/Entities/Enemies/BasicEnemy.gd.uid
Executable file
1
Scripts/Classes/Entities/Enemies/BasicEnemy.gd.uid
Executable file
@@ -0,0 +1 @@
|
||||
uid://q44gfy2ffos5
|
29
Scripts/Classes/Entities/Enemies/Blooper.gd
Normal file
29
Scripts/Classes/Entities/Enemies/Blooper.gd
Normal file
@@ -0,0 +1,29 @@
|
||||
extends Enemy
|
||||
|
||||
var falling := true
|
||||
var target_player: Player = null
|
||||
var can_rise := true
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
target_player = get_tree().get_first_node_in_group("Players")
|
||||
if falling:
|
||||
global_position.y += 32 * delta
|
||||
if global_position.y >= target_player.global_position.y - 24 and can_rise:
|
||||
rise_tween()
|
||||
$Sprite.play("Fall")
|
||||
else:
|
||||
$Sprite.play("Rise")
|
||||
|
||||
func rise_tween() -> void:
|
||||
falling = false
|
||||
can_rise = false
|
||||
var tween = create_tween().set_trans(Tween.TRANS_CUBIC)
|
||||
var dir = sign(target_player.global_position.x - global_position.x)
|
||||
var target_position := Vector2(32 * dir, -32)
|
||||
var final_position = global_position + target_position
|
||||
final_position.y = clamp(final_position.y, -176, 64)
|
||||
tween.tween_property(self, "global_position", final_position, 0.75)
|
||||
await tween.finished
|
||||
falling = true
|
||||
await get_tree().create_timer(0.25, false).timeout
|
||||
can_rise = true
|
1
Scripts/Classes/Entities/Enemies/Blooper.gd.uid
Executable file
1
Scripts/Classes/Entities/Enemies/Blooper.gd.uid
Executable file
@@ -0,0 +1 @@
|
||||
uid://coocdv3t4548x
|
23
Scripts/Classes/Entities/Enemies/BobOmb.gd
Normal file
23
Scripts/Classes/Entities/Enemies/BobOmb.gd
Normal file
@@ -0,0 +1,23 @@
|
||||
extends Enemy
|
||||
|
||||
@export var held_scene: PackedScene = null
|
||||
|
||||
func stomped_on(player: Player) -> void:
|
||||
player.enemy_bounce_off()
|
||||
AudioManager.play_sfx("enemy_stomp", global_position)
|
||||
summon_held()
|
||||
|
||||
func summon_held() -> Node:
|
||||
var node = held_scene.instantiate()
|
||||
node.global_position = global_position
|
||||
node.direction = direction
|
||||
if $TrackJoint.is_attached:
|
||||
get_parent().owner.add_sibling(node)
|
||||
else:
|
||||
add_sibling(node)
|
||||
queue_free()
|
||||
return node
|
||||
|
||||
func fireball_hit(fireball: Node2D) -> void:
|
||||
var held = summon_held()
|
||||
held.kick(fireball)
|
1
Scripts/Classes/Entities/Enemies/BobOmb.gd.uid
Executable file
1
Scripts/Classes/Entities/Enemies/BobOmb.gd.uid
Executable file
@@ -0,0 +1 @@
|
||||
uid://br4ltfynb4eqr
|
52
Scripts/Classes/Entities/Enemies/Boo.gd
Normal file
52
Scripts/Classes/Entities/Enemies/Boo.gd
Normal file
@@ -0,0 +1,52 @@
|
||||
extends Node2D
|
||||
|
||||
var target_player: Player = null
|
||||
|
||||
var velocity := Vector2.ZERO
|
||||
|
||||
const MOVE_SPEED := 30
|
||||
const SMOKE_PARTICLE = preload("uid://d08nv4qtfouv1")
|
||||
var direction := -1
|
||||
|
||||
signal killed
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
target_player = get_tree().get_first_node_in_group("Players")
|
||||
if $TrackJoint.is_attached == false:
|
||||
handle_movement(delta)
|
||||
$Sprite.scale.x = direction
|
||||
|
||||
func handle_movement(delta: float) -> void:
|
||||
var target_direction = sign(target_player.global_position.x - global_position.x)
|
||||
if target_direction != 0:
|
||||
direction = target_direction
|
||||
if target_player.direction == direction:
|
||||
if $Sprite.animation != "Move":
|
||||
$Sprite.play("Move")
|
||||
velocity = lerp(velocity, 30 * global_position.direction_to(target_player.global_position), delta * 5)
|
||||
else:
|
||||
if $Sprite.animation != "Idle":
|
||||
$Sprite.play("Idle")
|
||||
velocity = lerp(velocity, Vector2.ZERO, delta * 5)
|
||||
global_position += velocity * delta
|
||||
|
||||
|
||||
func on_area_entered(area: Area2D) -> void:
|
||||
if area.owner is Player:
|
||||
if area.owner.is_invincible:
|
||||
die()
|
||||
else:
|
||||
area.owner.damage()
|
||||
|
||||
func die() -> void:
|
||||
summon_smoke_particle()
|
||||
queue_free()
|
||||
killed.emit()
|
||||
|
||||
func flag_die() -> void:
|
||||
die()
|
||||
|
||||
func summon_smoke_particle() -> void:
|
||||
var particle = SMOKE_PARTICLE.instantiate()
|
||||
particle.global_position = global_position
|
||||
add_sibling(particle)
|
1
Scripts/Classes/Entities/Enemies/Boo.gd.uid
Executable file
1
Scripts/Classes/Entities/Enemies/Boo.gd.uid
Executable file
@@ -0,0 +1 @@
|
||||
uid://bbp3jg7yg1700
|
18
Scripts/Classes/Entities/Enemies/BooBuddies.gd
Normal file
18
Scripts/Classes/Entities/Enemies/BooBuddies.gd
Normal file
@@ -0,0 +1,18 @@
|
||||
extends Node2D
|
||||
|
||||
@export_range(25, 180) var length := 80
|
||||
@export_enum("Clockwise", "C-Clockwise") var direction := 0
|
||||
@export_range(4, 12) var boo_amount := 10
|
||||
@export var spread_boos := false
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
%RotationJoint.global_rotation_degrees = wrap(%RotationJoint.global_rotation_degrees + (45 * [1, -1][direction]) * delta, 0, 360)
|
||||
for i in $Boos.get_children():
|
||||
i.get_node("Sprite").scale.x = sign(get_tree().get_first_node_in_group("Players").global_position.x + 1 - i.global_position.x)
|
||||
|
||||
func on_area_entered(area: Area2D) -> void:
|
||||
if area.owner is Player:
|
||||
area.owner.damage()
|
||||
|
||||
func flag_die() -> void:
|
||||
queue_free()
|
1
Scripts/Classes/Entities/Enemies/BooBuddies.gd.uid
Executable file
1
Scripts/Classes/Entities/Enemies/BooBuddies.gd.uid
Executable file
@@ -0,0 +1 @@
|
||||
uid://djdtghrjbpv2i
|
144
Scripts/Classes/Entities/Enemies/Bowser.gd
Normal file
144
Scripts/Classes/Entities/Enemies/Bowser.gd
Normal file
@@ -0,0 +1,144 @@
|
||||
extends Enemy
|
||||
|
||||
const BOWSER_FLAME = preload("res://Scenes/Prefabs/Entities/Enemies/BowserFlame.tscn")
|
||||
const HAMMER = preload("res://Scenes/Prefabs/Entities/Items/Hammer.tscn")
|
||||
@onready var sprite: BetterAnimatedSprite2D = $SpriteScaleJoint/Sprite
|
||||
|
||||
@export var can_hammer := false
|
||||
@export var can_fire := true
|
||||
|
||||
@export var music_enabled := true
|
||||
|
||||
var target_player: Player = null
|
||||
|
||||
var can_move := true
|
||||
var can_fall := true
|
||||
|
||||
var health := 5
|
||||
|
||||
var move_dir := -1
|
||||
|
||||
func _ready() -> void:
|
||||
for i in [$JumpTimer, $HammerTime, $FlameTimer]:
|
||||
i.start()
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
target_player = get_tree().get_nodes_in_group("Players")[0]
|
||||
if is_on_floor():
|
||||
direction = sign(target_player.global_position.x - global_position.x)
|
||||
velocity.x = 0
|
||||
sprite.scale.x = direction
|
||||
if can_fall:
|
||||
apply_enemy_gravity(delta)
|
||||
move_and_slide()
|
||||
if Input.is_action_just_pressed("editor_move_player") and Global.debug_mode:
|
||||
die()
|
||||
|
||||
func jump() -> void:
|
||||
if is_on_floor():
|
||||
velocity.y = -100
|
||||
$JumpTimer.start(randf_range(1, 2.5))
|
||||
|
||||
func apply_enemy_gravity(delta: float) -> void:
|
||||
velocity.y += (2.5 / delta) * delta
|
||||
velocity.y = clamp(velocity.y, -INF, Global.entity_max_fall_speed)
|
||||
|
||||
func get_target_y(player: Player) -> float:
|
||||
if player.global_position.y + 16 < global_position.y:
|
||||
return player.global_position.y - 32
|
||||
else:
|
||||
return player.global_position.y - 8
|
||||
|
||||
func show_smoke() -> void:
|
||||
if has_meta("is_real"):
|
||||
return
|
||||
var smoke = preload("res://Scenes/Prefabs/Particles/SmokeParticle.tscn").instantiate()
|
||||
smoke.scale = Vector2(2, 2)
|
||||
smoke.global_position =global_position
|
||||
AudioManager.play_sfx("magic", global_position)
|
||||
add_sibling(smoke)
|
||||
|
||||
func breathe_fire() -> void:
|
||||
if can_fire == false:
|
||||
return
|
||||
sprite.play("FireCharge")
|
||||
await get_tree().create_timer(1, false).timeout
|
||||
var flame = BOWSER_FLAME.instantiate()
|
||||
flame.global_position = global_position + Vector2(18 * direction, -20)
|
||||
flame.mode = 1
|
||||
flame.direction = direction
|
||||
flame.target_y = get_target_y(target_player)
|
||||
if $TrackJoint.is_attached:
|
||||
get_parent().owner.add_sibling(flame)
|
||||
else:
|
||||
add_sibling(flame)
|
||||
sprite.play("FireBreathe")
|
||||
if is_instance_valid(get_node_or_null("FlameTimer")):
|
||||
$FlameTimer.start(randf_range(1.5, 4.5))
|
||||
await get_tree().create_timer(0.5, false).timeout
|
||||
sprite.play("Idle")
|
||||
|
||||
func bridge_fall() -> void:
|
||||
process_mode = Node.PROCESS_MODE_ALWAYS
|
||||
direction = 1
|
||||
$FlameTimer.queue_free()
|
||||
$HammerTime.queue_free()
|
||||
$JumpTimer.queue_free()
|
||||
sprite.play("Fall")
|
||||
sprite.reset_physics_interpolation()
|
||||
$MoveAnimation.queue_free()
|
||||
can_fall = false
|
||||
velocity.y = 0
|
||||
await get_tree().create_timer(2).timeout
|
||||
$FallSFX.play()
|
||||
can_fall = true
|
||||
$Collision.queue_free()
|
||||
await get_tree().create_timer(2).timeout
|
||||
queue_free()
|
||||
|
||||
func throw_hammers() -> void:
|
||||
if can_hammer == false:
|
||||
return
|
||||
$Hammer.show()
|
||||
await get_tree().create_timer(0.5, false).timeout
|
||||
for i in randi_range(3, 6):
|
||||
$Hammer.show()
|
||||
await get_tree().create_timer(0.1, false).timeout
|
||||
var node = HAMMER.instantiate()
|
||||
node.velocity.y = -200
|
||||
node.global_position = $Hammer.global_position
|
||||
node.direction = direction
|
||||
if $TrackJoint.is_attached:
|
||||
get_parent().owner.add_sibling(node)
|
||||
else:
|
||||
add_sibling(node)
|
||||
sprite.play("Idle")
|
||||
$Hammer.hide()
|
||||
await get_tree().create_timer(0.1, false).timeout
|
||||
if get_node_or_null("HammerTime") != null:
|
||||
$HammerTime.start()
|
||||
|
||||
func fireball_hit() -> void:
|
||||
health -= 1
|
||||
AudioManager.play_sfx("bump", global_position)
|
||||
if health <= 0:
|
||||
die()
|
||||
else:
|
||||
$SpriteScaleJoint/HurtAnimation.stop()
|
||||
$SpriteScaleJoint/HurtAnimation.play("Hurt")
|
||||
AudioManager.play_sfx("kick", global_position)
|
||||
|
||||
func play_music() -> void:
|
||||
for i: EntityGenerator in get_tree().get_nodes_in_group("EntityGenerators"):
|
||||
if i.entity_scene != null:
|
||||
if i.entity_scene.resource_path == "res://Scenes/Prefabs/Entities/Enemies/BowserFlame.tscn":
|
||||
i.queue_free()
|
||||
if Settings.file.audio.extra_bgm == 0: return
|
||||
if Global.level_editor != null:
|
||||
return
|
||||
if music_enabled:
|
||||
AudioManager.set_music_override(AudioManager.MUSIC_OVERRIDES.BOWSER, 5, false)
|
||||
|
||||
|
||||
func on_timeout() -> void:
|
||||
move_dir = [-1, 1].pick_random()
|
1
Scripts/Classes/Entities/Enemies/Bowser.gd.uid
Executable file
1
Scripts/Classes/Entities/Enemies/Bowser.gd.uid
Executable file
@@ -0,0 +1 @@
|
||||
uid://wtypg4d0l6j2
|
29
Scripts/Classes/Entities/Enemies/BowserFlame.gd
Normal file
29
Scripts/Classes/Entities/Enemies/BowserFlame.gd
Normal file
@@ -0,0 +1,29 @@
|
||||
class_name BowserFlame
|
||||
extends Node2D
|
||||
|
||||
@export_enum("Straight", "Aimed") var mode := 0
|
||||
|
||||
var target_y := 0
|
||||
var direction := -1
|
||||
|
||||
func _ready() -> void:
|
||||
pass
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
movement(delta)
|
||||
|
||||
func movement(delta: float) -> void:
|
||||
if mode == 1:
|
||||
global_position.y = move_toward(global_position.y, target_y, delta * 50)
|
||||
global_position.x += (100 * direction) * delta
|
||||
$Sprite.scale.x = direction
|
||||
|
||||
func flag_die() -> void:
|
||||
queue_free()
|
||||
|
||||
func on_area_entered(area: Area2D) -> void:
|
||||
if area.owner is Player:
|
||||
area.owner.damage()
|
||||
|
||||
func play_sfx() -> void:
|
||||
AudioManager.play_sfx("bowser_flame", global_position)
|
1
Scripts/Classes/Entities/Enemies/BowserFlame.gd.uid
Executable file
1
Scripts/Classes/Entities/Enemies/BowserFlame.gd.uid
Executable file
@@ -0,0 +1 @@
|
||||
uid://btstbvjk6e6aw
|
29
Scripts/Classes/Entities/Enemies/BulletBill.gd
Normal file
29
Scripts/Classes/Entities/Enemies/BulletBill.gd
Normal file
@@ -0,0 +1,29 @@
|
||||
class_name BulletBill
|
||||
extends Enemy
|
||||
|
||||
static var amount := 0
|
||||
|
||||
var can_despawn := false
|
||||
|
||||
const MOVE_SPEED := 96
|
||||
var cannon := false
|
||||
|
||||
func _ready() -> void:
|
||||
amount += 1
|
||||
$Sprite.scale.x = direction
|
||||
if cannon:
|
||||
await get_tree().create_timer(0.2, false).timeout
|
||||
z_index = 0
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
global_position.x += (90 * delta) * direction
|
||||
|
||||
func _exit_tree() -> void:
|
||||
amount -= 1
|
||||
|
||||
func on_screen_entered() -> void:
|
||||
if Global.level_editor != null:
|
||||
if Global.level_editor.current_state == LevelEditor.EditorState.PLAYTESTING or Global.current_game_mode == Global.GameMode.CUSTOM_LEVEL:
|
||||
AudioManager.play_sfx("cannon", global_position)
|
||||
else:
|
||||
AudioManager.play_sfx("cannon", global_position)
|
1
Scripts/Classes/Entities/Enemies/BulletBill.gd.uid
Executable file
1
Scripts/Classes/Entities/Enemies/BulletBill.gd.uid
Executable file
@@ -0,0 +1 @@
|
||||
uid://7b27p232kp7w
|
8
Scripts/Classes/Entities/Enemies/CannonBall.gd
Normal file
8
Scripts/Classes/Entities/Enemies/CannonBall.gd
Normal file
@@ -0,0 +1,8 @@
|
||||
extends Enemy
|
||||
|
||||
var direction_vector := Vector2.UP
|
||||
|
||||
const MOVE_SPEED := 70.0
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
global_position += direction_vector * MOVE_SPEED * delta
|
1
Scripts/Classes/Entities/Enemies/CannonBall.gd.uid
Normal file
1
Scripts/Classes/Entities/Enemies/CannonBall.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bfdtqldkrv4dn
|
36
Scripts/Classes/Entities/Enemies/DryBones.gd
Executable file
36
Scripts/Classes/Entities/Enemies/DryBones.gd
Executable file
@@ -0,0 +1,36 @@
|
||||
extends Enemy
|
||||
|
||||
const MOVE_SPEED := 32
|
||||
|
||||
var can_move := true
|
||||
const DRY_BONES_DESTRUCTION_PARTICLES = preload("uid://bhs5ly6bbaahk")
|
||||
func _physics_process(_delta: float) -> void:
|
||||
$Sprite.scale.x = direction
|
||||
|
||||
func stomped_on(player: Player) -> void:
|
||||
player.enemy_bounce_off(false)
|
||||
$Sprite.play("Crumble")
|
||||
AudioManager.play_sfx("dry_bones_crumble", global_position)
|
||||
$BasicEnemyMovement.can_move = false
|
||||
set_collision_layer_value(5, false)
|
||||
set_collision_mask_value(5, false)
|
||||
set_collision_mask_value(6, false)
|
||||
$Hitbox/Shape.set_deferred("disabled", true)
|
||||
await get_tree().create_timer(3, false).timeout
|
||||
$ShakeAnimation.play("Shake")
|
||||
await get_tree().create_timer(1, false).timeout
|
||||
$Sprite.play("GetUp")
|
||||
$ShakeAnimation.play("RESET")
|
||||
await $Sprite.animation_finished
|
||||
$BasicEnemyMovement.can_move = true
|
||||
$Hitbox/Shape.set_deferred("disabled", false)
|
||||
set_collision_layer_value(5, true)
|
||||
set_collision_mask_value(5, true)
|
||||
set_collision_mask_value(6, true)
|
||||
$Sprite.play("Walk")
|
||||
|
||||
func summon_particle() -> void:
|
||||
var particle = DRY_BONES_DESTRUCTION_PARTICLES.instantiate()
|
||||
particle.global_position = global_position + Vector2(0, -10)
|
||||
add_sibling(particle)
|
||||
AudioManager.play_sfx("dry_bones_crumble", global_position)
|
1
Scripts/Classes/Entities/Enemies/DryBones.gd.uid
Executable file
1
Scripts/Classes/Entities/Enemies/DryBones.gd.uid
Executable file
@@ -0,0 +1 @@
|
||||
uid://n123x5yuqpjd
|
28
Scripts/Classes/Entities/Enemies/FighterFly.gd
Executable file
28
Scripts/Classes/Entities/Enemies/FighterFly.gd
Executable file
@@ -0,0 +1,28 @@
|
||||
extends Enemy
|
||||
|
||||
const BUZZY_BEETLE = preload("res://Scenes/Prefabs/Entities/Enemies/BuzzyBeetle.tscn")
|
||||
|
||||
var jump_meter := 0.0
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
jump_meter += delta
|
||||
|
||||
$Sprite.play(["Fly", "Idle"][int(is_on_floor())])
|
||||
|
||||
if jump_meter >= 0.5:
|
||||
$BasicEnemyMovement.bounce_on_land = true
|
||||
$BasicEnemyMovement.move_speed = 30
|
||||
jump_meter = 0
|
||||
elif is_on_floor():
|
||||
$BasicEnemyMovement.bounce_on_land = false
|
||||
$BasicEnemyMovement.move_speed = 0
|
||||
|
||||
func stomped_on(player: Player) -> void:
|
||||
AudioManager.play_sfx("enemy_stomp", global_position)
|
||||
$BasicEnemyMovement.can_move = false
|
||||
Global.combo_amount += 1
|
||||
player.enemy_bounce_off()
|
||||
$Sprite.play("Stomped")
|
||||
$Hitbox.queue_free()
|
||||
await get_tree().create_timer(0.5, false).timeout
|
||||
queue_free()
|
1
Scripts/Classes/Entities/Enemies/FighterFly.gd.uid
Executable file
1
Scripts/Classes/Entities/Enemies/FighterFly.gd.uid
Executable file
@@ -0,0 +1 @@
|
||||
uid://cemetiu57dblq
|
37
Scripts/Classes/Entities/Enemies/Goomba.gd
Normal file
37
Scripts/Classes/Entities/Enemies/Goomba.gd
Normal file
@@ -0,0 +1,37 @@
|
||||
extends Enemy
|
||||
|
||||
var can_move := true
|
||||
|
||||
var angry := false
|
||||
|
||||
var can_turn := false
|
||||
|
||||
func _ready() -> void:
|
||||
$Sprite.play("Walk")
|
||||
|
||||
func _physics_process(_delta: float) -> void:
|
||||
if can_turn:
|
||||
$Sprite.scale.x = direction
|
||||
|
||||
func stomped_on(player: Player) -> void:
|
||||
AudioManager.play_sfx("enemy_stomp", global_position)
|
||||
can_move = false
|
||||
DiscoLevel.combo_amount += 1
|
||||
$BasicEnemyMovement.can_move = false
|
||||
player.enemy_bounce_off()
|
||||
$Sprite.play("Stomped")
|
||||
$Hitbox.queue_free()
|
||||
await get_tree().create_timer(0.5, false).timeout
|
||||
queue_free()
|
||||
|
||||
func damage(object: Node2D) -> void:
|
||||
if angry:
|
||||
die_from_object(object)
|
||||
$ScoreNoteSpawner.spawn_note(200)
|
||||
return
|
||||
AudioManager.play_sfx("kick", global_position)
|
||||
velocity.y = -150
|
||||
direction = sign(global_position.x - object.global_position.x)
|
||||
angry = true
|
||||
$Sprite.play("Angry")
|
||||
$BasicEnemyMovement.move_speed *= 2
|
1
Scripts/Classes/Entities/Enemies/Goomba.gd.uid
Executable file
1
Scripts/Classes/Entities/Enemies/Goomba.gd.uid
Executable file
@@ -0,0 +1 @@
|
||||
uid://dv18do583a3x0
|
93
Scripts/Classes/Entities/Enemies/HammerBro.gd
Normal file
93
Scripts/Classes/Entities/Enemies/HammerBro.gd
Normal file
@@ -0,0 +1,93 @@
|
||||
extends Enemy
|
||||
|
||||
var jumping := false
|
||||
var jump_direction := 0
|
||||
|
||||
@export var auto_charge := false
|
||||
|
||||
var charging := false
|
||||
|
||||
var wall_jump := false
|
||||
var target_player: Player = null
|
||||
const HAMMER = preload("res://Scenes/Prefabs/Entities/Items/Hammer.tscn")
|
||||
|
||||
func _ready() -> void:
|
||||
$MovementAnimations.play("Movement")
|
||||
$Timer.start()
|
||||
$JumpTimer.start()
|
||||
$HammerTimer.start()
|
||||
|
||||
func _process(delta: float) -> void:
|
||||
target_player = get_tree().get_first_node_in_group("Players")
|
||||
direction = sign(target_player.global_position.x - global_position.x)
|
||||
$Sprite.scale.x = direction
|
||||
if $TrackJoint.is_attached: $MovementAnimations.play("RESET")
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
apply_enemy_gravity(delta)
|
||||
if charging and target_player != null:
|
||||
if is_on_wall() and is_on_floor():
|
||||
jump(true)
|
||||
velocity.x = 50 * direction
|
||||
else:
|
||||
velocity.x = 0
|
||||
move_and_slide()
|
||||
handle_collision()
|
||||
|
||||
func handle_collision() -> void:
|
||||
var can_pass_block := false
|
||||
if jump_direction == -1:
|
||||
can_pass_block = velocity.y < -50
|
||||
elif jump_direction == 1:
|
||||
can_pass_block = velocity.y <= 250
|
||||
$Collision.set_deferred("disabled", can_pass_block and jumping and not wall_jump)
|
||||
if is_on_floor() and jumping:
|
||||
jumping = false
|
||||
|
||||
func jump(wall := false) -> void:
|
||||
if is_on_floor() == false:
|
||||
return
|
||||
wall_jump = wall
|
||||
jumping = true
|
||||
jump_direction = [-1, 1].pick_random()
|
||||
if jump_direction == -1 and $UpBlock.is_colliding() == false:
|
||||
jump_direction = 1
|
||||
if jump_direction == 1 and ($BlockDetect.is_colliding() or global_position.y >= -1):
|
||||
jump_direction = -1
|
||||
if jump_direction == -1:
|
||||
velocity.y = -300
|
||||
else:
|
||||
velocity.y = -140
|
||||
$JumpTimer.start(randf_range(1, 5))
|
||||
|
||||
func do_hammer_throw() -> void:
|
||||
for i in randi_range(1, 6):
|
||||
await throw_hammer()
|
||||
await get_tree().create_timer(0.25, false).timeout
|
||||
$HammerTimer.start(randf_range(2, 5))
|
||||
|
||||
func throw_hammer() -> void:
|
||||
$Sprite/Hammer.show()
|
||||
$Sprite.play("Hammer")
|
||||
await get_tree().create_timer(0.5, false).timeout
|
||||
spawn_hammer()
|
||||
$Sprite.play("Idle")
|
||||
$Sprite/Hammer.hide()
|
||||
|
||||
func spawn_hammer() -> void:
|
||||
var node = HAMMER.instantiate()
|
||||
node.global_position = $Sprite/Hammer.global_position
|
||||
node.direction = direction
|
||||
if $TrackJoint.is_attached:
|
||||
get_parent().owner.add_sibling(node)
|
||||
else:
|
||||
add_sibling(node)
|
||||
|
||||
func charge() -> void:
|
||||
charging = true
|
||||
$MovementAnimations.play("RESET")
|
||||
|
||||
|
||||
func on_screen_entered() -> void:
|
||||
if auto_charge:
|
||||
charge()
|
1
Scripts/Classes/Entities/Enemies/HammerBro.gd.uid
Executable file
1
Scripts/Classes/Entities/Enemies/HammerBro.gd.uid
Executable file
@@ -0,0 +1 @@
|
||||
uid://b8gdlotx0at6x
|
46
Scripts/Classes/Entities/Enemies/Icicle.gd
Normal file
46
Scripts/Classes/Entities/Enemies/Icicle.gd
Normal file
@@ -0,0 +1,46 @@
|
||||
class_name Icicle
|
||||
extends Enemy
|
||||
|
||||
var falling := false
|
||||
const ICICLE_DESTRUCTION = preload("res://Scenes/Parts/Particles/IcicleDestruction.tscn")
|
||||
func _physics_process(delta: float) -> void:
|
||||
if falling:
|
||||
handle_movement(delta)
|
||||
else:
|
||||
detect_player()
|
||||
|
||||
func detect_player() -> void:
|
||||
var shaking := false
|
||||
for i in get_tree().get_nodes_in_group("Players"):
|
||||
var distance = abs(i.global_position.x - global_position.x)
|
||||
if i.global_position.y > global_position.y:
|
||||
if distance <= 32:
|
||||
fall()
|
||||
elif distance <= 64:
|
||||
shaking = true
|
||||
if shaking:
|
||||
$AnimationPlayer.play("Shake")
|
||||
else:
|
||||
$AnimationPlayer.play("RESET")
|
||||
|
||||
|
||||
func handle_movement(delta: float) -> void:
|
||||
apply_enemy_gravity(delta)
|
||||
apply_enemy_gravity(delta / 2)
|
||||
if is_on_floor():
|
||||
destroy()
|
||||
move_and_slide()
|
||||
|
||||
func destroy() -> void:
|
||||
AudioManager.play_sfx("icicle_break", global_position)
|
||||
summon_particles()
|
||||
queue_free()
|
||||
|
||||
func summon_particles() -> void:
|
||||
var node = ICICLE_DESTRUCTION.instantiate()
|
||||
node.global_position = global_position - Vector2(0, 8)
|
||||
add_sibling(node)
|
||||
|
||||
func fall() -> void:
|
||||
AudioManager.play_sfx("icicle_fall", global_position)
|
||||
falling = true
|
1
Scripts/Classes/Entities/Enemies/Icicle.gd.uid
Executable file
1
Scripts/Classes/Entities/Enemies/Icicle.gd.uid
Executable file
@@ -0,0 +1 @@
|
||||
uid://cx0ak5ctcg0mi
|
76
Scripts/Classes/Entities/Enemies/KoopaTroopa.gd
Normal file
76
Scripts/Classes/Entities/Enemies/KoopaTroopa.gd
Normal file
@@ -0,0 +1,76 @@
|
||||
extends Enemy
|
||||
|
||||
const MOVE_SPEED := 32
|
||||
@export var winged := false
|
||||
@export_file("*.tscn") var shell_scene = ""
|
||||
|
||||
@onready var starting_position := global_position
|
||||
|
||||
var fly_wave := PI
|
||||
|
||||
var dead := false
|
||||
|
||||
func _ready() -> void:
|
||||
if has_meta("fly_2"):
|
||||
fly_wave = 0
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
if winged and (has_meta("is_red") or has_meta("fly_2")):
|
||||
handle_fly_movement(delta)
|
||||
else:
|
||||
$BasicEnemyMovement.bounce_on_land = winged
|
||||
$BasicEnemyMovement.handle_movement(delta)
|
||||
$Sprite.play("Walk")
|
||||
%Wing.visible = winged
|
||||
$Sprite.scale.x = direction
|
||||
|
||||
func handle_fly_movement(delta: float) -> void:
|
||||
velocity = Vector2.ZERO
|
||||
fly_wave += delta
|
||||
var old_x = global_position.x
|
||||
if has_meta("fly_2"):
|
||||
global_position.x = starting_position.x + (cos(fly_wave) * 48) - 48
|
||||
global_position.y = starting_position.y + (sin(fly_wave * 4) * 2)
|
||||
direction = sign(global_position.x - old_x + 0.001)
|
||||
else:
|
||||
global_position.y = starting_position.y + (cos(fly_wave) * 48) + 48
|
||||
|
||||
func stomped_on(player: Player) -> void:
|
||||
if dead:
|
||||
return
|
||||
player.enemy_bounce_off()
|
||||
AudioManager.play_sfx("enemy_stomp", global_position)
|
||||
if winged:
|
||||
DiscoLevel.combo_meter = 100
|
||||
DiscoLevel.combo_amount += 1
|
||||
velocity.y = 0
|
||||
winged = false
|
||||
var direction_to_change = sign(player.global_position.x - global_position.x)
|
||||
if direction_to_change != 0:
|
||||
direction = direction_to_change
|
||||
return
|
||||
dead = true
|
||||
await get_tree().physics_frame
|
||||
summon_shell(not is_on_floor(), false)
|
||||
queue_free()
|
||||
|
||||
func block_bounced() -> void:
|
||||
summon_shell(true, true)
|
||||
queue_free()
|
||||
|
||||
func summon_shell(flipped := false, launch := false) -> void:
|
||||
if is_queued_for_deletion():
|
||||
return
|
||||
DiscoLevel.combo_amount += 1
|
||||
var shell = load(shell_scene).instantiate()
|
||||
shell.flipped = flipped
|
||||
shell.old_entity = self.duplicate()
|
||||
if launch:
|
||||
AudioManager.play_sfx("kick", global_position)
|
||||
shell.can_air_kick = true
|
||||
shell.velocity = Vector2(50 * direction, -150)
|
||||
shell.global_position = global_position
|
||||
if $TrackJoint.is_attached:
|
||||
get_parent().owner.add_sibling(shell)
|
||||
else:
|
||||
add_sibling(shell)
|
1
Scripts/Classes/Entities/Enemies/KoopaTroopa.gd.uid
Executable file
1
Scripts/Classes/Entities/Enemies/KoopaTroopa.gd.uid
Executable file
@@ -0,0 +1 @@
|
||||
uid://q8gx0l64pcjh
|
97
Scripts/Classes/Entities/Enemies/Lakitu.gd
Normal file
97
Scripts/Classes/Entities/Enemies/Lakitu.gd
Normal file
@@ -0,0 +1,97 @@
|
||||
class_name Lakitu
|
||||
extends Enemy
|
||||
|
||||
static var present := false:
|
||||
set(value):
|
||||
if value == true:
|
||||
pass
|
||||
present = value
|
||||
|
||||
var screen_center := Vector2.ZERO
|
||||
var lakitu_point := Vector2.ZERO
|
||||
|
||||
const BLOCK_DISTANCE := 64
|
||||
|
||||
static var fixed_throw := true
|
||||
|
||||
var player: Player = null
|
||||
|
||||
var retreat := false
|
||||
|
||||
var can_enter := false
|
||||
|
||||
static var spiny_amount := 0
|
||||
@export var item: PackedScene = null
|
||||
@export var retreat_x := 3072
|
||||
|
||||
func _ready() -> void:
|
||||
can_enter = false
|
||||
$ThrowTimer.start()
|
||||
lakitu_point = to_local(global_position)
|
||||
fixed_throw = Settings.file.difficulty.lakitu_style == 1
|
||||
get_parent().move_child(self, 0)
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
screen_center = get_viewport().get_camera_2d().get_screen_center_position()
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
player = get_tree().get_first_node_in_group("Players")
|
||||
handle_movement(delta)
|
||||
|
||||
func handle_movement(_delta: float) -> void:
|
||||
retreat = get_viewport().get_camera_2d().get_screen_center_position().x >= retreat_x
|
||||
var player_x = player.global_position.x + ((player.velocity.x))
|
||||
var distance = abs(global_position.x - player_x)
|
||||
get_direction(player_x)
|
||||
if direction == 1:
|
||||
velocity.x = int(clamp((distance - 16) * 2, 48, INF))
|
||||
else:
|
||||
velocity.x = -48
|
||||
$Cloud.scale.x = direction
|
||||
move_and_slide()
|
||||
|
||||
func get_direction(player_x := 0.0) -> void:
|
||||
if retreat:
|
||||
present = false
|
||||
direction = -1
|
||||
return
|
||||
if direction == -1 and global_position.x < player_x - BLOCK_DISTANCE:
|
||||
direction = 1
|
||||
elif direction == 1 and global_position.x > player_x + BLOCK_DISTANCE:
|
||||
direction = -1
|
||||
|
||||
func summon_cloud_particle() -> void:
|
||||
var node = preload("res://Scenes/Prefabs/Particles/LakituCloudBurst.tscn").instantiate()
|
||||
node.global_position = $Cloud.global_position
|
||||
add_sibling(node)
|
||||
|
||||
func on_timeout() -> void:
|
||||
if spiny_amount >= 3 or retreat or $WallCheck.is_colliding():
|
||||
return
|
||||
$Cloud/Sprite.play("Throw")
|
||||
await get_tree().create_timer(0.5, false).timeout
|
||||
if $WallCheck.is_colliding() == false:
|
||||
throw_spiny()
|
||||
$Cloud/Sprite.play("Idle")
|
||||
|
||||
func throw_spiny() -> void:
|
||||
var node = item.instantiate()
|
||||
spiny_amount += 1
|
||||
node.set("in_egg", true)
|
||||
node.global_position = $Cloud/Sprite.global_position
|
||||
node.velocity = Vector2(0, -150)
|
||||
if fixed_throw:
|
||||
node.velocity.x = 50 * (sign(player.global_position.x - global_position.x))
|
||||
node.set("direction", sign(node.velocity.x))
|
||||
add_sibling(node)
|
||||
if Settings.file.audio.extra_sfx == 1:
|
||||
AudioManager.play_sfx("lakitu_throw", global_position)
|
||||
node.tree_exited.connect(func(): spiny_amount -= 1)
|
||||
|
||||
func on_screen_entered() -> void:
|
||||
if Global.level_editor != null:
|
||||
if Global.level_editor.playing_level == false:
|
||||
return
|
||||
add_to_group("Lakitus")
|
||||
if get_tree().get_node_count_in_group("Lakitus") >= 2:
|
||||
queue_free()
|
1
Scripts/Classes/Entities/Enemies/Lakitu.gd.uid
Executable file
1
Scripts/Classes/Entities/Enemies/Lakitu.gd.uid
Executable file
@@ -0,0 +1 @@
|
||||
uid://bohpv3almqrvg
|
27
Scripts/Classes/Entities/Enemies/LeapingCheepCheep.gd
Normal file
27
Scripts/Classes/Entities/Enemies/LeapingCheepCheep.gd
Normal file
@@ -0,0 +1,27 @@
|
||||
extends Enemy
|
||||
|
||||
func _ready() -> void:
|
||||
direction = sign(get_viewport().get_camera_2d().get_screen_center_position().x - global_position.x)
|
||||
velocity.x = randf_range(50, 200) * direction
|
||||
velocity.y = randf_range(-250, -350)
|
||||
$Sprite.scale.x = direction
|
||||
setup_line()
|
||||
if Settings.file.audio.extra_sfx == 1:
|
||||
AudioManager.play_sfx("cheep_cheep", global_position)
|
||||
|
||||
|
||||
func setup_line() -> void:
|
||||
$Line2D.clear_points()
|
||||
var line_velocity = velocity
|
||||
var line_position = $Sprite.global_position
|
||||
for i in 200:
|
||||
line_position += line_velocity * 0.016
|
||||
line_velocity.y += (5 / 0.016) * 0.016
|
||||
$Line2D.add_point(line_position)
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
velocity.y += (5 / delta) * delta
|
||||
$Line2D.remove_point(0)
|
||||
if global_position.y > 64 and velocity.y > 0:
|
||||
queue_free()
|
||||
move_and_slide()
|
1
Scripts/Classes/Entities/Enemies/LeapingCheepCheep.gd.uid
Executable file
1
Scripts/Classes/Entities/Enemies/LeapingCheepCheep.gd.uid
Executable file
@@ -0,0 +1 @@
|
||||
uid://mshpvsyuw15j
|
20
Scripts/Classes/Entities/Enemies/MontyMole.gd
Executable file
20
Scripts/Classes/Entities/Enemies/MontyMole.gd
Executable file
@@ -0,0 +1,20 @@
|
||||
extends Enemy
|
||||
|
||||
var target_player: Player = null
|
||||
|
||||
const MOVE_SPEED := 100.0
|
||||
const ACCEL := 1.0
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
target_player = get_tree().get_first_node_in_group("Players")
|
||||
direction = sign(target_player.global_position.x - global_position.x)
|
||||
$Sprite.scale.x = direction
|
||||
handle_movement(delta)
|
||||
|
||||
func handle_movement(delta: float) -> void:
|
||||
apply_enemy_gravity(delta)
|
||||
if is_on_wall():
|
||||
velocity.x = (MOVE_SPEED / 2) * get_wall_normal().x
|
||||
velocity.y = -100
|
||||
velocity.x = lerpf(velocity.x, MOVE_SPEED * direction, delta * ACCEL)
|
||||
move_and_slide()
|
1
Scripts/Classes/Entities/Enemies/MontyMole.gd.uid
Executable file
1
Scripts/Classes/Entities/Enemies/MontyMole.gd.uid
Executable file
@@ -0,0 +1 @@
|
||||
uid://dw05x347cr8jj
|
17
Scripts/Classes/Entities/Enemies/PiranhaPlant.gd
Normal file
17
Scripts/Classes/Entities/Enemies/PiranhaPlant.gd
Normal file
@@ -0,0 +1,17 @@
|
||||
extends Enemy
|
||||
|
||||
@export var player_range := 24
|
||||
|
||||
func _enter_tree() -> void:
|
||||
$Animation.play("Hide")
|
||||
|
||||
func _ready() -> void:
|
||||
print(abs(global_rotation_degrees))
|
||||
if is_equal_approx(abs(global_rotation_degrees), 180) == false:
|
||||
$Sprite/Hitbox/UpsideDownExtension.queue_free()
|
||||
$Timer.start()
|
||||
|
||||
func on_timeout() -> void:
|
||||
var player = get_tree().get_first_node_in_group("Players")
|
||||
if abs(player.global_position.x - global_position.x) >= player_range:
|
||||
$Animation.play("Rise")
|
1
Scripts/Classes/Entities/Enemies/PiranhaPlant.gd.uid
Executable file
1
Scripts/Classes/Entities/Enemies/PiranhaPlant.gd.uid
Executable file
@@ -0,0 +1 @@
|
||||
uid://d23hoj2qc2whq
|
55
Scripts/Classes/Entities/Enemies/Podoboo.gd
Normal file
55
Scripts/Classes/Entities/Enemies/Podoboo.gd
Normal file
@@ -0,0 +1,55 @@
|
||||
extends Node2D
|
||||
|
||||
var velocity := 5.0
|
||||
|
||||
var play_sfx := false
|
||||
|
||||
@onready var starting_y := global_position.y
|
||||
@export_range(0, 3) var jump_delay := 1
|
||||
var can_jump := true
|
||||
|
||||
signal killed
|
||||
|
||||
const BASE_LINE := 48
|
||||
|
||||
func _ready() -> void:
|
||||
if Global.current_game_mode != Global.GameMode.LEVEL_EDITOR and global_position.y > -32:
|
||||
Global.log_warning("Podoboo is too low! Forgot to update!")
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
velocity += (5 / delta) * delta
|
||||
velocity = clamp(velocity, -INF, 280)
|
||||
global_position.y += velocity * delta
|
||||
global_position.y = clamp(global_position.y, -INF, BASE_LINE)
|
||||
if global_position.y >= BASE_LINE and can_jump:
|
||||
can_jump = false
|
||||
do_jump()
|
||||
|
||||
$Sprite.flip_v = velocity > 0
|
||||
|
||||
func do_jump() -> void:
|
||||
if jump_delay > 0:
|
||||
$Timer.start(jump_delay)
|
||||
await $Timer.timeout
|
||||
if play_sfx:
|
||||
AudioManager.play_sfx("podoboo", global_position)
|
||||
velocity = calculate_jump_height()
|
||||
print(velocity)
|
||||
await get_tree().physics_frame
|
||||
can_jump = true
|
||||
|
||||
func damage_player(player: Player) -> void:
|
||||
player.damage()
|
||||
|
||||
func calculate_jump_height() -> float:
|
||||
global_position.y = BASE_LINE
|
||||
return -sqrt(2 * 5 * abs(starting_y - (global_position.y))) * 8
|
||||
|
||||
const SMOKE_PARTICLE = preload("uid://d08nv4qtfouv1")
|
||||
|
||||
func flag_die() -> void:
|
||||
die()
|
||||
|
||||
func die() -> void:
|
||||
killed.emit()
|
||||
queue_free()
|
1
Scripts/Classes/Entities/Enemies/Podoboo.gd.uid
Executable file
1
Scripts/Classes/Entities/Enemies/Podoboo.gd.uid
Executable file
@@ -0,0 +1 @@
|
||||
uid://bha5utvbhxppl
|
26
Scripts/Classes/Entities/Enemies/Pokey.gd
Normal file
26
Scripts/Classes/Entities/Enemies/Pokey.gd
Normal file
@@ -0,0 +1,26 @@
|
||||
extends Enemy
|
||||
|
||||
@export_range(1, 10, 1) var length := 3
|
||||
|
||||
var wave := 0.0
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
handle_collision()
|
||||
handle_part_animation(delta)
|
||||
|
||||
func handle_collision() -> void:
|
||||
$HeadHitbox.position.y = (-length * 16) + 8
|
||||
$Collision.shape.size.y = (length * 16)
|
||||
$Collision.position.y = (-length * 8)
|
||||
$BodyHitbox.position.y = $Collision.position.y
|
||||
|
||||
func handle_part_animation(delta: float) -> void:
|
||||
wave += delta
|
||||
for i in $Parts.get_children():
|
||||
if i.get_index() > 0:
|
||||
i.offset.x = sin(wave * 8) * 1 * [-1, 1][i.get_index() % 2]
|
||||
|
||||
func summon_part_gibs() -> void:
|
||||
for i in $Parts.get_children():
|
||||
if i.visible:
|
||||
i.get_node("GibSpawner").summon_gib([-1, 1][i.get_index() % 2])
|
1
Scripts/Classes/Entities/Enemies/Pokey.gd.uid
Executable file
1
Scripts/Classes/Entities/Enemies/Pokey.gd.uid
Executable file
@@ -0,0 +1 @@
|
||||
uid://b1b6aiai213ci
|
71
Scripts/Classes/Entities/Enemies/RaceBoo.gd
Normal file
71
Scripts/Classes/Entities/Enemies/RaceBoo.gd
Normal file
@@ -0,0 +1,71 @@
|
||||
extends Node2D
|
||||
|
||||
var moving := false
|
||||
|
||||
@export var path: PathFollow2D = null
|
||||
@export var time_needed := [60, 45, 30]
|
||||
|
||||
const COLOURS := ["White", "Green", "Red", "Black", "Gold"]
|
||||
|
||||
var last_position := global_position
|
||||
var tween: Tween = null
|
||||
|
||||
@export var force_colour := -1
|
||||
|
||||
func play_laugh_animation() -> void:
|
||||
if get_tree().get_nodes_in_group("BooSwitchBlocks").is_empty() == false:
|
||||
$Warning.show()
|
||||
$Sprite.play("Laugh")
|
||||
await get_tree().create_timer(1, false).timeout
|
||||
$Warning.hide()
|
||||
if moving:
|
||||
$Sprite.play("Idle")
|
||||
|
||||
func _ready() -> void:
|
||||
if force_colour != -1:
|
||||
BooRaceHandler.boo_colour = force_colour
|
||||
$Sprite.play("Lose")
|
||||
$OffScreenIcon.frame = BooRaceHandler.boo_colour
|
||||
$GoldParticles.visible = BooRaceHandler.boo_colour == 4
|
||||
get_tree().get_first_node_in_group("Players").dead.connect(func(): $Sprite.play("Win"))
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
if Global.current_game_mode == Global.GameMode.BOO_RACE:
|
||||
handle_off_screen_icon()
|
||||
|
||||
func handle_off_screen_icon() -> void:
|
||||
$OffScreenIcon.visible = $Sprite/VisibleOnScreenNotifier2D.is_on_screen() == false and moving
|
||||
var sprite_position = $Sprite.global_position
|
||||
var screen_center = get_viewport().get_camera_2d().get_screen_center_position()
|
||||
var screen_size = get_viewport().get_visible_rect().size
|
||||
sprite_position.x = clamp(sprite_position.x, (screen_center.x - (screen_size.x / 2)) + 8, (screen_center.x + (screen_size.x / 2)) - 8)
|
||||
sprite_position.y = clamp(sprite_position.y, (screen_center.y - (screen_size.y / 2)) + 8, (screen_center.y + (screen_size.y / 2)) - 8)
|
||||
$OffScreenIcon.global_position = sprite_position
|
||||
if global_position.x > get_tree().get_first_node_in_group("Players").global_position.x and path.progress_ratio >= 0.8:
|
||||
$OffScreenIcon/Animation.play("CloseFlash")
|
||||
$Sprite.play("Win")
|
||||
|
||||
func _physics_process(_delta: float) -> void:
|
||||
var dir = sign(global_position.x - last_position.x)
|
||||
if moving and dir != 0:
|
||||
$Sprite.scale.x = dir
|
||||
last_position = global_position
|
||||
|
||||
func flag_die() -> void:
|
||||
tween.kill()
|
||||
$Sprite.play("Lose")
|
||||
moving = false
|
||||
|
||||
func move_tween() -> void:
|
||||
if path == null:
|
||||
return
|
||||
moving = true
|
||||
$Sprite.play("Idle")
|
||||
tween = create_tween()
|
||||
tween.tween_property(path, "progress_ratio", 1, time_needed[BooRaceHandler.boo_colour])
|
||||
await tween.finished
|
||||
boo_win()
|
||||
|
||||
func boo_win() -> void:
|
||||
$Sprite.play("Win")
|
||||
get_tree().call_group("Players", "time_up")
|
1
Scripts/Classes/Entities/Enemies/RaceBoo.gd.uid
Executable file
1
Scripts/Classes/Entities/Enemies/RaceBoo.gd.uid
Executable file
@@ -0,0 +1 @@
|
||||
uid://b43onpjaw542l
|
35
Scripts/Classes/Entities/Enemies/RockyWrench.gd
Normal file
35
Scripts/Classes/Entities/Enemies/RockyWrench.gd
Normal file
@@ -0,0 +1,35 @@
|
||||
extends Enemy
|
||||
|
||||
@export var can_stomp := false
|
||||
const WRENCH_PROJECTILE = preload("uid://p42vcj0qmhxl")
|
||||
var count := 0
|
||||
|
||||
func _ready() -> void:
|
||||
$Timer.start()
|
||||
|
||||
func on_player_stomped_on(player: Player) -> void:
|
||||
if can_stomp:
|
||||
$GibSpawner.stomp_die(player)
|
||||
|
||||
func on_timeout() -> void:
|
||||
if is_on_floor() == false:
|
||||
return
|
||||
direction = sign(get_tree().get_first_node_in_group("Players").global_position.x - global_position.x + 1)
|
||||
$Sprite.scale.x = direction
|
||||
if count == 0:
|
||||
$Animations.play("PeekOut")
|
||||
$Sprite.play("Idle")
|
||||
else:
|
||||
count = -1
|
||||
$Sprite.play("Aim")
|
||||
$Animations.play("Throw")
|
||||
await $Animations.animation_finished
|
||||
$Timer.start()
|
||||
count += 1
|
||||
|
||||
func throw_wrench() -> void:
|
||||
$Sprite.play("Throw")
|
||||
var node = WRENCH_PROJECTILE.instantiate()
|
||||
node.global_position = $Sprite/Wrench.global_position
|
||||
node.direction = direction
|
||||
add_sibling(node)
|
1
Scripts/Classes/Entities/Enemies/RockyWrench.gd.uid
Normal file
1
Scripts/Classes/Entities/Enemies/RockyWrench.gd.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bfsh8bhcmknkh
|
39
Scripts/Classes/Entities/Enemies/Spike.gd
Normal file
39
Scripts/Classes/Entities/Enemies/Spike.gd
Normal file
@@ -0,0 +1,39 @@
|
||||
extends Enemy
|
||||
const SPIKE_BALL = preload("uid://c7il83r4ab05d")
|
||||
|
||||
@export var can_move := false
|
||||
|
||||
func _ready() -> void:
|
||||
$ThrowTimer.start()
|
||||
if can_move:
|
||||
$TurnTimer.start()
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
if can_move:
|
||||
$Movement.handle_movement(delta)
|
||||
else:
|
||||
$StaticMovement.handle_movement(delta)
|
||||
var target_player = get_tree().get_first_node_in_group("Players")
|
||||
var target_direction = sign(target_player.global_position.x - global_position.x)
|
||||
if target_direction != 0:
|
||||
direction = target_direction
|
||||
|
||||
func throw_ball() -> void:
|
||||
$Movement.can_move = false
|
||||
%Animations.play("BallSpawn")
|
||||
await %Animations.animation_finished
|
||||
summon_ball()
|
||||
%Animations.play("Idle")
|
||||
$Movement.can_move = true
|
||||
|
||||
func summon_ball() -> void:
|
||||
var ball = SPIKE_BALL.instantiate()
|
||||
ball.global_position = %Ball.global_position
|
||||
add_sibling(ball)
|
||||
ball.velocity.x = 100 * direction
|
||||
|
||||
|
||||
func on_timeout() -> void:
|
||||
if not $Movement.can_move: return
|
||||
var target_player = get_tree().get_first_node_in_group("Players")
|
||||
direction = sign(target_player.global_position.x - global_position.x)
|
1
Scripts/Classes/Entities/Enemies/Spike.gd.uid
Executable file
1
Scripts/Classes/Entities/Enemies/Spike.gd.uid
Executable file
@@ -0,0 +1 @@
|
||||
uid://4isgtypd8yqc
|
20
Scripts/Classes/Entities/Enemies/Spiny.gd
Executable file
20
Scripts/Classes/Entities/Enemies/Spiny.gd
Executable file
@@ -0,0 +1,20 @@
|
||||
extends Enemy
|
||||
|
||||
var in_egg := false
|
||||
|
||||
const MOVE_SPEED := 40
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
handle_movement(delta)
|
||||
|
||||
func handle_movement(_delta: float) -> void:
|
||||
if in_egg:
|
||||
if is_on_floor():
|
||||
var player = get_tree().get_first_node_in_group("Players")
|
||||
direction = sign(player.global_position.x - global_position.x)
|
||||
in_egg = false
|
||||
$Sprite.play("Egg")
|
||||
else:
|
||||
$Sprite.play("Walk")
|
||||
$Sprite.scale.x = direction
|
||||
|
1
Scripts/Classes/Entities/Enemies/Spiny.gd.uid
Executable file
1
Scripts/Classes/Entities/Enemies/Spiny.gd.uid
Executable file
@@ -0,0 +1 @@
|
||||
uid://bds7rntb0btee
|
19
Scripts/Classes/Entities/Enemies/SwimmingCheepCheep.gd
Normal file
19
Scripts/Classes/Entities/Enemies/SwimmingCheepCheep.gd
Normal file
@@ -0,0 +1,19 @@
|
||||
extends Enemy
|
||||
|
||||
@export var move_speed := 20
|
||||
|
||||
@export_enum ("Straight", "Wavey", "Random") var movement_type := 2
|
||||
|
||||
func _ready() -> void:
|
||||
if movement_type == 2:
|
||||
if [0, 1].pick_random() == 1:
|
||||
$WaveAnimations.play("Wave")
|
||||
else:
|
||||
$WaveAnimations.play("RESET")
|
||||
elif movement_type == 1:
|
||||
$WaveAnimations.play("Wave")
|
||||
else:
|
||||
$WaveAnimations.play("RESET")
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
global_position.x += (move_speed * direction) * delta
|
1
Scripts/Classes/Entities/Enemies/SwimmingCheepCheep.gd.uid
Executable file
1
Scripts/Classes/Entities/Enemies/SwimmingCheepCheep.gd.uid
Executable file
@@ -0,0 +1 @@
|
||||
uid://b475vfhcp2f30
|
65
Scripts/Classes/Entities/Enemies/Thwomp.gd
Normal file
65
Scripts/Classes/Entities/Enemies/Thwomp.gd
Normal file
@@ -0,0 +1,65 @@
|
||||
class_name Thwomp
|
||||
extends Enemy
|
||||
|
||||
enum States{IDLE, FALLING, LANDED, RISING}
|
||||
|
||||
var current_state := States.IDLE
|
||||
|
||||
@onready var starting_y := global_position.y
|
||||
|
||||
var can_fall := true
|
||||
|
||||
func _physics_process(delta: float) -> void:
|
||||
velocity.x = move_toward(velocity.x, 0, 20)
|
||||
match current_state:
|
||||
States.IDLE:
|
||||
handle_idle(delta)
|
||||
States.FALLING:
|
||||
handle_falling(delta)
|
||||
States.RISING:
|
||||
handle_rising(delta)
|
||||
_:
|
||||
pass
|
||||
move_and_slide()
|
||||
|
||||
func handle_idle(delta: float) -> void:
|
||||
var target_player = get_tree().get_first_node_in_group("Players")
|
||||
var x_distance = abs(target_player.global_position.x - global_position.x)
|
||||
velocity = Vector2.ZERO
|
||||
if x_distance < 24 and can_fall:
|
||||
can_fall = false
|
||||
current_state = States.FALLING
|
||||
$TrackJoint.detach()
|
||||
elif x_distance < 48:
|
||||
%Sprite.play("Look")
|
||||
else:
|
||||
%Sprite.play("Idle")
|
||||
|
||||
func handle_falling(delta: float) -> void:
|
||||
%Sprite.play("Fall")
|
||||
velocity.y += (15 / delta) * delta
|
||||
velocity.y = clamp(velocity.y, -INF, Global.entity_max_fall_speed)
|
||||
handle_block_breaking()
|
||||
if is_on_floor():
|
||||
land()
|
||||
|
||||
func handle_block_breaking() -> void:
|
||||
for i in %BlockBreakingHitbox.get_overlapping_bodies():
|
||||
if i is Block and i.get("destructable") == true:
|
||||
i.destroy()
|
||||
|
||||
func land() -> void:
|
||||
AudioManager.play_sfx("cannon", global_position)
|
||||
current_state = States.LANDED
|
||||
await get_tree().create_timer(1, false).timeout
|
||||
current_state = States.RISING
|
||||
|
||||
func handle_rising(delta: float) -> void:
|
||||
velocity.y = -50
|
||||
%Sprite.play("Idle")
|
||||
if global_position.y <= starting_y:
|
||||
global_position.y = starting_y
|
||||
if global_position.y <= starting_y or is_on_ceiling():
|
||||
current_state = States.IDLE
|
||||
await get_tree().create_timer(0.5, false).timeout
|
||||
can_fall = true
|
1
Scripts/Classes/Entities/Enemies/Thwomp.gd.uid
Executable file
1
Scripts/Classes/Entities/Enemies/Thwomp.gd.uid
Executable file
@@ -0,0 +1 @@
|
||||
uid://bxfc7hxw13s6q
|
Reference in New Issue
Block a user