z_mirror/EditorExtensions
git clone https://git.raiguard.me/z_mirror/EditorExtensions
b568b72
trunk
1local table =require ( "__flib__.table" ) 2 3--- @class ItemFilters table<integer, ItemFilter?> 4-- 5--- @class InventorySyncData 6--- @field filters ItemFilters 7--- @field hand_location uint? 8--- @field inventory LuaInventory 9 10--- @param player LuaPlayer 11local function pre_sync ( player ) 12if player . controller_type == defines . controllers . remote then 13player . exit_remote_view () 14end 15local prefix =table . find ( defines . controllers , player . controller_type ) .. "_" 16local hand_location =player . hand_location or {} 17--- @type table<string, InventorySyncData> 18local sync_tables ={} 19for _ , name in ipairs ( { "cursor" , "main" , "guns" , "armor" , "ammo" } ) do 20--- @type ItemFilters 21local sync_filters ={} 22local sync_inventory 23local inventory_def =defines . inventory [ prefix .. name ] 24if name == "cursor" then 25sync_inventory =game . create_inventory ( 1 ) 26local cursor_stack =player . cursor_stack 27if cursor_stack and cursor_stack . valid_for_read then 28sync_inventory [ 1 ]. transfer_stack ( cursor_stack ) 29end 30elseif inventory_def then 31local source_inventory =player . get_inventory ( inventory_def ) --[[@as LuaInventory]] 32local get_filter =source_inventory . get_filter 33local set_filter =source_inventory . set_filter 34local supports_filters =source_inventory . supports_filters () 35local source_inventory_len =# source_inventory --[[@as uint16]] 36sync_inventory =game . create_inventory ( source_inventory_len ) 37for i =1 , source_inventory_len do 38--- @cast i uint 39sync_inventory [ i ]. transfer_stack ( source_inventory [ i ]) 40if supports_filters then 41sync_filters [ i ] =get_filter ( i ) 42set_filter ( i , nil ) 43end 44end 45end 46if sync_inventory then 47--- @type InventorySyncData 48sync_tables [ name ] ={ 49filters =sync_filters , 50hand_location =hand_location . inventory == inventory_def and hand_location . slot or nil , 51inventory =sync_inventory , 52} 53end 54end 55storage . inventory_sync [ player . index ] =sync_tables 56end 57 58--- @param player LuaPlayer 59local function post_sync ( player ) 60-- determine prefix based on controller type 61local prefix =table . find ( defines . controllers , player . controller_type ) .. "_" 62-- iterate all inventories 63local sync_data =storage . inventory_sync [ player . index ] 64if not sync_data then 65return 66end 67storage . inventory_sync [ player . index ] =nil 68-- Cursor first to allow setting the hand, then armor to correct the inventory size 69for _ , name in ipairs ( { "cursor" , "armor" , "main" , "guns" , "ammo" } ) do 70local sync_table =sync_data [ name ] 71-- God mode doesn't have every inventory 72if not sync_table then 73goto continue 74end 75local sync_filters =sync_table . filters 76local sync_inventory =sync_table . inventory 77if name == "cursor" and player . cursor_stack then 78player . cursor_stack . transfer_stack ( sync_inventory [ 1 ]) 79else 80local inventory_def =defines . inventory [ prefix .. name ] 81if not inventory_def then 82goto continue 83end 84local destination_inventory =player . get_inventory ( inventory_def ) --[[@as LuaInventory]] 85local set_filter =destination_inventory . set_filter 86local supports_filters =destination_inventory . supports_filters () 87for i =1 , math . min ( # destination_inventory , # sync_inventory ) do 88--- @cast i uint 89if supports_filters then 90set_filter ( i , sync_filters [ i ]) 91end 92destination_inventory [ i ]. clear () 93destination_inventory [ i ]. transfer_stack ( sync_inventory [ i ]) 94end 95local hand_location =sync_table . hand_location 96if hand_location and hand_location <= # destination_inventory then 97player . hand_location ={ inventory =inventory_def , slot =hand_location } 98end 99end 100sync_inventory . destroy () 101:: continue :: 102end 103end 104 105--- @param e EventData.on_pre_player_toggled_map_editor 106local function on_pre_player_toggled_map_editor ( e ) 107local player =game . get_player ( e . player_index ) 108if not player or not player . cheat_mode then 109return 110end 111if not player . mod_settings [ "ee-inventory-sync" ]. value then 112return 113end 114pre_sync ( player ) 115end 116 117--- @param e EventData.on_player_toggled_map_editor 118local function on_player_toggled_map_editor ( e ) 119local player =game . get_player ( e . player_index ) 120if not player or not player . cheat_mode then 121return 122end 123if not player . mod_settings [ "ee-inventory-sync" ]. value then 124return 125end 126post_sync ( player ) 127end 128 129local inventory_sync ={} 130 131inventory_sync . on_init =function () 132--- @type table<uint, table<string, InventorySyncData?>> 133storage . inventory_sync ={} 134end 135 136inventory_sync . events ={ 137[ defines . events . on_pre_player_toggled_map_editor ] =on_pre_player_toggled_map_editor , 138[ defines . events . on_player_toggled_map_editor ] =on_player_toggled_map_editor , 139} 140 141return inventory_sync