z_mirror/Krastorio2
git clone https://git.raiguard.me/z_mirror/Krastorio2
a2aa5f2a
real-fusion-reactor
1local flib_direction =require ( "__flib__.direction" ) 2local flib_position =require ( "__flib__.position" ) 3 4--- @type table<defines.direction, Vector> 5local offsets ={ 6[ defines . direction . north ] ={ 0 , - 1 } , 7[ defines . direction . east ] ={ 1 , 0 } , 8[ defines . direction . south ] ={ 0 , 1 } , 9[ defines . direction . west ] ={ - 1 , 0 } , 10} 11 12local belt_types ={ 13"linked-belt" , 14"loader" , 15"loader-1x1" , 16"splitter" , 17"transport-belt" , 18"underground-belt" , 19} 20 21local container_types ={ 22"assembling-machine" , 23"beacon" , 24"boiler" , 25"burner-generator" , 26"container" , 27"curved-rail" , 28"furnace" , 29"infinity-container" , 30"lab" , 31"linked-container" , 32"logistic-container" , 33"mining-drill" , 34"proxy-container" , 35"rail" , 36"reactor" , 37"rocket-silo" , 38"straight-rail" , 39} 40 41--- @param entity LuaEntity 42local function flip_loader ( entity ) 43entity . direction =flib_direction . opposite ( entity . direction ) 44entity . loader_type =entity . loader_type == "output" and "input" or "output" 45end 46 47--- Find entities and entity ghosts of the corresponding types. 48--- @param surface LuaSurface 49--- @param position MapPosition 50--- @param force ForceID 51--- @param types string[] 52--- @return LuaEntity[] 53local function find_entities ( surface , position , force , types ) 54local entities =surface . find_entities_filtered ( { 55force =force , 56position =position , 57type =types , 58} ) 59local ghosts =surface . find_entities_filtered ( { 60force =force , 61ghost_type =types , 62position =position , 63} ) 64for i =1 , # ghosts do 65entities [ # entities + 1 ] =ghosts [ i ] 66end 67return entities 68end 69 70--- Ensure that the loader has the belt on the correct side. 71--- @param entity LuaEntity 72local function snap_direction ( entity ) 73local offset_direction =entity . direction 74if entity . loader_type == "input" then 75offset_direction =flib_direction . opposite ( offset_direction ) 76end 77local container_position =flib_position . add ( entity . position , offsets [ offset_direction ]) 78 79-- Case 1: If a container is in front, then flip the loader 80local containers =find_entities ( entity . surface , container_position , entity . force , container_types ) 81if # containers > 0 then 82-- Check that it's not a composite loader entity 83local is_composite =entity . surface . count_entities_filtered ( { 84force =entity . force , 85position =container_position , 86type ={ "loader" , "loader-1x1" } , 87} ) > 0 88if not is_composite then 89flip_loader ( entity ) 90return 91end 92end 93 94-- Case 2: If a belt is behind, then flip the loader 95offset_direction =flib_direction . opposite ( offset_direction ) 96local belt_position =flib_position . add ( entity . position , offsets [ offset_direction ]) 97local belt =find_entities ( entity . surface , belt_position , entity . force , belt_types )[ 1 ] 98if not belt then 99return 100end 101 102local belt_type =belt . type 103if belt_type == "entity-ghost" then 104belt_type =belt . ghost_type 105end 106if 107belt_type == "transport-belt" 108or belt_type == "underground-belt" 109or math . abs ( offset_direction - belt . direction ) % 4 == 0 110then 111flip_loader ( entity ) 112end 113end 114 115--- @param entity LuaEntity 116local function snap_to_belt ( entity ) 117local offset_direction =entity . direction 118if entity . loader_type == "input" then 119offset_direction =flib_direction . opposite ( offset_direction ) 120end 121local belt_position =flib_position . add ( entity . position , offsets [ offset_direction ]) 122 123local belt =find_entities ( entity . surface , belt_position , entity . force , belt_types )[ 1 ] 124if not belt then 125return 126end 127 128local belt_direction =belt . direction 129local belt_type =belt . type 130if belt_type == "entity-ghost" then 131belt_type =belt . ghost_type 132end 133if entity . direction == belt_direction then 134-- Pass 135elseif entity . direction == flib_direction . opposite ( belt_direction ) then 136entity . loader_type ="input" 137elseif belt_type == "transport-belt" or belt_type == "underground-belt" then 138-- Sideloading 139entity . loader_type ="output" 140end 141end 142 143--- @param e EntityBuiltEvent 144local function on_entity_built ( e ) 145local entity =e . entity or e . destination 146if not entity . valid or not string . match ( entity . name , "^kr.*%-loader$" ) then 147return 148end 149 150entity . update_connections () 151if not entity . loader_container then 152snap_direction ( entity ) 153end 154 155snap_to_belt ( entity ) 156end 157 158local snap_loader ={} 159 160snap_loader . events ={ 161[ defines . events . on_built_entity ] =on_entity_built , 162[ defines . events . on_entity_cloned ] =on_entity_built , 163[ defines . events . on_robot_built_entity ] =on_entity_built , 164[ defines . events . script_raised_built ] =on_entity_built , 165[ defines . events . script_raised_revive ] =on_entity_built , 166[ defines . events . on_space_platform_built_entity ] =on_entity_built , 167} 168 169return snap_loader