checheche/Robo-Bus-A31-HMI/common/global_map.gd

425 lines
14 KiB
GDScript3
Raw Normal View History

2024-12-06 21:22:11 +08:00
class_name Global_map
extends Node2D
signal demand(value)
var selected_build_id = ""
var instruct = ""#操作指令
var is_build_demand = false#是否更新需求
var build_detection = []
var frequency = 100
var grass_data = []#空地位置
var portability_data = []#可移动区域,不计算植被
var use_grass_data = []#被建筑物或植被覆盖位置
var mountain_data = []#山的位置
var mineral_data = {}#矿物的位置
var use_mountain_data = []#被占用的山位置
var plant_data = {}#植物位置
var water_data = []#水的位置
var scorched_earth = {} #焦土位置
var item_node = {}#物品位置数据
var item_type = {}#物品类型数据{"id":{"post":post,"data","data"}}
var box_data = {} #箱子数据{"post":post,"data":data}
var box_type_item = {} #箱子物品类型数据{"id":("post":post,"data":data)}
var box_type_number = {} #箱子物品数量数据{"id":()}
var flame_data = {}#火焰的位置{"post":post,"time":time,"node":node}
var reiki_data = {}#灵气数据
var room = {}#房间数据
var selected_node = []
var brightness = 0.
var brightness_time = 24#一天时间
var time_scale = 2
var role_node = []#人物数据
var light_data = []#发光node数据
var planting_demand = {
#{
#"node":null,Vector2(0,0)
#"type":"砍伐","种植",
#}
}#种植需求列
var excavate_demand = {
#{
#"node":null,Vector2(0,0)
#"type":"挖掘","放置",
#}
}#挖掘需求列
var transport_demand = {}#搬运需求列
var build_data = {}#建筑数据
var floor_data = {}#地板数据
var map_frame_data = []
var max_ranin = 1
var is_rain = false:
set(value):
is_rain = value
var tween = create_tween()
if is_rain:
RenderingServer.global_shader_parameter_set("gl_speed",1)
RenderingServer.global_shader_parameter_set("gl_maxStrength",1)
tween.tween_property(self,"max_ranin",1.,1)
await get_tree().create_timer(10).timeout
RenderingServer.global_shader_parameter_set("gl_speed",0)
RenderingServer.global_shader_parameter_set("gl_maxStrength",0)
is_rain = false
else:
RenderingServer.global_shader_parameter_set("gl_speed",0)
RenderingServer.global_shader_parameter_set("gl_maxStrength",0)
tween.tween_property(self,"max_ranin",0.,1)
var map_size = Vector2(50,50)
var child_size = Vector2(320,320)
func update_item_ui():
%itemCommonScrollContainer.data = []
%itemCommonScrollContainer.data = box_type_item.keys()
#生成柏林噪声
func get_noise(seed,fractal_type):
var noise = FastNoiseLite.new()
noise.noise_type = FastNoiseLite.TYPE_VALUE
noise.seed = seed
noise.frequency = 1.0 / frequency
noise.fractal_type = fractal_type
noise.fractal_octaves = 6
noise.fractal_lacunarity = 2.0
noise.fractal_gain = 1
return noise
#添加植物
func add_plant(id,map_post):
plant_data[map_post] = {"id":id,"post":map_post,"data":Global.build_data[id].duplicate()}
if plant_data[map_post].data.source is Array:
%plant_tilemap.set_cell(map_post,plant_data[map_post].data.source.pick_random(),Vector2(0,0))
if !use_grass_data.has(map_post):
use_grass_data.append(map_post)
#时间流逝
func time_brightness():
var tween1 = create_tween()
tween1.set_loops()
tween1.tween_property(%time_pointer,"rotation_degrees",360,(24)*(time_scale))
tween1.tween_property(%time_pointer,"rotation_degrees",0,0.001)
var tween = create_tween()
tween.set_loops()
tween.tween_property(self,"brightness",1.,6*time_scale)#白天
tween.tween_property(self,"brightness",1.,10*time_scale)#白天
tween.tween_property(self,"brightness",0.,4*time_scale)#晚上
tween.tween_property(self,"brightness",0.,4*time_scale)#晚上
#更新寻路
func update_astarMap():
var arr = mountain_data.duplicate()
for post in build_data:
if !build_data[post].general:
arr.append(post)
arr.append_array(map_frame_data)
AstarMap.up_map(map_size,child_size,arr)
#验证这个位置房间是否还有效果
func verify_room(post):
var data = query_room(post)
for room_key in room:
if room[room_key].queried_arr.has(post):
room.erase(room_key)
return true
return false
#验证位置是否在房间里面
func verify_room_post(post):
var data = query_room(post)
for room_key in room:
if room[room_key].queried_arr.has(post):
return true
await get_tree().physics_frame
return false
#计算房间
func calculate_room(m_data):
#var cx = m_data.duplicate()
var index = 0
for i in m_data.size()/1000:
var cx = m_data.slice(i*1000,(i+1)*1000)
while !cx.is_empty():
var cs_data = query_room_foundation(cx.front())
if cs_data.number < 15:
var data = query_room(cx.front())
var is_room = false
if data.number < 225:
if !room.has(data.queried_arr[0]):
room[data.queried_arr[0]] = data
is_room = true
for post in data.queried_arr:
if !cx.is_empty():
cx.erase(post)
await get_tree().physics_frame
else:
for post in cs_data.queried_arr:
if !cx.is_empty():
cx.erase(post)
update_astarMap()
#搜索路径
func search_path(post,number):
return Tool.query(number,[post],func(vec):
return !mountain_data.has(Vector2i(vec))
)
#角色移动
func role_move():
var post = get_global_mouse_position()
var index = 0
var map = %tile_map_environment.local_to_map(post)
var role_node = []
for node in selected_node:
if node != null and is_instance_valid(node) and node is Role:
if node.is_control:
role_node.append(node)
var post_arr = search_path(map,role_node.size())
for node in role_node:
node.set_target(%tile_map_environment.map_to_local(post_arr[index]))
node.cancel_job()
index += 1
#快速检查是否有房间的基础条件
func query_room_foundation(post,queried_arr = [],number = 0):
if number >= 15:
return {"queried_arr":queried_arr,"number":number,"is_open":false}
#如果当前方块为草地:
if portability_data.has(Vector2i(post)) or portability_data.has(Vector2i(post.x,post.y)) and !queried_arr.has(post):
number += 1
queried_arr.append(post)
if !queried_arr.has(post+Vector2i(1,0)):
number = query_room_foundation(post+Vector2i(1,0),queried_arr,number).number
return {"queried_arr":queried_arr,"number":number,"is_open":false}
#查询是否为房间
func query_room(post,queried_arr = [],number = 0):
if number >= 225:
return {"queried_arr":[],"number":225,"is_open":false}
#如果当前方块为草地:
if portability_data.has(Vector2i(post)) or portability_data.has(Vector2i(post.x,post.y)) and !queried_arr.has(post):
number += 1
queried_arr.append(post)
if !queried_arr.has(post+Vector2i(1,0)):
number = query_room(post+Vector2i(1,0),queried_arr,number).number
if !queried_arr.has(post+Vector2i(-1,0)):
number = query_room(post+Vector2i(-1,0),queried_arr,number).number
if !queried_arr.has(post+Vector2i(0,1)):
number = query_room(post+Vector2i(0,1),queried_arr,number).number
if !queried_arr.has(post+Vector2i(0,-1)):
number = query_room(post+Vector2i(0,-1),queried_arr,number).number
return {"queried_arr":queried_arr,"number":number,"is_open":false}
#添加火焰
func add_flame(post):
if !flame_data.has(post) and !scorched_earth.has(post) and !mountain_data.has(post) and !water_data.has(post) and %tile_map_environment.get_cell_alternative_tile(post) != -1:
scorched_earth[post] = {"time":0}
flame_data[post] = {"post":post,"time":0,"node":Sprite2D.new()}
%flame.add_child(flame_data[post].node)
flame_data[post].node.global_position = %tile_map_environment.map_to_local(post)
flame_data[post].node.texture = preload("res://item/res/flame/flame.png")
return true
return false
#添加闪电
func add_lightning(post):
var lightning = preload("res://item/lightning.tscn").instantiate()
lightning.global_position = post
add_child(lightning)
await lightning.end
add_flame(%tile_map_environment.local_to_map(post))
#判断是否可以放置建筑
func is_add_build(post,data):
var is_build = build_data.has(post)
var is_floor = floor_data.has(post)
if %tile_map_building.get_cell_source_id(post) == -1 and %tile_map_buildingfloor.get_cell_source_id(post) == -1:
if is_build or is_floor:
if is_build and !is_floor and (data.has("is_floor") and data.is_floor):#如果有没有地砖,但是有建筑,并且接下来是地砖
return true
elif !is_build and is_floor:#没建筑有地砖,并且不是地砖
if data.has("is_floor"):
if data.is_floor:
return false
else:
return true
else:
return true
else:#都有的情况
return false
else:
return true
else:
return false
#添加建筑墙面
func add_build(post,is_signal = true):
if selected_build_id == "cancellation":
if build_data.has(post):
build_data.erase(post)
#$TileMap.set_cells_terrain_connect(3,[post],2,0)
#for vec in Vec2.get_surrounding_cells(post):
#if build_data.has(vec):
#$TileMap.set_cells_terrain_connect(1,[vec],2,0)
#$TileMap.set_cells_terrain_connect(1,[vec],build_data[vec].data.terrain_set,build_data[vec].data.terrain)
pass
else:
var data = Global.build_data[selected_build_id].duplicate(true)
if is_add_build(post,data):
var is_place = false
for data_name in data.topographic_conditions:
if data_name == "grass_data" and grass_data.has(post):
is_place = true
break
if data_name == "portability_data" and portability_data.has(post):
is_place = true
break
if "build" in data_name:
if (build_data.has(post) and build_data[post].id == data_name) or (floor_data.has(post) and floor_data[post].id == data_name):
is_place = true
break
if is_place:
var level = %tile_map_building
if data.has("is_floor") and data.is_floor:
level = %tile_map_buildingfloor
if data.has("terrain_set"):
level.set_cells_terrain_connect([post],data.terrain_set,data.terrain)
else:
level.set_cell(post,data.source,Vector2(data.atlas_post[0],data.atlas_post[1]))
var work_item = add_work_item("建筑",post,excavate_demand,selected_build_id)
if is_signal:
is_build_demand = true
build_detection.append(post)
pass
#添加工作
func add_work_item(type,post,demand_data,id = "",box_post = Vector2i())->Dictionary:
if !demand_data.has(post):
demand_data[post] = {
"node":post,
"type":type,
"post":post,
"work_role":null,
"data": {}
}
if box_post != null:
demand_data[post]["box_post"] = box_post
match type:
"挖掘":
%tile_map_tool.set_cell(post,8,Vector2i(1,1))
if mineral_data.has(post):
demand_data[post].data = Global.build_data[mineral_data[post].id].duplicate(true)
else:
if build_data.has(post):
demand_data[post].data = Global.build_data[build_data[post].id].duplicate(true)
elif floor_data.has(post):
demand_data[post].data = Global.build_data[floor_data[post].id].duplicate(true)
else:
demand_data[post].data = Global.build_data["build_0"].duplicate(true)
"砍伐":
%tile_map_tool.set_cell(post,8,Vector2i(0,0))
demand_data[post].data = Global.build_data[plant_data[post].id].duplicate(true)
"建筑":
#$TileMap.set_cell(Global.TOOL,post,8,Vector2i(3,1))
demand_data[post].data = Global.build_data[id].duplicate(true)
"搬运":
%tile_map_tool.set_cell(post,8,Vector2i(0,1))
if demand_data.has(post) and item_node.has(post):
demand_data[post].data = item_node[post].data
return demand_data[post]
##选择山体,选择植物
func select_body(data,type,map_post_arr:Array):
var map_data = map_post_arr.duplicate()
var fun = func(post_arr,map_post_arr):
for post in post_arr:
if data.has(post):
var selector = preload("res://gui/selector.tscn").instantiate()
$mark.add_child(selector)
selector.global_position = %tile_map_environment.map_to_local(post)
selector.scale = Vector2(2,2)
selector.set_meta("type",type)
selected_node.append(selector)
map_post_arr.erase(post)
var index = 0
for i in map_post_arr.size()/1000+1:
var post_arr = map_data.slice(i*1000,(i+1)*1000)
fun.call(post_arr,map_post_arr)
await get_tree().process_frame
return map_post_arr
#开启工作
func destruction_body(type,demand_data):
for i in selected_node.size()/200+1:
var post_arr = selected_node.slice(i*200,(i+1)*200)
for node in post_arr:
if is_instance_valid(node):
if node.has_meta("type") and node.get_meta("type") == type:
var post = %tile_map_environment.local_to_map(node.global_position)
add_work_item(type,post,demand_data)
node.queue_free()
elif node is Role :
if node is Role:
node.is_control = false
node.is_selected = false
else:
node.queue_free()
await get_tree().process_frame
demand.emit(type)
selected_node = []
#直接开始工作
func direct_destruction_body(type,demand_data,determine_data,map_post_arr):
for i in map_post_arr.size()/200+1:
var post_arr = map_post_arr.slice(i*200,(i+1)*200)
for post in post_arr:
#if is_instance_valid(node):
if determine_data.has(post):
add_work_item(type,post,demand_data)
await get_tree().process_frame
demand.emit(type)
#全局坐标转屏幕坐标
func post_to_screen(post):
return $Camera2D.get_canvas_transform().basis_xform(post)+$Camera2D.get_canvas_transform().origin
#计算光
func calculate_light():
var circle_center = []
var circle_radius = []
circle_center.append(post_to_screen(get_global_mouse_position()))
circle_radius.append(0.5*$Camera2D.zoom.x)
#添加node光
for node in light_data:
if node is Lightning:
for post in node.points:
circle_center.append(post_to_screen(node.global_position +post))
circle_radius.append(0.5*$Camera2D.zoom.x)
#添加火焰光
for post in flame_data.keys():
circle_center.append(post_to_screen(%tile_map_environment.map_to_local(post)))
circle_radius.append(1*$Camera2D.zoom.x)
#添加人物
if !role_node.is_empty():
for node in role_node:
if node != null and is_instance_valid(node):
var post = node.global_position
circle_center.append(post_to_screen(post))
circle_radius.append(2.7*$Camera2D.zoom.x)
else:
role_node.erase(node)
%dense_fog.material.set_shader_parameter("brightness",brightness)
%dense_fog.material.set_shader_parameter("circle_center",circle_center)
%dense_fog.material.set_shader_parameter("circle_radius",circle_radius)
#掉落物是否可以生成:
func is_add_dropped_objects(post):
if !item_node.has(post) and %tile_map_build.get_cell_source_id(post) == -1:
return true
else:
return false