z_mirror/Krastorio2
git clone https://git.raiguard.me/z_mirror/Krastorio2
26da534e
santichu95/patch-1
1local flib_position =require ( "__flib__.position" ) 2local flib_table =require ( "__flib__.table" ) 3 4local data_util ={} 5 6--- Overwrites or adds ammo effects for the given technology. 7--- @param tech data.TechnologyPrototype 8--- @param effects data.Modifier[] 9function data_util . update_ammo_effects ( tech , effects ) 10if not tech . effects then 11tech . effects ={} 12end 13 14for _ , updated_effect in pairs ( effects ) do 15local exists =false 16for _ , effect in pairs ( tech . effects ) do 17if 18effect . type == updated_effect . type 19and ( 20( effect . ammo_category ~= nil and effect . ammo_category == updated_effect . ammo_category ) 21or ( effect . turret_id ~= nil and effect . turret_id == updated_effect . turret_id ) 22) 23then 24effect . modifier =updated_effect . modifier 25exists =true 26break 27end 28end 29if not exists then 30table . insert ( 31tech . effects , 32{ type =updated_effect . type , ammo_category =updated_effect . ammo_category , modifier =updated_effect . modifier } 33) 34end 35end 36end 37 38--- @param technology_name data.TechnologyID 39--- @param new_effect data.Modifier 40function data_util . add_effect ( technology_name , new_effect ) 41local technology =data . raw . technology [ technology_name ] 42if not technology then 43error ( "Technology " .. technology_name .. " does not exist." ) 44end 45local effects =technology . effects 46if not effects or not next ( effects ) then 47technology . effects ={ new_effect } 48return 49end 50 51local found =false 52for _ , effect in pairs ( effects ) do 53if effect . type == new_effect . type then 54-- TODO: Update for new effect types. 55if effect . type == "gun-speed" then 56if effect . ammo_category == new_effect . ammo_category and effect . modifier == new_effect . modifier then 57found =true 58break 59end 60elseif effect . type == "ammo-damage" then 61if effect . ammo_category == new_effect . ammo_category and effect . modifier == new_effect . modifier then 62found =true 63break 64end 65elseif effect . type == "give-item" then 66if effect . item == new_effect . item and effect . count == new_effect . count then 67found =true 68break 69end 70elseif effect . type == "turret-attack" then 71if effect . turret_id == new_effect . turret_id and effect . modifier == new_effect . modifier then 72found =true 73break 74end 75elseif effect . type == "unlock-recipe" then 76if effect . recipe == new_effect . recipe then 77found =true 78break 79end 80elseif effect . type == "nothing" then 81if effect . effect_description == new_effect . effect_description then 82found =true 83break 84end 85else 86if effect . modifier == new_effect . modifier then 87found =true 88break 89end 90end 91end 92end 93 94if not found then 95table . insert ( effects , new_effect ) 96end 97end 98 99--- Adds the given recipe as an unlock of the given technology. 100--- @param technology_name data.TechnologyID 101--- @param recipe_name data.RecipeID 102function data_util . add_recipe_unlock ( technology_name , recipe_name ) 103local technology =data . raw . technology [ technology_name ] 104if not technology then 105error ( "Technology " .. technology_name .. " does not exist." ) 106end 107for _ , effect in pairs ( technology . effects ) do 108if effect . type == "unlock-recipe" and effect . recipe == recipe_name then 109error ( "Technology " .. technology_name .. " already unlocks recipe " .. recipe_name .. "." ) 110end 111end 112table . insert ( technology . effects , { type ="unlock-recipe" , recipe =recipe_name } ) 113end 114 115--- Removes the given recipe from the unlocks of the given technology. 116--- @param technology_name data.TechnologyID 117--- @param recipe_name data.RecipeID 118function data_util . remove_recipe_unlock ( technology_name , recipe_name ) 119local technology =data . raw . technology [ technology_name ] 120if not technology then 121error ( "Technology " .. technology_name .. " does not exist." ) 122end 123for i , effect in pairs ( technology . effects ) do 124if effect . type == "unlock-recipe" and effect . recipe == recipe_name then 125table . remove ( technology . effects , i ) 126return 127end 128end 129error ( "Technology " .. technology_name .. " does not unlock recipe " .. recipe_name .. "." ) 130end 131 132--- Adds the given prerequisite to the technology. 133--- @param technology_id data.TechnologyID 134--- @param prerequisite_id data.TechnologyID 135function data_util . add_prerequisite ( technology_id , prerequisite_id ) 136local technology =data . raw . technology [ technology_id ] 137if not technology then 138error ( "Technology " .. technology_id .. " does not exist." ) 139end 140local prerequisite =data . raw . technology [ prerequisite_id ] 141if not prerequisite then 142error ( "Technology prerequisite " .. prerequisite_id .. " does not exist." ) 143end 144if not technology . prerequisites then 145technology . prerequisites ={ prerequisite_id } 146return 147end 148if flib_table . find ( technology . prerequisites , prerequisite_id ) then 149error ( "Technology " .. technology_id .. " already has prerequisite " .. prerequisite_id ) 150end 151table . insert ( technology . prerequisites , prerequisite_id ) 152end 153 154--- Removes the given prerequisite from the technology. 155--- @param technology_id data.TechnologyID 156--- @param prerequisite_id data.TechnologyID 157function data_util . remove_prerequisite ( technology_id , prerequisite_id ) 158local technology =data . raw . technology [ technology_id ] 159if not technology then 160error ( "Technology " .. technology_id .. " does not exist." ) 161end 162local prerequisite =data . raw . technology [ prerequisite_id ] 163if not prerequisite then 164error ( "Technology prerequisite " .. prerequisite_id .. " does not exist." ) 165end 166local i =flib_table . find ( technology . prerequisites or {} , prerequisite_id ) 167if not i then 168error ( "Technology " .. technology_id .. " does not have prerequisite " .. prerequisite_id ) 169end 170table . remove ( technology . prerequisites , i ) 171end 172 173--- Converts one research unit ingredient to another, updating science pack prerequisites if needed. 174--- @param technology_id data.TechnologyID 175--- @param from_id data.ItemID 176--- @param to_id data.ItemID 177function data_util . convert_research_unit_ingredient ( technology_id , from_id , to_id ) 178local technology =data . raw . technology [ technology_id ] 179if not technology then 180error ( "Technology " .. technology_id .. " does not exist." ) 181end 182if not technology . unit or not technology . unit . ingredients then 183error ( "Technology " .. technology_id .. " has no research unit ingredients." ) 184end 185local converted =false 186for _ , ingredient in pairs ( technology . unit . ingredients ) do 187if ingredient [ 1 ] == from_id then 188converted =true 189ingredient [ 1 ] =to_id 190elseif ingredient [ 1 ] == to_id then 191error ( "Technology " .. technology_id .. " already has research unit ingredient " .. to_id ) 192end 193end 194if not converted then 195error ( "Technology " .. technology_id .. " does not have research unit ingredient " .. from_id ) 196end 197-- TODO: Hardcoding the science pack name like this feels bad, but it's what the old code did... 198local from_index =flib_table . find ( technology . prerequisites , from_id ) 199if from_index then 200table . remove ( technology . prerequisites , from_index ) 201end 202local new_tech =data . raw . technology [ to_id ] 203if not new_tech then 204log ( "Aborting due to lack of " .. to_id .. " tech" ) 205return 206end 207if not technology . prerequisites then 208technology . prerequisites ={ to_id } 209return 210end 211if not flib_table . find ( technology . prerequisites , to_id ) then 212log ( "Adding prerequisite " .. to_id ) 213table . insert ( technology . prerequisites , to_id ) 214end 215end 216 217--- Adds the given research ingredient to the technology. 218--- @param technology_id data.TechnologyID 219--- @param ingredient_id data.ItemID 220--- @param ingredient_count uint? Defaults to 1. 221function data_util . add_research_unit_ingredient ( technology_id , ingredient_id , ingredient_count ) 222ingredient_count =ingredient_count or 1 223local technology =data . raw . technology [ technology_id ] 224if not technology then 225error ( "Technology " .. technology_id .. " does not exist." ) 226end 227-- TODO: Make this a base game error. 228if technology . research_trigger then 229error ( "Technology " .. technology_id .. " has a research trigger, so cannot have ingredients." ) 230end 231local unit =technology . unit 232if not unit then 233error ( "Technology " .. technology_id .. " has no research unit." ) 234end 235for _ , ingredient in pairs ( technology . unit . ingredients ) do 236if ingredient [ 1 ] == ingredient_id then 237error ( "Technology " .. technology_id .. " already has research unit ingredient" .. ingredient_id ) 238end 239end 240table . insert ( technology . unit . ingredients , { ingredient_id , ingredient_count } ) 241-- TODO: Automatically add science pack prereq? 242end 243 244--- Removes the given research ingredient from the technology. 245--- @param technology_id data.TechnologyID 246--- @param ingredient_id data.ItemID 247function data_util . remove_research_unit_ingredient ( technology_id , ingredient_id ) 248local technology =data . raw . technology [ technology_id ] 249if not technology then 250error ( "Technology " .. technology_id .. " does not exist." ) 251end 252if not technology . unit then 253error ( "Technology " .. technology_id .. " has no research units." ) 254end 255for i , ingredient in pairs ( technology . unit . ingredients ) do 256if ingredient [ 1 ] == ingredient_id then 257table . remove ( technology . unit . ingredients , i ) 258return 259end 260end 261error ( "Technology " .. technology_id .. " does not have research unit ingredient " .. ingredient_id .. "." ) 262end 263 264--- Returns a technology that unlocks the given recipe. The technology returned will be the one that was added earliest. 265--- @param recipe_id data.RecipeID 266--- @return data.TechnologyPrototype? 267function data_util . get_technology_for_recipe ( recipe_id ) 268for _ , technology in pairs ( data . raw . technology ) do 269for _ , effect in pairs ( technology . effects or {} ) do 270if effect . type == "unlock-recipe" and effect . recipe == recipe_id then 271return technology 272end 273end 274end 275end 276 277--- Converts a furnace prototype into an assembling machine prototype. 278--- @param furnace_name data.EntityID 279--- @return data.AssemblingMachinePrototype 280function data_util . furnace_to_assembler ( furnace_name ) 281local furnace =data . raw . furnace [ furnace_name ] 282if not furnace then 283error ( "Furnace " .. furnace_name .. " does not exist." ) 284end 285 286local assembler =table . deepcopy ( furnace ) --[[@as data.AssemblingMachinePrototype]] 287assembler . type ="assembling-machine" 288assembler . source_inventory_size =nil --- @diagnostic disable-line 289assembler . energy_source . emissions_per_minute ={ pollution =2 } 290assembler . energy_usage ="0.2MW" 291data . raw . furnace [ furnace_name ] =nil 292data : extend ( { assembler } ) 293return assembler 294end 295 296--- Returns a copy of the given prototype's icons in the standard format. 297--- @param prototype k2.PrototypeWithIcons 298--- @return data.IconData[] 299function data_util . get_icons ( prototype ) 300local icons =prototype . icons -- LuaLS isn't inferring the dropped optional unless we assign it to a local first. 301if icons then 302return table . deepcopy ( icons ) 303end 304return { { icon =prototype . icon , icon_size =prototype . icon_size } } 305end 306 307--- Converts the given prototype's icons to the standard format and returns a reference to them. 308--- The game will throw an error if you provide an empty icons array, so if using the function, care must be taken to 309--- ensure that at least one icon layer exists at tne end of loading. 310--- @param prototype k2.PrototypeWithIcons 311--- @return data.IconData[] 312function data_util . standardize_icons ( prototype ) 313if not prototype . icons then 314prototype . icons ={} 315if prototype . icon then 316table . insert ( prototype . icons , { icon =prototype . icon , icon_size =prototype . icon_size } ) 317prototype . icon =nil 318prototype . icon_size =nil 319end 320end 321return prototype . icons 322end 323 324--- Overrides the prototype's icon. 325--- @param prototype k2.PrototypeWithIcons 326--- @param icon data.FileName 327--- @param icon_size double? 328function data_util . set_icon ( prototype , icon , icon_size ) 329assert ( prototype , "Provided prototype was nil." ) 330if prototype . icons then 331prototype . icons =nil 332end 333prototype . icon =icon 334prototype . icon_size =icon_size 335end 336 337--- Overrides the prototype's icons array. 338--- @param prototype k2.PrototypeWithIcons 339--- @param icons data.IconData[] 340function data_util . set_icons ( prototype , icons ) 341assert ( prototype , "Provided prototype was nil." ) 342prototype . icons =icons 343prototype . icon =nil 344prototype . icon_size =nil 345end 346 347--- Fields are analagous to `data.IconData`. 348--- @class k2.IconTransformOptions 349--- @field shift Vector? 350--- @field scale double? 351 352--- Applies the given transformations to each layer in the icons array in-place and returns the array. 353--- @param icons data.IconData[] 354--- @param transforms k2.IconTransformOptions 355--- @return data.IconData[] 356function data_util . transform_icons ( icons , transforms ) 357for _ , icon in pairs ( icons ) do 358if transforms . shift then 359icon . shift =flib_position . add (( icon . shift or { 0 , 0 } ), transforms . shift ) 360end 361if transforms . scale then 362icon . scale =( icon . scale or 1 ) * transforms . scale 363end 364end 365return icons 366end 367 368--- Adds or replaces the recipe's ingredient matching the given name. 369--- @param recipe_name data.RecipeID 370--- @param old_ingredient_name data.FluidID|data.ItemID 371--- @param new_ingredient data.IngredientPrototype 372function data_util . add_or_replace_ingredient ( recipe_name , old_ingredient_name , new_ingredient ) 373local recipe =data . raw . recipe [ recipe_name ] 374if not recipe then 375error ( "Recipe " .. recipe_name .. " does not exist." ) 376end 377if not recipe . ingredients then 378recipe . ingredients ={ new_ingredient } 379return 380end 381for i , ingredient in pairs ( recipe . ingredients ) do 382if ingredient . name == old_ingredient_name then 383recipe . ingredients [ i ] =new_ingredient 384return 385end 386end 387table . insert ( recipe . ingredients , new_ingredient ) 388end 389 390--- Converts the given ingredient to the new ingredient, carrying over other properties. 391--- @param recipe_name data.RecipeID 392--- @param old_ingredient_name data.FluidID|data.ItemID 393--- @param new_ingredient_name data.FluidID|data.ItemID 394function data_util . convert_ingredient ( recipe_name , old_ingredient_name , new_ingredient_name ) 395local recipe =data . raw . recipe [ recipe_name ] 396if not recipe then 397error ( "Recipe " .. recipe_name .. " does not exist." ) 398end 399if not recipe . ingredients then 400error ( "Recipe " .. recipe_name .. " has no ingredients." ) 401return 402end 403for i , ingredient in pairs ( recipe . ingredients ) do 404if ingredient . name == old_ingredient_name then 405ingredient . name =new_ingredient_name 406break 407end 408end 409end 410 411--- Remove the given ingredient from the recipe. 412--- @param recipe_name data.RecipeID 413--- @param ingredient_name data.FluidID|data.ItemID 414function data_util . remove_ingredient ( recipe_name , ingredient_name ) 415local recipe =data . raw . recipe [ recipe_name ] 416if not recipe then 417error ( "Recipe " .. recipe_name .. " does not exist." ) 418end 419if not recipe . ingredients then 420error ( "Recipe " .. recipe_name .. " has no ingredients." ) 421return 422end 423for i , ingredient in pairs ( recipe . ingredients ) do 424if ingredient . name == ingredient_name then 425table . remove ( recipe . ingredients , i ) 426return 427end 428end 429error ( "Recipe " .. recipe_name .. " does not have ingredient " .. ingredient_name .. "." ) 430end 431 432--- Adds or replaces the recipe's product matching the given name. 433--- @param recipe_name data.RecipeID 434--- @param old_product_name data.FluidID|data.ItemID 435--- @param new_product data.IngredientPrototype 436function data_util . add_or_replace_product ( recipe_name , old_product_name , new_product ) 437local recipe =data . raw . recipe [ recipe_name ] 438if not recipe then 439error ( "Recipe " .. recipe_name .. " does not exist." ) 440end 441if not recipe . results then 442recipe . results ={ new_product } 443return 444end 445for i , product in pairs ( recipe . results ) do 446if product . name == old_product_name then 447recipe . results [ i ] =new_product 448return 449end 450end 451table . insert ( recipe . results , new_product ) 452end 453 454--- @param lab_name data.EntityID 455--- @param input_name data.ItemID 456function data_util . remove_lab_input ( lab_name , input_name ) 457local lab =data . raw . lab [ lab_name ] 458assert ( lab , "Lab " .. lab_name .. " does not exist." ) 459local inputs =lab . inputs 460assert ( inputs , "Lab inputs are nil." ) 461for i =1 , # inputs do 462if inputs [ i ] == input_name then 463table . remove ( inputs , i ) 464return 465end 466end 467error ( "Lab " .. lab_name .. " does not contain input " .. input_name .. "." ) 468end 469 470--- @param energy_source data.EnergySource 471--- @param category_name data.FuelCategoryID 472function data_util . add_fuel_category ( energy_source , category_name ) 473if energy_source . type ~= "burner" then 474error ( "Energy source must be a burner to add a fuel category." ) 475end 476if not energy_source . fuel_categories then 477energy_source . fuel_categories ={} 478end 479table . insert ( energy_source . fuel_categories , category_name ) 480end 481 482return data_util