mirror of
https://github.com/JHDev2006/Super-Mario-Bros.-Remastered-Public.git
synced 2025-10-22 07:28:14 +00:00

This is a simple bugfix that allows the Title Screen music to loop. It also works with Resource Packs. For the purposes of faithfulness, this fix is only needed for the Lost Levels title music to match the All-Stars counterpart.
316 lines
11 KiB
GDScript
316 lines
11 KiB
GDScript
class_name ResourceSetterNew
|
|
extends Node
|
|
|
|
@export var node_to_affect: Node = null
|
|
@export var property_node: Node = null
|
|
@export var property_name := ""
|
|
@export var mode: ResourceMode = ResourceMode.SPRITE_FRAMES
|
|
@export var resource_json: JSON = null:
|
|
set(value):
|
|
resource_json = value
|
|
update_resource()
|
|
|
|
enum ResourceMode {SPRITE_FRAMES, TEXTURE, AUDIO, RAW}
|
|
@export var use_cache := true
|
|
|
|
static var cache := {}
|
|
static var property_cache := {}
|
|
|
|
var current_json_path := ""
|
|
|
|
static var state := [0, 0]
|
|
|
|
static var pack_configs := {}
|
|
|
|
var config_to_use := {}
|
|
|
|
var is_random := false
|
|
|
|
signal updated
|
|
|
|
@export var force_properties := {}
|
|
var update_on_spawn := true
|
|
|
|
func _init() -> void:
|
|
set_process_mode(Node.PROCESS_MODE_ALWAYS)
|
|
|
|
func _ready() -> void:
|
|
safety_check()
|
|
if update_on_spawn:
|
|
update_resource()
|
|
Global.level_time_changed.connect(update_resource)
|
|
Global.level_theme_changed.connect(update_resource)
|
|
|
|
|
|
func safety_check() -> void:
|
|
if Settings.file.visuals.resource_packs.has("BaseAssets") == false:
|
|
Settings.file.visuals.resource_packs.append("BaseAssets")
|
|
|
|
func update_resource() -> void:
|
|
randomize()
|
|
if is_inside_tree() == false or is_queued_for_deletion() or resource_json == null or node_to_affect == null:
|
|
return
|
|
if state != [Global.level_theme, Global.theme_time]:
|
|
cache.clear()
|
|
property_cache.clear()
|
|
if node_to_affect != null:
|
|
var resource = get_resource(resource_json)
|
|
node_to_affect.set(property_name, resource)
|
|
if node_to_affect is AnimatedSprite2D:
|
|
node_to_affect.play()
|
|
state = [Global.level_theme, Global.theme_time]
|
|
updated.emit()
|
|
|
|
func get_resource(json_file: JSON) -> Resource:
|
|
if cache.has(json_file.resource_path) and use_cache and force_properties.is_empty():
|
|
if property_cache.has(json_file.resource_path):
|
|
apply_properties(property_cache[json_file.resource_path])
|
|
return cache[json_file.resource_path]
|
|
|
|
var resource: Resource = null
|
|
var resource_path = json_file.resource_path
|
|
config_to_use = {}
|
|
for i in Settings.file.visuals.resource_packs:
|
|
resource_path = get_resource_pack_path(resource_path, i)
|
|
|
|
var source_json = JSON.parse_string(FileAccess.open(resource_path, FileAccess.READ).get_as_text())
|
|
if source_json == null:
|
|
Global.log_error("Error parsing " + resource_path + "!")
|
|
return
|
|
var json = source_json.duplicate()
|
|
var source_resource_path = ""
|
|
if json.has("variations"):
|
|
json = get_variation_json(json.variations)
|
|
if json.has("source"):
|
|
if json.get("source") is String:
|
|
source_resource_path = json_file.resource_path.replace(json_file.resource_path.get_file(), json.source)
|
|
else:
|
|
Global.log_error("Error getting variations! " + resource_path)
|
|
return
|
|
for i in Settings.file.visuals.resource_packs:
|
|
source_resource_path = get_resource_pack_path(source_resource_path, i)
|
|
if json.has("rect"):
|
|
resource = load_image_from_path(source_resource_path)
|
|
var atlas = AtlasTexture.new()
|
|
atlas.atlas = resource
|
|
atlas.region = Rect2(json.rect[0], json.rect[1], json.rect[2], json.rect[3])
|
|
resource = atlas
|
|
if json.has("properties"):
|
|
apply_properties(json.get("properties"))
|
|
if use_cache:
|
|
property_cache[json_file.resource_path] = json.properties.duplicate()
|
|
elif source_json.has("properties"):
|
|
apply_properties(source_json.get("properties"))
|
|
if use_cache:
|
|
property_cache[json_file.resource_path] = source_json.properties.duplicate()
|
|
match mode:
|
|
ResourceMode.SPRITE_FRAMES:
|
|
var animation_json = {}
|
|
if json.has("animations"):
|
|
animation_json = json.get("animations")
|
|
elif source_json.has("animations"):
|
|
animation_json = source_json.get("animations")
|
|
if animation_json != {}:
|
|
resource = load_image_from_path(source_resource_path)
|
|
if json.has("rect"):
|
|
var atlas = AtlasTexture.new()
|
|
atlas.atlas = resource
|
|
atlas.region = Rect2(json.rect[0], json.rect[1], json.rect[2], json.rect[3])
|
|
resource = atlas
|
|
resource = create_sprite_frames_from_image(resource, animation_json)
|
|
else:
|
|
resource = load_image_from_path(source_resource_path)
|
|
if json.has("rect"):
|
|
var atlas = AtlasTexture.new()
|
|
atlas.atlas = resource
|
|
atlas.region = Rect2(json.rect[0], json.rect[1], json.rect[2], json.rect[3])
|
|
resource = atlas
|
|
var sprite_frames = SpriteFrames.new()
|
|
sprite_frames.add_frame("default", resource)
|
|
resource = sprite_frames
|
|
ResourceMode.TEXTURE:
|
|
if json.get("source") is Array:
|
|
resource = AnimatedTexture.new()
|
|
resource.frames = json.get("source").size()
|
|
var idx := 0
|
|
for i in json.get("source"):
|
|
var frame_path = ResourceSetter.get_pure_resource_path(json_file.resource_path.replace(json_file.resource_path.get_file(), i))
|
|
print(frame_path)
|
|
resource.set_frame_texture(idx, load_image_from_path(frame_path))
|
|
idx += 1
|
|
else:
|
|
resource = load_image_from_path(source_resource_path)
|
|
if json.has("rect"):
|
|
var rect = json.rect
|
|
var atlas = AtlasTexture.new()
|
|
atlas.atlas = resource
|
|
atlas.region = Rect2(rect[0], rect[1], rect[2], rect[3])
|
|
resource = atlas
|
|
ResourceMode.AUDIO:
|
|
resource = load_audio_from_path(source_resource_path)
|
|
ResourceMode.RAW:
|
|
pass
|
|
if cache.has(json_file.resource_path) == false and use_cache and not is_random:
|
|
cache[json_file.resource_path] = resource
|
|
return resource
|
|
|
|
func apply_properties(properties := {}) -> void:
|
|
if property_node == null:
|
|
return
|
|
for i in properties.keys():
|
|
property_node.set(i, properties[i])
|
|
|
|
func get_variation_json(json := {}) -> Dictionary:
|
|
var level_theme = Global.level_theme
|
|
if force_properties.has("Theme"):
|
|
level_theme = force_properties.Theme
|
|
|
|
for i in json.keys().filter(func(key): return key.contains("config:")):
|
|
if config_to_use != {}:
|
|
var option_name = i.get_slice(":", 1)
|
|
if config_to_use.options.has(option_name):
|
|
json = get_variation_json(json[i][config_to_use.options[option_name]])
|
|
break
|
|
|
|
if json.has(level_theme) == false:
|
|
level_theme = "default"
|
|
if json.has(level_theme):
|
|
if json.get(level_theme).has("link"):
|
|
json = get_variation_json(json[json.get(level_theme).get("link")])
|
|
else:
|
|
json = get_variation_json(json[level_theme])
|
|
|
|
var level_time = Global.theme_time
|
|
if force_properties.has("Time"):
|
|
level_time = force_properties.Time
|
|
if json.has(level_time):
|
|
json = get_variation_json(json[level_time])
|
|
|
|
var campaign = Global.current_campaign
|
|
if force_properties.has("Campaign"):
|
|
is_random = true
|
|
campaign = force_properties.Campaign
|
|
if json.has(campaign) == false:
|
|
campaign = "SMB1"
|
|
if json.has(campaign):
|
|
if json.get(campaign).has("link"):
|
|
json = get_variation_json(json[json.get(campaign).get("link")])
|
|
else:
|
|
json = get_variation_json(json[campaign])
|
|
|
|
if json.has("choices"):
|
|
is_random = true
|
|
json = get_variation_json(json.choices.pick_random())
|
|
|
|
var world = "World" + str(Global.world_num)
|
|
if force_properties.has("World"):
|
|
is_random = true
|
|
world = "World" + str(force_properties.World)
|
|
print(world)
|
|
if json.has(world) == false:
|
|
world = "World1"
|
|
if json.has(world):
|
|
if json.get(world).has("link"):
|
|
json = get_variation_json(json[json.get(world).get("link")])
|
|
else:
|
|
json = get_variation_json(json[world])
|
|
|
|
var level_string = "Level" + str(Global.level_num)
|
|
if json.has(level_string) == false:
|
|
level_string = "Level1"
|
|
if json.has(level_string):
|
|
if json.get(level_string).has("link"):
|
|
json = get_variation_json(json[json.get(level_string).get("link")])
|
|
else:
|
|
json = get_variation_json(json[level_string])
|
|
|
|
var game_mode = "GameMode:" + Global.game_mode_strings[Global.current_game_mode]
|
|
if json.has(game_mode) == false:
|
|
game_mode = "GameMode:" + Global.game_mode_strings[0]
|
|
if json.has(game_mode):
|
|
if json.get(game_mode).has("link"):
|
|
json = get_variation_json(json[json.get(game_mode).get("link")])
|
|
else:
|
|
json = get_variation_json(json[game_mode])
|
|
|
|
var chara = "Character:" + Player.CHARACTERS[int(Global.player_characters[0])]
|
|
if json.has(chara) == false:
|
|
chara = "Character:Mario"
|
|
if json.has(chara):
|
|
if json.get(chara).has("link"):
|
|
json = get_variation_json(json[json.get(chara).get("link")])
|
|
else:
|
|
json = get_variation_json(json[chara])
|
|
|
|
var boo = "RaceBoo:" + str(BooRaceHandler.boo_colour)
|
|
if json.has(boo) == false:
|
|
boo = "RaceBoo:0"
|
|
if force_properties.has("RaceBoo"):
|
|
boo = "RaceBoo:" + str(force_properties["RaceBoo"])
|
|
if json.has(boo):
|
|
if json.get(boo).has("link"):
|
|
json = get_variation_json(json[json.get(boo).get("link")])
|
|
else:
|
|
json = get_variation_json(json[boo])
|
|
|
|
return json
|
|
|
|
func get_resource_pack_path(res_path := "", resource_pack := "") -> String:
|
|
var user_path := res_path.replace("res://Assets", "user://resource_packs/" + resource_pack)
|
|
user_path = user_path.replace("user://custom_characters/", "user://resource_packs/" + resource_pack + "/Sprites/Players/CustomCharacters/")
|
|
if FileAccess.file_exists(user_path):
|
|
if FileAccess.file_exists("user://resource_packs/" + resource_pack + "/config.json"):
|
|
config_to_use = JSON.parse_string(FileAccess.open("user://resource_packs/" + resource_pack + "/config.json", FileAccess.READ).get_as_text())
|
|
if config_to_use == null:
|
|
Global.log_error("Error parsing Config File! (" + resource_pack + ")")
|
|
config_to_use = {}
|
|
return user_path
|
|
else:
|
|
return res_path
|
|
|
|
func create_sprite_frames_from_image(image: Resource, animation_json := {}) -> SpriteFrames:
|
|
var sprite_frames = SpriteFrames.new()
|
|
sprite_frames.remove_animation("default")
|
|
for anim_name in animation_json.keys():
|
|
sprite_frames.add_animation(anim_name)
|
|
for frame in animation_json[anim_name].frames:
|
|
var frame_texture = AtlasTexture.new()
|
|
frame_texture.atlas = image
|
|
frame_texture.region = Rect2(frame[0], frame[1], frame[2], frame[3])
|
|
frame_texture.filter_clip = true
|
|
sprite_frames.add_frame(anim_name, frame_texture)
|
|
sprite_frames.set_animation_loop(anim_name, animation_json[anim_name].loop)
|
|
sprite_frames.set_animation_speed(anim_name, animation_json[anim_name].speed)
|
|
|
|
return sprite_frames
|
|
|
|
func clear_cache() -> void:
|
|
for i in cache.keys():
|
|
if cache[i] == null:
|
|
cache.erase(i)
|
|
cache.clear()
|
|
property_cache.clear()
|
|
|
|
func load_image_from_path(path := "") -> ImageTexture:
|
|
if path.contains("res://"):
|
|
if path.contains("NULL"):
|
|
return null
|
|
return load(path)
|
|
var image = Image.new()
|
|
if path == "":
|
|
print([path, owner.name])
|
|
image.load(path)
|
|
return ImageTexture.create_from_image(image)
|
|
|
|
func load_audio_from_path(path := "") -> AudioStream:
|
|
var stream = null
|
|
if path.contains(".bgm"):
|
|
stream = AudioManager.generate_interactive_stream(JSON.parse_string(FileAccess.get_file_as_string(path)))
|
|
elif path.contains("res://"):
|
|
return load(path)
|
|
if path.contains(".wav"):
|
|
stream = AudioStreamWAV.load_from_file(path)
|
|
elif path.contains(".mp3"):
|
|
stream = AudioStreamMP3.load_from_file(path)
|
|
return stream
|