Global.gd 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. extends Node
  2. var level_theme := "Overworld":
  3. set(value):
  4. level_theme = value
  5. level_theme_changed.emit()
  6. var theme_time := "Day":
  7. set(value):
  8. theme_time = value
  9. level_time_changed.emit()
  10. signal level_theme_changed
  11. signal level_time_changed
  12. const BASE64_CHARSET := "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
  13. const VERSION_CHECK_URL := "https://raw.githubusercontent.com/JHDev2006/smb1r-version/refs/heads/main/version.txt"
  14. var entity_gravity := 10.0
  15. var entity_max_fall_speed := 280
  16. var level_editor: LevelEditor = null
  17. var current_level: Level = null
  18. var second_quest := false
  19. var extra_worlds_win := false
  20. const lang_codes := ["en", "fr", "es", "de", "it", "pt", "pl", "tr", "ru", "jp", "fil", "id", "ga"]
  21. var rom_path := ""
  22. var rom_assets_exist := false
  23. const ROM_POINTER_PATH := "user://rom_pointer.smb"
  24. const ROM_PATH := "user://baserom.nes"
  25. const ROM_ASSETS_PATH := "user://resource_packs/BaseAssets"
  26. const ROM_PACK_NAME := "BaseAssets"
  27. const ROM_ASSETS_VERSION := 0
  28. var server_version := -1
  29. var current_version := -1
  30. var version_number := ""
  31. const LEVEL_THEMES := {
  32. "SMB1": SMB1_LEVEL_THEMES,
  33. "SMBLL": SMB1_LEVEL_THEMES,
  34. "SMBANN": SMB1_LEVEL_THEMES,
  35. "SMBS": SMBS_LEVEL_THEMES
  36. }
  37. const SMB1_LEVEL_THEMES := ["Overworld", "Desert", "Snow", "Jungle", "Desert", "Snow", "Jungle", "Overworld", "Space", "Autumn", "Pipeland", "Skyland", "Volcano"]
  38. const SMBS_LEVEL_THEMES := ["Overworld", "Garden", "Beach", "Mountain", "Garden", "Beach", "Mountain", "Overworld", "Autumn", "Pipeland", "Skyland", "Volcano", "Fuck"]
  39. const FORCE_NIGHT_THEMES := ["Space"]
  40. const FORCE_DAY_THEMES := []
  41. signal text_shadow_changed
  42. @onready var player_ghost: PlayerGhost = $PlayerGhost
  43. var debugged_in := true
  44. var score_tween = create_tween()
  45. var time_tween = create_tween()
  46. var score := 0:
  47. set(value):
  48. if disco_mode == true:
  49. if value > score:
  50. var diff = value - score
  51. score = score + (diff * 1)
  52. else:
  53. score = value
  54. else:
  55. score = value
  56. var coins := 0:
  57. set(value):
  58. coins = value
  59. if coins >= 100:#
  60. coins = coins % 100
  61. if Settings.file.difficulty.inf_lives == 0 and (Global.current_game_mode != Global.GameMode.CHALLENGE and Global.current_campaign != "SMBANN"):
  62. lives += floor(coins / 100.0)
  63. AudioManager.play_sfx("1_up", get_viewport().get_camera_2d().get_screen_center_position())
  64. var time := 300
  65. var lives := 3
  66. var world_num := 1
  67. var level_num := 1
  68. var disco_mode := false
  69. signal transition_finished
  70. var transitioning_scene := false
  71. var awaiting_transition := false
  72. signal level_complete_begin
  73. signal score_tally_finished
  74. var achievements := "0000000000000000000000000000"
  75. const LSS_GAME_ID := 5
  76. enum AchievementID{
  77. SMB1_CLEAR, SMBLL_CLEAR, SMBS_CLEAR, SMBANN_CLEAR,
  78. SMB1_CHALLENGE, SMBLL_CHALLENGE, SMBS_CHALLENGE,
  79. SMB1_BOO, SMBLL_BOO, SMBS_BOO,
  80. SMB1_GOLD_BOO, SMBLL_GOLD_BOO, SMBS_GOLD_BOO,
  81. SMB1_BRONZE, SMBLL_BRONZE, SMBS_BRONZE,
  82. SMB1_SILVER, SMBLL_SILVER, SMBS_SILVER,
  83. SMB1_GOLD, SMBLL_GOLD, SMBS_GOLD,
  84. SMB1_RUN, SMBLL_RUN, SMBS_RUN,
  85. ANN_PRANK, SMBLL_WORLD9,
  86. COMPLETIONIST
  87. }
  88. const HIDDEN_ACHIEVEMENTS := [AchievementID.COMPLETIONIST]
  89. var can_time_tick := true:
  90. set(value):
  91. can_time_tick = value
  92. if value == false:
  93. pass
  94. var player_power_states := "0000"
  95. var connected_players := 1
  96. const CAMPAIGNS := ["SMB1", "SMBLL", "SMBS", "SMBANN"]
  97. var player_characters := "0000":
  98. set(value):
  99. player_characters = value
  100. player_characters_changed.emit()
  101. signal player_characters_changed
  102. signal disco_level_continued
  103. signal frame_rule
  104. var hard_mode := false
  105. var current_campaign := "SMB1"
  106. var death_load := false
  107. var tallying_score := false
  108. var in_title_screen := false
  109. var game_paused := false
  110. var can_pause := true
  111. var fade_transition := true
  112. enum GameMode{NONE, CAMPAIGN, BOO_RACE, CHALLENGE, MARATHON, MARATHON_PRACTICE, LEVEL_EDITOR, CUSTOM_LEVEL, DISCO}
  113. const game_mode_strings := ["Default", "Campaign", "BooRace", "Challenge", "Marathon", "MarathonPractice", "LevelEditor", "CustomLevel", "Disco"]
  114. var current_game_mode: GameMode = GameMode.NONE
  115. var high_score := 0
  116. var game_beaten := false
  117. signal p_switch_toggle
  118. var p_switch_active := false
  119. var p_switch_timer := 0.0
  120. var p_switch_timer_paused := false
  121. var debug_mode := false
  122. func _ready() -> void:
  123. current_version = get_version_number()
  124. get_server_version()
  125. if OS.is_debug_build():
  126. debug_mode = false
  127. setup_discord_rpc()
  128. check_for_rom()
  129. func check_for_rom() -> void:
  130. if FileAccess.file_exists(Global.ROM_PATH) == false:
  131. return
  132. var path = Global.ROM_PATH
  133. if FileAccess.file_exists(path):
  134. if ROMVerifier.is_valid_rom(path):
  135. rom_path = path
  136. if DirAccess.dir_exists_absolute(ROM_ASSETS_PATH):
  137. var pack_json: String = FileAccess.get_file_as_string(ROM_ASSETS_PATH + "/pack_info.json")
  138. var pack_dict: Dictionary = JSON.parse_string(pack_json)
  139. if pack_dict.get("version", -1) == ROM_ASSETS_VERSION:
  140. rom_assets_exist = true
  141. else:
  142. OS.move_to_trash(ROM_ASSETS_PATH)
  143. func _process(delta: float) -> void:
  144. if Input.is_action_just_pressed("debug_reload"):
  145. ResourceSetter.cache.clear()
  146. ResourceSetterNew.cache.clear()
  147. ResourceGetter.cache.clear()
  148. AudioManager.current_level_theme = ""
  149. level_theme_changed.emit()
  150. log_comment("Reloaded resource packs!")
  151. handle_p_switch(delta)
  152. if Input.is_key_label_pressed(KEY_F11) and debug_mode == false and OS.is_debug_build():
  153. AudioManager.play_global_sfx("switch")
  154. debug_mode = true
  155. log_comment("Debug Mode enabled! some bugs may occur!")
  156. func handle_p_switch(delta: float) -> void:
  157. if p_switch_active and get_tree().paused == false:
  158. if p_switch_timer_paused == false:
  159. p_switch_timer -= delta
  160. if p_switch_timer <= 0:
  161. p_switch_active = false
  162. p_switch_toggle.emit()
  163. AudioManager.stop_music_override(AudioManager.MUSIC_OVERRIDES.PSWITCH)
  164. func get_build_time() -> void:
  165. print(int(Time.get_unix_time_from_system()))
  166. func get_version_number() -> int:
  167. var number = (FileAccess.open("res://version.txt", FileAccess.READ).get_as_text())
  168. version_number = str(number)
  169. return int(number)
  170. func player_action_pressed(action := "", player_id := 0) -> bool:
  171. return Input.is_action_pressed(action + "_" + str(player_id))
  172. func player_action_just_pressed(action := "", player_id := 0) -> bool:
  173. return Input.is_action_just_pressed(action + "_" + str(player_id))
  174. func player_action_just_released(action := "", player_id := 0) -> bool:
  175. return Input.is_action_just_released(action + "_" + str(player_id))
  176. func tally_time() -> void:
  177. if tallying_score:
  178. return
  179. $ScoreTally.play()
  180. tallying_score = true
  181. var target_score = score + (time * 50)
  182. score_tween = create_tween()
  183. time_tween = create_tween()
  184. var duration = float(time) / 120
  185. score_tween.tween_property(self, "score", target_score, duration)
  186. time_tween.tween_property(self, "time", 0, duration)
  187. await score_tween.finished
  188. tallying_score = false
  189. $ScoreTally.stop()
  190. $ScoreTallyEnd.play()
  191. score_tally_finished.emit()
  192. func cancel_score_tally() -> void:
  193. score_tween.kill()
  194. time_tween.kill()
  195. tallying_score = false
  196. $ScoreTally.stop()
  197. func activate_p_switch() -> void:
  198. if p_switch_active == false:
  199. p_switch_toggle.emit()
  200. AudioManager.set_music_override(AudioManager.MUSIC_OVERRIDES.PSWITCH, 99, false)
  201. p_switch_timer = 10
  202. p_switch_active = true
  203. func reset_values() -> void:
  204. PlayerGhost.idx = 0
  205. Checkpoint.passed = false
  206. Checkpoint.sublevel_id = 0
  207. Level.start_level_path = Level.get_scene_string(Global.world_num, Global.level_num)
  208. LevelPersistance.reset_states()
  209. Level.first_load = true
  210. Level.can_set_time = true
  211. Level.in_vine_level = false
  212. Level.vine_return_level = ""
  213. Level.vine_warp_level = ""
  214. func clear_saved_values() -> void:
  215. coins = 0
  216. score = 0
  217. lives = 3
  218. player_power_states = "0000"
  219. func transition_to_scene(scene_path := "") -> void:
  220. Global.fade_transition = bool(Settings.file.visuals.transition_animation)
  221. if transitioning_scene:
  222. return
  223. transitioning_scene = true
  224. if fade_transition:
  225. $Transition/AnimationPlayer.play("FadeIn")
  226. await $Transition/AnimationPlayer.animation_finished
  227. await get_tree().create_timer(0.1, true).timeout
  228. else:
  229. %TransitionBlock.modulate.a = 1
  230. $Transition.show()
  231. await get_tree().create_timer(0.1, true).timeout
  232. get_tree().change_scene_to_file(scene_path)
  233. await get_tree().scene_changed
  234. await get_tree().create_timer(0.15, true).timeout
  235. if fade_transition:
  236. $Transition/AnimationPlayer.play_backwards("FadeIn")
  237. else:
  238. $Transition/AnimationPlayer.play("RESET")
  239. $Transition.hide()
  240. transitioning_scene = false
  241. func do_fake_transition() -> void:
  242. if fade_transition:
  243. $Transition/AnimationPlayer.play("FadeIn")
  244. await $Transition/AnimationPlayer.animation_finished
  245. await get_tree().create_timer(0.2, false).timeout
  246. $Transition/AnimationPlayer.play_backwards("FadeIn")
  247. else:
  248. %TransitionBlock.modulate.a = 1
  249. $Transition.show()
  250. await get_tree().create_timer(0.25, false).timeout
  251. $Transition.hide()
  252. func freeze_screen() -> void:
  253. if Settings.file.video.visuals == 1:
  254. return
  255. $Transition.show()
  256. $Transition/Freeze.show()
  257. $Transition/Freeze.texture = ImageTexture.create_from_image(get_viewport().get_texture().get_image())
  258. func close_freeze() -> void:
  259. $Transition/Freeze.hide()
  260. $Transition.hide()
  261. var recording_dir = "user://marathon_recordings/"
  262. func setup_discord_rpc() -> void:
  263. DiscordRPC.app_id = 1331261692381757562
  264. DiscordRPC.start_timestamp = int(Time.get_unix_time_from_system())
  265. DiscordRPC.details = "In Title Screen.."
  266. if DiscordRPC.get_is_discord_working():
  267. DiscordRPC.refresh()
  268. func set_discord_status(details := "") -> void:
  269. DiscordRPC.details = details
  270. if DiscordRPC.get_is_discord_working():
  271. DiscordRPC.refresh()
  272. func update_game_status() -> void:
  273. var lives_str := str(Global.lives)
  274. if Settings.file.difficulty.inf_lives == 1:
  275. lives_str = "∞"
  276. var string := "Coins = " + str(Global.coins) + " Lives = " + lives_str
  277. DiscordRPC.large_image = (Global.level_theme + Global.theme_time).to_lower()
  278. DiscordRPC.small_image = Global.current_campaign.to_lower()
  279. DiscordRPC.state = string
  280. func refresh_discord_rpc() -> void:
  281. if DiscordRPC.get_is_discord_working() == false:
  282. return
  283. update_game_status()
  284. DiscordRPC.refresh()
  285. func open_marathon_results() -> void:
  286. get_node("GameHUD/MarathonResults").open()
  287. func open_disco_results() -> void:
  288. get_node("GameHUD/DiscoResults").open()
  289. func on_score_sfx_finished() -> void:
  290. if tallying_score:
  291. $ScoreTally.play()
  292. func get_server_version() -> void:
  293. var http = HTTPRequest.new()
  294. add_child(http)
  295. http.request_completed.connect(version_got)
  296. http.request(VERSION_CHECK_URL, [], HTTPClient.METHOD_GET)
  297. func version_got(_result, response_code, _headers, body) -> void:
  298. if response_code == 200:
  299. server_version = int(body.get_string_from_utf8())
  300. else:
  301. server_version = -2
  302. func log_error(msg := "") -> void:
  303. var error_message = $CanvasLayer/VBoxContainer/ErrorMessage.duplicate()
  304. error_message.text = "Error - " + msg
  305. error_message.visible = true
  306. $CanvasLayer/VBoxContainer.add_child(error_message)
  307. await get_tree().create_timer(10, false).timeout
  308. error_message.queue_free()
  309. func log_warning(msg := "") -> void:
  310. var error_message = $CanvasLayer/VBoxContainer/Warning.duplicate()
  311. error_message.text = "Warning - " + msg
  312. error_message.visible = true
  313. $CanvasLayer/VBoxContainer.add_child(error_message)
  314. await get_tree().create_timer(10, false).timeout
  315. error_message.queue_free()
  316. func log_comment(msg := "") -> void:
  317. var error_message = $CanvasLayer/VBoxContainer/Comment.duplicate()
  318. error_message.text = msg
  319. error_message.visible = true
  320. $CanvasLayer/VBoxContainer.add_child(error_message)
  321. await get_tree().create_timer(2, false).timeout
  322. error_message.queue_free()
  323. func unlock_achievement(achievement_id := AchievementID.SMB1_CLEAR) -> void:
  324. achievements[achievement_id] = "1"
  325. if achievement_id != AchievementID.COMPLETIONIST:
  326. check_completionist_achievement()
  327. SaveManager.write_achievements()
  328. func check_completionist_achievement() -> void:
  329. if achievements.count("0") == 1:
  330. unlock_achievement(AchievementID.COMPLETIONIST)
  331. const FONT = preload("uid://cd221873lbtj1")
  332. func sanitize_string(string := "") -> String:
  333. string = string.to_upper()
  334. for i in string.length():
  335. if FONT.has_char(string.unicode_at(i)) == false and string[i] != "\n":
  336. string = string.replace(string[i], " ")
  337. return string