#73 Вырезана механика потребления дополнительных конвееров и труб при размещении сверхдлинных конвееров и труб Вырезаны связанные с ней конфиги Убран флаг not-deconstructable со сверхдлинных конвееров и труб, что упрощает их использование с дронами Изменено английское описание сверхдлинных конвееров и труб (русское изменений не требует)
1077 lines
37 KiB
Lua
1077 lines
37 KiB
Lua
require "util"
|
|
require "utils"
|
|
require "speech-bubbles"
|
|
local format_number = util.format_number
|
|
|
|
function d_format_number(number, form)
|
|
if not form then form = "%.2f" end
|
|
return string.format(form, number)
|
|
end
|
|
|
|
|
|
|
|
local inputs =
|
|
{
|
|
"hs_hologram_image",
|
|
"hs_signal",
|
|
"hs_logistic",
|
|
"hs_production_m",
|
|
"hs_consumption_m",
|
|
"hs_research",
|
|
"hs_rockets",
|
|
"hs_players",
|
|
"hs_enemy_evolution",
|
|
"hs_kill_count",
|
|
-- "hs_wind_speed",
|
|
"hs_timers",
|
|
"hs_pollution",
|
|
"hs_charge"
|
|
}
|
|
|
|
local sub_inputs = {
|
|
['hs_research'] = {'hs_research_progress','hs_research_time_remaining'},
|
|
['hs_timers'] = {'hs_total_time','hs_day_time','hs_time_from_last_death'},
|
|
['hs_rockets'] = {"hs_rockets_launched","hs_item_launched"},
|
|
['hs_production_m'] = {"hs_production","hs_production_f","hs_production_p","hs_production_ratio","hs_production_ratio_f"},
|
|
['hs_consumption_m'] = {"hs_consumption","hs_consumption_f","hs_consumption_p"},
|
|
['hs_players'] = {"hs_player_casualties","hs_connected_players"},
|
|
['hs_warpdrive'] = {"hs_wdm_warping_in","hs_wdm_time_on_planet", "hs_native_evolution", "hs_planet_image"},
|
|
}
|
|
|
|
local cb_opts = {'[img=utility/time_editor_icon]05 s','[img=utility/time_editor_icon]01 m','[img=utility/time_editor_icon]10 m','[img=utility/time_editor_icon]01 h','[img=utility/time_editor_icon]15 h','[img=infinity]'}
|
|
|
|
local sub_options = {
|
|
['hs_production_ratio'] = {type = "drop-down", options=cb_opts },
|
|
['hs_production_ratio_f'] = {type = "drop-down", options=cb_opts},
|
|
}
|
|
|
|
|
|
|
|
local pk_item_list = {"hs_logistic","hs_production","hs_consumption","hs_item_launched","hs_production_ratio"}
|
|
local pk_fluid_list = {"hs_production_f","hs_consumption_f","hs_production_ratio_f"}
|
|
local pk_entity_list = {"hs_kill_count"}
|
|
local pk_signal_list = {"hs_hologram_image","hs_signal"}
|
|
|
|
|
|
|
|
function setup_mod_vars()
|
|
global.entity_speech = global.entity_speech or {}
|
|
global.signs = global.signs or {}
|
|
global.players = global.players or {} -- to control opened guis
|
|
global.last_death_tick = global.last_death_tick or 0
|
|
global.force_research = global.force_research or {}
|
|
|
|
global.inputs = table.deepcopy(inputs)
|
|
global.sub_inputs = table.deepcopy(sub_inputs)
|
|
--[[global.signs[1] = {entity =
|
|
text=
|
|
icon =
|
|
add_tag=
|
|
maptag=}]]
|
|
if game.active_mods['shield-projector'] then
|
|
global.animation = 'hs_hologram_animated'
|
|
else
|
|
global.animation = 'hs_hologram'
|
|
end
|
|
if game.active_mods['WindSpeedChanging'] or game.active_mods['nullius'] or game.active_mods['windturbines-redux'] then add_list(global.inputs, "hs_wind_speed") end
|
|
if game.active_mods['Warp-Drive-Machine'] then add_list(global.inputs, "hs_warpdrive") add_list(global.inputs, "hs_wind_speed") end
|
|
|
|
ReadRunTimeSettings()
|
|
end
|
|
|
|
|
|
|
|
|
|
function on_init()
|
|
setup_mod_vars()
|
|
if game and game.forces.player.technologies['optics'] and game.forces.player.technologies['optics'].researched and (not game.forces.player.recipes['hs_holo_sign'].enabled) then
|
|
game.forces.player.recipes['hs_holo_sign'].enabled=true
|
|
end
|
|
end
|
|
|
|
function on_configuration_changed()
|
|
setup_mod_vars()
|
|
ValidateAllSigns()
|
|
end
|
|
script.on_init(on_init)
|
|
script.on_configuration_changed(on_configuration_changed)
|
|
|
|
|
|
function ReadRunTimeSettings(event)
|
|
global.opt_animation = settings.global["hs-opt-animation"].value
|
|
ValidateAnimations()
|
|
end
|
|
script.on_event(defines.events.on_runtime_mod_setting_changed, ReadRunTimeSettings)
|
|
|
|
|
|
|
|
function ValidateAnimations()
|
|
for UN, Sign_Data in pairs (global.signs) do
|
|
local animation = Sign_Data.animation
|
|
local entity = Sign_Data.entity
|
|
if animation and rendering.is_valid(animation) and (not global.opt_animation) then rendering.destroy(animation) Sign_Data.animation=nil end
|
|
if global.opt_animation and ((not animation) or (not rendering.is_valid(animation))) then
|
|
if global.animation == 'hs_hologram_animated' then
|
|
animation = rendering.draw_animation {
|
|
animation = 'hs_hologram_animated',
|
|
x_scale=0.07,y_scale=0.35,
|
|
target = entity,
|
|
target_offset = {0, -1.1},
|
|
surface = entity.surface,
|
|
animation_offset = 0}
|
|
else
|
|
animation = rendering.draw_sprite {
|
|
sprite = 'hs_hologram',
|
|
x_scale=0.4,y_scale=0.5,
|
|
target = entity,
|
|
target_offset = {0, -1.1},
|
|
surface = entity.surface}
|
|
end
|
|
Sign_Data.animation = animation
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
|
|
function is_valid_input(input)
|
|
local valid = false
|
|
if in_list(global.inputs, input) then valid=true
|
|
else
|
|
for g,tab in pairs (global.sub_inputs) do
|
|
if in_list(tab, input) then valid=true break end
|
|
end
|
|
end
|
|
return valid
|
|
end
|
|
|
|
|
|
-- avoid crash if removed mod icons
|
|
function ValidateAllSigns()
|
|
for UN, Sign_Data in pairs (global.signs) do
|
|
local entity = Sign_Data.entity
|
|
local icon = Sign_Data.icon
|
|
local input = Sign_Data.input
|
|
-- Manage INPUTS
|
|
if input then
|
|
if in_list(pk_signal_list, input) then --'hs_signal'
|
|
local signal = Sign_Data.input_signal
|
|
if signal then
|
|
if signal.type=='item' then if not game.item_prototypes[signal.name] then Sign_Data.input=nil end
|
|
elseif signal.type=='fluid' then if not game.fluid_prototypes[signal.name] then Sign_Data.input=nil end
|
|
elseif signal.type=='virtual' then if not game.virtual_signal_prototypes[signal.name] then Sign_Data.input=nil end
|
|
end
|
|
end
|
|
elseif in_list(pk_item_list, input) then
|
|
local item = Sign_Data.input_item
|
|
if not (item and game.item_prototypes[item]) then Sign_Data.input=nil end
|
|
elseif in_list(pk_fluid_list, input) then
|
|
local fluid = Sign_Data.input_fluid
|
|
if not (fluid and game.fluid_prototypes[fluid]) then Sign_Data.input=nil end
|
|
elseif input=='hs_kill_count' then
|
|
local killed = Sign_Data.input_entity
|
|
if not (killed and game.entity_prototypes[killed]) then Sign_Data.input=nil end
|
|
|
|
elseif not is_valid_input(input) then Sign_Data.input=nil end
|
|
end
|
|
-- MAP TAG
|
|
if icon and icon.type and icon.name then
|
|
if icon.type=='item' then if not game.item_prototypes[icon.name] then Sign_Data.icon=nil end
|
|
elseif icon.type=='fluid' then if not game.fluid_prototypes[icon.name] then Sign_Data.icon=nil end
|
|
elseif icon.type=='virtual' then if not game.virtual_signal_prototypes[icon.name] then Sign_Data.icon=nil end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---Gui creation
|
|
|
|
function add_gui(parent,element,destroy,style)
|
|
local E = parent[element.name]
|
|
if destroy and E then E.destroy() E=nil end
|
|
if not E then E=parent.add(element) end
|
|
if style then for s=1,#style do E.style[style[s][1]]=style[s][2] end end
|
|
return E
|
|
end
|
|
|
|
|
|
|
|
local function open_gui (player, entity)
|
|
if not (entity and entity.valid) then return end
|
|
|
|
local gui = player.gui.screen
|
|
--player.opened = nil
|
|
|
|
local UN = entity.unit_number
|
|
local Sign_Data = global.signs[UN] or {}
|
|
|
|
if not Sign_Data.entity then Sign_Data.entity=entity end
|
|
|
|
global.players[player.name] = Sign_Data
|
|
|
|
--gui.clear()
|
|
|
|
if gui.frame_holo_sign then gui.frame_holo_sign.destroy() end
|
|
|
|
local frame = add_gui(player.gui.screen,{type = "frame", name = "frame_holo_sign", caption ={'','[img=item/hs_holo_sign]',{'holographic_sign'}}, direction = "vertical"})
|
|
player.opened = frame
|
|
frame.style.minimal_width = 100
|
|
frame.auto_center = true
|
|
local tab = add_gui(frame, {type="table", name='tab1', column_count = 3})
|
|
|
|
tab.add{type = "label", caption = {'hs_icon'}}.style.font = "default-bold"
|
|
tab.add{type = "label", caption = {'hs_text'}}.style.font = "default-bold"
|
|
tab.add{type="switch",name='hs_sw_onoff', tooltip={'hs_on_off'}, allow_none_state = false, switch_state=Sign_Data.state or 'right'}
|
|
|
|
|
|
local ico = add_gui(tab, {type="choose-elem-button", name='hs_icon_bt', elem_type="signal"} ) --elem_type ='item' item='steel-plate' elem_value
|
|
ico.elem_value= Sign_Data.icon
|
|
local txt = add_gui(tab, {type="textfield", name='hs_text_field' , text =Sign_Data.text} )
|
|
local ico = add_gui(tab, {type="choose-elem-button", name='hs_icon_bt', elem_type="signal"} ) --elem_type ='item' item='steel-plate' elem_value
|
|
|
|
local btc = add_gui(tab, {type="sprite-button", name='bt_hs_text_color', tooltip={'hs_color'}, style = "tool_button", sprite = "utility/brush_icon"})
|
|
|
|
|
|
local tab = add_gui(frame, {type="table", name='tab_cb', column_count = 2})
|
|
tab.add{type="checkbox",name='hs_cb_add_map', caption={'hs_add_tag'}, state=Sign_Data.add_tag or false}.style.font = "default-bold"
|
|
tab.add{type="checkbox",name='hs_cb_plain_text', caption={'hs_plain_text'}, state=Sign_Data.plain_text or false}.style.font = "default-bold"
|
|
|
|
local tab = add_gui(frame, {type="table", name='tab3', column_count = 4})
|
|
add_gui(tab, {type="sprite-button", sprite = "utility/close_white", name='bt_destroy_my_2parent', style = "back_button" }) --style='rounded_button'style="tool_button"
|
|
add_gui(tab, {type="sprite-button", name='bt_holo_sign_textbox', tooltip={'bt_holo_sign_textbox'}, style = "tool_button", sprite = "utility/custom_tag_icon"}) --rename_icon_normal
|
|
add_gui(tab, {type="sprite-button", name='bt_holo_sign_inputs', tooltip={'bt_holo_sign_inputs'},style = "tool_button", sprite = "utility/logistic_network_panel_black" }) --"item/red-wire"
|
|
add_gui(tab, {type="button", caption ='OK', name='bt_holo_sign_ok', tooltip={'bt_holo_sign_confirm'}, style = "confirm_button"})
|
|
|
|
|
|
|
|
if Sign_Data.input then add_inputs(frame,player) end
|
|
if Sign_Data.show_textbox then add_textbox(frame,player) end
|
|
|
|
|
|
--frame.force_auto_center()
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
-- RGB Color editor
|
|
function show_team_color_gui(gui,player)
|
|
|
|
local Sign_Data = global.players[player.name]
|
|
local color = Sign_Data.text_color or {r = 1, g = 1, b = 1}
|
|
local frame = gui.hs_color_frame
|
|
if frame then frame.destroy()
|
|
else
|
|
frame = gui.add{type="frame", name="hs_color_frame", direction = "vertical", caption={"hs_color"}} --style=mod_gui.frame_style,
|
|
|
|
local tabBars = frame.add{type = "table", name='hs_tab_rgb', column_count = 2}
|
|
tabBars.add{type = "label", caption='R'}.style.font_color={r = 1, g = 0.5, b = 0.5}
|
|
local sliderR = tabBars.add{type = "slider", name='hs_slider_color_R', value = color.r,minimum_value=0,maximum_value=1}
|
|
|
|
tabBars.add{type = "label", caption='G'}.style.font_color={r = 0.5, g = 1, b = 0.5}
|
|
local sliderG = tabBars.add{type = "slider", name='hs_slider_color_G', value = color.g,minimum_value=0,maximum_value=1}
|
|
|
|
tabBars.add{type = "label", caption='B'}.style.font_color={r = 0.5, g = 0.5, b = 1}
|
|
local sliderB = tabBars.add{type = "slider", name='hs_slider_color_B', value = color.b,minimum_value=0,maximum_value=1}
|
|
|
|
local tabBarsBt = frame.add{type = "table", name='hs_color_bt_tab', column_count = 3}
|
|
|
|
local btCancel= tabBarsBt.add{name="bt_destroy_my_2parent", type="sprite-button", style = "slot_button", sprite = "utility/deconstruction_mark"} --rounded_button --back_button
|
|
local btApply = tabBarsBt.add{name="bt_hs_color_apply", type="sprite-button", style = "slot_button", sprite = "utility/check_mark_green"} --confirm_slot
|
|
local label = tabBarsBt.add{name="label_hs_color", type="label", caption={"hs_color"}} --confirm_slot
|
|
label.style.font_color = color
|
|
label.style.font = "default-large-bold"
|
|
end
|
|
end
|
|
|
|
|
|
function color_apply(gui,player)
|
|
local Sign_Data = global.players[player.name]
|
|
|
|
if gui and gui.hs_tab_rgb then
|
|
local R = gui.hs_tab_rgb.hs_slider_color_R.slider_value
|
|
local G = gui.hs_tab_rgb.hs_slider_color_G.slider_value
|
|
local B = gui.hs_tab_rgb.hs_slider_color_B.slider_value
|
|
Sign_Data.text_color = {r = R, g = G, b = B}
|
|
gui.destroy()
|
|
end
|
|
end
|
|
|
|
|
|
local function on_gui_value_changed(event)
|
|
local gui = event.element
|
|
local player = game.players[event.player_index]
|
|
|
|
if gui.get_mod()=='holographic_signs' then
|
|
if gui.type=='slider' then
|
|
if gui.name=='hs_slider_color_R' or gui.name=='hs_slider_color_G' or gui.name=='hs_slider_color_B' then
|
|
local tab = gui.parent
|
|
local R=tab.hs_slider_color_R.slider_value
|
|
local G=tab.hs_slider_color_G.slider_value
|
|
local B=tab.hs_slider_color_B.slider_value
|
|
local tab = tab.parent
|
|
tab.hs_color_bt_tab.label_hs_color.style.font_color = {r=R,g=G,b=B}
|
|
end
|
|
end
|
|
end
|
|
|
|
end
|
|
script.on_event(defines.events.on_gui_value_changed, on_gui_value_changed)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local function on_gui_switch_state_changed(event)
|
|
local gui = event.element
|
|
local player = game.players[event.player_index]
|
|
if gui.get_mod()=='holographic_signs' then
|
|
if gui.name=="hs_sw_onoff" then
|
|
local Sign_Data = global.players[player.name]
|
|
Sign_Data.state = gui.switch_state
|
|
apply_holo_sign(Sign_Data)
|
|
end
|
|
end
|
|
end
|
|
script.on_event(defines.events.on_gui_switch_state_changed, on_gui_switch_state_changed)
|
|
|
|
|
|
|
|
local function on_gui_click(event)
|
|
local gui = event.element
|
|
local player = game.players[event.player_index]
|
|
|
|
if not (player) then return end
|
|
if not (gui and gui.valid) then return end
|
|
|
|
if gui.name and gui.name~='' then
|
|
if gui.name == "bt_holo_sign_ok" then add_holo_sign(gui.parent.parent,player,event.shift)
|
|
elseif gui.name == "bt_destroy_my_parent" then gui.parent.destroy()
|
|
elseif gui.name == "bt_destroy_my_2parent" then gui.parent.parent.destroy()
|
|
elseif gui.name == "bt_holo_sign_textbox" then toggle_textbox(gui.parent.parent,player)
|
|
elseif gui.name == "bt_holo_sign_inputs" then toggle_inputs(gui.parent.parent,player)
|
|
elseif gui.name == "bt_hs_cancel_input" then cancel_input(gui.parent.parent.parent,player) return
|
|
elseif gui.name == "bt_hs_text_color" then show_team_color_gui(gui.parent.parent,player) return
|
|
elseif gui.name == "bt_hs_color_apply" then color_apply(gui.parent.parent,player) return
|
|
end
|
|
end
|
|
end
|
|
script.on_event(defines.events.on_gui_click, on_gui_click)
|
|
|
|
function toggle_textbox(gui,player)
|
|
if gui.hs_textbox then
|
|
gui.hs_textbox.destroy()
|
|
else
|
|
add_textbox(gui,player)
|
|
end
|
|
end
|
|
|
|
function toggle_inputs(gui,player)
|
|
if gui.hs_inputs then
|
|
gui.hs_inputs.destroy()
|
|
else
|
|
add_inputs(gui,player)
|
|
end
|
|
end
|
|
|
|
function cancel_input(gui,player)
|
|
local Sign_Data = global.players[player.name]
|
|
if Sign_Data then Sign_Data.input = nil end
|
|
toggle_inputs(gui,player)
|
|
end
|
|
|
|
|
|
function add_inputs(gui,player)
|
|
local Sign_Data = global.players[player.name]
|
|
if gui.hs_inputs then gui.hs_inputs.destroy() end
|
|
local input = Sign_Data.input
|
|
local frame = gui.add{type="frame", name="hs_inputs",caption={"hs_input_box"}, direction='vertical'}
|
|
frame.style.width=290
|
|
--frame.style.height=100
|
|
-- will need scroll-pane here
|
|
|
|
|
|
--game.print(input)
|
|
if not input then
|
|
for i=1, #global.inputs do
|
|
frame.add{type="radiobutton",name=global.inputs[i], caption={global.inputs[i]}, state=iif(global.inputs[i]==input, true, false) }.style.font = "default-bold"
|
|
end
|
|
else
|
|
|
|
|
|
local tab = add_gui(frame, {type="table", name='tab_inp_sel', column_count = 2})
|
|
tab.add{type="label",name=input, caption={input}}.style.font = "default-bold"
|
|
tab.add{name="bt_hs_cancel_input", type="sprite-button", sprite = "utility/close_black", style = "shortcut_bar_button_small"}
|
|
|
|
if global.sub_inputs[input] then
|
|
for i=1, #global.sub_inputs[input] do
|
|
frame.add{type="radiobutton",name=global.sub_inputs[input][i], caption={global.sub_inputs[input][i]}, state=iif(global.sub_inputs[input][i]==input, true, false) }.style.font = "default-bold"
|
|
end
|
|
end
|
|
|
|
if in_list(pk_signal_list, input) then
|
|
local ico = add_gui(frame, {type="choose-elem-button", name='hs_choose_input', elem_type="signal"} ) --elem_type ='item' item='steel-plate' elem_value
|
|
ico.elem_value= Sign_Data.input_signal
|
|
|
|
elseif (in_list(pk_item_list, input)) then
|
|
local ico = add_gui(frame, {type="choose-elem-button", name='hs_choose_item', elem_type="item"} ) --elem_type ='item' item='steel-plate' elem_value
|
|
ico.elem_value= Sign_Data.input_item
|
|
|
|
elseif (in_list(pk_entity_list, input)) then
|
|
local ico = add_gui(frame, {type="choose-elem-button", name='hs_choose_entity', elem_type="entity", elem_filters={{type = "entity", filter = "entity-with-health"}} } ) --elem_type ='item' item='steel-plate' elem_value
|
|
ico.elem_value= Sign_Data.input_entity
|
|
|
|
elseif (in_list(pk_fluid_list,input)) then
|
|
local ico = add_gui(frame, {type="choose-elem-button", name='hs_choose_fluid', elem_type="fluid"} ) --elem_type ='item' item='steel-plate' elem_value
|
|
ico.elem_value= Sign_Data.input_fluid
|
|
-- else
|
|
-- tab.add{type="label"}
|
|
end
|
|
|
|
if sub_options[input] then
|
|
local t=sub_options[input].type
|
|
if t=="drop-down" then add_gui(frame, {type=t, name=t,items=sub_options[input].options, selected_index = Sign_Data.sub_option or 1}) end
|
|
end
|
|
|
|
--add_gui(frame, {type="sprite-button", sprite = "utility/close_white", name='bt_back_input', style = "back_button"})
|
|
|
|
end
|
|
-- frame.style.horizontally_stretchable=false
|
|
end
|
|
|
|
|
|
local function on_gui_checked_state_changed(event)
|
|
local gui = event.element
|
|
if gui.get_mod()=='holographic_signs' then
|
|
local player = game.players[event.player_index]
|
|
--if in_list(global.inputs,gui.name) or in_list(global.sub_inputs[1],gui.name) or in_list(global.sub_inputs[2],gui.name) then
|
|
if gui.parent.name=='hs_inputs' then
|
|
local Sign_Data = global.players[player.name]
|
|
Sign_Data.input = gui.name
|
|
add_inputs(gui.parent.parent,player)
|
|
end
|
|
end
|
|
end
|
|
script.on_event(defines.events.on_gui_checked_state_changed, on_gui_checked_state_changed)
|
|
|
|
|
|
|
|
function add_textbox(gui,player)
|
|
local Sign_Data = global.players[player.name]
|
|
local textbox = gui.add{type="text-box", name="hs_textbox",text=Sign_Data.textbox}
|
|
textbox.style.width=290
|
|
textbox.style.height=100 --300
|
|
textbox.style.horizontally_stretchable=false
|
|
textbox.word_wrap=true
|
|
end
|
|
|
|
|
|
|
|
function add_holo_sign(gui,player,k_shift)
|
|
local Sign_Data = global.players[player.name]
|
|
local entity = Sign_Data.entity
|
|
|
|
if entity and entity.valid then
|
|
local text = gui.tab1.hs_text_field.text
|
|
local icon = gui.tab1.hs_icon_bt.elem_value
|
|
local add_tag = gui.tab_cb.hs_cb_add_map.state
|
|
local plain_text = gui.tab_cb.hs_cb_plain_text.state
|
|
local big_hologram_render = Sign_Data.big_hologram_render
|
|
if big_hologram_render then
|
|
if big_hologram_render and rendering.is_valid(big_hologram_render) then rendering.destroy(big_hologram_render) end
|
|
Sign_Data.big_hologram_render = nil
|
|
end
|
|
if gui.hs_textbox then
|
|
Sign_Data.show_textbox = true
|
|
Sign_Data.textbox = gui.hs_textbox.text
|
|
else
|
|
Sign_Data.show_textbox = false
|
|
end
|
|
if gui.hs_inputs then
|
|
if in_list(pk_signal_list, Sign_Data.input) then
|
|
Sign_Data.input_signal = gui.hs_inputs.hs_choose_input.elem_value
|
|
--if k_shift then icon = Sign_Data.input_signal game.print (icon) end
|
|
elseif in_list(pk_item_list, Sign_Data.input) then
|
|
Sign_Data.input_item = gui.hs_inputs.hs_choose_item.elem_value
|
|
--if k_shift then icon = Sign_Data.input_item game.print (icon) end
|
|
elseif in_list(pk_fluid_list, Sign_Data.input) then
|
|
Sign_Data.input_fluid = gui.hs_inputs.hs_choose_fluid.elem_value
|
|
--if k_shift then icon = Sign_Data.input_fluid game.print (icon)end
|
|
elseif in_list(pk_entity_list, Sign_Data.input) then
|
|
Sign_Data.input_entity = gui.hs_inputs.hs_choose_entity.elem_value
|
|
--if k_shift then icon = Sign_Data.input_entity game.print (icon)end
|
|
else
|
|
--Sign_Data.input = nil
|
|
end
|
|
|
|
if sub_options[Sign_Data.input] then
|
|
local t = sub_options[Sign_Data.input].type
|
|
local sub_option
|
|
if t=='drop-down' then sub_option = gui.hs_inputs[t].selected_index end
|
|
Sign_Data.sub_option=sub_option
|
|
end
|
|
|
|
|
|
else
|
|
Sign_Data.input = nil
|
|
end
|
|
|
|
Sign_Data.text = text
|
|
Sign_Data.icon = icon
|
|
Sign_Data.add_tag = add_tag
|
|
Sign_Data.plain_text= plain_text
|
|
|
|
Sign_Data.last_user = player.name
|
|
|
|
apply_holo_sign(Sign_Data)
|
|
end
|
|
gui.destroy()
|
|
end
|
|
|
|
|
|
|
|
|
|
local function on_gui_opened(event)
|
|
local player_index = event.player_index
|
|
local player = game.players[player_index]
|
|
if event.entity and event.entity.valid and event.entity.name=='hs_holo_sign' then
|
|
open_gui(player, event.entity)
|
|
else
|
|
local gui = player.gui.screen
|
|
if gui.frame_holo_sign then
|
|
if player.opened ~= gui.frame_holo_sign then gui.frame_holo_sign.destroy() end
|
|
end
|
|
end
|
|
end
|
|
script.on_event(defines.events.on_gui_opened, on_gui_opened)
|
|
|
|
|
|
local function on_gui_closed(event)
|
|
if event.element and event.element.valid and event.element.name == 'frame_holo_sign' then
|
|
event.element.destroy()
|
|
end
|
|
end
|
|
script.on_event(defines.events.on_gui_closed, on_gui_closed)
|
|
|
|
|
|
|
|
function apply_holo_sign(Sign_Data)
|
|
local function get_precision_index(opt)
|
|
local def = {
|
|
defines.flow_precision_index.five_seconds,
|
|
defines.flow_precision_index.one_minute,
|
|
defines.flow_precision_index.ten_minutes,
|
|
defines.flow_precision_index.one_hour,
|
|
defines.flow_precision_index.fifty_hours,
|
|
defines.flow_precision_index.one_thousand_hours
|
|
}
|
|
return def[opt] or defines.flow_precision_index.one_minute
|
|
end
|
|
|
|
local entity = Sign_Data.entity
|
|
|
|
if entity and entity.valid then
|
|
local force = entity.force
|
|
local text = Sign_Data.text or ''
|
|
local icon = Sign_Data.icon
|
|
local add_tag = Sign_Data.add_tag
|
|
local input = Sign_Data.input
|
|
local color = Sign_Data.text_color or {r=255,g=255,b=255}
|
|
local plain_text = Sign_Data.plain_text
|
|
local the_plain_text = Sign_Data.the_plain_text
|
|
local animation = Sign_Data.animation
|
|
local big_hologram_render = Sign_Data.big_hologram_render
|
|
|
|
local state = Sign_Data.state or 'right' -- left=off right=on
|
|
|
|
local is_it_on = true
|
|
|
|
if global.all_turned_off==true or state=='left' then is_it_on = false end
|
|
|
|
-- Manage INPUTS
|
|
local ipt, holo_img,img_scale
|
|
if is_it_on then
|
|
if input then
|
|
if input=='hs_signal' then
|
|
local signal = Sign_Data.input_signal
|
|
if signal and signal.type and signal.name then
|
|
ipt = format_number (entity.get_merged_signal(signal)) --get signal
|
|
end
|
|
elseif input=='hs_hologram_image' then
|
|
local signal = Sign_Data.input_signal
|
|
if signal and signal.type and signal.name then
|
|
img_scale = 2
|
|
if signal.type=='virtual' then
|
|
holo_img ='virtual-signal/'..signal.name
|
|
|
|
else
|
|
holo_img =signal.type .. '/'..signal.name
|
|
end
|
|
end
|
|
elseif input=='hs_logistic' then
|
|
local item = Sign_Data.input_item
|
|
local logistic_network = entity.surface.find_logistic_network_by_position(entity.position, force)
|
|
if item and logistic_network then
|
|
ipt = logistic_network.get_item_count(item) --get signal
|
|
end
|
|
|
|
elseif in_list({'hs_production','hs_consumption','hs_item_launched'},input) then
|
|
local item = Sign_Data.input_item
|
|
if item then
|
|
local count
|
|
if input=='hs_production' then count = force.item_production_statistics.get_input_count(item)
|
|
elseif input=='hs_consumption' then count = force.item_production_statistics.get_output_count(item)
|
|
elseif input=='hs_item_launched' then count = force.get_item_launched(item)
|
|
end
|
|
ipt = format_number(count)
|
|
end
|
|
|
|
elseif input=='hs_production_ratio' then
|
|
local item = Sign_Data.input_item
|
|
if item then
|
|
local sub_option = Sign_Data.sub_option
|
|
sub_option = get_precision_index(sub_option)
|
|
local count = force.item_production_statistics.get_flow_count{name=item,input=true, precision_index=sub_option}
|
|
local cons = force.item_production_statistics.get_flow_count{name=item,input=false, precision_index=sub_option}
|
|
local ratio = 0
|
|
if cons>0 then ratio=count/cons end
|
|
ipt = math.ceil(count) .. '/' .. math.ceil(cons) .. iif(count>=cons,'[img=virtual-signal/signal-green]','[img=virtual-signal/signal-red]').. d_format_number(ratio, "%.1f")
|
|
end
|
|
|
|
elseif input=='hs_production_ratio_f' then
|
|
local fluid = Sign_Data.input_fluid
|
|
if fluid then
|
|
local sub_option = Sign_Data.sub_option
|
|
sub_option = get_precision_index(sub_option)
|
|
local count = force.fluid_production_statistics.get_flow_count{name=fluid,input=true, precision_index=sub_option}
|
|
local cons = force.fluid_production_statistics.get_flow_count{name=fluid,input=false, precision_index=sub_option}
|
|
local ratio = 0
|
|
if cons>0 then ratio=count/cons end
|
|
ipt = my_format_number(math.ceil(count) , 1000000).. '/' .. my_format_number(math.ceil(cons), 1000000) .. iif(count>=cons,'[img=virtual-signal/signal-green]','[img=virtual-signal/signal-red]').. d_format_number(ratio, "%.1f")
|
|
end
|
|
|
|
|
|
elseif input=='hs_production_f' or input=='hs_consumption_f' then
|
|
local fluid = Sign_Data.input_fluid
|
|
if fluid then
|
|
local count
|
|
if input=='hs_production_f' then count = force.fluid_production_statistics.get_input_count(fluid)
|
|
elseif input=='hs_consumption_f' then count = force.fluid_production_statistics.get_output_count(fluid)
|
|
end
|
|
ipt = my_format_number(math.floor(count), 1000000)
|
|
end
|
|
|
|
elseif input=='hs_production_p' or input=='hs_consumption_p' then
|
|
local pole = entity.surface.find_entities_filtered{type='electric-pole', force=force, position=entity.position, radius=2, limit=1}
|
|
if pole[1] then
|
|
local NS = pole[1].electric_network_statistics
|
|
local cons=0
|
|
local prod=0
|
|
-- prod
|
|
for n,v in pairs (NS.output_counts) do
|
|
prod = prod + NS.get_flow_count{name=n,input=false, precision_index=defines.flow_precision_index.five_seconds, sample=1}
|
|
end
|
|
-- cons
|
|
for n,v in pairs (NS.input_counts) do
|
|
cons = cons + NS.get_flow_count{name=n,input=true, precision_index=defines.flow_precision_index.five_seconds, sample=1}
|
|
end
|
|
|
|
prod=prod*60/1000000
|
|
cons=cons*60/1000000
|
|
|
|
if input=='hs_production_p' then ipt =d_format_number(prod, "%.1f").. " MJ"
|
|
elseif input=='hs_consumption_p' then ipt = d_format_number(cons, "%.1f") .. " MJ"
|
|
end
|
|
end
|
|
|
|
|
|
elseif input=='hs_charge' then
|
|
local ch,t =0,0
|
|
local acc = entity.surface.find_entities_filtered{type='accumulator', force=force}
|
|
for _,a in pairs(acc) do
|
|
ch = ch + a.energy
|
|
t = t + a.electric_buffer_size
|
|
end
|
|
ipt = d_format_number(ch/1000000, "%.1f") .. " / " .. d_format_number(t/1000000, "%.1f") .. " MJ"
|
|
|
|
|
|
elseif input=='hs_research_progress' then
|
|
if force.research_progress then ipt = d_format_number(force.research_progress*100, "%.1f") end --.. '%'
|
|
elseif input=='hs_rockets_launched' then
|
|
ipt = format_number(force.rockets_launched )
|
|
elseif input=='hs_connected_players' then
|
|
ipt = #force.connected_players
|
|
elseif input=='hs_player_casualties' then
|
|
ipt = force.kill_count_statistics.get_output_count('character')
|
|
elseif input=='hs_enemy_evolution' then
|
|
ipt = format_evolution(game.forces.enemy) -- .. '%'
|
|
elseif input=='hs_kill_count' then
|
|
local killed = Sign_Data.input_entity
|
|
if killed then ipt = format_number(force.kill_count_statistics.get_input_count(killed)) end
|
|
elseif input=='hs_wind_speed' then
|
|
ipt = d_format_number(entity.surface.wind_speed*100, "%.1f") -- 'default 0.02'
|
|
elseif input=='hs_day_time' then
|
|
ipt = getDayTimeString(entity.surface)
|
|
|
|
elseif input=='hs_total_time' then
|
|
ipt = format_time_hour(game.tick)
|
|
elseif input=='hs_time_from_last_death' then
|
|
ipt = format_time_from_tick(global.last_death_tick)
|
|
|
|
elseif input=='hs_research_time_remaining' then
|
|
ipt = get_force_research_time_remaining(force)
|
|
|
|
elseif input=='hs_pollution' then
|
|
ipt = d_format_number(entity.surface.get_pollution(entity.position))
|
|
|
|
--WARP DRIVE MACHINE remote interface
|
|
elseif input=='hs_wdm_warping_in' then
|
|
ipt = remote.call("WDM","get_ship_warp_time",force.name)
|
|
elseif input=='hs_wdm_time_on_planet' then
|
|
ipt = remote.call("WDM","get_ship_planet_time",force.name)
|
|
elseif input=='hs_native_evolution' then
|
|
ipt = remote.call("WDM","get_planet_natives_evolution",force.name)
|
|
elseif input=='hs_planet_image' then
|
|
holo_img = remote.call("WDM","get_planet_image",force.name)
|
|
img_scale = 0.65
|
|
end
|
|
end
|
|
|
|
|
|
local iss, ise
|
|
if ipt then
|
|
iss, ise = string.find(text, '|#|')
|
|
if iss then
|
|
text = string.gsub(text, '|#|', ipt)
|
|
else
|
|
text = text.. ' ' .. ipt
|
|
end
|
|
end
|
|
|
|
end
|
|
|
|
|
|
local pt = text
|
|
if icon and icon.type and icon.name and (not plain_text) then
|
|
pt = '[img=' .. iif(icon.type=='virtual','virtual-signal', icon.type) .. '/' .. icon.name ..']' .. text
|
|
end
|
|
|
|
local destroy_plan_text = false
|
|
clear_speach_bubble(entity)
|
|
|
|
if (pt~='' or holo_img) and is_it_on then
|
|
if pt~='' then
|
|
if plain_text then
|
|
if the_plain_text and rendering.is_valid(the_plain_text) then
|
|
rendering.set_color(the_plain_text, color)
|
|
rendering.set_text(the_plain_text, pt)
|
|
else
|
|
the_plain_text = rendering.draw_text{text=pt, surface=entity.surface, target=entity, color=color,target_offset={-1,-1} }
|
|
Sign_Data.the_plain_text = the_plain_text
|
|
end
|
|
else
|
|
if the_plain_text then destroy_plan_text =true end
|
|
pt = '[color=' .. color.r ..',' .. color.g ..',' .. color.b ..']' .. pt .. '[/color]'
|
|
Entity_Speak(entity,pt)
|
|
end
|
|
end
|
|
|
|
|
|
if holo_img then
|
|
if big_hologram_render and rendering.is_valid(big_hologram_render) then
|
|
if rendering.get_sprite(big_hologram_render) ~= holo_img then rendering.set_sprite(big_hologram_render, holo_img) end
|
|
else
|
|
big_hologram_render = rendering.draw_sprite {
|
|
sprite = holo_img,
|
|
x_scale=img_scale,y_scale=img_scale,
|
|
target = entity,
|
|
target_offset = {0, -2},
|
|
surface = entity.surface}
|
|
Sign_Data.big_hologram_render=big_hologram_render
|
|
end
|
|
end
|
|
|
|
|
|
if global.opt_animation and ((not animation) or (not rendering.is_valid(animation))) then
|
|
if global.animation == 'hs_hologram_animated' then
|
|
animation = rendering.draw_animation {
|
|
animation = 'hs_hologram_animated',
|
|
x_scale=0.07,y_scale=0.35,
|
|
target = entity,
|
|
target_offset = {0, -1.1},
|
|
surface = entity.surface,
|
|
animation_offset = 0}
|
|
else
|
|
animation = rendering.draw_sprite {
|
|
sprite = 'hs_hologram',
|
|
x_scale=0.4,y_scale=0.5,
|
|
target = entity,
|
|
target_offset = {0, -1.1},
|
|
surface = entity.surface}
|
|
end
|
|
Sign_Data.animation = animation
|
|
end
|
|
|
|
else
|
|
if the_plain_text then destroy_plan_text =true end
|
|
if animation and rendering.is_valid(animation) then rendering.destroy(animation) Sign_Data.animation=nil end
|
|
if big_hologram_render and rendering.is_valid(big_hologram_render) then rendering.destroy(big_hologram_render) Sign_Data.big_hologram_render=nil end
|
|
end
|
|
|
|
if destroy_plan_text then
|
|
rendering.destroy(the_plain_text)
|
|
Sign_Data.the_plain_text = nil
|
|
end
|
|
|
|
|
|
-- MAP TAG
|
|
if Sign_Data.maptag and Sign_Data.maptag.valid then Sign_Data.maptag.destroy() end
|
|
if add_tag and is_it_on then
|
|
local ico
|
|
if icon and icon.type and icon.name then ico=icon end
|
|
if ico or (text~='') then
|
|
local tag = {icon=ico,text=text,position=entity.position}
|
|
local thetag = force.add_chart_tag(entity.surface,tag)
|
|
Sign_Data.maptag = thetag
|
|
end
|
|
end
|
|
|
|
local UN = entity.unit_number
|
|
global.signs[UN]=Sign_Data
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
function update_force_research_durations(force, current_research)
|
|
local force_table = global.force_research[force.name]
|
|
local current_progress = force.research_progress
|
|
local research_time = current_research.research_unit_energy * get_research_unit_count(current_research)
|
|
|
|
local last_research_progress = force_table.last_research_progress or 0
|
|
local last_research_progress_tick = force_table.last_research_progress_tick or 0
|
|
local progress_delta = current_progress - last_research_progress
|
|
local tick_delta = game.tick - last_research_progress_tick
|
|
|
|
local research_speed = (progress_delta * research_time) / tick_delta
|
|
|
|
force_table.last_research_progress = current_progress
|
|
force_table.last_research_progress_tick = game.tick
|
|
force_table.research_speed = research_speed
|
|
|
|
local duration_text = "[img=infinity]"
|
|
if research_speed > 0 then
|
|
local level = current_research.level
|
|
local progress = get_research_progress(current_research, level)
|
|
local duration = (1 - progress)
|
|
* get_research_unit_count(current_research, level)
|
|
* current_research.research_unit_energy
|
|
/ research_speed
|
|
duration_text = format_t(duration)
|
|
end
|
|
force_table.duration_text = duration_text
|
|
end
|
|
|
|
|
|
|
|
function get_force_research_time_remaining(force)
|
|
if not global.force_research[force.name] then global.force_research[force.name] = {} end
|
|
|
|
local last_check = global.force_research[force.name].last_research_progress_tick or 0
|
|
if game.tick - last_check > 60 then
|
|
local current_research = force.current_research
|
|
if current_research then
|
|
update_force_research_durations(force, current_research)
|
|
else
|
|
global.force_research[force.name].duration_text = "[img=infinity]"
|
|
end
|
|
end
|
|
return global.force_research[force.name].duration_text
|
|
end
|
|
|
|
|
|
function Copy_Sign_Data(Entity, Sign_Data)
|
|
Sign_Data.entity = Entity
|
|
Sign_Data.maptag = nil
|
|
Sign_Data.animation = nil
|
|
Sign_Data.the_plain_text = nil
|
|
Sign_Data.big_hologram_render=nil
|
|
local NUN = Entity.unit_number
|
|
if global.signs[NUN] then
|
|
if global.signs[NUN].the_plain_text then
|
|
rendering.destroy(global.signs[NUN].the_plain_text)
|
|
global.signs[NUN].the_plain_text=nil
|
|
end
|
|
if global.signs[NUN].animation then
|
|
rendering.destroy(global.signs[NUN].animation)
|
|
global.signs[NUN].animation=nil
|
|
end
|
|
if global.signs[NUN].big_hologram_render then
|
|
rendering.destroy(global.signs[NUN].big_hologram_render)
|
|
global.signs[NUN].big_hologram_render=nil
|
|
end
|
|
|
|
|
|
if global.signs[NUN].maptag and global.signs[NUN].maptag.valid then global.signs[NUN].maptag.destroy() end
|
|
end
|
|
global.signs[NUN] = Sign_Data
|
|
apply_holo_sign(Sign_Data)
|
|
end
|
|
|
|
|
|
function on_entity_cloned(event)
|
|
local new = event.destination
|
|
local old = event.source
|
|
if new.name=='hs_holo_sign' and old.name=='hs_holo_sign' then
|
|
local UN = old.unit_number
|
|
if global.signs[UN] then
|
|
local Sign_Data = table.deepcopy(global.signs[UN])
|
|
Copy_Sign_Data(new, Sign_Data)
|
|
end
|
|
end
|
|
end
|
|
script.on_event(defines.events.on_entity_cloned, on_entity_cloned, {{filter = "name", name = 'hs_holo_sign'}})
|
|
script.on_event(defines.events.on_entity_settings_pasted, on_entity_cloned)
|
|
|
|
|
|
|
|
function on_player_setup_blueprint(event)
|
|
local player = game.get_player(event.player_index)
|
|
if not (player and player.valid) then return end
|
|
|
|
local item = player.cursor_stack
|
|
if not (item and item.valid_for_read) then
|
|
item = player.blueprint_to_setup
|
|
if not (item and item.valid_for_read) then return end
|
|
end
|
|
local count = item.get_blueprint_entity_count()
|
|
if count == 0 then return end
|
|
|
|
for index, entity in pairs(event.mapping.get()) do
|
|
if entity.valid and entity.name == "hs_holo_sign" then
|
|
local UN = entity.unit_number
|
|
if global.signs[UN] then
|
|
local Sign_Data = table.deepcopy(global.signs[UN])
|
|
if index <= count then
|
|
item.set_blueprint_entity_tag(index, "Sign_Data", Sign_Data)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
script.on_event(defines.events.on_player_setup_blueprint, on_player_setup_blueprint)
|
|
|
|
|
|
function restore_data_from_tags(entity, tags)
|
|
local Sign_Data = tags.Sign_Data
|
|
if not Sign_Data then return end
|
|
Copy_Sign_Data(entity, Sign_Data)
|
|
end
|
|
|
|
local ghost_revived_event = function(event)
|
|
local entity = event.created_entity or event.entity
|
|
if not (entity and entity.valid) then return end
|
|
if entity.name ~= "hs_holo_sign" then return end
|
|
|
|
local tags = event.tags
|
|
if not tags then return end
|
|
|
|
restore_data_from_tags(entity, tags)
|
|
end
|
|
script.on_event(defines.events.on_robot_built_entity, ghost_revived_event)
|
|
script.on_event(defines.events.script_raised_revive, ghost_revived_event)
|
|
|
|
|
|
function on_post_entity_died(event)
|
|
local UN = event.unit_number
|
|
if not UN then return end
|
|
if global.signs[UN] then
|
|
local Sign_Data = table.deepcopy(global.signs[UN])
|
|
if not Sign_Data then return end
|
|
local ghost = event.ghost
|
|
if not (ghost and ghost.valid) then return end
|
|
local tags = ghost.tags or {}
|
|
tags.Sign_Data = Sign_Data
|
|
ghost.tags = tags
|
|
end
|
|
end
|
|
script.on_event(defines.events.on_post_entity_died, on_post_entity_died)
|
|
|
|
script.on_event(defines.events.on_pre_player_died, function(event)
|
|
local player = game.players[event.player_index]
|
|
global.last_death_tick = game.tick
|
|
end)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
commands.add_command('hologram-turn-on', 'Turn ON all holograms', function(event)
|
|
local player = game.players[event.player_index]
|
|
if player.admin then
|
|
global.all_turned_off = false
|
|
UpdateAll()
|
|
end
|
|
end)
|
|
commands.add_command('hologram-turn-off', 'Turn OFF all holograms', function(event)
|
|
local player = game.players[event.player_index]
|
|
if player.admin then
|
|
global.all_turned_off = true
|
|
UpdateAll()
|
|
end
|
|
end)
|
|
|
|
|
|
function UpdateAll()
|
|
for UN, Sign_Data in pairs (global.signs) do
|
|
local entity = Sign_Data.entity
|
|
if entity and entity.valid then apply_holo_sign(Sign_Data)
|
|
else global.signs[UN]=nil end
|
|
end
|
|
end
|
|
|
|
|
|
script.on_nth_tick(60*2, function (event)
|
|
for UN, Sign_Data in pairs (global.signs) do
|
|
local entity = Sign_Data.entity
|
|
if entity and entity.valid then
|
|
local green = entity.get_merged_signal({type="virtual",name='signal-green'})==1
|
|
local red = entity.get_merged_signal({type="virtual",name='signal-red'})==1
|
|
if green then Sign_Data.state='right' end
|
|
if red then Sign_Data.state='left' end
|
|
if Sign_Data.input or green or red then apply_holo_sign(Sign_Data) end
|
|
else
|
|
global.signs[UN]=nil
|
|
end
|
|
end
|
|
end)
|
|
|
|
|
|
|
|
--------------------------------------------------------------------------------------
|
|
|
|
-- INTERFACE
|
|
|
|
--------------------------------------------------------------------------------------
|
|
local interface = {}
|
|
function interface.refresh_all()
|
|
UpdateAll()
|
|
end
|
|
remote.add_interface( "holographic_signs", interface )
|
|
|
|
|