]> git.somenet.org - factorio/Waterbomb.git/blob - control.lua
RELEASE 2.0.0 - Initial compatibility with Factorio 2.0
[factorio/Waterbomb.git] / control.lua
1
2 local waterbombs
3 local replaceableTiles = {
4     ["water"] = "grass-1",
5     ["deepwater"] = "grass-1",
6     ["water-green"] = "grass-1",
7     ["deepwater-green"] = "grass-1"
8 }
9
10
11 script.on_configuration_changed(function(data)
12     if waterbombs ~= nil then
13         script.on_event(defines.events.on_tick, tickBombs)
14     end
15 end)
16
17
18 script.on_load(function(event)
19     if waterbombs ~= nil then
20         script.on_event(defines.events.on_tick, tickBombs)
21     end
22 end)
23
24
25 script.on_event(defines.events.on_built_entity, function(event)
26     if event.entity.name == "waterbomb" then
27         waterbombs = {}
28         for _, surface in pairs(game.surfaces) do
29             for _, entity in pairs(surface.find_entities_filtered{name="waterbomb"}) do
30                 table.insert(waterbombs, entity)
31             end
32         end
33         script.on_event(defines.events.on_tick, tickBombs)
34     end
35 end)
36
37
38 function tickBombs(event)
39     if event.tick % 20 == 0 then
40         for k,e in pairs(waterbombs) do
41             if not e.valid then
42                 table.remove(waterbombs, k)
43
44             elseif e.energy > 49000000 then
45                 local epos, x, y, distX, distY, surface
46                 local explosionRadius = settings.global["Waterbomb-explosion-radius"].value
47
48                 epos = e.position
49                 x = epos.x
50                 y = epos.y
51                 surface =  e.surface
52
53                 -- create explosions
54                 for xx = x - explosionRadius, x + explosionRadius, 2 do
55                     for yy = y - explosionRadius, y + explosionRadius, 2 do
56                         distX = math.abs(x - xx)
57                         distY = math.abs(y - yy)
58
59                         if math.floor(math.sqrt((distX * distX) + (distY * distY))) <= explosionRadius then
60                             e.surface.create_entity({name = "medium-explosion", position = {x = xx, y = yy}})
61                         end
62                     end
63                 end
64
65                 -- big detonation
66                 e.surface.create_entity({name = "waterbomb-detonation", position = e.position, target = e, speed = 1})
67
68                 -- bomb explodes
69                 e.destroy()
70                 table.remove(waterbombs, k)
71
72                 -- water is created
73                 createWater(x, y, explosionRadius, surface)
74                 throwDirt(x, y, explosionRadius, surface)
75
76                 -- random stones
77                 for a = 1, (explosionRadius * 10) do
78                     createRandomStone(epos, surface)
79                     createRandomStone(epos, surface)
80                 end
81             end
82         end
83
84         -- nothing more to be exploded. Stop ticking.
85         if #waterbombs == 0 then
86             waterbombs = nil
87             script.on_event(defines.events.on_tick, nil)
88         end
89     end
90 end
91
92 function createWater(x, y, size, surface)
93     -- Setting tiles to water where player characters are standing deletes the character and sets them to god mode. We dont want that.
94     local players = surface.find_entities_filtered({area = {{x - size - 1, y - size - 1}, {x + size + 1, y + size + 1}}, type="character"})
95     if #players ~= 0 then
96         return
97     end
98
99     local waterTiles = {}
100     x = math.floor(x)
101     y = math.floor(y)
102
103     for wx = x - size, x + size, 1 do
104         for wy = y - size, y + size, 1 do
105         table.insert(waterTiles, {name="water", position={wx, wy}})
106         end
107     end
108     surface.set_tiles(waterTiles)
109
110     waterTiles = {}
111     table.insert(waterTiles, {name="deepwater", position={x, y}})
112     surface.set_tiles(waterTiles)
113 end
114
115
116 function throwDirt(x, y, size, surface)
117     local dirtTiles = {}
118     local tileName
119     local distX,distY
120
121     if settings.global["Waterbomb-throw-dirt"].value == true then
122         x = math.floor(x)
123         y = math.floor(y)
124
125         for xx = x - size, x + (size + 1), 1 do
126             for yy = y - size, y + (size + 1), 1 do
127                 distX = math.abs(x - xx)
128                 distY = math.abs(y - yy)
129
130                 if math.floor(math.random(1, 4)) >= 4 then
131                     table.insert(dirtTiles, {name = "grass-1", position = {xx, yy}})
132                 end
133             end
134         end
135
136         if #dirtTiles ~= 0 then
137             surface.set_tiles(dirtTiles)
138         end
139     end
140 end
141
142
143 function createRandomStone(position, surface)
144     local x,y
145     local maximumRockThrowDistance = settings.global["Waterbomb-explosion-radius"].value + 7
146
147     if settings.global["Waterbomb-throw-stone"].value == true then
148         x = position.x
149         y = position.y
150
151         if math.random() > 0.5 then
152             x = x - math.floor(math.random(1, maximumRockThrowDistance))
153             else
154             x = x + math.floor(math.random(1, maximumRockThrowDistance))
155         end
156
157         if math.random() < 0.5 then
158             y = y - math.floor(math.random(1, maximumRockThrowDistance))
159             else
160             y = y + math.floor(math.random(1, maximumRockThrowDistance))
161         end
162
163         if math.floor(math.random(1, 4)) >= 3 then
164             if settings.global["Waterbomb-throw-stone-into-water"].value == true then
165                 surface.set_tiles({{name="grass-1", position={math.floor(x), math.floor(y)}}})
166             end
167
168             local tileName = surface.get_tile(math.floor(x), math.floor(y)).name
169             if not replaceableTiles[tileName] then
170                 surface.create_entity({name="stone", position={x, y}}).amount = math.floor(math.random(13, 37))
171                 surface.create_entity({name="explosion", position={x, y}})
172             end
173         end
174     end
175 end