z_mirror/flib
git clone https://git.raiguard.me/z_mirror/flib
a9f2be7
trunk
1--- Utilities for data stage prototype manipulation. 2--- ```lua 3--- local flib_data_util = require("__flib__.data-util") 4--- ``` 5--- @class flib_data_util 6local flib_data_util ={} 7 8--- Copy a prototype, assigning a new name and minable properties. 9--- @param prototype table 10--- @param new_name string string 11--- @param remove_icon? boolean 12--- @return table 13function flib_data_util . copy_prototype ( prototype , new_name , remove_icon ) 14if not prototype . type or not prototype . name then 15error ( "Invalid prototype: prototypes must have name and type properties." ) 16return --- @diagnostic disable-line 17end 18local p =table . deepcopy ( prototype ) 19p . name =new_name 20if p . minable and p . minable . result then 21p . minable . result =new_name 22end 23if p . place_result then 24p . place_result =new_name 25end 26if p . result then 27p . result =new_name 28end 29if p . results then 30for _ , result in pairs ( p . results ) do 31if result . name == prototype . name then 32result . name =new_name 33end 34end 35end 36if remove_icon then 37p . icon =nil 38p . icon_size =nil 39p . icons =nil 40end 41 42return p 43end 44 45--- Copy prototype.icon/icons to a new fully defined icons array, optionally adding new icon layers. 46--- 47--- Returns `nil` if the prototype's icons are incorrectly or incompletely defined. 48--- @param prototype table 49--- @param new_layers? data.IconData[] 50--- @return data.IconData[]|nil 51function flib_data_util . create_icons ( prototype , new_layers ) 52if new_layers then 53for _ , new_layer in pairs ( new_layers ) do 54if not new_layer . icon or not new_layer . icon_size then 55return nil 56end 57end 58end 59 60if prototype . icons then 61local icons ={} 62for _ , v in pairs ( prototype . icons ) do 63-- Over define as much as possible to minimize weirdness: https://forums.factorio.com/viewtopic.php?f=25&t=81980 64icons [ # icons + 1 ] ={ 65icon =v . icon , 66icon_size =v . icon_size or prototype . icon_size , 67tint =v . tint , 68scale =v . scale , 69shift =v . shift , 70} 71end 72if new_layers then 73for _ , new_layer in pairs ( new_layers ) do 74icons [ # icons + 1 ] =new_layer 75end 76end 77return icons 78elseif prototype . icon then 79local icons ={ 80{ 81icon =prototype . icon , 82icon_size =prototype . icon_size , 83tint ={ r =1 , g =1 , b =1 , a =1 } , 84} , 85} 86if new_layers then 87for _ , new_layer in pairs ( new_layers ) do 88icons [ # icons + 1 ] =new_layer 89end 90end 91return icons 92else 93return nil 94end 95end 96 97local exponent_multipliers ={ 98[ "q" ] =0.000000000000000000000000000001 , 99[ "r" ] =0.000000000000000000000000001 , 100[ "y" ] =0.000000000000000000000001 , 101[ "z" ] =0.000000000000000000001 , 102[ "a" ] =0.000000000000000001 , 103[ "f" ] =0.000000000000001 , 104[ "p" ] =0.000000000001 , 105[ "n" ] =0.000000001 , 106[ "u" ] =0.000001 , -- μ is invalid 107[ "m" ] =0.001 , 108[ "c" ] =0.01 , 109[ "d" ] =0.1 , 110[ "" ] =1 , 111[ "da" ] =10 , 112[ "h" ] =100 , 113[ "k" ] =1000 , 114[ "M" ] =1000000 , 115[ "G" ] =1000000000 , 116[ "T" ] =1000000000000 , 117[ "P" ] =1000000000000000 , 118[ "E" ] =1000000000000000000 , 119[ "Z" ] =1000000000000000000000 , 120[ "Y" ] =1000000000000000000000000 , 121[ "R" ] =1000000000000000000000000000 , 122[ "Q" ] =1000000000000000000000000000000 , 123} 124 125--- Convert an energy string to base unit value + suffix. 126--- 127--- Returns `nil` if `energy_string` is incorrectly formatted. 128--- @param energy_string string 129--- @return number? 130--- @return string? 131function flib_data_util . get_energy_value ( energy_string ) 132if type ( energy_string ) == "string" then 133local v , _ , exp , unit =string . match ( energy_string , "([%-+]?[0-9]*%.?[0-9]+)((%D*)([WJ]))" ) 134local value =tonumber ( v ) 135if value and exp and exponent_multipliers [ exp ] then 136value =value * exponent_multipliers [ exp ] 137return value , unit 138end 139end 140return nil 141end 142 143--- Build a sprite from constituent parts. 144--- @param name? string 145--- @param position? MapPosition 146--- @param filename? string 147--- @param size? Vector 148--- @param mods? table 149--- @return data.Sprite 150function flib_data_util . build_sprite ( name , position , filename , size , mods ) 151--- @type data.Sprite 152local def ={ 153type ="sprite" , 154name =name , 155filename =filename , 156position =position , 157size =size , 158flags ={ "icon" } , 159} 160if mods then 161for k , v in pairs ( mods ) do 162def [ k ] =v 163end 164end 165return def 166end 167 168--- An empty image. This image is 8x8 to facilitate usage with GUI styles. 169flib_data_util . empty_image ="__flib__/graphics/empty.png" 170 171--- A black image, for use with tool backgrounds. This image is 1x1. 172flib_data_util . black_image ="__flib__/graphics/black.png" 173 174--- A desaturated planner image. Tint this sprite to easily add your own planners. 175flib_data_util . planner_base_image ="__flib__/graphics/planner.png" 176 177--- A dark red button tileset. Used for the `flib_tool_button_dark_red` style. 178flib_data_util . dark_red_button_tileset ="__flib__/graphics/dark-red-button.png" 179 180return flib_data_util