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