challenge-editor/autoload/global/script/global.gd

624 lines
19 KiB
GDScript3
Raw Normal View History

2024-09-19 12:04:52 +08:00
extends Node
2024-10-04 18:08:33 +08:00
#存档路径
var save_file_path:String="user://save.data"
#加载的存档数据
var save_data:Array=[]
2024-09-23 11:47:55 +08:00
2024-10-04 18:08:33 +08:00
func load_save_data():
var f= FileAccess.open(save_file_path,FileAccess.READ)
2024-09-27 11:47:19 +08:00
if f!=null:
2024-10-04 18:08:33 +08:00
save_data=f.get_var()
2024-09-27 11:47:19 +08:00
else:
2024-10-04 18:08:33 +08:00
f=FileAccess.open(save_file_path,FileAccess.WRITE)
f.store_var(save_data)
#将所有存档数据保存到硬盘
func save_save_data():
var f=FileAccess.open(save_file_path,FileAccess.WRITE)
f.store_var(save_data)
#将当前的游戏数据以存档名n的名字添加到存储队列
func add_now_game_to_save(n:String):
var new_save=now_game_data.duplicate(true)
new_save["name"]=n
save_data.append(new_save)
save_save_data()
#将当前的游戏数据以存档原名覆盖到第ind个存档上
func cover_now_game_to_save(ind:int):
var n:String=save_data[ind]["name"]
var new_save=now_game_data.duplicate(true)
new_save["name"]=n
save_data[ind]=new_save
save_save_data()
#获取当前存档队列
func get_all_save():
return save_data.duplicate(true)
#加载第ind个存档
func load_save(ind:int):
now_game_data=save_data[ind].duplicate()
SceneManager.change_scene_to("res://scene/game_flow.tscn")
pass
#删除第ind个存档
func delete_save(ind:int):
save_data.pop_at(ind)
save_save_data()
2024-10-01 19:11:46 +08:00
var system_config_data_path:String="user://config.data"
#加载配置文件
func load_config():
var f=FileAccess.open(system_config_data_path,FileAccess.READ)
if f!=null:
system_config_data=f.get_var()
else:
f=FileAccess.open(system_config_data_path,FileAccess.WRITE)
f.store_var(system_config_data)
Bgm.set_BGM_volume(system_config_data["BGM_volume"])
Bgm.set_effect_volume(system_config_data["effect_volume"])
#存储配置文件
func save_config():
var f=FileAccess.open(system_config_data_path,FileAccess.WRITE)
f.store_var(system_config_data)
#更改BGM音量
func change_BGM_volume(value:float):
Bgm.set_BGM_volume(value)
system_config_data["BGM_volume"]=value
save_config()
2024-09-27 11:47:19 +08:00
pass
2024-10-01 19:11:46 +08:00
#更改音效音量
func change_effect_volume(value:float):
Bgm.set_effect_volume(value)
system_config_data["effect_volume"]=value
save_config()
pass
func get_BGM_volume():
return system_config_data["BGM_volume"]
pass
func get_effect_volume():
return system_config_data["effect_volume"]
2024-09-19 17:56:05 +08:00
var system_config_data:Dictionary={
2024-10-01 19:11:46 +08:00
#BGM音量
"BGM_volume":0.7,
#音效音量
"effect_volume":0.7,
2024-09-19 17:56:05 +08:00
}
2024-10-01 19:11:46 +08:00
#局外游戏数据文件目录
var system_game_data_path:String="user://system_game.data"
#局外游戏数据
2024-09-20 17:31:23 +08:00
var system_game_data:Dictionary={
2024-09-27 17:51:20 +08:00
"unlock_character":["test_character_01","test_character_02"],
#全局物品
2024-10-01 19:11:46 +08:00
"item":[],
"jifen":100,
"jinqian":100,
"zuanshi":100,
"tili":100,
2024-09-20 17:31:23 +08:00
}
2024-10-01 19:11:46 +08:00
#获取系统全局物品
func get_all_item_system_data():
pass
#货币变更信号
signal system_currency_changed
#获取货币0积分,1金钱2钻石3体力
func get_currency_system(ind:int):
match ind:
0:
return system_game_data["jifen"]
1:
return system_game_data["jinqian"]
2:
return system_game_data["zuanshi"]
3:
return system_game_data["tili"]
#更改货币数据
func set_currency_system(ind:int,value):
match ind:
0:
system_game_data["jifen"]=value
1:
system_game_data["jinqian"]=value
2:
system_game_data["zuanshi"]=value
3:
system_game_data["tili"]=value
system_currency_changed.emit()
save_system_game_data()
pass
#加载局外游戏数据文件
func load_system_game_data():
var f=FileAccess.open(system_game_data_path,FileAccess.READ)
if f!=null:
system_game_data=f.get_var()
else:
f=FileAccess.open(system_game_data_path,FileAccess.WRITE)
f.store_var(system_game_data)
#存储局外游戏数据
func save_system_game_data():
var f=FileAccess.open(system_game_data_path,FileAccess.WRITE)
f.store_var(system_game_data)
2024-09-28 18:46:15 +08:00
#获取当前游戏内所有物品
func get_all_item_game_data()->Array:
return now_game_data["item"].duplicate(true)
#根据type获取当前物品
func get_type_item_game_data(type:int)->Array:
var item:Array=now_game_data["item"].duplicate(true)
var res:Array=[]
for i in item:
if i.has("type") and int(i["type"])==type:
res.append(i)
return res
func get_now_character_equip_page(page:int):
return CharacterTool.get_character_equip_page(get_now_character_data(),page)
func get_now_character_equip_use():
return CharacterTool.get_character_equip_now(get_now_character_data())
2024-09-29 11:46:15 +08:00
func replace_equip_with_data(page:int,pos:int,item_data):
2024-09-28 12:04:15 +08:00
2024-09-28 18:46:15 +08:00
var left=CharacterTool.replace_character_equip(now_game_data["character_data"],page,pos,item_data)
if left!=null:
add_item_to_bag(left)
2024-09-28 12:04:15 +08:00
pass
2024-09-28 18:46:15 +08:00
#向背包中添加item会根据allow merger属性决定是否自动合并并创建num属性
func add_item_to_bag(item_data:Dictionary):
var item:Array=now_game_data["item"]
if item_data["allow_merge"]:
for i in item_data.size():
if item_data[i]["id"]==item_data["id"]:
if item_data[i].has("num"):
item_data[i]["num"]+=1
else:
item_data[i]["num"]=2
pass
pass
else:
item.append(item_data)
2024-09-29 18:09:09 +08:00
2024-09-28 18:46:15 +08:00
#根据在背包的排序减少对应物品的数量
func decrease_item_num_index(ind:int,num:int=1):
var item:Array=now_game_data["item"]
if ind<item.size():
var item_data=item[ind]
if item_data.has("num"):
item_data["num"]-=1
if item_data["num"]<=0:
item.pop_at(ind)
else:
item.pop_at(ind)
#根据ID减少在背包内的物品
func decrease_item_num_id(id:String,num:int=1)->bool:
var item:Array=now_game_data["item"]
var item_data:Dictionary
var ind:int
for i in item.size():
if item[i]["id"]==id:
item_data=item[i]
ind=i
break
if item_data==null:
return false
else:
if not item_data.has("num"):
item_data["num"]=1
var item_num:int=item_data["num"]
if item_num>num:
item_data["num"]-=num
return true
elif item_num==num:
item.pop_at(ind)
return true
else:
return false
#通过id获取当前背包数量如果是不允许合并的物品则返回1或者0没有
func get_item_by_id(id:String)->int:
var item:Array=now_game_data["item"]
var item_data:Dictionary
var ind:int
for i in item.size():
if item[i]["id"]==id:
item_data=item[i]
ind=i
break
if item_data!=null:
if item_data.has("num"):
return item_data["num"]
else:
return 1
else:
return 0
2024-09-28 12:04:15 +08:00
pass
2024-09-28 18:46:15 +08:00
#返回一个长度为2的数组第一个数组存储的item中装备的index另一个是对应的item_data
func get_all_equip_index_and_data_in_bag()->Array:
var item:Array=now_game_data["item"].duplicate(true)
var res:Array=[]
var ind_arr:Array=[]
var data_arr:Array=[]
for i in item.size():
if is_item_a_equip(item[i]):
ind_arr.append(i)
data_arr.append(item[i])
res=[ind_arr,data_arr]
return res
2024-09-30 18:06:45 +08:00
#返回一个长度为2的数组第一个数组存储的item中技能的index另一个是对应的item_data
func get_all_skill_index_and_data_in_bag()->Array:
var item:Array=now_game_data["item"].duplicate(true)
var res:Array=[]
var ind_arr:Array=[]
var data_arr:Array=[]
for i in item.size():
if is_item_a_skill(item[i]):
ind_arr.append(i)
data_arr.append(item[i])
res=[ind_arr,data_arr]
return res
2024-09-28 18:46:15 +08:00
#判断item是否为一个装备暂时将武器除外
func is_item_a_equip(item_data:Dictionary)->bool:
2024-09-28 12:04:15 +08:00
2024-09-28 18:46:15 +08:00
if not item_data.has("type"):
return false
var type:int=item_data["type"]
if type in [0,1,2,3]:
return true
else:
return false
2024-09-30 18:06:45 +08:00
#判断item是否为一个技能
func is_item_a_skill(item_data:Dictionary):
if not item_data.has("type"):
return false
var type:int=item_data["type"]
if type ==6:
return true
else:
return false
2024-09-28 18:46:15 +08:00
#改变当前角色使用的装备页
func change_character_equip_now_use(page:int):
print(page)
CharacterTool.change_character_equip_now_use(now_game_data["character_data"],page)
#获取当前使用装备页数
func get_character_page_now_use()->int:
return CharacterTool.get_character_equip_now_use_page(now_game_data["character_data"])
2024-09-30 18:06:45 +08:00
#将角色第ind个技能卡移除放入背包
func remove_skill_card_ind_to_bag(ind:int):
var now_character_data:Dictionary=now_game_data["character_data"]
var left=CharacterTool.remove_skill_index(now_character_data,ind)
if left!=null:
add_item_to_bag(left)
#将背包中序列为ind的技能卡装备到角色
func add_sill_card_from_bag_to_character(ind:int):
var item_data=now_game_data["item"][ind]
if is_item_a_skill(item_data):
var res=CharacterTool.add_skill_card(now_game_data["character_data"],item_data)
if res:
decrease_item_num_index(ind)
#获取当前角色的所有技能
func get_now_character_skill():
var character_data=now_game_data["character_data"]
return CharacterTool.get_character_skill_all(character_data)
2024-10-01 19:11:46 +08:00
##当前局内数据
2024-09-19 17:56:05 +08:00
var now_game_data:Dictionary={
2024-09-20 17:31:23 +08:00
"character_data":{
},
"script_data":{
2024-09-20 12:02:11 +08:00
},
2024-09-27 17:51:20 +08:00
#游戏内物品
"item":[],
2024-10-02 18:35:48 +08:00
#存储的NPC数据(仅包含遇到的NPC用于存储NPC的背包在申请NPCdata时进行写入
"NPC_data":{},
2024-09-26 11:49:53 +08:00
"now_scene":"",
2024-09-20 20:20:14 +08:00
"difficulty":0,
2024-10-02 18:35:48 +08:00
"gold":1000,
2024-09-21 11:52:44 +08:00
"health":100,
2024-09-21 17:51:05 +08:00
"spirit":999,
2024-09-22 11:48:18 +08:00
"map":"map_01",
"move_ability":1,
2024-09-25 18:04:02 +08:00
"time_unix":0,
2024-10-04 18:08:33 +08:00
"card_in_bag":["card_03","card_03","card_02","card_02","card_01","card_01","card_01","card_01"],
"condition_triger_randi_dic":{
}
2024-09-19 17:56:05 +08:00
}
2024-10-02 18:35:48 +08:00
#获取当前局内NPC数据
func get_now_game_npc_data(NPC_id:String):
var now_npc_data:Dictionary=now_game_data["NPC_data"]
if now_npc_data.has(NPC_id):
#这里不进行duplicate副本的原因是trade交易场景要对数据进行操作
return now_npc_data[NPC_id]
else:
#填入npc数据并实例出售卖的道具可以通过在get item data上施加影响来实现随机
2024-10-04 18:08:33 +08:00
var n_data=Database.get_npc_data(NPC_id)
2024-10-02 18:35:48 +08:00
for i in n_data["sold_item"].size():
2024-10-04 18:08:33 +08:00
n_data["sold_item"][i]=Database.get_item_data(n_data["sold_item"][i])
2024-10-02 18:35:48 +08:00
now_game_data["NPC_data"][NPC_id]=n_data
return now_npc_data[NPC_id]
#获取当前角色与NPC的好感度
func get_now_game_npc_favor(npc_id):
return CharacterTool.get_character_with_npc_favor(now_game_data["character_data"],npc_id)
#展示和NPC id对应的交易界面
func show_trade(npc_id:String):
now_game_flow.show_trade(npc_id)
2024-10-01 19:11:46 +08:00
#游戏内货币改变信号
signal game_currency_changed
#获取游戏内的“货币”0生命1金钱2精神
func get_currency_game(ind:int):
match ind:
0:
return now_game_data["health"]
1:
return now_game_data["gold"]
2:
return now_game_data["spirit"]
func set_currency_game(ind:int,value):
match ind:
0:
now_game_data["health"]=value
1:
now_game_data["gold"]=value
2:
now_game_data["spirit"]=value
game_currency_changed.emit()
#更改
func change_currency_game(ind:int,change):
set_currency_game(ind,get_currency_game(ind)+change)
2024-09-25 18:04:02 +08:00
#当前战斗场景
var now_fight_scene:FightScene
#向卡组中添加卡牌
func add_card(card_id:String):
now_game_data["card_in_bag"].append(card_id)
#从卡组中删除卡牌
func delete_card(card_id:String)->bool:
var now_arr:Array= now_game_data["card_in_bag"]
var ind=now_arr.find(card_id)
if ind==-1:
return false
else:
now_game_data["card_in_bag"].pop_at(ind)
return true
2024-09-30 18:06:45 +08:00
var now_fight_enermy_data:Array=[]
var now_fight_friend_data:Array=[]
func fight(data:Dictionary):
if data.has("friend"):
now_fight_friend_data=data["friend"]
now_fight_enermy_data
SceneManager.change_scene_to("res://scene/fight.tscn")
pass
2024-09-26 17:54:02 +08:00
#使用卡牌,character为使用者target为目标card_data为使用的卡牌数据
func use_card(card_data:Dictionary,user=null,target=null):
2024-09-25 18:04:02 +08:00
print("执行了卡牌:\n"+str(card_data)+"\n目标"+str(target))
2024-09-26 17:54:02 +08:00
if card_data.has("triger"):
for funcitem in card_data["triger"]:
var _func=Callable(self,funcitem.func)
var value:Array=funcitem.value.duplicate()
for i in value.size():
if value[i] is String and value[i]=="user":
value[i]=user
elif value[i] is String and value[i]=="target":
value[i]=target
_func.callv(value)
##下面是例子
##打击单位
func hit(target,value):
if target is FightCharacterCard ||target is FightEnermyCard:
target.HP-=value
#打击全部单位
func hit_all(value):
var all_character=now_fight_scene.get_all_unit()
for i in all_character:
i.HP-=value
#回血
func recover(target,value):
if target is FightCharacterCard ||target is FightEnermyCard:
target.HP+=value
2024-09-25 18:04:02 +08:00
func get_all_card()->Array:
return now_game_data["card_in_bag"].duplicate()
2024-09-22 17:37:51 +08:00
func get_move_ability():
return now_game_data["move_ability"]
func get_time_dictionary():
var time_unix=int(now_game_data["time_unix"])
return Time.get_datetime_dict_from_unix_time(time_unix)
2024-09-23 17:27:43 +08:00
func get_time_unix():
return now_game_data["time_unix"]
2024-09-22 17:37:51 +08:00
#year、month、day、weekday、hour、minute 和 second
func flow_time(data:Dictionary):
var date=get_time_dictionary()
var change_unix:float=0
if data.has("day"):
var day=data["year"]
change_unix+=day*86400
if data.has("hour"):
var hour=data["hour"]
change_unix+=3600*hour
if data.has("minute"):
var minute=data["minute"]
change_unix+=minute*60
now_game_data["time_unix"]+=change_unix
time_changed.emit()
2024-09-27 11:47:19 +08:00
#时间改变的信号
2024-09-22 17:37:51 +08:00
signal time_changed
2024-09-27 11:47:19 +08:00
#事件触发器列表
2024-09-22 11:48:18 +08:00
var triger:Dictionary={
"change_event":func (data):now_game_flow.show_event(data),
"change_texture": func (data):now_game_flow.event_panel.change_texture(data),
"change_text":func(data):now_game_flow.event_panel.change_text(data),
"change_choice":func(data):now_game_flow.event_panel.change_choice(data),
"increase_health":func (data):now_game_data.health-=data,
2024-09-22 17:37:51 +08:00
"end_event":func(data):now_game_flow.event_panel.hide(),
2024-09-30 18:06:45 +08:00
"flow_time":func (data):flow_time(data),
2024-10-01 19:11:46 +08:00
"fight":func (data):fight(data),
2024-10-02 18:35:48 +08:00
"add_currency":func (data):change_currency_game(data["ind"],data["value"]),
2024-10-05 18:44:58 +08:00
"trade":func(data): show_trade(data),
"show_identifaction":func(data):show_identification(data)
2024-09-22 11:48:18 +08:00
}
2024-09-27 11:47:19 +08:00
#使用事件触发器
2024-09-22 11:48:18 +08:00
func call_triger(triger_type:String,data):
if triger.has(triger_type):
return triger[triger_type].call(data)
else:
return null
2024-10-05 18:44:58 +08:00
#条件触发器(用于返回是否的条件判定结果)
2024-09-23 11:47:55 +08:00
var condition_triger:Dictionary={
2024-09-23 17:27:43 +08:00
"date_limit":func (data:Dictionary):return TimeTool.is_in_date(data,get_time_dictionary()),
"time_limit":func (data:Dictionary):return TimeTool.is_in_time(data,get_time_dictionary()),
"rand":func (data:Dictionary):return get_rand(data["scene_id"],data["touch_id"],data["index"],data["condition"]),
2024-10-01 19:11:46 +08:00
"currency_more_than": func (data:Dictionary) :return get_currency_game(data["ind"])>=data["value"]
2024-09-23 11:47:55 +08:00
}
2024-09-27 11:47:19 +08:00
#使用条件触发器
2024-09-23 17:27:43 +08:00
func call_condition_triger(triger_type:String,data):
if condition_triger.has(triger_type):
return condition_triger[triger_type].call(data)
else:
2024-10-01 19:11:46 +08:00
return false
2024-09-27 11:47:19 +08:00
#记录随机的场景上一次结果,如果时间不变则直接取上一次结果
2024-10-04 18:08:33 +08:00
#记录在游戏存档内,保证加载数据不改变
2024-09-23 17:27:43 +08:00
func get_rand(scene_id:String,touch_name:String,index:String,condition:float)->bool:
2024-10-04 18:08:33 +08:00
if now_game_data["condition_triger_randi_dic"].has(scene_id):
var scene_data=now_game_data["condition_triger_randi_dic"][scene_id]
2024-09-23 17:27:43 +08:00
if scene_data.has(touch_name):
var touch_data=scene_data[touch_name]
if touch_data.has(index):
var triger_data=touch_data[index]
var last_time_triger=triger_data["last_time_triger"]
if last_time_triger==get_time_unix():
return triger_data["last_rand_result"]
else:
var dic=recreate_rand_dic(condition)
2024-10-04 18:08:33 +08:00
now_game_data["condition_triger_randi_dic"][scene_id][touch_name][index]=dic
2024-09-23 17:27:43 +08:00
return dic["last_rand_result"]
pass
else:
var dic=recreate_rand_dic(condition)
2024-10-04 18:08:33 +08:00
now_game_data["condition_triger_randi_dic"][scene_id][touch_name][index]=dic
2024-09-23 17:27:43 +08:00
return dic["last_rand_result"]
else:
var dic=recreate_rand_dic(condition)
2024-10-04 18:08:33 +08:00
now_game_data["condition_triger_randi_dic"][scene_id][touch_name]={
2024-09-23 17:27:43 +08:00
index:dic
}
return dic["last_rand_result"]
pass
else:
var dic=recreate_rand_dic(condition)
2024-10-04 18:08:33 +08:00
now_game_data["condition_triger_randi_dic"][scene_id]={
2024-09-23 17:27:43 +08:00
touch_name:{
index:dic
}
}
return dic["last_rand_result"]
2024-10-05 18:44:58 +08:00
#显示鉴定界面(用于触发器)
func show_identification(data:String):
if now_game_flow!=null:
now_game_flow.show_identification(data)
pass
2024-09-27 11:47:19 +08:00
#为随机创建一个新的随机字典
2024-09-23 17:27:43 +08:00
func recreate_rand_dic(condition:float)->Dictionary:
var new_rand_result:bool=(randf()<condition)
var dic={
"last_time_triger":get_time_unix(),
"last_rand_result":new_rand_result,
}
return dic
2024-10-05 18:44:58 +08:00
#多次鉴定时每回合使用的处理函数(对字典处理),返回bool类型表示本轮是否成功
var identfication_round_triger_dic:Dictionary={
"fish_round": fish_round,
}
func call_round_triger(triger_type:String,character_data:Dictionary,round_dic:Dictionary,choice:String):
if identfication_round_triger_dic.has(triger_type):
return identfication_round_triger_dic[triger_type].call(character_data,round_dic,choice)
else:
return null
func fish_round(character_data:Dictionary,round_dic:Dictionary,choice:String)->bool:
print(choice)
return true
pass
#用来获取鉴定每轮显示的难易度
var indetification_difficulty_get_triger:Dictionary={
"fish":fish_get_difficulty
}
func call_difficulty_triger(triger_type:String,character_data:Dictionary,round_dic:Dictionary):
if indetification_difficulty_get_triger.has(triger_type):
return indetification_difficulty_get_triger[triger_type].call(character_data,round_dic)
else:
return null
func fish_get_difficulty(character_data:Dictionary,round_dic:Dictionary):
pass
#用来判断鉴定是否结束的函数
var identification_is_finish_triger:Dictionary={
"normal":normal_is_finish,
}
func call_is_finish_triger(triger_type:String,character_data:Dictionary,round_dic:Dictionary):
if identification_is_finish_triger.has(triger_type):
return identification_is_finish_triger[triger_type].call(character_data,round_dic)
else:
return null
func normal_is_finish(character_data:Dictionary,round_dic:Dictionary)->bool:
if round_dic["left_cost"]==0 ||round_dic["left_total"]==round_dic["left_total_max"] || round_dic["right_cost"]==0:
return true
else:
return false
#鉴定结束触发的函数(用于获得奖励一类的)
var identification_finish_triger:Dictionary={
"fish":fish_finish,
}
func call_finish_triger(triger_type:String,character_data:Dictionary,round_dic:Dictionary):
if identification_finish_triger.has(triger_type):
return identification_finish_triger[triger_type].call(character_data,round_dic)
else:
return null
func fish_finish(character_data:Dictionary,round_data:Dictionary):
pass
2024-09-27 11:47:19 +08:00
#移动场景前者是scene的ID后者是距离当前场景的距离
2024-09-22 11:48:18 +08:00
func move_scene(scene_id:String,distance):
2024-09-22 17:37:51 +08:00
if scene_id==get_now_scene():
return false
flow_time({
"minute":distance/get_move_ability()
})
now_game_flow.change_scene(scene_id,distance)
set_now_scene(scene_id)
return true
2024-09-22 11:48:18 +08:00
pass
2024-09-27 11:47:19 +08:00
#获取当前场景ID
2024-09-22 11:48:18 +08:00
func get_now_scene():
return now_game_data["now_scene"]
2024-09-27 11:47:19 +08:00
#设置当前场景,只用于开局重置位置
2024-09-22 17:37:51 +08:00
func set_now_scene(scene_id:String):
now_game_data["now_scene"]=scene_id
2024-09-27 11:47:19 +08:00
#当前的游戏流程场景
2024-09-21 11:52:44 +08:00
var now_game_flow:GameFlow
2024-09-27 11:47:19 +08:00
#获取当前角色数据的拷贝
2024-09-20 20:20:14 +08:00
func get_now_character_data():
2024-09-24 11:59:54 +08:00
return now_game_data["character_data"].duplicate()
2024-09-28 18:46:15 +08:00
#设置当前角色(游戏内)
func set_now_character(id:String):
2024-10-04 18:08:33 +08:00
now_game_data["character_data"]=Database.get_character_data(id)
2024-09-28 18:46:15 +08:00
2024-09-19 12:04:52 +08:00
func _ready() -> void:
2024-10-04 18:08:33 +08:00
2024-10-01 19:11:46 +08:00
load_config()
load_system_game_data()
2024-10-04 18:08:33 +08:00
load_save_data()