z_mirror/Krastorio2
git clone https://git.raiguard.me/z_mirror/Krastorio2
20f5f8fb
discrete-steel-pipes
1local flib_position =require ( "__flib__.position" ) 2 3--- @class RadioactivityPlayerData 4--- @field entity boolean 5--- @field damaged boolean 6--- @field inventory boolean 7--- @field last_position MapPosition 8 9local default_entities ={ "uranium-ore" } 10local default_items ={ 11"nuclear-fuel" , 12"uranium-235" , 13"uranium-238" , 14"uranium-fuel-cell" , 15"uranium-ore" , 16"depleted-uranium-fuel-cell" , 17} 18local range =7 19 20--- @param player LuaPlayer 21local function check_inventory ( player ) 22if not storage . radioactivity . enabled or not next ( storage . radioactivity . entities ) then 23return 24end 25 26local player_data =storage . radioactivity . players [ player . index ] 27if not player_data then 28return 29end 30 31if not player . character or not player . character . valid then 32player_data . inventory =false 33return 34end 35 36for _ , item_name in pairs ( storage . radioactivity . items ) do 37-- FIXME: This does not check trash inventory 38if player . get_item_count ( item_name ) > 0 then 39player_data . inventory =true 40return 41end 42end 43 44player_data . inventory =false 45end 46 47--- @param player LuaPlayer 48local function check_around_player ( player ) 49if not storage . radioactivity . enabled or not next ( storage . radioactivity . items ) then 50return 51end 52 53local player_data =storage . radioactivity . players [ player . index ] 54if not player_data then 55return 56end 57 58if not player . character or not player . character . valid then 59player_data . entity =false 60return 61end 62 63local position =flib_position . floor ( player . physical_position ) 64local last_position =player_data . last_position 65if flib_position . eq ( position , last_position ) then 66return 67end 68player_data . last_position =position 69 70player_data . entity =player . surface . count_entities_filtered ( { 71name =storage . radioactivity . entities , 72radius =range , 73position =position , 74} ) > 0 75end 76 77--- @param player LuaPlayer 78local function add_player ( player ) 79storage . radioactivity . players [ player . index ] ={ 80entity =false , 81inventory =false , 82last_position ={ x =0 , y =0 } , 83} 84end 85 86--- @param player_index uint 87local function remove_player ( player_index ) 88storage . radioactivity . players [ player_index ] =nil 89end 90 91local function update_and_damage () 92if not storage . radioactivity . enabled then 93return 94end 95 96for player_index , player_data in pairs ( storage . radioactivity . players ) do 97if not player_data . entity and not player_data . inventory then 98goto continue 99end 100 101local player =game . get_player ( player_index ) 102if not player or not player . connected or not player . character then 103goto continue 104end 105 106player . add_custom_alert ( 107player . character , 108{ type ="virtual" , name ="kr-nuclear-2" } , 109{ "other.kr-taking-radioactive-damage" } , 110false 111) 112 113-- Damage the player 114-- TODO: Account for armor and energy shields 115local base_damage =7.25 116player_data . damaged =player . character . damage ( base_damage , "enemy" , "kr-radioactive" ) > 0 117 118:: continue :: 119end 120end 121 122local function update_sounds () 123if not storage . radioactivity . enabled then 124return 125end 126 127for player_index , player_data in pairs ( storage . radioactivity . players ) do 128if not player_data . entity and not player_data . inventory then 129goto continue 130end 131 132if not player_data . damaged then 133goto continue 134end 135 136local player =game . get_player ( player_index ) 137if not player or not player . connected then 138goto continue 139end 140 141player . play_sound ( { 142path ="kr-radioactive" , 143position =player . physical_position , 144volume_modifier =0.5 , 145} ) 146 147:: continue :: 148end 149end 150 151--- @param e EventData.on_player_changed_position|EventData.on_player_changed_surface 152local function on_player_moved ( e ) 153local player =game . get_player ( e . player_index ) 154if player then 155check_around_player ( player ) 156end 157end 158 159--- @param e EventData.on_player_main_inventory_changed|EventData.on_player_trash_inventory_changed 160local function on_player_inventory_changed ( e ) 161local player =game . get_player ( e . player_index ) 162if player then 163check_inventory ( player ) 164end 165end 166 167--- @param e EventData.on_player_created 168local function on_player_created ( e ) 169local player =game . get_player ( e . player_index ) 170if not player then 171return 172end 173 174add_player ( player ) 175end 176 177--- @param e EventData.on_player_removed 178local function on_player_removed ( e ) 179remove_player ( e . player_index ) 180end 181 182--- @param e EventData.on_runtime_mod_setting_changed 183local function on_runtime_mod_setting_changed ( e ) 184if e . setting ~= "kr-enable-radioactivity" or not storage . radioactivity then 185return 186end 187 188storage . radioactivity . enabled =settings . global [ "kr-enable-radioactivity" ]. value --[[@as boolean]] 189end 190 191local radioactivity ={} 192 193function radioactivity . on_init () 194storage . radioactivity ={ 195enabled =settings . global [ "kr-enable-radioactivity" ]. value --[[@as boolean]] , 196--- @type table<uint, RadioactivityPlayerData> 197players ={} , 198} 199radioactivity . on_configuration_changed () 200end 201 202function radioactivity . on_configuration_changed () 203storage . radioactivity . entities ={} 204for _ , entity_name in pairs ( default_entities ) do 205if prototypes . entity [ entity_name ] then 206table . insert ( storage . radioactivity . entities , entity_name ) 207end 208end 209storage . radioactivity . items ={} 210for _ , item_name in pairs ( default_items ) do 211if prototypes . item [ item_name ] then 212table . insert ( storage . radioactivity . items , item_name ) 213end 214end 215end 216 217remote . add_interface ( "kr-radioactivity" , { 218--- @param name string 219add_entity =function ( name ) 220if not storage . radioactivity then 221return 222end 223if not name or type ( name ) ~= "string" then 224error ( "`name` must be a string." ) 225end 226 227if not prototypes . entity [ name ] then 228error ( "Entity `" .. name .. "` does not exist." ) 229end 230 231table . insert ( storage . radioactivity . entities , name ) 232end , 233--- @param name string 234add_item =function ( name ) 235if not storage . radioactivity then 236return 237end 238if not name or type ( name ) ~= "string" then 239error ( "`name` must be a string." ) 240end 241 242if not prototypes . item [ name ] then 243error ( "Item `" .. name .. "` does not exist." ) 244end 245 246table . insert ( storage . radioactivity . items , name ) 247end , 248} ) 249 250radioactivity . events ={ 251[ defines . events . on_player_changed_position ] =on_player_moved , 252[ defines . events . on_player_changed_surface ] =on_player_moved , 253[ defines . events . on_player_created ] =on_player_created , 254[ defines . events . on_player_cursor_stack_changed ] =on_player_inventory_changed , 255[ defines . events . on_player_died ] =on_player_moved , 256[ defines . events . on_player_main_inventory_changed ] =on_player_inventory_changed , 257[ defines . events . on_player_removed ] =on_player_removed , 258[ defines . events . on_player_respawned ] =on_player_moved , 259[ defines . events . on_player_toggled_map_editor ] =on_player_moved , 260[ defines . events . on_player_trash_inventory_changed ] =on_player_inventory_changed , 261[ defines . events . on_runtime_mod_setting_changed ] =on_runtime_mod_setting_changed , 262[ defines . events . on_tick ] =update_sounds , 263} 264 265radioactivity . on_nth_tick ={ 266[ 20 ] =update_and_damage , 267} 268 269return radioactivity