z_mirror/Krastorio2

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

Caleb HeuerClean up legacy event parameter041f29c4

santichu95/patch-1
6.7 KiB233 linesraw
1local flib_table = require("__flib__.table")
2
3--- @class PlanetaryTeleporterData
4--- @field entities PlanetaryTeleporterEntities
5--- @field force LuaForce
6--- @field name string?
7--- @field position MapPosition
8--- @field surface LuaSurface
9--- @field turret_unit_number UnitNumber
10
11--- @class PlanetaryTeleporterEntities
12--- @field base LuaEntity
13--- @field turret LuaEntity
14--- @field collision_1 LuaEntity
15--- @field collision_2 LuaEntity
16--- @field collision_3 LuaEntity
17--- @field front_layer LuaEntity
18
19local collision_entity_offsets = {
20  { x = 0, y = 0 },
21  { x = -2, y = 2 },
22  { x = 2, y = 2 },
23}
24
25--- @param base_entity LuaEntity
26--- @return PlanetaryTeleporterEntities?
27local function create_entities(base_entity)
28  local entities = {
29    base = base_entity,
30  }
31  local surface = base_entity.surface
32  local position = base_entity.position
33
34  -- Building the turret can fail due to AAI vehicles
35  entities.turret = surface.create_entity({
36    name = "kr-planetary-teleporter-turret",
37    position = { x = position.x, y = position.y + 1.15 },
38    force = "kr-internal-turrets",
39    create_build_effect_smoke = false,
40    raise_built = true,
41  })
42
43  if not entities.turret or not entities.turret.valid then
44    game.print(
45      "Building planetary teleporter failed due to AAI Programmable Vehicles. This teleporter will not function."
46    )
47    base_entity.active = false
48    return
49  end
50
51  for i, offset in ipairs(collision_entity_offsets) do
52    entities["collision_" .. i] = surface.create_entity({
53      name = "kr-planetary-teleporter-collision-" .. i,
54      position = { x = position.x + offset.x, y = position.y + offset.y },
55      create_build_effect_smoke = false,
56      raise_built = true,
57    })
58  end
59  entities.front_layer = surface.create_entity({
60    name = "kr-planetary-teleporter-front-layer",
61    position = position,
62    create_build_effect_smoke = false,
63    raise_built = true,
64  })
65  for name, entity in pairs(entities) do
66    if name ~= "base" then
67      entity.destructible = false
68    end
69  end
70  return entities
71end
72
73--- @param e EntityBuiltEvent
74local function on_entity_built(e)
75  local entity = e.entity or e.destination
76  if not entity or not entity.valid then
77    return
78  end
79  local entity_name = entity.name
80
81  -- Don't keep cloned internal entities.
82  if
83    e.name == defines.events.on_entity_cloned
84    and (
85      entity_name == "kr-planetary-teleporter-front-layer"
86      or entity_name == "kr-planetary-teleporter-turret"
87      or string.find(entity_name, "kr-planetary-teleporter-collision", nil, true)
88    )
89  then
90    entity.destroy()
91    return
92  end
93
94  if entity_name ~= "kr-planetary-teleporter" then
95    return
96  end
97
98  -- If revived from a blueprint and it has a name, get it from the tags
99  local name = e.tags and e.tags.kr_planetary_teleporter_name or nil --[[@as string?]]
100  local entities = create_entities(entity)
101  if not entities then
102    return
103  end
104
105  storage.planetary_teleporter[entity.unit_number] = {
106    entities = entities,
107    force = entity.force --[[@as LuaForce]],
108    name = name,
109    position = entity.position,
110    surface = entity.surface,
111    turret_unit_number = entities.turret.unit_number,
112  }
113end
114
115--- @param e EntityDestroyedEvent
116local function on_entity_destroyed(e)
117  local entity = e.entity
118  if not entity or not entity.valid or entity.name ~= "kr-planetary-teleporter" then
119    return
120  end
121  local unit_number = entity.unit_number --[[@as uint]]
122  local data = storage.planetary_teleporter[unit_number]
123  -- AAI vehicles will destroy the entity before we have an opportuity to create data.
124  if not data then
125    return
126  end
127  for _, entity_to_destroy in pairs(data.entities) do
128    if entity_to_destroy.valid then
129      entity_to_destroy.destroy()
130    end
131  end
132  storage.planetary_teleporter[unit_number] = nil
133end
134
135--- @param e EventData.on_player_setup_blueprint
136local function on_player_setup_blueprint(e)
137  local player = game.get_player(e.player_index)
138  if not player then
139    return
140  end
141
142  -- Get blueprint
143  local bp = player.blueprint_to_setup
144  if not bp or not bp.valid_for_read then
145    bp = player.cursor_stack
146    if not bp then
147      return
148    end
149    if bp.type == "blueprint-book" then
150      local item_inventory = bp.get_inventory(defines.inventory.item_main)
151      if item_inventory then
152        bp = item_inventory[bp.active_index]
153      else
154        return
155      end
156    end
157  end
158
159  local entities = bp.get_blueprint_entities()
160  if not entities then
161    return
162  end
163
164  -- Iterate each entity
165  for i = 1, #entities do
166    local entity = entities[i]
167    local entity_name = entity.name
168    if entity_name == "kr-planetary-teleporter" then
169      local real_entity = player.surface.find_entity("kr-planetary-teleporter", entity.position)
170      if real_entity then
171        local unit_number = real_entity.unit_number --[[@as uint]]
172        local data = storage.planetary_teleporter[unit_number]
173        if data and data.name then
174          bp.set_blueprint_entity_tag(i, "kr_planetary_teleporter_name", data.name)
175        end
176      end
177    end
178  end
179end
180
181--- @param e EventData.on_script_trigger_effect
182local function on_script_trigger_effect(e)
183  if e.effect_id ~= "kr-planetary-teleporter-character-trigger" then
184    return
185  end
186
187  if not e.source_entity.valid or not e.target_entity.valid then
188    return
189  end
190
191  local player = e.target_entity.player
192  if not player or not player.valid then
193    return
194  end
195
196  table.insert(
197    flib_table.get_or_insert(storage.planetary_teleporter_players, e.source_entity.unit_number, {}),
198    player.index
199  )
200end
201
202-- on_tick is executed before on_script_trigger_effect
203local function on_tick()
204  storage.planetary_teleporter_players = {}
205end
206
207local planetary_teleporter = {}
208
209function planetary_teleporter.on_init()
210  --- @type table<uint, PlanetaryTeleporterData>
211  storage.planetary_teleporter = {}
212  --- @type table<UnitNumber, PlayerIndex[]>
213  storage.planetary_teleporter_players = {}
214end
215
216planetary_teleporter.events = {
217  [defines.events.on_built_entity] = on_entity_built,
218  [defines.events.on_entity_cloned] = on_entity_built,
219  [defines.events.on_entity_died] = on_entity_destroyed,
220  [defines.events.on_player_mined_entity] = on_entity_destroyed,
221  [defines.events.on_player_setup_blueprint] = on_player_setup_blueprint,
222  [defines.events.on_robot_built_entity] = on_entity_built,
223  [defines.events.on_robot_mined_entity] = on_entity_destroyed,
224  [defines.events.on_script_trigger_effect] = on_script_trigger_effect,
225  [defines.events.on_tick] = on_tick,
226  [defines.events.script_raised_built] = on_entity_built,
227  [defines.events.script_raised_destroy] = on_entity_destroyed,
228  [defines.events.script_raised_revive] = on_entity_built,
229  [defines.events.on_space_platform_built_entity] = on_entity_built,
230  [defines.events.on_space_platform_mined_entity] = on_entity_destroyed,
231}
232
233return planetary_teleporter