z_mirror/Krastorio2

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

Caleb HeuerChange to four-space indentation07409ca6

four-space-indentation
5.7 KiB184 linesraw
1local util = require("scripts.util")
2
3--- @class ShelterData
4--- @field container LuaEntity
5--- @field electric LuaEntity
6--- @field light LuaEntity
7--- @field former_spawn_point MapPosition
8
9--- @param force LuaForce
10local function init_force(force)
11    if not storage.shelter then
12        return
13    end
14    storage.shelter.forces[force.index] = {}
15end
16
17local function spawn_flying_texts()
18    for unit_number, entity in pairs(storage.shelter.inactive) do
19        if entity.valid then
20            util.entity_flying_text(entity, { "message.kr-shelter-is-inactive" }, { r = 1 })
21        else
22            storage.shelter.inactive[unit_number] = nil
23        end
24    end
25end
26
27--- @param shelter_data ShelterData
28local function all_are_valid(shelter_data)
29    return shelter_data.container.valid and shelter_data.electric.valid and shelter_data.light.valid
30end
31
32--- @param entity LuaEntity
33local function destroy_if_valid(entity)
34    if entity.valid then
35        entity.destroy()
36    end
37end
38
39--- @param e EntityBuiltEvent
40local function on_entity_built(e)
41    local entity = e.entity or e.destination
42    if not entity.valid then
43        return
44    end
45    if entity.name ~= "kr-shelter-container" and entity.name ~= "kr-shelter-plus-container" then
46        return
47    end
48    --- @cast entity LuaEntity
49
50    local force = entity.force
51    local surface = entity.surface
52    local force_shelters = storage.shelter.forces[force.index]
53
54    local existing_shelter_data = force_shelters[surface.index]
55    if existing_shelter_data then
56        if all_are_valid(existing_shelter_data) then
57            local name = entity.name:gsub("kr%-", "kr-inactive-"):gsub("%-container", "")
58            local position = entity.position
59            local force = entity.force
60            local player = entity.last_user
61            local surface = entity.surface
62            entity.destroy()
63
64            local new_entity = surface.create_entity({
65                name = name,
66                position = position,
67                force = force,
68                player = player,
69                create_build_effect_smoke = false,
70                raise_built = true,
71            })
72            if new_entity and new_entity.valid then
73                storage.shelter.inactive[new_entity.unit_number] = new_entity
74            end
75            return
76        else
77            force.set_spawn_position(existing_shelter_data.former_spawn_point, surface)
78            destroy_if_valid(existing_shelter_data.container)
79            destroy_if_valid(existing_shelter_data.electric)
80            destroy_if_valid(existing_shelter_data.light)
81            force_shelters[force.index] = nil
82        end
83    end
84
85    local _, _, base_name = string.find(entity.name, "^(.*)%-container")
86    --- @type ShelterData
87    local shelter_data = { container = entity }
88
89    for key, suffix in pairs({ electric = "", light = "-light" }) do
90        local name = base_name .. suffix
91        shelter_data[key] = surface.create_entity({
92            name = name,
93            position = entity.position,
94            force = force,
95            player = entity.last_user,
96            create_build_effect_smoke = false,
97            raise_built = true,
98        })
99    end
100
101    shelter_data.former_spawn_point = force.get_spawn_position(surface)
102    force.set_spawn_position({ x = entity.position.x, y = entity.position.y + 3.5 }, surface)
103
104    force_shelters[surface.index] = shelter_data
105end
106
107--- @param e EntityDestroyedEvent
108local function on_entity_destroyed(e)
109    local entity = e.entity
110    if not entity or not entity.valid then
111        return
112    end
113    if entity.name ~= "kr-shelter-container" and entity.name ~= "kr-shelter-plus-container" then
114        return
115    end
116
117    local inactive = storage.shelter.inactive[entity.unit_number]
118    if inactive then
119        storage.shelter.inactive[entity.unit_number] = nil
120    else
121        local force = entity.force
122
123        local force_shelters = storage.shelter.forces[force.index]
124        if not force_shelters then
125            return
126        end
127
128        local surface_index = entity.surface.index
129        local shelter_data = force_shelters[surface_index]
130        if not shelter_data then
131            return
132        end
133
134        destroy_if_valid(shelter_data.electric)
135        destroy_if_valid(shelter_data.light)
136        force_shelters[surface_index] = nil
137
138        force.set_spawn_position(shelter_data.former_spawn_point, surface_index)
139    end
140end
141
142--- @param e EventData.on_force_created
143local function on_force_created(e)
144    if e.force.valid then
145        init_force(e.force)
146    end
147end
148
149--- @class ShelterHandler : event_handler
150local shelter = {}
151
152function shelter.on_init()
153    storage.shelter = {
154        --- @type table<uint, table<uint, ShelterData>>
155        forces = {},
156        --- @type table<uint, LuaEntity>
157        inactive = {},
158    }
159
160    for _, force in pairs(game.forces) do
161        init_force(force)
162    end
163end
164
165shelter.events = {
166    [defines.events.on_built_entity] = on_entity_built,
167    [defines.events.on_entity_cloned] = on_entity_built,
168    [defines.events.on_entity_died] = on_entity_destroyed,
169    [defines.events.on_force_created] = on_force_created,
170    [defines.events.on_player_mined_entity] = on_entity_destroyed,
171    [defines.events.on_robot_built_entity] = on_entity_built,
172    [defines.events.on_robot_mined_entity] = on_entity_destroyed,
173    [defines.events.script_raised_built] = on_entity_built,
174    [defines.events.script_raised_destroy] = on_entity_destroyed,
175    [defines.events.script_raised_revive] = on_entity_built,
176    [defines.events.on_space_platform_built_entity] = on_entity_built,
177    [defines.events.on_space_platform_mined_entity] = on_entity_destroyed,
178}
179
180shelter.on_nth_tick = {
181    [180] = spawn_flying_texts,
182}
183
184return shelter