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