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