z_mirror/Krastorio2
git clone https://git.raiguard.me/z_mirror/Krastorio2
21723abc
discrete-steel-pipes
1local flib_gui =require ( "__flib__.gui" ) 2 3local util =require ( "scripts.util" ) 4 5--- @type table<string, {color: Color?, suffix: string, text: string} 6local mode_data ={ 7normal ={ suffix ="" , text ="normal" } , 8construction ={ color ={ r =0.5 , g =1 , b =0.4 } , suffix ="-construction-mode" , text ="construction" } , 9logistic ={ color ={ r =1 , g =0.5 , b =0.25 } , suffix ="-logistic-mode" , text ="logistic" } , 10} 11 12local next_roboport_mode ={ 13[ "" ] ="construction" , 14[ "-construction-mode" ] ="logistic" , 15[ "-logistic-mode" ] ="normal" , 16} 17 18--- @param player LuaPlayer 19--- @param entity LuaEntity 20local function update_gui ( player , entity ) 21local player_gui =storage . roboport_guis [ player . index ] 22if not player_gui or not player_gui . valid then 23return 24end 25local mode =string . match ( entity . name , "^.*%-(%w*)%-mode" ) or "normal" 26 27for _ , button in pairs ( player_gui . inner_frame . children ) do 28if button . name == mode then 29button . state =true 30else 31button . state =false 32end 33end 34end 35 36--- @param entity LuaEntity 37--- @param player LuaPlayer 38--- @param to_mode string? 39local function change_mode ( entity , player , to_mode ) 40local matched , _ , base_name , suffix =string . find ( entity . name , "^(.-)(%-%w-%-mode)$" ) 41if not matched then 42base_name =entity . name 43suffix ="" 44end 45 46local new_mode_data 47if to_mode then 48new_mode_data =mode_data [ to_mode ] 49else 50new_mode_data =mode_data [ next_roboport_mode [ suffix ]] 51end 52 53local new_name =base_name .. new_mode_data . suffix 54 55if not prototypes . entity [ new_name ] then 56util . flying_text_with_sound ( player , { "message.kr-roboport-modes-not-supported" } , { position =entity . position } ) 57return 58end 59 60local energy =entity . energy 61local health =entity . health 62 63-- Find all players that have this roboport open 64-- This must be done before the roboport is swapped 65local guis_to_update ={} 66for player_index in pairs ( storage . roboport_guis ) do 67local gui_player =game . get_player ( player_index ) 68if gui_player and gui_player . opened_gui_type == defines . gui_type . entity then 69local opened =gui_player . opened 70if opened and opened == entity then 71table . insert ( guis_to_update , gui_player ) 72end 73end 74end 75 76local new_entity =entity . surface . create_entity ( { 77name =new_name , 78position =entity . position , 79force =entity . force , 80direction =entity . direction , 81fast_replace =true , 82raise_built =true , 83spill =false , 84create_build_effect_smoke =false , 85} ) 86 87if not new_entity then 88return 89end 90new_entity . energy =energy 91new_entity . health =health 92new_entity . last_user =player 93 94util . entity_flying_text ( new_entity , { "message.kr-" .. new_mode_data . text .. "-mode" } , new_mode_data . color ) 95game . play_sound ( { 96path ="kr-welding" , 97position =new_entity . position , 98volume_modifier =1.0 , 99} ) 100new_entity . surface . create_particle ( { 101name ="kr-welding-particle" , 102position ={ new_entity . position . x , new_entity . position . y + 1 } , 103movement ={ 0.0 , - 0.05 } , 104height =1.0 , 105vertical_speed =0.015 , 106frame_speed =1 , 107} ) 108 109-- Swapping the entity will close any open GUIs, so we must re-open them. 110for _ , gui_player in pairs ( guis_to_update ) do 111gui_player . opened =new_entity 112update_gui ( gui_player , new_entity ) 113end 114end 115 116--- @param e EventData.on_gui_checked_state_changed 117local function on_mode_radio_button_checked ( e ) 118local player =game . get_player ( e . player_index ) 119if not player or player . opened_gui_type ~= defines . gui_type . entity then 120return 121end 122local entity =player . opened --[[@as LuaEntity]] 123if not entity . valid or entity . type ~= "roboport" then 124return 125end 126change_mode ( entity , player , e . element . name ) 127end 128 129--- @param mode string 130local function radio_button ( mode ) 131return { 132type ="radiobutton" , 133name =mode , 134caption ={ "message.kr-" .. mode .. "-mode" } , 135state =false , 136handler ={ [ defines . events . on_gui_checked_state_changed ] =on_mode_radio_button_checked } , 137} 138end 139 140--- @param player_index uint 141local function destroy_gui ( player_index ) 142local player_gui =storage . roboport_guis [ player_index ] 143if not player_gui then 144return 145end 146if player_gui . valid then 147player_gui . destroy () 148end 149storage . roboport_guis [ player_index ] =nil 150end 151 152--- @param player LuaPlayer 153local function refresh_gui ( player ) 154destroy_gui ( player . index ) 155 156_ , storage . roboport_guis [ player . index ] =flib_gui . add ( player . gui . relative , { 157type ="frame" , 158name ="kr_roboport_mode_window" , 159caption ={ "gui.kr-change-mode" } , 160anchor ={ 161gui =defines . relative_gui_type . roboport_gui , 162position =defines . relative_gui_position . right , 163names =storage . roboport_has_variants_gui , 164} , 165{ 166type ="frame" , 167name ="inner_frame" , 168style ="inside_shallow_frame_with_padding" , 169direction ="vertical" , 170radio_button ( "normal" ), 171radio_button ( "construction" ), 172radio_button ( "logistic" ), 173} , 174} ) 175end 176 177local function find_variants () 178-- Find all compatible roboports 179local has_variants_gui ={} 180for _ , entity in pairs ( prototypes . get_entity_filtered ( { { filter ="type" , type ="roboport" } } )) do 181local matched , _ , base_name =string . find ( entity . name , "^(.-)%-%w*%-mode" ) 182if matched then 183has_variants_gui [ base_name ] =true 184has_variants_gui [ entity . name ] =true 185end 186end 187 188-- Convert to a format usable by GuiAnchor 189local output ={} 190local i =0 191for entity in pairs ( has_variants_gui ) do 192i =i + 1 193output [ i ] =entity 194end 195 196storage . roboport_has_variants_gui =output 197end 198 199--- @param e EventData.on_gui_opened 200local function on_gui_opened ( e ) 201local entity =e . entity 202if not entity or not entity . valid then 203return 204end 205local player =game . get_player ( e . player_index ) 206if not player then 207return 208end 209if entity . type == "roboport" then 210update_gui ( player , entity ) 211end 212end 213 214--- @param e EventData.on_player_created 215local function on_player_created ( e ) 216local player =game . get_player ( e . player_index ) 217if player then 218refresh_gui ( player ) 219end 220end 221 222--- @param e EventData.on_player_removed 223local function on_player_removed ( e ) 224destroy_gui ( e . player_index ) 225end 226 227--- @param e EventData.CustomInputEvent 228local function on_change_roboport_mode_hotkey ( e ) 229local player =game . get_player ( e . player_index ) 230if not player then 231return 232end 233local selected =player . selected 234if selected and selected . valid and selected . type == "roboport" then 235change_mode ( selected , player ) 236end 237end 238 239local function on_configuration_changed () 240find_variants () 241for _ , player in pairs ( game . players ) do 242refresh_gui ( player ) 243end 244end 245 246local function on_init () 247--- @type table<uint, LuaGuiElement> 248storage . roboport_guis ={} 249on_configuration_changed () 250end 251 252local roboport ={} 253 254roboport . on_init =on_init 255roboport . on_configuration_changed =on_configuration_changed 256 257roboport . events ={ 258[ defines . events . on_gui_opened ] =on_gui_opened , 259[ defines . events . on_player_created ] =on_player_created , 260[ defines . events . on_player_removed ] =on_player_removed , 261[ "kr-change-roboport-state" ] =on_change_roboport_mode_hotkey , 262} 263 264flib_gui . add_handlers ( { roboport_on_mode_radio_button_checked =on_mode_radio_button_checked } ) 265 266return roboport