z_mirror/Krastorio2
git clone https://git.raiguard.me/z_mirror/Krastorio2
1e9ba188
trunk
1local flib_bounding_box =require ( "__flib__.bounding-box" ) 2 3--- @alias k2.ResourceRestrictions.Forces table<ForceIndex, k2.ResourceRestrictions.ForceData?> 4 5--- @class k2.ResourceRestrictions.ForceData 6--- @field disabled_mining_drills table<UnitNumber, k2.ResourceRestrictions.DrillData> 7--- @field force LuaForce 8--- @field restricted_resources Set<string> 9 10--- @class k2.ResourceRestrictions.DrillData 11--- @field drill LuaEntity 12--- @field icon LuaRenderObject 13 14--- @return k2.ResourceRestrictions.Forces 15local function get_forces () 16if not storage . resource_restrictions then 17--- @type k2.ResourceRestrictions.Forces 18storage . resource_restrictions ={} 19end 20return storage . resource_restrictions 21end 22 23--- @param force LuaForce 24local function get_force_data ( force ) 25local forces =get_forces () 26local force_index =force . index 27local force_data =forces [ force_index ] 28if not force_data then 29force_data ={ 30disabled_mining_drills ={} , 31force =force , 32restricted_resources ={} , 33} 34forces [ force_index ] =force_data 35end 36return force_data 37end 38 39--- @param force_data k2.ResourceRestrictions.ForceData 40--- @param drill LuaEntity 41--- @return LuaEntityPrototype? restricted_resource 42local function get_first_restricted_resource ( force_data , drill ) 43local radius =drill . prototype . get_mining_drill_radius ( drill . quality ) 44--- @cast radius -? 45local area =flib_bounding_box . from_dimensions ( drill . position , radius * 2 , radius * 2 ) 46local targets =drill . surface . find_entities_filtered ( { type ="resource" , area =area } ) 47local drill_categories =drill . prototype . resource_categories or {} 48local restrictions =force_data . restricted_resources 49for i =1 , # targets do 50local target =targets [ i ] 51if drill_categories [ target . prototype . resource_category ] and restrictions [ target . name ] then 52return target . prototype 53end 54end 55end 56 57--- @param force_data k2.ResourceRestrictions.ForceData 58--- @param drill LuaEntity 59local function update_drill ( force_data , drill ) 60local disabled_mining_drills =force_data . disabled_mining_drills 61 62local unit_number =drill . unit_number 63--- @cast unit_number -? 64 65local drill_data =disabled_mining_drills [ unit_number ] 66 67local restriction =get_first_restricted_resource ( force_data , drill ) 68if restriction then 69if not drill_data then 70drill . disabled_by_script =true 71drill . custom_status ={ 72diode =defines . entity_status_diode . red , 73label ={ "entity-status.kr-unable-to-mine" , restriction . localised_name } , 74} 75disabled_mining_drills [ unit_number ] ={ 76drill =drill , 77icon =rendering . draw_sprite ( { 78sprite ="utility/resources_depleted_icon" , 79target =drill , 80surface =drill . surface , 81x_scale =0.5 , 82y_scale =0.5 , 83blink_interval =30 , 84} ), 85} 86end 87else 88if drill_data then 89drill . disabled_by_script =false 90drill . custom_status =nil 91if drill_data . icon . valid then 92drill_data . icon . destroy () 93end 94disabled_mining_drills [ unit_number ] =nil 95end 96end 97end 98 99--- @param force_data k2.ResourceRestrictions.ForceData 100local function refresh_all_drills ( force_data ) 101for _ , drill_data in pairs ( force_data . disabled_mining_drills ) do 102if drill_data . icon . valid then 103drill_data . icon . destroy () 104end 105end 106force_data . disabled_mining_drills ={} 107for _ , surface in pairs ( game . surfaces ) do 108for _ , drill in pairs ( surface . find_entities_filtered ( { type ="mining-drill" , force =force_data . force } )) do 109update_drill ( force_data , drill ) 110end 111end 112end 113 114local unlocks =prototypes . mod_data [ "kr-resource-restrictions" ]. data --[[ @as table<data.TechnologyID, data.EntityID[]?> ]] 115 116--- @param force_data k2.ResourceRestrictions.ForceData 117--- @param technology LuaTechnology 118--- @param restrict boolean 119local function process_effects ( force_data , technology , restrict ) 120local technology_unlocks =unlocks [ technology . name ] 121if not technology_unlocks then 122return 123end 124 125local restricted_resources =force_data . restricted_resources 126for _ , resource_name in pairs ( technology_unlocks ) do 127restricted_resources [ resource_name ] =restrict or nil 128end 129 130if restrict then 131-- The on_research_reversed event is very rare, and never happens during regular gameplay, so it is acceptable to have a lag spike in this case. 132refresh_all_drills ( force_data ) 133else 134for _ , drill_data in pairs ( force_data . disabled_mining_drills ) do 135update_drill ( force_data , drill_data . drill ) 136end 137end 138end 139 140--- @param force LuaForce 141local function refresh_force ( force ) 142force . mining_with_fluid =true 143local force_data =get_force_data ( force ) 144for _ , technology in pairs ( force . technologies ) do 145if not technology . researched then 146-- TODO: This is doing a full scan of all surfaces every time! 147process_effects ( force_data , technology , true ) 148end 149end 150end 151 152--- @param e EntityBuiltEvent 153local function on_entity_built ( e ) 154local entity =e . entity or e . destination 155if not entity . valid or entity . type ~= "mining-drill" then 156return 157end 158update_drill ( get_force_data ( entity . force --[[@as LuaForce]] ), entity ) 159end 160 161--- @param e EntityDestroyedEvent 162local function on_entity_destroyed ( e ) 163local entity =e . entity 164if not entity . valid or entity . type ~= "mining-drill" then 165return 166end 167 168-- The icon will get destroyed automatically because its target is the mining drill. 169get_force_data ( e . entity . force --[[@as LuaForce]] ). disabled_mining_drills [ entity . unit_number ] =nil 170end 171 172--- @param e EventData.on_research_finished 173local function on_research_finished ( e ) 174process_effects ( get_force_data ( e . research . force ), e . research , false ) 175end 176 177--- @param e EventData.on_research_finished 178local function on_research_reversed ( e ) 179process_effects ( get_force_data ( e . research . force ), e . research , true ) 180end 181 182--- @param e EventData.on_force_created 183local function on_force_created ( e ) 184refresh_force ( e . force ) 185end 186 187--- @param e EventData.on_force_reset 188local function on_force_reset ( e ) 189refresh_force ( e . force ) 190end 191 192--- @param e EventData.on_forces_merging 193local function on_forces_merging ( e ) 194local source_data =get_force_data ( e . source ) 195for _ , drill_data in pairs ( source_data . disabled_mining_drills ) do 196if drill_data . icon . valid then 197drill_data . icon . destroy () 198end 199end 200get_forces ()[ e . source . index ] =nil 201refresh_force ( e . destination ) 202end 203 204--- @param e EventData.on_technology_effects_reset 205local function on_technology_effects_reset ( e ) 206refresh_force ( e . force ) 207end 208 209local function refresh () 210storage . resource_restrictions =nil 211for _ , force in pairs ( game . forces ) do 212refresh_force ( force ) 213refresh_all_drills ( get_force_data ( force )) 214end 215end 216 217--- @class MiningDrillRestrictionsHandler: event_handler 218local handler ={} 219 220handler . on_init =refresh 221handler . on_configuration_changed =refresh 222 223handler . events ={ 224[ defines . events . on_built_entity ] =on_entity_built , 225[ defines . events . on_entity_cloned ] =on_entity_built , 226[ defines . events . on_entity_died ] =on_entity_destroyed , 227[ defines . events . on_force_created ] =on_force_created , 228[ defines . events . on_force_reset ] =on_force_reset , 229[ defines . events . on_forces_merging ] =on_forces_merging , 230[ defines . events . on_player_mined_entity ] =on_entity_destroyed , 231[ defines . events . on_research_finished ] =on_research_finished , 232[ defines . events . on_research_reversed ] =on_research_reversed , 233[ defines . events . on_robot_built_entity ] =on_entity_built , 234[ defines . events . on_robot_mined_entity ] =on_entity_destroyed , 235[ defines . events . on_space_platform_built_entity ] =on_entity_built , 236[ defines . events . on_space_platform_mined_entity ] =on_entity_destroyed , 237[ defines . events . on_technology_effects_reset ] =on_technology_effects_reset , 238[ defines . events . script_raised_built ] =on_entity_built , 239[ defines . events . script_raised_destroy ] =on_entity_destroyed , 240[ defines . events . script_raised_revive ] =on_entity_built , 241} 242 243return handler