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