z_mirror/Tapeline
git clone https://git.raiguard.me/z_mirror/Tapeline
37bb3aa
color-setting
1local area =require ( "__flib__/area" ) 2local event =require ( "__flib__/event" ) 3local migration =require ( "__flib__/migration" ) 4 5local constants =require ( "__Tapeline__/constants" ) 6local migrations =require ( "__Tapeline__/migrations" ) 7local player_data =require ( "__Tapeline__/player-data" ) 8local tape =require ( "__Tapeline__/tape" ) 9 10--- @param player_table PlayerTable 11local function destroy_last_entity ( player_table ) 12local last_entity =player_table . last_entity 13if last_entity then 14last_entity . destroy () 15player_table . last_entity =nil 16end 17end 18 19--- @param tapes table<number, TapeData> 20--- @param cursor_position MapPosition 21--- @param surface LuaSurface 22local function select_tape ( tapes , cursor_position , surface ) 23local topmost_tape 24local most_recent_update_time =0 25for i , tape_data in ipairs ( tapes ) do 26local TapeArea =area . load ( tape_data . Area ) 27if tape_data . surface == surface and TapeArea : contains_position ( cursor_position ) then 28if tape_data . last_update_tick > most_recent_update_time then 29most_recent_update_time =tape_data . last_update_tick 30topmost_tape =i 31end 32end 33end 34 35return topmost_tape 36end 37 38--- @param player LuaPlayer 39local function holding_tl_tool ( player ) 40local cursor_stack =player . cursor_stack 41return cursor_stack and cursor_stack . valid_for_read and cursor_stack . name == "tl-tool" 42end 43 44--- @param player LuaPlayer 45--- @param player_table PlayerTable 46local function set_cursor_label ( player , player_table ) 47local settings , TapeArea 48if player_table . flags . drawing then 49settings =player_table . tape_settings 50TapeArea =area . load ( player_table . tapes . drawing . Area ) 51elseif player_table . flags . editing then 52local tape_data =player_table . tapes . editing 53settings =tape_data . settings 54TapeArea =area . load ( tape_data . Area ) 55else 56settings =player_table . tape_settings 57end 58 59local cursor_stack =player . cursor_stack 60if cursor_stack and cursor_stack . valid_for_read then 61cursor_stack . label =( 62( TapeArea and ( TapeArea : width () .. "x" .. TapeArea : height () .. " | " ) or "" ) 63.. constants . mode_labels [ settings . mode ] 64.. " mode | " 65.. constants . divisor_labels [ settings . mode ] 66.. " " 67.. settings [ settings . mode .. "_divisor" ] 68) 69end 70end 71 72event . on_init ( function () 73--- @type table<uint, PlayerTable> 74global . players ={} 75 76for _ , player in pairs ( game . players ) do 77player_data . init ( player . index ) 78player_data . refresh ( player , global . players [ player . index ]) 79end 80end ) 81 82event . on_configuration_changed ( function ( e ) 83if migration . on_config_changed ( e , migrations ) then 84for i , player_table in pairs ( global . players ) do 85local player =game . get_player ( i ) --[[@as LuaPlayer]] 86player_data . refresh ( player , player_table ) 87end 88end 89end ) 90 91event . register ( "tl-get-tool" , function ( e ) 92local player =game . get_player ( e . player_index ) --[[@as LuaPlayer]] 93if player . clear_cursor () then 94player . cursor_stack . set_stack ( { name ="tl-tool" , count =100 } ) 95end 96end ) 97 98event . register ( "tl-edit-tape" , function ( e ) 99local player =game . get_player ( e . player_index ) --[[@as LuaPlayer]] 100local player_table =global . players [ e . player_index ] 101 102if holding_tl_tool ( player ) then 103local tapes =player_table . tapes 104local tape_to_edit =select_tape ( tapes , e . cursor_position , player . surface ) 105if tape_to_edit then 106if player_table . flags . editing then 107tape . exit_edit_mode ( player_table ) 108set_cursor_label ( player , player_table ) 109end 110tape . enter_edit_mode ( player , player_table , tape_to_edit ) 111set_cursor_label ( player , player_table ) 112end 113end 114end ) 115 116event . register ( "tl-delete-tape" , function ( e ) 117local player =game . get_player ( e . player_index ) --[[@as LuaPlayer]] 118local player_table =global . players [ e . player_index ] 119 120if holding_tl_tool ( player ) then 121local tapes =player_table . tapes 122local tape_to_delete =select_tape ( tapes , e . cursor_position , player . surface ) 123if tape_to_delete then 124tape . delete ( player_table , tape_to_delete ) 125set_cursor_label ( player , player_table ) 126end 127end 128end ) 129 130event . register ( { 131"tl-increase-divisor" , 132"tl-decrease-divisor" , 133} , function ( e ) 134local player =game . get_player ( e . player_index ) --[[@as LuaPlayer]] 135if holding_tl_tool ( player ) then 136local player_table =global . players [ e . player_index ] 137local settings 138if player_table . flags . editing then 139settings =player_table . tapes . editing . settings 140else 141settings =player_table . tape_settings 142end 143local mode =settings . mode 144local key =mode .. "_divisor" 145local delta =string . find ( e . input_name , "increase" ) and 1 or - 1 146local new_divisor =settings [ key ] + delta 147if new_divisor >= constants . divisor_minimums [ mode ] then 148settings [ key ] =new_divisor 149set_cursor_label ( player , player_table ) 150if player_table . flags . drawing then 151tape . update_draw ( player , player_table ) 152elseif player_table . flags . editing then 153tape . edit_settings ( e . player_index , player_table , mode , new_divisor ) 154end 155else 156player . create_local_flying_text ( { 157text ={ "message.tl-minimal-value-is" , constants . divisor_minimums [ mode ] } , 158create_at_cursor =true , 159} ) 160player . play_sound ( { path ="utility/cannot_build" , volume_modifier =0.75 } ) 161end 162end 163end ) 164 165event . register ( { 166"tl-next-mode" , 167"tl-previous-mode" , 168} , function ( e ) 169local player =game . get_player ( e . player_index ) --[[@as LuaPlayer]] 170if holding_tl_tool ( player ) then 171local player_table =global . players [ e . player_index ] 172local settings 173if player_table . flags . editing then 174settings =player_table . tapes . editing . settings 175else 176settings =player_table . tape_settings 177end 178local new_mode =next ( constants . modes , settings . mode ) 179if not new_mode then 180new_mode =next ( constants . modes ) 181end 182settings . mode =new_mode 183local divisor =settings [ new_mode .. "_divisor" ] 184set_cursor_label ( player , player_table ) 185if player_table . flags . drawing then 186tape . update_draw ( player , player_table ) 187elseif player_table . flags . editing then 188tape . edit_settings ( e . player_index , player_table , new_mode , divisor ) 189end 190end 191end ) 192 193event . register ( "tl-clear-cursor" , function ( e ) 194local player_table =global . players [ e . player_index ] 195if player_table . flags . drawing or player_table . flags . editing then 196local player =game . get_player ( e . player_index ) --[[@as LuaPlayer]] 197player . clear_cursor () 198end 199end ) 200 201event . on_built_entity ( function ( e ) 202local player =game . get_player ( e . player_index ) --[[@as LuaPlayer]] 203local player_table =global . players [ e . player_index ] 204local entity =e . created_entity 205local is_ghost =entity . name == "entity-ghost" 206 207destroy_last_entity ( player_table ) 208 209if is_ghost then 210-- instantly revive the entity if it is a ghost 211local _ , new_entity =entity . silent_revive () 212if not new_entity then 213return 214end 215entity =new_entity 216end 217-- make the entity invincible to prevent attacks 218entity . destructible =false 219player_table . last_entity =entity 220 221-- update tape 222if player_table . flags . drawing then 223tape . update_draw ( player , player_table , entity . position , is_ghost ) 224elseif player_table . flags . editing then 225tape . move ( player , player_table , entity . position , entity . surface ) 226else 227tape . start_draw ( player , player_table , entity . position , entity . surface ) 228end 229 230-- update the cursor 231player . cursor_stack . set_stack ( { name ="tl-tool" , count =100 } ) 232set_cursor_label ( player , player_table ) 233end , { 234{ filter ="name" , name ="tl-dummy-entity" } , 235{ filter ="ghost_name" , name ="tl-dummy-entity" } , 236} ) 237 238event . register ( { 239defines . events . on_player_selected_area , 240defines . events . on_player_alt_selected_area , 241} , function ( e ) 242local player =game . get_player ( e . player_index ) --[[@as LuaPlayer]] 243local player_table =global . players [ e . player_index ] 244if player_table . flags . drawing then 245player_table . flags . drawing =false 246destroy_last_entity ( player_table ) 247tape . complete_draw ( player , player_table , e . name == defines . events . on_player_selected_area ) 248set_cursor_label ( player , player_table ) 249elseif player_table . flags . editing then 250destroy_last_entity ( player_table ) 251tape . complete_move ( player_table ) 252end 253end ) 254 255event . on_player_created ( function ( e ) 256local player =game . get_player ( e . player_index ) --[[@as LuaPlayer]] 257player_data . init ( e . player_index ) 258player_data . refresh ( player , global . players [ e . player_index ]) 259end ) 260 261event . on_player_removed ( function ( e ) 262global . players [ e . player_index ] =nil 263end ) 264 265event . on_player_cursor_stack_changed ( function ( e ) 266local player =game . get_player ( e . player_index ) --[[@as LuaPlayer]] 267local player_table =global . players [ e . player_index ] 268if not player_table then 269return 270end 271local cursor_stack =player . cursor_stack 272local is_empty =not cursor_stack or not cursor_stack . valid_for_read 273if player_table . flags . holding_tool then 274if is_empty or cursor_stack . name ~= "tl-tool" then --- @diagnostic disable-line 275player_table . flags . holding_tool =false 276destroy_last_entity ( player_table ) 277if player_table . flags . editing then 278tape . exit_edit_mode ( player_table ) 279player . cursor_stack . set_stack ( { name ="tl-tool" , count =100 } ) 280set_cursor_label ( player , player_table ) 281else 282if player_table . flags . drawing then 283tape . cancel_draw ( player_table ) 284end 285if player . controller_type == defines . controllers . character and player_table . flags . increased_build_distance then 286player_table . flags . increased_build_distance =false 287local build_distance =player . character_build_distance_bonus 288if build_distance >= 1000000 then 289-- decrease build distance 290player . character_build_distance_bonus =build_distance - 1000000 --[[@as uint]] 291end 292end 293end 294end 295elseif holding_tl_tool ( player ) then 296player_table . flags . holding_tool =true 297player . cursor_stack . set_stack ( { name ="tl-tool" , count =100 } ) 298set_cursor_label ( player , player_table ) 299if player . controller_type == defines . controllers . character and not player_table . flags . increased_build_distance then 300-- increase build distance 301player_table . flags . increased_build_distance =true 302player . character_build_distance_bonus =player . character_build_distance_bonus + 1000000 --[[@as uint]] 303end 304end 305end ) 306 307-- FIXME: Cancel draw when any controller change occurs (requires API addition) 308event . on_pre_player_toggled_map_editor ( function ( e ) 309local player =game . get_player ( e . player_index ) --[[@as LuaPlayer]] 310local player_table =global . players [ e . player_index ] 311if not player_table then 312return 313end 314if player_table . flags . increased_build_distance then 315player_table . flags . increased_build_distance =false 316local build_distance =player . character_build_distance_bonus 317if build_distance >= 1000000 then 318-- decrease build distance 319player . character_build_distance_bonus =build_distance - 1000000 --[[@as uint]] 320end 321end 322end ) 323 324event . on_runtime_mod_setting_changed ( function ( e ) 325local internal =constants . setting_names [ e . setting ] 326if internal then 327local player =game . get_player ( e . player_index ) --[[@as LuaPlayer]] 328local player_table =global . players [ e . player_index ] 329local visual_settings =player_table . visual_settings 330player_data . update_visual_setting ( player , visual_settings , e . setting , internal ) 331for _ , tape_data in ipairs ( player_table . tapes ) do 332tape . update_visual_settings ( tape_data , visual_settings ) 333end 334end 335end )