720 lines
29 KiB
GDScript
720 lines
29 KiB
GDScript
class_name work extends Panel
|
||
|
||
## Основной скрипт для режима "Работа".
|
||
|
||
@export var Bip: PackedScene ## Индикатор излучения цели.
|
||
@export var col_grey: Color ## Второй цвет для фона.
|
||
@export var col_red: Color ## Первый цвет для фона.
|
||
@export var drag_scale_band: float ## Масштаб изменения параметра от движения мыши для строба по радиальному размеру.
|
||
@export var drag_scale_width: float ## Масштаб изменения параметра от движения мыши для строба по угловому размеру.
|
||
@export var freq_high: float ## Верхняя рабочая частота, МГЦ.
|
||
@export var freq_low: float ## Нижняя рабочая частота, МГЦ.
|
||
@export var radius_center: Vector2 ## Координаты центра диаграммы пеленг-частота.
|
||
@export var radius_internal: float ## Внутренний радиус диаграммы пеленг-частота.
|
||
@export var radius_outter: float ## Внешний радиус диаграммы пеленг-частота.
|
||
@export var strob_max_band: float ## Максимальная ширина строба по углу.
|
||
@export var strob_max_width: float ## Максимальная ширина строба по углу.
|
||
@export var strob_min_band: float ## Минимальная ширина строба по частоте.
|
||
@export var strob_min_width: float ## Минимальная ширина строба по углу.
|
||
@export var window_0_id: int ## Идентификатор окна. Присваивается godot от 0 до количества созданных окон.
|
||
|
||
const SVK_EMIT = 1 ## Код состояния выполнения помехи - выполняется
|
||
|
||
var drag_button: MouseButton ## Кнопка мыши нажатая при перетаскивании.
|
||
var drag_fsm: DragFSM = DragFSM.IDLE ## Текущее состояние перетаскивания.
|
||
var btn_select: BtnSel = BtnSel.SECTOR ## Текущее состояние кнопки выбора цели.
|
||
var drag_pos_begin: Vector2 ## Точка начала перетаскивания.
|
||
var max_zoom: int ## Максимальный уровень детализации.
|
||
var min_zoom: int ## Минимальный уровень детализации.
|
||
var shift_pressed: bool ## Кнопка SHIFT нажата.
|
||
var strob_band_begin: float ## Ширина строба в момент начала перетаскивания.
|
||
var strob_dir_begin: float ## Направление антенны в момент начала перетаскивания.
|
||
var strob_width_begin: float ## Ширина строба по углу в момент начала перетаскивания.
|
||
var view_mode: MapViewMode ## Режим отображения карты
|
||
var thrs_dict: Dictionary ## Ссылка на словарь целей
|
||
var gos_flag = true ## Флаг работать по своим целям
|
||
var color_ecm: Color
|
||
var color_select: Color
|
||
var color_emit: Color
|
||
var color_emit_sel: Color
|
||
var color_closed: Color
|
||
var col_btn_act: Color = Color.WHITE
|
||
var color_closed_emit: Color
|
||
var signal_conections: Array
|
||
|
||
var course = 0.0 ## Курс корабля
|
||
|
||
signal drag_begin ## Вызывается в момент начала перетаскивания.
|
||
signal drag_continue ## Вызывается во время продолжения перетаскивания.
|
||
signal drag_end ## Вызывается в момент завершения перетаскивания.
|
||
|
||
|
||
## Размеры карты для разных режимов РТО и РЛС соответственно
|
||
const map_sizes = [
|
||
Rect2i(360, 360, 400, 400),
|
||
Rect2i(82, 82, 955, 955)]
|
||
var fs_band = prd.FS_BAND_RTO ## Текущий режим блоков ФС по частоте
|
||
var fs_selected: Dictionary ## Словарь выбранных секторов
|
||
var fs_active: Dictionary ## Словарь секторов назначенных на подавление
|
||
var fs_emit: Dictionary ## Словарь секторов назначенных на подавление
|
||
var fs_closed: Dictionary ## Словарь для секторов запрета
|
||
var fs_failed: PackedInt32Array ## Индикация сломанных секторов (модули ФС). AntBandState.ANT_BAND_READY - исправен, AntBandState.ANT_BAND_FAILURE - сломан.
|
||
|
||
## Состояние перетаскивания.
|
||
enum DragFSM {
|
||
DRAG, ## В процессе.
|
||
IDLE, ## Не активно, ожидание.
|
||
OFF ## Выключено.
|
||
}
|
||
|
||
## Режим выбора
|
||
enum BtnSel {
|
||
SECTOR, ## Выбор сектора.
|
||
THREAT, ## Выбор цели.
|
||
FS ## Выбор стробом.
|
||
}
|
||
|
||
|
||
## Режим отображения карты
|
||
enum MapViewMode {
|
||
RTO = 0, ## Режим приоритет РТО (малая карта, широкие секторы)
|
||
RLS = 1 ## Режим приоритет РЛС (большая карта, узкие секторы)
|
||
}
|
||
|
||
|
||
enum AntBandState {
|
||
ANT_BAND_FAILED = 0,
|
||
ANT_BAND_READY = 1,
|
||
ANT_BAND_ASSIGNED = 2
|
||
}
|
||
|
||
const VAL_TO_EVENT = {
|
||
false: 'manual_control', ## Выбор целей и установка помех вручную.
|
||
true: 'full_auto' } ## Выбор целей и установка помех автоматически.
|
||
|
||
|
||
var SIGNALS_CONNECTIONS = [
|
||
[interfer, 'interfer_update', 'on_interfer_new'],
|
||
[signaller, 'bip_pressed', 'on_bip_pressed'],
|
||
[signaller, 'clear_klaster', 'clear_all_klaster'],
|
||
[signaller, 'fs_selected', 'on_fs_selected'],
|
||
[signaller, 'fs_update_color', 'set_fs_color'],
|
||
[signaller, 'fs_update_state', 'on_fs_update_state'],
|
||
[signaller, 'interfer_new', 'on_interfer_new'],
|
||
[signaller, 'interfer_off_all', 'on_interfer_off_all'],
|
||
[signaller, 'interfer_prinuditelno', 'on_chk_interfer_prinuditelno'],
|
||
[signaller, 'interfer_prinuditelno', 'on_interfer_prinuditelno'],
|
||
[signaller, 'interfer_selected', 'on_interfer_selected'],
|
||
[signaller, 'map_user_panning', 'on_user_panning'],
|
||
[signaller, 'prog_ecm_off', 'on_interfer_new'],
|
||
[signaller, 'rto_threat_sel', 'on_rto_threat_sel'],
|
||
[signaller, 'rto_threat_unsel', 'on_rto_threat_unsel'],
|
||
[signaller, 'sector_klaster', 'sector_klaster'],
|
||
[signaller, 'th_aoa_update', 'on_th_aoa_update'],
|
||
[signaller, 'threat_selected', 'on_threat_selected'],
|
||
[signaller, 'update_coordinates_map', 'on_update_coordinates_label'],
|
||
[signaller, 'update_scale_map', 'on_update_scale_label'],
|
||
[threats, 'threat_lost', 'on_threat_lost'],
|
||
[threats, 'threat_new', 'on_threat_new'],
|
||
[threats, 'threat_update', 'on_threat_update'],
|
||
[threats, 'threats_resized', 'on_threats_resized'] ]
|
||
|
||
|
||
## Обработчик выбора цели.
|
||
func on_threat_selected(th): on_rto_threat_sel(th.id)
|
||
|
||
|
||
## Встроенный обратный вызов.
|
||
func on_enter_tree() -> void: call_deferred('on_button_strobe_pressed')
|
||
|
||
|
||
func clear_all_klaster(): $canvas.clear_all_seczap()
|
||
|
||
|
||
func on_user_panning(): $btn_center.button_pressed = false
|
||
|
||
|
||
func on_settings_changed():
|
||
gos_flag = ProjectSettings.get_setting('application/config/Включить работу по своим целям', true)
|
||
color_emit = ProjectSettings.get_setting('application/interfer/emit_color', Color(0.58, 0.47, 0.51, 1.0))
|
||
color_ecm = ProjectSettings.get_setting('application/interfer/interfer_color', Color(0.58, 0.47, 0.51, 1.0))
|
||
color_select = ProjectSettings.get_setting('application/interfer/select_color', Color(1.0, 1.0, 1.0, 1.0))
|
||
color_closed = ProjectSettings.get_setting('application/interfer/closed_sectors', Color(0.0, 0.0, 0.0, 1.0))
|
||
min_zoom = ProjectSettings.get_setting('application/config/map_minimum_zoom', 5)
|
||
max_zoom = ProjectSettings.get_setting('application/config/map_maximum_zoom', 19)
|
||
color_emit_sel = color_select
|
||
color_closed_emit = color_closed
|
||
|
||
color_select *= Color(1.0, 1.0, 1.0, 0.0)
|
||
color_ecm *= Color(1.0, 1.0, 1.0, 0.0)
|
||
color_emit_sel *= Color(1.0, 1.0, 1.0, 0.2)
|
||
color_closed *= Color(1.0, 1.0, 1.0, 0.0)
|
||
color_closed_emit *= Color(1.0, 1.0, 1.0, 1.0)
|
||
|
||
var json_col = ProjectSettings.get_setting('application/config/%s' % 'Цвет кнопки \"Подавление\"', '[1.0, 1.0, 1.0, 1.0]')
|
||
var arr_col = JSON.parse_string(json_col)
|
||
col_btn_act = Color(arr_col[0], arr_col[1], arr_col[2], arr_col[3]) if arr_col else Color.WHITE
|
||
apply_colors()
|
||
|
||
|
||
func apply_colors():
|
||
var is_light: bool = ProjectSettings.get_setting("application/config/Цвет темы программы", false)
|
||
var style = StyleBoxFlat.new()
|
||
if is_light:
|
||
style.bg_color = Color.DARK_GRAY
|
||
add_theme_stylebox_override("panel", style)
|
||
else:
|
||
style.bg_color = Color(0.12, 0.12, 0.12)
|
||
add_theme_stylebox_override("panel", style)
|
||
|
||
|
||
## Обработчик сигнала изменения списка целей.
|
||
func on_threats_resized(ths: Dictionary):
|
||
count_threats(ths)
|
||
thrs_dict = ths
|
||
|
||
|
||
## Обработчик нажатия на кнопку вид.
|
||
func on_button_view_toggled(toggled: bool):
|
||
signaller.emit_signal('map_mode_changed', int(toggled))
|
||
fs_band = prd.FS_BAND_RLS if toggled else prd.FS_BAND_RTO
|
||
var s = map_sizes[int(toggled)]
|
||
$tilemap.size = s.size
|
||
$tilemap.position = s.position
|
||
view_mode = MapViewMode.RLS if toggled else MapViewMode.RTO
|
||
if view_mode != MapViewMode.RTO:
|
||
fs_selected.clear()
|
||
$btns_select/btn_strob.disabled = toggled
|
||
$btns_select/btn_fs_sector.disabled = toggled
|
||
$'canvas/строб'.visible = $btns_select/btn_strob.pressed and (not toggled)
|
||
|
||
|
||
## Встроенный обратный вызов.
|
||
func _enter_tree() -> void:
|
||
var timer1 = Timer.new()
|
||
timer1.name = 'timer1'
|
||
add_child(timer1)
|
||
timer1.one_shot = true
|
||
timer1.connect('timeout', Callable(self, 'on_enter_tree'))
|
||
timer1.start(1.0)
|
||
|
||
|
||
## Встроенный обратный вызов.
|
||
func _exit_tree() -> void:
|
||
var timer1 = get_node('timer1')
|
||
remove_child(timer1)
|
||
timer1.queue_free()
|
||
|
||
|
||
func init_fs_failed():
|
||
var sectors_count = $canvas.fs_default_colors.size()
|
||
fs_failed.resize(sectors_count)
|
||
for i in fs_failed.size():
|
||
fs_failed[i] = AntBandState.ANT_BAND_FAILED
|
||
|
||
|
||
## Производит инициализацию.
|
||
func _ready():
|
||
ProjectSettings.connect('settings_changed', on_settings_changed)
|
||
on_settings_changed()
|
||
init_fs_failed()
|
||
drag_fsm = DragFSM.OFF
|
||
var btns_select: Array = get_tree().get_nodes_in_group('группа-режим-выбора')
|
||
btns_select.any(func(btn): btn.button_connect('pressed', Callable(self, 'on_button_select').bind(btn, btns_select)))
|
||
on_button_select($btns_select/btn_fs_sector, btns_select)
|
||
var nodes: Array = get_tree().get_nodes_in_group('группа-режим-помехи')
|
||
nodes.any(func(btn): btn.button_connect('pressed', Callable(self, 'on_button_pressed').bind(btn, nodes)))
|
||
$btn_close.button_connect('pressed', on_btn_close)
|
||
$btn_work.button_connect('pressed', on_btn_work)
|
||
var unit_nav = network.get_unit_instance('навигация')
|
||
unit_nav.connect('data_received', on_navi_data_received)
|
||
on_btn_center_toggled(true)
|
||
on_btn_activate_toggled(true)
|
||
signaller.connect('режим_работа', connect_all)
|
||
signaller.connect('режим_контроль', disconnect_all)
|
||
signaller.connect('режим_журнал', disconnect_all)
|
||
signaller.connect('режим_эмс', disconnect_all)
|
||
signaller.connect('режим_эмс2', disconnect_all)
|
||
signaller.connect('режим_настройки', disconnect_all)
|
||
connect_all()
|
||
|
||
|
||
func connect_all() -> void:
|
||
signal_conections.clear()
|
||
for item in SIGNALS_CONNECTIONS:
|
||
var proc = Callable(self, item[2])
|
||
var rc = item[0].connect(item[1], proc)
|
||
if rc == Error.OK:
|
||
signal_conections.append([item[0], item[1], proc])
|
||
else:
|
||
var ers = error_string(rc)
|
||
push_error('%s: %s %s %s' % [ers, item[0], item[1], item[2]])
|
||
signaller.emit_signal('connect_work_signal')
|
||
for th in thrs_dict.values():
|
||
var bip = Bip.instantiate()
|
||
bip.name = '%d' % th.id
|
||
map_threat_to_bip(th, bip)
|
||
add_child(bip)
|
||
|
||
|
||
func disconnect_all() -> void:
|
||
for item in signal_conections:
|
||
item[0].disconnect(item[1], item[2])
|
||
signal_conections.clear()
|
||
var bips: Array = get_children().filter(func(item): return item.name.is_valid_int())
|
||
for bip in bips:
|
||
remove_child(bip)
|
||
bip.free()
|
||
|
||
|
||
func sector_klaster(sector_data):
|
||
if sector_data['draw']:
|
||
var rect: Rect2 = sector_data['rect']
|
||
var color: Color = sector_data['color']
|
||
var id: int = sector_data['index']
|
||
$canvas.add_seczap(id, Vector4(rect.position.x, rect.position.y, rect.size.x, rect.size.y))
|
||
$canvas.set_seczap_color(id, color)
|
||
|
||
|
||
func on_navi_data_received(data: Dictionary):
|
||
var k = data.get('k', 0.0)
|
||
$canvas.set_canvas_rotation(k)
|
||
course = k
|
||
|
||
|
||
func on_chk_interfer_prinuditelno(_interfer_sectors):
|
||
$chk_auto.set_pressed_no_signal(false)
|
||
on_value_changed(false)
|
||
|
||
|
||
func on_value_changed(val: bool):
|
||
signaller.emit_signal(VAL_TO_EVENT[val])
|
||
|
||
|
||
func get_all_nodes(root):
|
||
var nodes = []
|
||
nodes.append(root)
|
||
for child in root.get_children():
|
||
nodes.append_array(get_all_nodes(child))
|
||
return nodes
|
||
|
||
|
||
## Производит отображение цели на диаграмму.
|
||
func map_threat_to_bip(th: threats.Threat, bip: Control) -> bool:
|
||
var freq = th.freq
|
||
var sector_key = null
|
||
var sector_width = 50.0
|
||
for key in prd.FS_FREQ:
|
||
var freq_range = prd.FS_FREQ[key]
|
||
var _num_values = (freq_range[1] - freq_range[0]) / sector_width
|
||
if freq_range[0] <= freq and freq <= freq_range[1]:
|
||
sector_key = key
|
||
break
|
||
if sector_key != null:
|
||
radius_internal = fs_band[sector_key][0]
|
||
radius_outter = fs_band[sector_key][1]
|
||
freq_low = prd.FS_FREQ[sector_key][0]
|
||
freq_high = prd.FS_FREQ[sector_key][1]
|
||
bip.position = tools.pos_calc(
|
||
th.freq,
|
||
th.aoa,
|
||
radius_center,
|
||
radius_internal,
|
||
radius_outter,
|
||
freq_low,
|
||
freq_high) - bip.size / 2
|
||
return sector_key != null
|
||
|
||
|
||
## Обработчик сигнала обновления цели.
|
||
func on_threat_update(th: threats.Threat):
|
||
var bip = get_node('%d' % th.id)
|
||
bip.update(th.tick_rx)
|
||
if th.gos:
|
||
bip.set_bip_color(Color.GREEN)
|
||
else:
|
||
bip.set_bip_color(Color.CORAL if th.proto else Color.WHITE)
|
||
bip.visible = map_threat_to_bip(th, bip)
|
||
|
||
|
||
## Обработчик выбора помехи для цели.
|
||
func on_interfer_new(ecm):
|
||
if not interfer.thrs.has(ecm.ispp): return
|
||
var th_id = interfer.thrs[ecm.ispp]
|
||
var bip = get_node('%d' % th_id)
|
||
if bip != null:
|
||
if ecm.krp!= interfer.INTERFER_OFF:
|
||
bip.set_track_visible(true)
|
||
if ecm.svk == 1:
|
||
bip.set_ecm_visible(true)
|
||
else: bip.set_ecm_visible(false)
|
||
else:
|
||
bip.set_ecm_visible(false)
|
||
bip.set_track_visible(false)
|
||
else:
|
||
interfer.thrs.erase(ecm.ispp)
|
||
update_fs_colors()
|
||
|
||
|
||
## Обработчик выключения всех помех.
|
||
func on_interfer_off_all():
|
||
var bips: Array = get_children().filter(func(item): return item.name.is_valid_int())
|
||
for bip in bips:
|
||
bip.set_ecm_visible(false)
|
||
bip.set_track_visible(false)
|
||
fs_active.clear()
|
||
fs_emit.clear()
|
||
update_fs_colors()
|
||
|
||
|
||
## Обработчик сигнала обнаружения цели.
|
||
func on_threat_new(th) -> void:
|
||
var bip = Bip.instantiate()
|
||
bip.name = '%d' % th.id
|
||
map_threat_to_bip(th, bip)
|
||
add_child(bip)
|
||
|
||
|
||
## Обработчик сигнала потери цели.
|
||
func on_threat_lost(th) -> void:
|
||
var bip = get_node('%d' % th.id)
|
||
remove_child(bip)
|
||
bip.free()
|
||
|
||
|
||
## обработчик нажатия на цель на экране.
|
||
func on_bip_pressed(th_id):
|
||
if btn_select == BtnSel.THREAT:
|
||
signaller.emit_signal('rto_threat_sel', th_id)
|
||
|
||
|
||
## Обработчик выбора РТО цели.
|
||
func on_rto_threat_sel(th_id):
|
||
var bips: Array = get_children().filter(func(item): return item.name.is_valid_int())
|
||
for item in bips:
|
||
if th_id == item.name.to_int():
|
||
item.set_sel_visible(true)
|
||
unsel_fs_all(false)
|
||
else:
|
||
item.set_sel_visible(false)
|
||
var th = thrs_dict[th_id]
|
||
var krp = interfer.get_krp(th)
|
||
var ecm_btns: Array = get_tree().get_nodes_in_group('группа-режим-помехи')
|
||
for btn in ecm_btns:
|
||
set_btns_disabled(false, btn)
|
||
var btn_meta = btn.get_meta('rfi_name')
|
||
if krp == btn_meta:
|
||
btn.set_rec_visible(true)
|
||
else:
|
||
btn.set_rec_visible(false)
|
||
|
||
|
||
## Обработчик снятия выбора РТО цели.
|
||
func on_rto_threat_unsel(th_id):
|
||
var bips: Array = get_children().filter(func(item): return item.name.is_valid_int())
|
||
for item in bips:
|
||
if th_id == item.name.to_int():
|
||
item.set_sel_visible(false)
|
||
break
|
||
set_ecm_btns_state(true)
|
||
var ecm_btns: Array = get_tree().get_nodes_in_group('группа-режим-помехи')
|
||
for btn in ecm_btns:
|
||
btn.set_rec_visible(false)
|
||
|
||
|
||
## Обработчик нажатия кнопки "Строб". Управляет отображением строба.
|
||
func on_button_strobe_pressed() -> void:
|
||
drag_fsm = DragFSM.IDLE if $btns_select/btn_strob.is_pressed() else DragFSM.OFF
|
||
$canvas.set_strob_visible((drag_fsm == DragFSM.IDLE) and (view_mode == MapViewMode.RTO))
|
||
|
||
|
||
## Поведение радиокнопок в группе. Управляет состоянием кнопок выбора целей.
|
||
func on_button_select(btn_this, btn_others) -> void:
|
||
for btn_other in btn_others: btn_other.set_pressed(btn_this == btn_other)
|
||
btn_select = btn_this.get_meta('state')
|
||
on_button_strobe_pressed()
|
||
signaller.emit_signal('rto_threat_unsel_all')
|
||
unsel_fs_all(true)
|
||
set_ecm_btns_state(true)
|
||
|
||
|
||
## Поведение радиокнопок в группе. Управляет состоянием кнопок в радиогруппе.
|
||
func on_button_pressed(btn_this, btn_others) -> void:
|
||
$chk_auto.set_pressed_no_signal(false)
|
||
on_value_changed(false)
|
||
for btn_other in btn_others: btn_other.set_pressed(btn_this == btn_other)
|
||
var interfer_name: String = btn_this.get_meta('rfi_name', 'off')
|
||
var fs_arr: Array = []
|
||
for key in fs_selected.keys():
|
||
fs_arr.append(prd.get_fs_param(key))
|
||
signaller.emit_signal('interfer_init', interfer_name, fs_arr, interfer.POW_DEFAULT)
|
||
|
||
|
||
## Управляет состоянием кнопок в радиогруппе при выборе помехи.
|
||
func on_interfer_selected(ecm) -> void:
|
||
var ecm_name: String
|
||
if ecm != null:
|
||
ecm_name = ecm.krp
|
||
else:
|
||
ecm_name = interfer.INTERFER_OFF
|
||
var btns: Array = get_tree().get_nodes_in_group('группа-режим-помехи')
|
||
for btn in btns:
|
||
set_btns_disabled(false, btn)
|
||
btn.get_meta('rfi_name')
|
||
if ecm_name == btn.get_meta('rfi_name'):
|
||
btn.set_pressed(true)
|
||
else:
|
||
btn.set_pressed(false)
|
||
|
||
|
||
## Возвращает ширину строба по направлению.
|
||
func get_strob_width(pos: Vector2, prev: float) -> float:
|
||
var strob_dir_width: float = prev + (drag_pos_begin.y - pos.y) * drag_scale_width
|
||
strob_dir_width = tools.clip_value(strob_dir_width, strob_min_width, strob_max_width)
|
||
return strob_dir_width
|
||
|
||
|
||
## Возвращает ширину строба по частоте.
|
||
func get_strob_band(pos: Vector2, prev: float) -> float:
|
||
var strob_dir_band: float = prev - (drag_pos_begin.y - pos.y) * drag_scale_band
|
||
strob_dir_band = tools.clip_value(strob_dir_band, strob_min_band, strob_max_band)
|
||
return strob_dir_band
|
||
|
||
|
||
## Устанавливает центр строба по частоте и направлению.
|
||
func set_strob(pos: Vector2) -> void:
|
||
var radp: Vector2 = tools.map_dec_to_rad(radius_center / 2.0, pos / 2.0)
|
||
if radp.y < $canvas.get_radius_outter():
|
||
$canvas.set_strob_dir(radp.x)
|
||
$canvas.set_strob_radius(radp.y)
|
||
|
||
|
||
## Обработка движения мыши для управления стробом. Вызывается во время движения мыши.
|
||
func _on_drag_continue(event) -> void:
|
||
if not $canvas.get_strob_visible(): return
|
||
if drag_button == MOUSE_BUTTON_RIGHT:
|
||
if shift_pressed:
|
||
var strob_width: float = get_strob_width(event.position, strob_width_begin)
|
||
$canvas.set_strob_width(strob_width)
|
||
else:
|
||
var strob_band: float = get_strob_band(event.position, strob_band_begin)
|
||
$canvas.set_strob_band(strob_band)
|
||
elif drag_button == MOUSE_BUTTON_LEFT:
|
||
set_strob(event.position)
|
||
|
||
|
||
## Обработка движения мыши для управления стробом. Вызывается при нажатии мыши.
|
||
func _on_drag_begin(event) -> void:
|
||
if not $canvas.get_strob_visible(): return
|
||
drag_pos_begin = event.position
|
||
if drag_button == MOUSE_BUTTON_LEFT:
|
||
set_strob(event.position)
|
||
elif drag_button == MOUSE_BUTTON_RIGHT:
|
||
strob_width_begin = $canvas.get_strob_width()
|
||
strob_band_begin = $canvas.get_strob_band()
|
||
|
||
|
||
## Обработчик событий ввода. Вызывается godot.
|
||
func _input(event) -> void:
|
||
if not is_visible_in_tree(): return
|
||
if (event is InputEventMouseMotion) and (view_mode == MapViewMode.RTO):
|
||
if drag_fsm == DragFSM.DRAG:
|
||
emit_signal('drag_continue', event)
|
||
elif event is InputEventMouseButton:
|
||
drag_button = event.button_index
|
||
if event.pressed:
|
||
if drag_fsm == DragFSM.IDLE:
|
||
drag_fsm = DragFSM.DRAG
|
||
emit_signal('drag_begin', event)
|
||
else:
|
||
if btn_select == BtnSel.FS:
|
||
sel_fs_sector(event)
|
||
drag_fsm = DragFSM.IDLE
|
||
emit_signal('drag_end', event)
|
||
|
||
elif event is InputEventKey:
|
||
if event.physical_keycode == KEY_SHIFT:
|
||
shift_pressed = event.pressed
|
||
|
||
|
||
## Обработчик нажатия по сектору формирователя сигналов.
|
||
func sel_fs_sector(event):
|
||
if view_mode != MapViewMode.RTO: return
|
||
if (event.button_index == MOUSE_BUTTON_LEFT) or (event.button_index == MOUSE_BUTTON_RIGHT):
|
||
var center: Vector2 = $tilemap.position
|
||
var center_offset: Vector2 = ProjectSettings.get_setting('application/interfer/center_offset', Vector2i(0, 25))
|
||
var angle: float = event.position.angle_to_point(center + center_offset) * 180/PI - 45.0 - course
|
||
if angle < 0:
|
||
angle += 360
|
||
var distance: float = event.position.distance_to(center + center_offset)
|
||
var sector: int
|
||
var band: int
|
||
var has_band: bool = false
|
||
for sec in prd.FS_SECTORS.values():
|
||
if angle >= sec[0] and angle <= sec[1]:
|
||
sector = prd.FS_SECTORS.find_key(sec)
|
||
for diap in fs_band.values():
|
||
if distance >= diap[0] and distance <= diap[1]:
|
||
band = fs_band.find_key(diap)
|
||
has_band = true
|
||
if not has_band:
|
||
return
|
||
var fs_index = band * 4 + sector
|
||
if event.button_index == MOUSE_BUTTON_LEFT:
|
||
fs_selected[fs_index] = null
|
||
else:
|
||
fs_selected.erase(fs_index)
|
||
update_fs_colors()
|
||
signaller.emit_signal('rto_threat_unsel_all')
|
||
var btn_state = len(fs_selected) == 0
|
||
set_ecm_btns_state(btn_state)
|
||
|
||
|
||
func set_fs_color(ecms):
|
||
fs_active.clear()
|
||
fs_emit.clear()
|
||
for ecm in ecms.values():
|
||
if not prd.fs_caps_id.has(ecm.nmfs):
|
||
push_warning('нет такого модуля ФС: %d, но имеется: %s' % [ecm.nmfs, prd.fs_caps_id.keys()])
|
||
continue
|
||
if ecm.krp != interfer.INTERFER_OFF:
|
||
fs_active[prd.fs_caps_id[ecm.nmfs]] = null
|
||
if ecm.svk == SVK_EMIT:
|
||
fs_emit[prd.fs_caps_id[ecm.nmfs]] = null
|
||
update_fs_colors()
|
||
|
||
|
||
func update_fs_colors():
|
||
var fs_colors = $canvas.fs_default_colors.duplicate()
|
||
for key in fs_active.keys():
|
||
fs_colors[key] = color_ecm
|
||
for key in fs_emit.keys():
|
||
fs_colors[key] = color_emit
|
||
for key in fs_closed:
|
||
if key in fs_emit:
|
||
fs_colors[key] = color_closed_emit
|
||
else:
|
||
fs_colors[key] = color_closed
|
||
for key in fs_selected.keys():
|
||
if key in fs_emit:
|
||
fs_colors[key] = color_emit_sel
|
||
else:
|
||
fs_colors[key] = color_select
|
||
$canvas.set_band_colors(fs_colors)
|
||
$canvas.set_band_failures(fs_failed)
|
||
if fs_emit.size():
|
||
if $btn_activate.pressed:
|
||
$btn_activate.self_modulate = col_btn_act
|
||
else:
|
||
$btn_activate.self_modulate = Color.WHITE
|
||
else:
|
||
$btn_activate.self_modulate = Color.WHITE
|
||
|
||
|
||
func unsel_fs_all(need_btns_off: bool):
|
||
fs_selected.clear()
|
||
update_fs_colors()
|
||
if need_btns_off:
|
||
set_ecm_btns_state(true)
|
||
|
||
|
||
func set_ecm_btns_state(value: bool):
|
||
var btns: Array = get_tree().get_nodes_in_group('группа-режим-помехи')
|
||
for btn in btns:
|
||
btn.set_pressed(false)
|
||
set_btns_disabled(value, btn)
|
||
|
||
|
||
func on_fs_selected(ecm):
|
||
var fs_index_arr: Array = []
|
||
prd.get_fs_index(ecm, fs_index_arr)
|
||
fs_selected.clear()
|
||
if view_mode != MapViewMode.RTO: return
|
||
for item in fs_index_arr:
|
||
fs_selected[item] = null
|
||
update_fs_colors()
|
||
|
||
|
||
func set_btns_disabled(value: bool, btn):
|
||
var external_ctl = ProjectSettings.get_setting('application/config/Внешнее управление', false)
|
||
if external_ctl:
|
||
btn.set_pressed(false)
|
||
btn.set_disabled(true)
|
||
else:
|
||
btn.set_disabled(value)
|
||
|
||
|
||
func on_interfer_prinuditelno(prenuditelno_sectors):
|
||
for key in prenuditelno_sectors:
|
||
var sectors = []
|
||
for sector in prenuditelno_sectors[key]:
|
||
sectors.append(prd.get_fs_param(sector))
|
||
signaller.emit_signal('interfer_init', key, sectors, interfer.POW_DEFAULT)
|
||
update_fs_colors()
|
||
var btns: Array = get_tree().get_nodes_in_group('группа-режим-помехи')
|
||
for btn in btns:
|
||
btn.set_pressed(false)
|
||
set_btns_disabled(true, btn)
|
||
|
||
|
||
## Вызывается при получении информации о состоянии модулей ФС от КАПС РПБ.
|
||
func on_fs_update_state(fs_dict: Dictionary):
|
||
for key in fs_dict.keys():
|
||
fs_failed[key] = AntBandState.ANT_BAND_READY if fs_dict[key].ready else AntBandState.ANT_BAND_FAILED
|
||
|
||
|
||
func on_btn_center_toggled(toggled_on: bool) -> void:
|
||
$btn_center.tooltip_text = 'Центрирует карту на текущие координаты (%s)' % ('включено' if toggled_on else 'отключено')
|
||
signaller.emit_signal('map_centered', toggled_on)
|
||
|
||
|
||
func on_btn_activate_toggled(toggled_on: bool) -> void:
|
||
$btn_activate.tooltip_text = 'Включает подавление (%s)' % ('включено' if toggled_on else 'отключено')
|
||
signaller.emit_signal('emit_changed', toggled_on)
|
||
if not toggled_on:
|
||
$btn_activate.self_modulate = Color.WHITE
|
||
|
||
|
||
func on_update_coordinates_label(coordinates_label) -> void:
|
||
$coordinates_map.text = str(coordinates_label)
|
||
|
||
|
||
func on_update_scale_label(scale_label) -> void:
|
||
$scale_map.text = str(scale_label)
|
||
|
||
|
||
func on_btn_close():
|
||
await get_tree().create_timer(0.2).timeout
|
||
$btn_close.pressed = false
|
||
fs_closed.merge(fs_selected)
|
||
signaller.emit_signal('update_fs_closed', fs_closed)
|
||
|
||
|
||
func on_btn_work():
|
||
await get_tree().create_timer(0.2).timeout
|
||
$btn_work.pressed = false
|
||
fs_closed.clear()
|
||
for fs_index in prd.FS_PRD.keys():
|
||
if fs_index in fs_selected: continue
|
||
fs_closed[fs_index] = null
|
||
signaller.emit_signal('update_fs_closed', fs_closed)
|
||
|
||
|
||
func _on_btn_all_work_pressed() -> void:
|
||
fs_closed.clear()
|
||
signaller.emit_signal('update_fs_closed', fs_closed)
|
||
|
||
|
||
func on_th_aoa_update(ths):
|
||
count_threats(ths)
|
||
|
||
|
||
func count_threats(ths):
|
||
$count_all_pad/count_all.text = '%02d' % ths.size()
|
||
var c: int = 0
|
||
if gos_flag:
|
||
c = ths.values().filter(func(th: threats.Threat): return th.proto != '').size()
|
||
else:
|
||
c = ths.values().filter(func(th: threats.Threat): return ((th.proto != '') and th.proto not in interfer.gos_protocols)).size()
|
||
$count_danger_pad/count_danger.text = '%02d' % c
|