challenge-editor/autoload/global/script/global.gd
2024-10-04 18:08:33 +08:00

562 lines
17 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

extends Node
#存档路径
var save_file_path:String="user://save.data"
#加载的存档数据
var save_data:Array=[]
func load_save_data():
var f= FileAccess.open(save_file_path,FileAccess.READ)
if f!=null:
save_data=f.get_var()
else:
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()
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()
pass
#更改音效音量
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"]
var system_config_data:Dictionary={
#BGM音量
"BGM_volume":0.7,
#音效音量
"effect_volume":0.7,
}
#局外游戏数据文件目录
var system_game_data_path:String="user://system_game.data"
#局外游戏数据
var system_game_data:Dictionary={
"unlock_character":["test_character_01","test_character_02"],
#全局物品
"item":[],
"jifen":100,
"jinqian":100,
"zuanshi":100,
"tili":100,
}
#获取系统全局物品
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)
#获取当前游戏内所有物品
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())
func replace_equip_with_data(page:int,pos:int,item_data):
var left=CharacterTool.replace_character_equip(now_game_data["character_data"],page,pos,item_data)
if left!=null:
add_item_to_bag(left)
pass
#向背包中添加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)
#根据在背包的排序减少对应物品的数量
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
pass
#返回一个长度为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
#返回一个长度为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
#判断item是否为一个装备暂时将武器除外
func is_item_a_equip(item_data:Dictionary)->bool:
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
#判断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
#改变当前角色使用的装备页
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"])
#将角色第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)
##当前局内数据
var now_game_data:Dictionary={
"character_data":{
},
"script_data":{
},
#游戏内物品
"item":[],
#存储的NPC数据(仅包含遇到的NPC用于存储NPC的背包在申请NPCdata时进行写入
"NPC_data":{},
"now_scene":"",
"difficulty":0,
"gold":1000,
"health":100,
"spirit":999,
"map":"map_01",
"move_ability":1,
"time_unix":0,
"card_in_bag":["card_03","card_03","card_02","card_02","card_01","card_01","card_01","card_01"],
"condition_triger_randi_dic":{
}
}
#获取当前局内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上施加影响来实现随机
var n_data=Database.get_npc_data(NPC_id)
for i in n_data["sold_item"].size():
n_data["sold_item"][i]=Database.get_item_data(n_data["sold_item"][i])
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)
#游戏内货币改变信号
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)
#当前战斗场景
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
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
#使用卡牌,character为使用者target为目标card_data为使用的卡牌数据
func use_card(card_data:Dictionary,user=null,target=null):
print("执行了卡牌:\n"+str(card_data)+"\n目标"+str(target))
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
func get_all_card()->Array:
return now_game_data["card_in_bag"].duplicate()
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)
func get_time_unix():
return now_game_data["time_unix"]
#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()
#时间改变的信号
signal time_changed
#事件触发器列表
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,
"end_event":func(data):now_game_flow.event_panel.hide(),
"flow_time":func (data):flow_time(data),
"fight":func (data):fight(data),
"add_currency":func (data):change_currency_game(data["ind"],data["value"]),
"trade":func(data): show_trade(data)
}
#使用事件触发器
func call_triger(triger_type:String,data):
if triger.has(triger_type):
return triger[triger_type].call(data)
else:
return null
#条件触发器(用于返回是否返回条件)
var condition_triger:Dictionary={
"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"]),
"currency_more_than": func (data:Dictionary) :return get_currency_game(data["ind"])>=data["value"]
}
#使用条件触发器
func call_condition_triger(triger_type:String,data):
if condition_triger.has(triger_type):
return condition_triger[triger_type].call(data)
else:
return false
#记录随机的场景上一次结果,如果时间不变则直接取上一次结果
#记录在游戏存档内,保证加载数据不改变
func get_rand(scene_id:String,touch_name:String,index:String,condition:float)->bool:
if now_game_data["condition_triger_randi_dic"].has(scene_id):
var scene_data=now_game_data["condition_triger_randi_dic"][scene_id]
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)
now_game_data["condition_triger_randi_dic"][scene_id][touch_name][index]=dic
return dic["last_rand_result"]
pass
else:
var dic=recreate_rand_dic(condition)
now_game_data["condition_triger_randi_dic"][scene_id][touch_name][index]=dic
return dic["last_rand_result"]
else:
var dic=recreate_rand_dic(condition)
now_game_data["condition_triger_randi_dic"][scene_id][touch_name]={
index:dic
}
return dic["last_rand_result"]
pass
else:
var dic=recreate_rand_dic(condition)
now_game_data["condition_triger_randi_dic"][scene_id]={
touch_name:{
index:dic
}
}
return dic["last_rand_result"]
#为随机创建一个新的随机字典
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
#移动场景前者是scene的ID后者是距离当前场景的距离
func move_scene(scene_id:String,distance):
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
pass
#获取当前场景ID
func get_now_scene():
return now_game_data["now_scene"]
#设置当前场景,只用于开局重置位置
func set_now_scene(scene_id:String):
now_game_data["now_scene"]=scene_id
#当前的游戏流程场景
var now_game_flow:GameFlow
#获取当前角色数据的拷贝
func get_now_character_data():
return now_game_data["character_data"].duplicate()
#设置当前角色(游戏内)
func set_now_character(id:String):
now_game_data["character_data"]=Database.get_character_data(id)
func _ready() -> void:
load_config()
load_system_game_data()
load_save_data()