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