z_mirror/Krastorio2
git clone https://git.raiguard.me/z_mirror/Krastorio2
1182a831
real-fusion-reactor
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 , 81damaged =false , 82inventory =false , 83last_position ={ x =0 , y =0 } , 84} 85end 86 87--- @param player_index uint 88local function remove_player ( player_index ) 89storage . radioactivity . players [ player_index ] =nil 90end 91 92local function update_and_damage () 93if not storage . radioactivity . enabled then 94return 95end 96 97for player_index , player_data in pairs ( storage . radioactivity . players ) do 98if not player_data . entity and not player_data . inventory then 99goto continue 100end 101 102local player =game . get_player ( player_index ) 103if not player or not player . connected or not player . character then 104goto continue 105end 106 107player . add_custom_alert ( 108player . character , 109{ type ="virtual" , name ="kr-nuclear-2" } , 110{ "gui-alert-tooltip.kr-taking-radioactive-damage" } , 111false 112) 113 114-- Damage the player 115-- TODO: Account for armor and energy shields 116local base_damage =7.25 117player_data . damaged =player . character . damage ( base_damage , "enemy" , "kr-radioactive" ) > 0 118 119:: continue :: 120end 121end 122 123local function update_sounds () 124if not storage . radioactivity . enabled then 125return 126end 127 128for player_index , player_data in pairs ( storage . radioactivity . players ) do 129if not player_data . entity and not player_data . inventory then 130goto continue 131end 132 133if not player_data . damaged then 134goto continue 135end 136 137local player =game . get_player ( player_index ) 138if not player or not player . connected then 139goto continue 140end 141 142player . play_sound ( { 143path ="kr-radioactive" , 144position =player . physical_position , 145volume_modifier =0.5 , 146} ) 147 148:: continue :: 149end 150end 151 152--- @param e EventData.on_player_changed_position|EventData.on_player_changed_surface 153local function on_player_moved ( e ) 154local player =game . get_player ( e . player_index ) 155if player then 156check_around_player ( player ) 157end 158end 159 160--- @param e EventData.on_player_main_inventory_changed|EventData.on_player_trash_inventory_changed 161local function on_player_inventory_changed ( e ) 162local player =game . get_player ( e . player_index ) 163if player then 164check_inventory ( player ) 165end 166end 167 168--- @param e EventData.on_player_died|EventData.on_player_respawned 169local function on_player_alive_state_changed ( e ) 170local player =game . get_player ( e . player_index ) 171if player then 172check_around_player ( player ) 173check_inventory ( player ) 174end 175end 176 177--- @param e EventData.on_player_created 178local function on_player_created ( e ) 179local player =game . get_player ( e . player_index ) 180if not player then 181return 182end 183 184add_player ( player ) 185end 186 187--- @param e EventData.on_player_removed 188local function on_player_removed ( e ) 189remove_player ( e . player_index ) 190end 191 192--- @param e EventData.on_runtime_mod_setting_changed 193local function on_runtime_mod_setting_changed ( e ) 194if e . setting ~= "kr-enable-radioactivity" or not storage . radioactivity then 195return 196end 197 198storage . radioactivity . enabled =settings . global [ "kr-enable-radioactivity" ]. value --[[@as boolean]] 199end 200 201local radioactivity ={} 202 203function radioactivity . on_init () 204storage . radioactivity ={ 205enabled =settings . global [ "kr-enable-radioactivity" ]. value --[[@as boolean]] , 206--- @type table<uint, RadioactivityPlayerData> 207players ={} , 208} 209radioactivity . on_configuration_changed () 210end 211 212function radioactivity . on_configuration_changed () 213storage . radioactivity . entities ={} 214for _ , entity_name in pairs ( default_entities ) do 215if prototypes . entity [ entity_name ] then 216table . insert ( storage . radioactivity . entities , entity_name ) 217end 218end 219storage . radioactivity . items ={} 220for _ , item_name in pairs ( default_items ) do 221if prototypes . item [ item_name ] then 222table . insert ( storage . radioactivity . items , item_name ) 223end 224end 225end 226 227remote . add_interface ( "kr-radioactivity" , { 228--- @param name string 229add_entity =function ( name ) 230if not storage . radioactivity then 231return 232end 233if not name or type ( name ) ~= "string" then 234error ( "`name` must be a string." ) 235end 236 237if not prototypes . entity [ name ] then 238error ( "Entity `" .. name .. "` does not exist." ) 239end 240 241table . insert ( storage . radioactivity . entities , name ) 242end , 243--- @param name string 244add_item =function ( name ) 245if not storage . radioactivity then 246return 247end 248if not name or type ( name ) ~= "string" then 249error ( "`name` must be a string." ) 250end 251 252if not prototypes . item [ name ] then 253error ( "Item `" .. name .. "` does not exist." ) 254end 255 256table . insert ( storage . radioactivity . items , name ) 257end , 258} ) 259 260radioactivity . events ={ 261[ defines . events . on_player_changed_position ] =on_player_moved , 262[ defines . events . on_player_changed_surface ] =on_player_moved , 263[ defines . events . on_player_created ] =on_player_created , 264[ defines . events . on_player_cursor_stack_changed ] =on_player_inventory_changed , 265[ defines . events . on_player_died ] =on_player_alive_state_changed , 266[ defines . events . on_player_main_inventory_changed ] =on_player_inventory_changed , 267[ defines . events . on_player_removed ] =on_player_removed , 268[ defines . events . on_player_respawned ] =on_player_alive_state_changed , 269[ defines . events . on_player_toggled_map_editor ] =on_player_moved , 270[ defines . events . on_player_trash_inventory_changed ] =on_player_inventory_changed , 271[ defines . events . on_runtime_mod_setting_changed ] =on_runtime_mod_setting_changed , 272[ defines . events . on_tick ] =update_sounds , 273} 274 275radioactivity . on_nth_tick ={ 276[ 20 ] =update_and_damage , 277} 278 279return radioactivity