z_mirror/Krastorio2

git clone https://git.raiguard.me/z_mirror/Krastorio2

Caleb HeuerFix warningsc358df2e

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