Merge branch 'main' into custom-level-loading-rewrite

This commit is contained in:
JHDev2006
2025-10-26 12:33:16 +00:00
158 changed files with 2106 additions and 1148 deletions

View File

@@ -163,8 +163,11 @@ func get_resource(json_file: JSON) -> Resource:
ResourceMode.RAW:
pass
ResourceMode.FONT:
resource = FontFile.new()
resource.load_bitmap_font(source_resource_path)
if source_resource_path.contains(Global.get_config_path()):
resource = FontFile.new()
resource.load_bitmap_font(source_resource_path)
else:
resource = load(source_resource_path)
resource.set_meta("base_path", source_resource_path)
if cache.has(json_file.resource_path) == false and use_cache and not is_random:
cache[json_file.resource_path] = resource
@@ -273,7 +276,7 @@ func get_variation_json(json := {}) -> Dictionary:
var chara = "Character:" + Player.CHARACTERS[int(Global.player_characters[0])]
if json.has(chara) == false:
chara = "Character:Mario"
chara = "Character:default"
if json.has(chara):
if json.get(chara).has("link"):
json = get_variation_json(json[json.get(chara).get("link")])

View File

@@ -10,15 +10,16 @@ func _physics_process(delta: float) -> void:
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:
$Sprite.play("Rise")
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)
if dir != 0:
direction = dir
$Sprite.scale.x = direction
var target_position := Vector2(32 * dir, -32)
var final_position = global_position + target_position
var top_point = -176
@@ -28,6 +29,7 @@ func rise_tween() -> void:
tween.tween_property(self, "global_position", final_position, 0.75)
await tween.finished
$Sprite.play("Fall")
falling = true
await get_tree().create_timer(0.25, false).timeout
can_rise = true

View File

@@ -50,15 +50,12 @@ func get_target_y(player: Player) -> float:
return player.global_position.y - 8
func show_smoke() -> void:
# guzlad: ugly but it'll have to do until we move the metadata stuff to actual variables
if (((Global.current_game_mode == Global.GameMode.CUSTOM_LEVEL) or (Global.current_game_mode == Global.GameMode.LEVEL_EDITOR)) and !is_real):
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)
elif has_meta("is_real"):
return
if 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:
@@ -141,6 +138,14 @@ func play_music() -> void:
if music_enabled:
AudioManager.set_music_override(AudioManager.MUSIC_OVERRIDES.BOWSER, 5, false)
func on_timeout() -> void:
move_dir = [-1, 1].pick_random()
func on_gib_about_to_spawn() -> void:
if is_real:
$FallSFX.play()
$FallSFX.finished.connect($FallSFX.queue_free)
$FallSFX.reparent(get_parent())
# guzlad: ugly but it'll have to do until we move the metadata stuff to actual variables
if ((Global.current_game_mode == Global.GameMode.CUSTOM_LEVEL) or (Global.current_game_mode == Global.GameMode.LEVEL_EDITOR)) and !is_real:
$SpriteScaleJoint/DeathSprite/ResourceSetterNew.resource_json = load("res://Assets/Sprites/Enemies/Goomba.json")

View File

@@ -20,7 +20,8 @@ func _ready() -> void:
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
$MovementJoint/Sprite.scale.x = -direction
if $TrackJoint.is_attached: $MovementAnimations.play("RESET")
func _physics_process(delta: float) -> void:
@@ -67,16 +68,16 @@ func do_hammer_throw() -> void:
$HammerTimer.start(randf_range(2, 5))
func throw_hammer() -> void:
$Sprite/Hammer.show()
$Sprite.play("Hammer")
$MovementJoint/Sprite/Hammer.show()
$MovementJoint/Sprite.play("Hammer")
await get_tree().create_timer(0.5, false).timeout
spawn_hammer()
$Sprite.play("Idle")
$Sprite/Hammer.hide()
$MovementJoint/Sprite.play("Idle")
$MovementJoint/Sprite/Hammer.hide()
func spawn_hammer() -> void:
var node = HAMMER.instantiate()
node.global_position = $Sprite/Hammer.global_position
node.global_position = $MovementJoint/Sprite/Hammer.global_position
node.direction = direction
if $TrackJoint.is_attached:
get_parent().owner.add_sibling(node)

View File

@@ -12,8 +12,6 @@ var lakitu_point := Vector2.ZERO
const BLOCK_DISTANCE := 64
static var fixed_throw := true
var player: Player = null
var retreat := false
@@ -28,7 +26,6 @@ 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:
@@ -80,7 +77,7 @@ func throw_spiny() -> void:
node.set("in_egg", true)
node.global_position = $Cloud/Sprite.global_position
node.velocity = Vector2(0, -150)
if fixed_throw:
if Settings.file.difficulty.lakitu_style == 1:
node.velocity.x = 50 * (sign(player.global_position.x - global_position.x))
node.set("direction", sign(node.velocity.x))
add_sibling(node)

4
Scripts/Classes/Entities/Enemies/MontyMole.gd Executable file → Normal file
View File

@@ -7,7 +7,9 @@ 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)
var dir = sign(target_player.global_position.x - global_position.x)
if dir != 0:
direction = dir
$Sprite.scale.x = direction
handle_movement(delta)

View File

@@ -9,9 +9,13 @@ func _physics_process(delta: float) -> void:
func handle_movement(_delta: float) -> void:
if in_egg:
$BasicEnemyMovement.move_speed = 0
$BasicEnemyMovement.second_quest_speed = 0
if is_on_floor():
var player = get_tree().get_first_node_in_group("Players")
direction = sign(player.global_position.x - global_position.x)
$BasicEnemyMovement.move_speed = 32
$BasicEnemyMovement.second_quest_speed = 36
in_egg = false
$Sprite.play("Egg")
else:

View File

@@ -8,6 +8,8 @@ var can_spawn_particles := false
@onready var COIN_SPARKLE = load("res://Scenes/Prefabs/Particles/RedCoinSparkle.tscn")
signal collected
func _ready() -> void:
if ChallengeModeHandler.is_coin_collected(id):
already_collected = true
@@ -16,9 +18,10 @@ func _ready() -> void:
func on_area_entered(area: Area2D) -> void:
if area.owner is Player:
collected()
collect()
func collected() -> void:
func collect() -> void:
collected.emit()
if already_collected:
AudioManager.play_sfx("coin", global_position, 2)
else:

View File

@@ -18,10 +18,10 @@ func on_area_entered(area: Area2D) -> void:
func give_life(_player: Player) -> void:
DiscoLevel.combo_amount += 1
AudioManager.play_sfx("1_up", global_position)
if Global.current_game_mode == Global.GameMode.CHALLENGE or Settings.file.difficulty.inf_lives:
if [Global.GameMode.CHALLENGE, Global.GameMode.BOO_RACE].has(Global.current_game_mode) or Settings.file.difficulty.inf_lives:
Global.score += 2000
$ScoreNoteSpawner.spawn_note(2000)
else:
$ScoreNoteSpawner.spawn_one_up_note()
Global.lives += 1
$ScoreNoteSpawner.spawn_one_up_note()
queue_free()

View File

@@ -32,7 +32,7 @@ func bounce_player(player: Player) -> void:
$Sprite.play("Idle")
func refresh_hitbox() -> void:
$Hitbox/CollisionShape2D.set_deferred("disabled", true)
$PlayerDetection/CollisionShape2D.set_deferred("disabled", true)
await get_tree().physics_frame
$Hitbox/CollisionShape2D.set_deferred("disabled", false)
$PlayerDetection/CollisionShape2D.set_deferred("disabled", false)

View File

@@ -6,9 +6,6 @@ static var character_save := "Mario"
func _ready() -> void:
activated.get_node("ResourceSetterNew").resource_json = load(get_character_sprite_path(0))
if Settings.file.difficulty.checkpoint_style == 0 and (Global.current_game_mode != Global.GameMode.LEVEL_EDITOR and Global.current_game_mode != Global.GameMode.CUSTOM_LEVEL) or Global.current_campaign == "SMBANN":
owner.queue_free()
return
owner.show()
if owner.passed:
sprite.hide()

View File

@@ -161,6 +161,8 @@ const ANIMATION_FALLBACKS := {
"CrouchJump": "Crouch",
"CrouchBump": "Bump",
"CrouchMove": "Crouch",
"WaterCrouchMove": "CrouchMove",
"WingCrouchMove": "WaterCrouchMove",
"IdleAttack": "MoveAttack",
"CrouchAttack": "IdleAttack",
"MoveAttack": "Attack",
@@ -216,7 +218,9 @@ func _ready() -> void:
character = CHARACTERS[int(Global.player_characters[player_id])]
Global.can_time_tick = true
if [Global.GameMode.BOO_RACE, Global.GameMode.MARATHON, Global.GameMode.MARATHON_PRACTICE].has(Global.current_game_mode) == false:
apply_character_physics()
apply_character_physics(true)
else:
apply_character_physics(false)
apply_character_sfx_map()
Global.level_theme_changed.connect(apply_character_sfx_map)
Global.level_theme_changed.connect(apply_character_physics)
@@ -232,22 +236,24 @@ func _ready() -> void:
if [Global.GameMode.LEVEL_EDITOR, Global.GameMode.CUSTOM_LEVEL].has(Global.current_game_mode):
recenter_camera()
func apply_character_physics() -> void:
func apply_character_physics(apply: bool) -> void:
var path = "res://Assets/Sprites/Players/" + character + "/CharacterInfo.json"
if int(Global.player_characters[player_id]) > 3:
path = path.replace("res://Assets/Sprites/Players", Global.config_path.path_join("custom_characters/"))
path = ResourceSetter.get_pure_resource_path(path)
var json = JSON.parse_string(FileAccess.open(path, FileAccess.READ).get_as_text())
for i in json.physics:
set(i, json.physics[i])
if apply:
for i in json.physics:
set(i, json.physics[i])
for i in get_tree().get_nodes_in_group("SmallCollisions"):
var hitbox_scale = json.get("small_hitbox_scale", [1, 1])
i.hitbox = Vector3(hitbox_scale[0], hitbox_scale[1] if i.get_meta("scalable", true) else 1, json.get("small_crouch_scale", 0.75))
var hitbox_scale = json.get("small_hitbox_scale", [1, 1]) if apply else [1, 1]
i.hitbox = Vector3(hitbox_scale[0], hitbox_scale[1] if i.get_meta("scalable", true) else 1, json.get("small_crouch_scale", 0.75) if apply else 0.75)
i._physics_process(0)
for i in get_tree().get_nodes_in_group("BigCollisions"):
var hitbox_scale = json.get("big_hitbox_scale", [1, 1])
i.hitbox = Vector3(hitbox_scale[0], hitbox_scale[1] if i.get_meta("scalable", true) else 1, json.get("big_crouch_scale", 0.5))
var hitbox_scale = json.get("big_hitbox_scale", [1, 1]) if apply else [1, 1]
i.hitbox = Vector3(hitbox_scale[0], hitbox_scale[1] if i.get_meta("scalable", true) else 1, json.get("big_crouch_scale", 0.5) if apply else 0.5)
i._physics_process(0)
func apply_classic_physics() -> void:
@@ -280,9 +286,16 @@ func editor_level_start() -> void:
func _physics_process(delta: float) -> void:
if Input.is_action_just_pressed("debug_reload"):
set_power_state_frame()
if Input.is_action_just_pressed("debug_noclip") and Global.debug_mode:
state_machine.transition_to("NoClip")
Global.log_comment("NOCLIP Enabled")
# guzlad: noclip without dev only works while playtesting.
if (Input.is_action_just_pressed("debug_noclip") or Input.is_action_just_pressed("jump_0")) and ((Global.debug_mode) or (Global.level_editor_is_playtesting())):
if state_machine.is_state("NoClip"):
state_machine.transition_to("Normal")
Global.log_comment("NOCLIP Disabled")
elif !Input.is_action_just_pressed("jump_0") and !state_machine.is_state("NoClip"):
state_machine.transition_to("NoClip")
Global.log_comment("NOCLIP Enabled")
up_direction = -gravity_vector
handle_directions()
handle_block_collision_detection()
@@ -438,7 +451,7 @@ func enemy_bounce_off(add_combo := true, award_score := true) -> void:
func add_stomp_combo(award_score := true) -> void:
if stomp_combo >= 10:
if award_score:
if Global.current_game_mode == Global.GameMode.CHALLENGE or Settings.file.difficulty.inf_lives:
if [Global.GameMode.CHALLENGE, Global.GameMode.BOO_RACE].has(Global.current_gamemode) or Settings.file.difficulty.inf_lives:
Global.score += 10000
score_note_spawner.spawn_note(10000)
else:
@@ -691,12 +704,13 @@ func set_power_state_frame() -> void:
can_bump_fly = %Sprite.sprite_frames.has_animation("FlyBump")
can_kick_anim = %Sprite.sprite_frames.has_animation("Kick")
func get_power_up(power_name := "") -> void:
func get_power_up(power_name := "", give_points := true) -> void:
if is_dead:
return
Global.score += 1000
DiscoLevel.combo_amount += 1
score_note_spawner.spawn_note(1000)
if give_points:
Global.score += 1000
DiscoLevel.combo_amount += 1
score_note_spawner.spawn_note(1000)
AudioManager.play_sfx("power_up", global_position)
if Settings.file.difficulty.damage_style == 0 and power_state.state_name != power_name:
if power_name != "Big" and power_state.state_name != "Big":
@@ -879,7 +893,8 @@ func do_smoke_effect() -> void:
func on_timeout() -> void:
AudioManager.stop_music_override(AudioManager.MUSIC_OVERRIDES.STAR)
await get_tree().create_timer(1, false).timeout
is_invincible = false
if $StarTimer.is_stopped():
is_invincible = false
func on_area_entered(area: Area2D) -> void:

View File

@@ -67,7 +67,7 @@ func on_player_hit(hit_player: Player) -> void:
func award_score(award_level: int) -> void:
if award_level >= 10:
if Global.current_game_mode == Global.GameMode.CHALLENGE or Settings.file.difficulty.inf_lives:
if [Global.GameMode.CHALLENGE, Global.GameMode.BOO_RACE].has(Global.current_game_mode) or Settings.file.difficulty.inf_lives:
$ScoreNoteSpawner.spawn_note(10000)
else:
AudioManager.play_global_sfx("1_up")

View File

@@ -59,8 +59,8 @@ signal text_shadow_changed
var debugged_in := true
var score_tween = create_tween()
var time_tween = create_tween()
var score_tween = null
var time_tween = null
var total_deaths := 0
@@ -314,8 +314,10 @@ func tally_time() -> void:
score_tally_finished.emit()
func cancel_score_tally() -> void:
score_tween.kill()
time_tween.kill()
if score_tween != null:
score_tween.kill()
if time_tween != null:
time_tween.kill()
tallying_score = false
$ScoreTally.stop()
@@ -457,6 +459,12 @@ func log_comment(msg := "") -> void:
await get_tree().create_timer(2, false).timeout
error_message.queue_free()
func level_editor_is_playtesting() -> bool:
if Global.current_game_mode == Global.GameMode.LEVEL_EDITOR:
if Global.level_editor.current_state == LevelEditor.EditorState.PLAYTESTING:
return true
return false
func unlock_achievement(achievement_id := AchievementID.SMB1_CLEAR) -> void:
achievements[achievement_id] = "1"
if achievement_id != AchievementID.COMPLETIONIST:

View File

@@ -68,6 +68,7 @@ var file := {
"bridge_animation": 0,
"visible_timers": 0,
"transition_animation": 0,
"smbs_scroll": 0,
"colour_pipes": 1,
"firebar_style": 0,
"extra_particles": 0

View File

@@ -13,9 +13,6 @@ func enter(_msg := {}) -> void:
func physics_update(_delta: float) -> void:
player.velocity = Input.get_vector("move_left_0", "move_right_0", "move_up_0", "move_down_0") * (FAST_SPEED if Input.is_action_pressed("run_0") else SLOW_SPEED)
player.move_and_slide()
if Input.is_action_just_pressed("jump_0"):
state_machine.transition_to("Normal")
Global.log_comment("NOCLIP Disabled")
func exit() -> void:
player.can_hurt = false

View File

@@ -221,13 +221,19 @@ func get_animation_name() -> String:
return "CrouchJump"
elif player.is_actually_on_floor():
if abs(player.velocity.x) >= 5 and not player.is_actually_on_wall():
return "CrouchMove"
elif player.in_water:
return "WaterCrouch"
elif player.flight_meter > 0:
return "WingCrouch"
if player.in_water:
return "WaterCrouchMove"
elif player.flight_meter > 0:
return "WingCrouchMove"
else:
return "CrouchMove"
else:
return "Crouch"
if player.in_water:
return "WaterCrouch"
elif player.flight_meter > 0:
return "WingCrouch"
else:
return "Crouch"
if player.is_actually_on_floor():
if player.skidding:
return "Skid"

View File

@@ -15,3 +15,11 @@ func _physics_process(delta: float) -> void:
func _process(delta: float) -> void:
state.update(delta)
func get_state() -> String:
if (state != null):
return state.name
return ""
func is_state(state_to_check := "") -> bool:
return get_state() == state_to_check