ResourceSetter.gd 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. class_name ResourceSetter
  2. extends Node
  3. @export var node_to_affect: Node = null
  4. @export var property_name := ""
  5. @export var themed_resource: ThemedResource = null
  6. @export var use_classic_theming := false
  7. @export var use_cache := true
  8. signal sprites_updated
  9. static var cache := {}
  10. func _enter_tree() -> void:
  11. Global.level_theme_changed.connect(update_sprites)
  12. Global.level_time_changed.connect(update_sprites)
  13. func _ready() -> void:
  14. update_sprites()
  15. func update_sprites() -> void:
  16. cache.clear()
  17. if themed_resource == null:
  18. node_to_affect.set(property_name, null)
  19. return
  20. var resource = get_resource(themed_resource, node_to_affect, true, use_cache)
  21. node_to_affect.set(property_name, resource)
  22. if node_to_affect is AnimatedSprite2D:
  23. node_to_affect.play()
  24. sprites_updated.emit()
  25. static func get_resource(resource: Resource, node: Node = null, assign := false, cache_enabled := true) -> RefCounted:
  26. if resource == null:
  27. return resource
  28. var og_path = resource.resource_path
  29. if resource is AtlasTexture:
  30. og_path = resource.atlas.resource_path
  31. if resource is ThemedResource:
  32. if resource.get(Global.level_theme) != null:
  33. resource = get_resource(resource.get(Global.level_theme))
  34. else:
  35. resource = get_resource(resource.Overworld)
  36. if resource is CampaignResource:
  37. if resource.get(Global.current_campaign) != null:
  38. resource = get_resource(resource.get(Global.current_campaign))
  39. else:
  40. resource = get_resource(resource.SMB1)
  41. if assign:
  42. if resource is AtlasTexture:
  43. resource.filter_clip = true
  44. if resource is SpriteFrames:
  45. if node is not AnimatedSprite2D:
  46. resource = resource.get_frame_texture(resource.get_animation_names()[0], 0)
  47. if Settings.file.visuals.resource_packs.is_empty() == false:
  48. for i in Settings.file.visuals.resource_packs:
  49. resource = get_override_resource(resource, i)
  50. if cache.has(og_path) == false:
  51. cache[og_path] = resource.duplicate()
  52. if resource == null:
  53. pass
  54. return resource
  55. static func get_override_resource(resource: Resource = null, resource_pack := "") -> Object:
  56. if resource == null:
  57. return
  58. if resource_pack == "":
  59. return
  60. var original_resource_path = resource.resource_path
  61. var resource_path = get_override_resource_path(resource.resource_path, resource_pack)
  62. if FileAccess.file_exists(resource_path):
  63. if resource is Texture:
  64. resource = create_image_from_path(resource_path)
  65. elif resource is SpriteFrames:
  66. resource = create_new_sprite_frames(resource, resource_pack)
  67. if resource is AudioStream:
  68. if resource_path.contains(".mp3"):
  69. var resource_loops = resource.has_loop()
  70. resource = AudioStreamMP3.load_from_file(resource_path)
  71. resource.set_loop(resource_loops)
  72. elif resource_path.contains(".wav"):
  73. resource = AudioStreamWAV.load_from_file(resource_path)
  74. if resource is FontVariation:
  75. resource_path = get_override_resource_path(resource.base_font.resource_path, resource_pack)
  76. if FileAccess.file_exists(resource_path):
  77. var new_font = FontFile.new()
  78. var variation = resource.duplicate()
  79. new_font.load_bitmap_font(resource_path.replace(".png", ".fnt"))
  80. variation.base_font = new_font
  81. resource = variation
  82. else:
  83. if resource is SpriteFrames:
  84. resource = create_new_sprite_frames(resource, resource_pack)
  85. if resource is AtlasTexture:
  86. resource_path = get_override_resource_path(resource.atlas.resource_path, resource_pack)
  87. if FileAccess.file_exists(resource_path):
  88. var new_resource = AtlasTexture.new()
  89. new_resource.atlas = create_image_from_path(get_override_resource_path(resource.atlas.resource_path, resource_pack))
  90. new_resource.region = resource.region
  91. return new_resource
  92. if resource is AudioStreamInteractive:
  93. resource = get_override_resource(resource.get_clip_stream(0), resource_pack)
  94. if resource is FontVariation:
  95. resource_path = get_override_resource_path(resource.base_font.resource_path, resource_pack)
  96. if FileAccess.file_exists(resource_path):
  97. var new_font = FontFile.new()
  98. var variation = resource.duplicate()
  99. new_font.load_bitmap_font(resource_path.replace(".png", ".fnt"))
  100. variation.base_font = new_font
  101. resource = variation
  102. return resource
  103. static func create_image_from_path(file_path := "") -> ImageTexture:
  104. var image = Image.new()
  105. image.load(file_path)
  106. return ImageTexture.create_from_image(image)
  107. static func create_new_sprite_frames(old_sprite_frames: SpriteFrames, resource_pack := "") -> SpriteFrames:
  108. var new_frames = SpriteFrames.new()
  109. new_frames.remove_animation("default")
  110. for i in old_sprite_frames.get_animation_names():
  111. new_frames.add_animation(i)
  112. for x in old_sprite_frames.get_frame_count(i):
  113. var frame = AtlasTexture.new()
  114. var old_frame = old_sprite_frames.get_frame_texture(i, x)
  115. frame.atlas = get_override_resource(old_frame.atlas, resource_pack)
  116. frame.region = old_frame.region
  117. new_frames.add_frame(i, frame, old_sprite_frames.get_frame_duration(i, x))
  118. new_frames.set_animation_loop(i, old_sprite_frames.get_animation_loop(i))
  119. new_frames.set_animation_speed(i, old_sprite_frames.get_animation_speed(i))
  120. return new_frames
  121. static func get_pure_resource_path(resource_path := "") -> String:
  122. if Settings.file.visuals.resource_packs.is_empty() == false:
  123. for i in Settings.file.visuals.resource_packs:
  124. var new_path = get_override_resource_path(resource_path, i)
  125. new_path = new_path.replace("user://custom_characters/", "user://resource_packs/" + new_path + "/Sprites/Players/CustomCharacters/")
  126. if FileAccess.file_exists(new_path):
  127. return new_path
  128. return resource_path
  129. static func get_override_resource_path(resource_path := "", resource_pack := "") -> String:
  130. if resource_pack != "":
  131. return resource_path.replace("res://Assets", "user://resource_packs/" + resource_pack)
  132. else:
  133. return resource_path