prog
This commit is contained in:
307
addons/madtalk/runtime/MadTalkGlobals.gd
Normal file
307
addons/madtalk/runtime/MadTalkGlobals.gd
Normal file
@@ -0,0 +1,307 @@
|
||||
extends Node
|
||||
|
||||
var is_during_dialog = false
|
||||
var is_during_cinematic = false
|
||||
|
||||
var variables := {
|
||||
}
|
||||
var options_visited_global := {
|
||||
}
|
||||
var options_visited_dialog := {
|
||||
}
|
||||
|
||||
var time = 0
|
||||
var gametime_offset = 0
|
||||
var gametime_year = 1
|
||||
|
||||
@onready var gametime = epoch_to_game_time(time)
|
||||
|
||||
func set_variable(var_name: String, var_value) -> void:
|
||||
variables[var_name] = var_value
|
||||
|
||||
func get_variable(var_name: String, default = 0.0):
|
||||
if var_name in variables:
|
||||
return variables[var_name]
|
||||
else:
|
||||
return default
|
||||
|
||||
func set_option_visited(option: DialogNodeOptionData, visited: bool):
|
||||
options_visited_global[option.resource_scene_unique_id] = visited
|
||||
options_visited_dialog[option.resource_scene_unique_id] = visited
|
||||
|
||||
func get_option_visited_global(option: DialogNodeOptionData) -> bool:
|
||||
if not option.resource_scene_unique_id in options_visited_global:
|
||||
return false
|
||||
return options_visited_global[option.resource_scene_unique_id]
|
||||
|
||||
func get_option_visited_dialog(option: DialogNodeOptionData) -> bool:
|
||||
if not option.resource_scene_unique_id in options_visited_dialog:
|
||||
return false
|
||||
return options_visited_dialog[option.resource_scene_unique_id]
|
||||
|
||||
func reset_options_visited_dialog():
|
||||
options_visited_dialog.clear()
|
||||
|
||||
|
||||
# ==============================================================================
|
||||
# LOCALE
|
||||
|
||||
var default_locale := "en"
|
||||
var current_locale := ""
|
||||
|
||||
|
||||
func set_locale(locale_code: String):
|
||||
current_locale = locale_code
|
||||
if current_locale == default_locale:
|
||||
current_locale = ""
|
||||
|
||||
|
||||
func set_default_locale(locale_code: String):
|
||||
default_locale = locale_code
|
||||
if current_locale == default_locale:
|
||||
current_locale = ""
|
||||
|
||||
|
||||
func set_locale_automatic(def_locale: String = default_locale):
|
||||
default_locale = def_locale
|
||||
var locale = OS.get_locale_language()
|
||||
set_locale(locale)
|
||||
|
||||
|
||||
func set_locale_from_project(def_locale: String = default_locale):
|
||||
default_locale = def_locale
|
||||
var locale = TranslationServer.get_locale()
|
||||
if "_" in locale:
|
||||
locale = locale.left(locale.find("_"))
|
||||
set_locale(locale)
|
||||
|
||||
|
||||
# ==============================================================================
|
||||
# TIME
|
||||
|
||||
func set_game_year(year: int) -> void:
|
||||
gametime_year = year
|
||||
var dt = {
|
||||
"year": year,
|
||||
"month": 1,
|
||||
"day": 1,
|
||||
"hour": 0,
|
||||
"minute": 0,
|
||||
"second": 0
|
||||
}
|
||||
gametime_offset = Time.get_unix_time_from_datetime_dict(dt)
|
||||
gametime = epoch_to_game_time(time)
|
||||
|
||||
##
|
||||
# Returns datetime in game reference (that is,
|
||||
# start of game is 01/01/0001 00:00:00)
|
||||
# Can be seen as "elapsed gameplay time"
|
||||
func epoch_to_game_time(epoch_time: int) -> Dictionary:
|
||||
# Date time dictionary has the format:
|
||||
# {
|
||||
# "year": ...,
|
||||
# "month": ...,
|
||||
# "day": ...,
|
||||
# "weekday": ...,
|
||||
# "hour": ...,
|
||||
# "minute": ...,
|
||||
# "second": ...
|
||||
# }
|
||||
# Custom values added here are:
|
||||
# "time": String hour/minute in format HH:MM
|
||||
# "date": String day/month in format DD/MM
|
||||
# "date_inv": String day/month in format MM/DD
|
||||
|
||||
var dt = Time.get_datetime_dict_from_unix_time(gametime_offset + epoch_time)
|
||||
dt["year"] -= gametime_year-1 # year - 1, so starts at year 1
|
||||
dt["time"] = "%02d:%02d" % [dt["hour"], dt["minute"]]
|
||||
dt["date"] = "%02d/%02d" % [dt["day"], dt["month"]]
|
||||
dt["date_inv"] = "%02d/%02d" % [dt["month"], dt["day"]]
|
||||
dt["weekday_name"] = MTDefs.WeekdayNames[dt["weekday"]]
|
||||
dt["wday_name"] = MTDefs.WeekdayNamesShort[dt["weekday"]]
|
||||
return dt
|
||||
|
||||
# Converts day, month, year to unix epoch time
|
||||
func game_time_to_epoch(p_gametime: Dictionary) -> int:
|
||||
p_gametime["year"] += gametime_year-1 # Year 1 is base,
|
||||
return Time.get_unix_time_from_datetime_dict(p_gametime) - gametime_offset
|
||||
|
||||
func update_gametime_dict():
|
||||
gametime = epoch_to_game_time(time)
|
||||
|
||||
|
||||
# Converts day, month, year to unix epoch time
|
||||
func date_to_int(day: int, month: int, year: int) -> int:
|
||||
return game_time_to_epoch({
|
||||
"year": year, "month": month, "day": day,
|
||||
"hour": 0, "minute": 0, "second": 0
|
||||
})
|
||||
|
||||
# Converts hour, minute to float fractional hour
|
||||
# Example: 2, 30 becomes 2.5
|
||||
func time_to_float(hour: int, minute: int) -> float:
|
||||
return float(hour) + float(minute)/60.0
|
||||
|
||||
func time_to_string(epoch_time: int, simplified: bool = true) -> String:
|
||||
# Date time dictionary has the format:
|
||||
# {
|
||||
# "year": ...,
|
||||
# "month": ...,
|
||||
# "day": ...,
|
||||
# "weekday": ...,
|
||||
# "hour": ...,
|
||||
# "minute": ...,
|
||||
# "second": ...
|
||||
# }
|
||||
var dt = epoch_to_game_time(epoch_time)
|
||||
var res = ""
|
||||
|
||||
# Simplified version is Weekday HH:MM
|
||||
if (simplified):
|
||||
res = MTDefs.WeekdayNames[dt['weekday']].left(3)
|
||||
res += " %02d:%02d" % [dt['hour'], dt['minute']]
|
||||
|
||||
# Non-simplified is Weekday, DD of MonthName HH:MM
|
||||
else:
|
||||
res = MTDefs.WeekdayNames[dt['weekday']]
|
||||
res += ", "+str(dt['day'])
|
||||
res += " "+MTDefs.MonthNames[dt['month']]
|
||||
res += " %02d:%02d" % [dt['hour'], dt['minute']]
|
||||
|
||||
return res
|
||||
|
||||
|
||||
func split_time(value: String) -> Array:
|
||||
# TODO: this is not very efficient code. To be rewritten to run faster
|
||||
var nums_psa = Array(str(value).split(':'))
|
||||
while nums_psa.size() < 2:
|
||||
nums_psa.append(0)
|
||||
var nums = [int(nums_psa[0]), int(nums_psa[1])]
|
||||
if (nums[0] < 0) or (nums[0] > 23):
|
||||
nums[0] = 0
|
||||
if (nums[1] < 0) or (nums[1] > 59):
|
||||
nums[1] = 0
|
||||
return [nums[0], nums[1]]
|
||||
|
||||
func split_date(value: String) -> Array:
|
||||
# TODO: this is not very efficient code. To be rewritten to run faster
|
||||
var nums_psa = Array(str(value).split('/'))
|
||||
while nums_psa.size() < 2:
|
||||
nums_psa.append(1)
|
||||
var nums = [int(nums_psa[0]), int(nums_psa[1])]
|
||||
if (nums[0] < 1) or (nums[0] > 31):
|
||||
nums[0] = 1
|
||||
if (nums[1] < 1) or (nums[1] > 12):
|
||||
nums[1] = 1
|
||||
return [nums[0], nums[1]]
|
||||
|
||||
func print_date(value: String) -> String:
|
||||
var nums = split_date(value)
|
||||
var day = "%02d" % nums[0]
|
||||
var month = MTDefs.MonthNames[nums[1]].left(3)
|
||||
return day+' '+month
|
||||
|
||||
func print_weekday(value):
|
||||
while value > 6:
|
||||
value -= 7
|
||||
return MTDefs.WeekdayNames[value]
|
||||
|
||||
func split_string_autodetect_rn(value: String) -> Array:
|
||||
var result = []
|
||||
|
||||
value = str(value)
|
||||
|
||||
if "\r\n" in value:
|
||||
# Windows style
|
||||
result = value.split("\r\n")
|
||||
elif "\r" in value:
|
||||
# MacOS style
|
||||
result = value.split("\r")
|
||||
else:
|
||||
# Unix style
|
||||
result = value.split("\n")
|
||||
|
||||
return result
|
||||
|
||||
|
||||
func next_time_at_time(time_value: String) -> int:
|
||||
var asked_time = split_time(time_value)
|
||||
|
||||
# We calculate epoch time value for the requested hour happening today
|
||||
# if we are before this time, this is what we want
|
||||
var ingame_time_as_today = game_time_to_epoch({
|
||||
"year": gametime["year"],
|
||||
"month": gametime["month"],
|
||||
"day": gametime["day"],
|
||||
"hour": asked_time[0],
|
||||
"minute": asked_time[1],
|
||||
"second": 0
|
||||
})
|
||||
|
||||
if time <= ingame_time_as_today:
|
||||
return ingame_time_as_today
|
||||
|
||||
# If we are after this time, we want the same time but tomorrow
|
||||
# so we add 24 hours
|
||||
else:
|
||||
return ingame_time_as_today + 24*60*60 # seconds
|
||||
|
||||
func next_time_at_weekday(weekday: int) -> int:
|
||||
# First we find the weekday delta handling when the requested weekday
|
||||
# is lower (or equal) than current one
|
||||
var asked_weekday = weekday if weekday > gametime["weekday"] else weekday + 7
|
||||
var weekday_delta = asked_weekday - gametime["weekday"]
|
||||
|
||||
# Find time for midnight of today
|
||||
var ingame_midnight_today = game_time_to_epoch({
|
||||
"year": gametime["year"],
|
||||
"month": gametime["month"],
|
||||
"day": gametime["day"],
|
||||
"hour": 0,
|
||||
"minute": 0,
|
||||
"second": 0
|
||||
})
|
||||
# Finally we just offset the weekday_delta days into the future
|
||||
return ingame_midnight_today + weekday_delta*24*60*60 # seconds
|
||||
|
||||
|
||||
func export_game_data() -> Dictionary:
|
||||
var visited_options := {}
|
||||
for item_ui in options_visited_global:
|
||||
visited_options[item_ui] = "1" if options_visited_global[item_ui] else "0"
|
||||
|
||||
var result = {
|
||||
"time": time,
|
||||
"gametime_offset": gametime_offset,
|
||||
"gametime_year": gametime_year,
|
||||
"variables": variables,
|
||||
"visited_options": visited_options,
|
||||
}
|
||||
return result
|
||||
|
||||
func import_game_data(data: Dictionary) -> void:
|
||||
if ("time" in data):
|
||||
time = int(round(float(data["time"])))
|
||||
if ("gametime_offset" in data):
|
||||
gametime_offset = int(round(float(data["gametime_offset"])))
|
||||
if ("gametime_year" in data):
|
||||
gametime_year = int(round(float(data["gametime_year"])))
|
||||
|
||||
options_visited_global.clear()
|
||||
if "visited_options" in data:
|
||||
var visited_dict: Dictionary = data["visited_options"]
|
||||
for item_ui in visited_dict:
|
||||
# If coming from a saved file, item_ui will never be StringName
|
||||
# but this Dictionary might be coming from a serialized Resource (bad idea, but still)
|
||||
if (item_ui is String) or (item_ui is StringName):
|
||||
options_visited_global[item_ui] = (not visited_dict[item_ui] in [false, "false", 0, 0.0, "0", "0.0", "no"])
|
||||
|
||||
variables.clear()
|
||||
for variable_name in data["variables"]:
|
||||
if variable_name is String:
|
||||
var value = data["variables"][variable_name]
|
||||
if typeof(value) in [TYPE_INT, TYPE_FLOAT, TYPE_STRING]:
|
||||
# All numeric values can be safely assumed float (as per JSON)
|
||||
# since all methods using them do proper casting
|
||||
variables[variable_name] = value
|
||||
# Silently ignore everything else
|
Reference in New Issue
Block a user