From 3278093b3a2f6852b23f4aa3c462fc167044a3e3 Mon Sep 17 00:00:00 2001 From: Someone Date: Sun, 13 Jan 2019 02:12:46 +0100 Subject: [PATCH] Basically a full rewrite/heavy cleanup. --- changelog.txt | 8 + control.lua | 445 +++++++----------- data.lua | 8 +- graphics/entity/Bomb.png | Bin 5608 -> 0 bytes ... - Charging.png => waterbomb-charging.png} | Bin .../entity/{Bomb - Area.png => waterbomb.png} | Bin graphics/icons/{Bomb.png => waterbomb.png} | Bin info.json | 20 +- locale/en/entity-descriptions.cfg | 4 - locale/en/entity-names.cfg | 4 - locale/en/landfill.cfg | 27 -- locale/en/waterbomb.cfg | 11 + migrations/Waterbomb_0.16.5.json | 12 + prototypes/entities.lua | 111 ++--- prototypes/items.lua | 28 +- prototypes/projectiles.lua | 140 +++--- prototypes/recipes.lua | 38 +- 17 files changed, 360 insertions(+), 496 deletions(-) delete mode 100644 graphics/entity/Bomb.png rename graphics/entity/{Bomb - Charging.png => waterbomb-charging.png} (100%) rename graphics/entity/{Bomb - Area.png => waterbomb.png} (100%) rename graphics/icons/{Bomb.png => waterbomb.png} (100%) delete mode 100644 locale/en/entity-descriptions.cfg delete mode 100644 locale/en/entity-names.cfg delete mode 100644 locale/en/landfill.cfg create mode 100644 locale/en/waterbomb.cfg create mode 100644 migrations/Waterbomb_0.16.5.json diff --git a/changelog.txt b/changelog.txt index 9edd64a..edc4bfb 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,11 @@ +--------------------------------------------------------------------------------------------------- +Version: 0.16.6 +Date: 2019-01-13 + + Changed: + - Basically a full rewrite/code cleanup. + - Losing previous changes made me GITify all my mods. + --------------------------------------------------------------------------------------------------- Version: 0.16.4 Date: 2018-08-21 diff --git a/control.lua b/control.lua index a3a833f..b50bd79 100644 --- a/control.lua +++ b/control.lua @@ -1,264 +1,181 @@ - ---[[added by someone1337: water-creation + displace dirt radius]] -local explosionRadius = 3 - -local displaceDirt = false -local throwRocksIntoWater = false -local throwRocks = true -local maximumRockThrowDistance = explosionRadius + 9 -local bombs -local replaceableTiles = -{ - ["water"] = "grass-1", - ["deepwater"] = "grass-1", - ["water-green"] = "grass-1", - ["deepwater-green"] = "grass-1" -} - -script.on_configuration_changed(function(data) - if global.bombs ~= nil then - for k,v in pairs(global.bombs) do - if v[1].valid and v[5] == nil then - v[5] = v[1].surface - end - end - - if global.ticks == nil then - global.ticks = 0 - end - end -end) - -script.on_load(function(event) - if global.bombs ~= nil then - bombs = global.bombs - script.on_event(defines.events.on_tick, tickBombs) - end -end) - -function tickBombs() - if global.ticks > 0 then global.ticks = global.ticks - 1 else global.ticks = 10, executeTicks() end -end - -function executeTicks() - local x,y - local distX,distY - local energy - - for k,v in pairs(bombs) do - if v[1].valid and v[2] == 0 then - energy = v[1].energy - - if energy > 49000000 then - x = v[1].position.x - y = v[1].position.y - - for xx = x - 5.5,x + 5.5,1.5 do - for yy = y - 5.5,y + 5.5,1.5 do - distX = math.abs(x - xx) - distY = math.abs(y - yy) - - if math.floor(math.sqrt((distX * distX) + (distY * distY))) <= 5 then - v[1].surface.create_entity({name = "medium-explosion", position = {x = xx, y = yy}}) - end - end - end - - v[5].create_entity({name = "water-bomb-detonation", position = v[1].position, target = v[1], speed = 1}) - v[4] = v[1].position - v[1].destroy() - v[2] = 1 - v[3] = game.tick - - --[[changed by someone1337: use explosionRadius instead of hardcoded radius]] - createWater(x, y, explosionRadius, v[5]) - throwDirt(x, y, explosionRadius, v[5]) --- no smoke for now - -- else - -- if energy > 40000000 then - -- v[5].create_entity({name = "smoke", position = v[1].position}) - -- v[5].create_entity({name = "smoke", position = {x = v[1].position.x, y = v[1].position.y - 0.2}}) - -- elseif energy > 30000000 then - -- v[5].create_entity({name = "smoke", position = v[1].position}) - -- end - end - else - if v[2] == 1 then - if game.tick - v[3] > 90 then - for a = 1,explosionRadius*2 do - createRandomStone(v[4], v[5]) - createRandomStone(v[4], v[5]) - createRandomStone(v[4], v[5]) - createRandomStone(v[4], v[5]) - end - v[2] = 0 - elseif game.tick - v[3] > 80 then - for a = 1,explosionRadius*2 do - createRandomStone(v[4], v[5]) - createRandomStone(v[4], v[5]) - createRandomStone(v[4], v[5]) - createRandomStone(v[4], v[5]) - end - elseif game.tick - v[3] > 70 then - for a = 1,explosionRadius*2 do - createRandomStone(v[4], v[5]) - createRandomStone(v[4], v[5]) - end - elseif game.tick - v[3] > 60 then - for a = 1,explosionRadius*2 do - createRandomStone(v[4], v[5]) - createRandomStone(v[4], v[5]) - createRandomStone(v[4], v[5]) - end - end - else - table.remove(bombs, k) - if #global.bombs == 0 then - bombs = nil - global.bombs = nil - script.on_event(defines.events.on_tick, nil) - end - end - end - end -end - -function createWater(x, y, size, surface) - local players = surface.find_entities_filtered({area = {{x - size - 1, y - size - 1}, {x + size + 1, y + size + 1}}, type="player"}) - -- Setting tiles to water where players are standing deletes the player and sets them to god mode. - if #players ~= 0 then - return - end - - local waterTiles = {} - x = math.floor(x) - y = math.floor(y) - - for wx = x - size, x + size, 1 do - for wy = y - size, y + size, 1 do - table.insert(waterTiles, {name="water", position={wx, wy}}) - end - end - - surface.set_tiles(waterTiles) - - -- [[ changed by someone1337: deep water at the place of the bomb itself]] - waterTiles = {} - table.insert(waterTiles, {name="deepwater", position={x, y}}) - surface.set_tiles(waterTiles) -end - -function throwDirt(x, y, size, surface) - local dirtTiles = {} - local tileName - local floor = math.floor - local distX,distY - - if displaceDirt == true then - x = floor(x) - y = floor(y) - - for xx = x - (size + 1), x + (size + 1), 1 do - for yy = y - (size + 1), y + (size + 1), 1 do - distX = math.abs(x - xx) - distY = math.abs(y - yy) - - if floor(math.sqrt((distX * distX) + (distY * distY))) >= 2 then - table.insert(dirtTiles, {name = "grass-1", position = {xx, yy}}) - end - end - end - - if #dirtTiles ~= 0 then - surface.set_tiles(dirtTiles) - end - end -end - -function createRandomStone(position, surface) - local x,y - local tileName - local floor = math.floor - local random = math.random - - if throwRocks == true then - x = position.x - y = position.y - - if random() > 0.5 then - x = x - floor(random(2, maximumRockThrowDistance)) - else - x = x + floor(random(2, maximumRockThrowDistance)) - end - - if random() < 0.5 then - y = y - floor(random(2, maximumRockThrowDistance)) - else - y = y + floor(random(2, maximumRockThrowDistance)) - end - - tileName = surface.get_tile(floor(x), floor(y)).name - - if replaceableTiles[tileName] then - if throwRocksIntoWater == true then - surface.set_tiles({{name=replaceableTiles[tileName], position={floor(x), floor(y)}}}) - end - else - if floor(random(1, 4)) > 2 then - surface.create_entity({name = "stone", position = {x, y}}).amount = floor(random(13, 27)) - surface.create_entity({name = "explosion", position = {x, y}}) --- surface.create_entity({name = "smoke", position = {x, y}}) - end - end - end -end - -script.on_event(defines.events.on_built_entity, function(event) - local newBomb - local bombEntity - local player = game.players[event.player_index] - - if event.created_entity.name == "water-bomb-area" then - bombEntity = player.surface.create_entity({name = "water-bomb", position = event.created_entity.position, force = event.created_entity.force}) - event.created_entity.destroy() - - if global.bombs == nil then - global.bombs = {} - bombs = global.bombs - script.on_event(defines.events.on_tick, tickBombs) - if global.ticks == nil then - global.ticks = 0 - end - end - - newBomb = {} - newBomb[1] = bombEntity -- Bomb entity - newBomb[2] = 0 -- Bomb state (charging:0, detonated:1) - newBomb[3] = 0 -- Tick detonation occurred - newBomb[5] = bombEntity.surface - - table.insert(bombs, newBomb) - end -end) - - -function setTilesAndUpdateChunks(tiles, chunks, player) - player.surface.set_tiles(tiles) - - -- Creates a stone entity in each chunk effected by the flood fill triggering a minimap update and then destroys it - if chunks ~= nil then - local force = player.force - for x in pairs(chunks) do - for y in pairs(chunks[x]) do - player.surface.create_entity({name = "stone", position = {x * 32, y * 32}, force = force}).destroy() - end - end - end -end - - -function modifyReplaceableTile(sourceTile, replaceTile) - if not replaceableTiles[sourceTile] or replaceableTiles[sourceTile] ~= replaceTile then - replaceableTiles[sourceTile] = replaceTile - end -end +local explosionRadius = 2 + +local displaceDirt = true +local throwRocksIntoWater = true +local throwRocks = true +local maximumRockThrowDistance = explosionRadius + 8 +local bombs +local replaceableTiles = { + ["water"] = "grass-1", + ["deepwater"] = "grass-1", + ["water-green"] = "grass-1", + ["deepwater-green"] = "grass-1" +} + + +script.on_configuration_changed(function(data) + if global.waterbombs ~= nil then + script.on_event(defines.events.on_tick, tickBombs) + end +end) + + +script.on_load(function(event) + if global.waterbombs ~= nil then + script.on_event(defines.events.on_tick, tickBombs) + end +end) + + +script.on_event(defines.events.on_built_entity, function(event) + if event.created_entity.name == "waterbomb" then + global.waterbombs = {} + for _, surface in pairs(game.surfaces) do + for _, entity in pairs(surface.find_entities_filtered{name="waterbomb"}) do + table.insert(global.waterbombs, entity) + end + end + script.on_event(defines.events.on_tick, tickBombs) + end +end) + + +function tickBombs(event) + if event.tick % 20 == 0 then + for k,e in pairs(global.waterbombs) do + if not e.valid then + table.remove(global.waterbombs, k) + + elseif e.energy > 49000000 then + local x, y, distX, distY, surface + x = e.position.x + y = e.position.y + surface = e.surface + + -- create explosions + for xx = x - explosionRadius, x + explosionRadius, 2 do + for yy = y - explosionRadius, y + explosionRadius, 2 do + distX = math.abs(x - xx) + distY = math.abs(y - yy) + + if math.floor(math.sqrt((distX * distX) + (distY * distY))) <= explosionRadius then + e.surface.create_entity({name = "medium-explosion", position = {x = xx, y = yy}}) + end + end + end + + -- big detonation + e.surface.create_entity({name = "waterbomb-detonation", position = e.position, target = e, speed = 1}) + + -- random stones + for a = 1, explosionRadius * 10 do + createRandomStone(e.position, surface) + createRandomStone(e.position, surface) + end + + -- bomb explodes + e.destroy() + table.remove(global.waterbombs, k) + + -- water is created + createWater(x, y, explosionRadius, surface) + throwDirt(x, y, explosionRadius, surface) + end + end + + -- nothing more to be exploded. Stop ticking. + if #global.waterbombs == 0 then + global.waterbombs = nil + script.on_event(defines.events.on_tick, nil) + end + end +end + +function createWater(x, y, size, surface) + -- Setting tiles to water where players are standing deletes the player and sets them to god mode. + local players = surface.find_entities_filtered({area = {{x - size - 1, y - size - 1}, {x + size + 1, y + size + 1}}, type="player"}) + if #players ~= 0 then + return + end + + local waterTiles = {} + x = math.floor(x) + y = math.floor(y) + + for wx = x - size, x + size, 1 do + for wy = y - size, y + size, 1 do + table.insert(waterTiles, {name="water", position={wx, wy}}) + end + end + surface.set_tiles(waterTiles) + + waterTiles = {} + table.insert(waterTiles, {name="deepwater", position={x, y}}) + surface.set_tiles(waterTiles) +end + + +function throwDirt(x, y, size, surface) + local dirtTiles = {} + local tileName + local floor = math.floor + local distX,distY + + if displaceDirt == true then + x = floor(x) + y = floor(y) + + for xx = x - (size + 1), x + (size + 1), 1 do + for yy = y - (size + 1), y + (size + 1), 1 do + distX = math.abs(x - xx) + distY = math.abs(y - yy) + + if floor(math.sqrt((distX * distX) + (distY * distY))) >= 2 then + table.insert(dirtTiles, {name = "grass-1", position = {xx, yy}}) + end + end + end + + if #dirtTiles ~= 0 then + surface.set_tiles(dirtTiles) + end + end +end + + +function createRandomStone(position, surface) + local x,y + local tileName + local floor = math.floor + local random = math.random + + if throwRocks == true then + x = position.x + y = position.y + + if random() > 0.5 then + x = x - floor(random(2, maximumRockThrowDistance)) + else + x = x + floor(random(2, maximumRockThrowDistance)) + end + + if random() < 0.5 then + y = y - floor(random(2, maximumRockThrowDistance)) + else + y = y + floor(random(2, maximumRockThrowDistance)) + end + + tileName = surface.get_tile(floor(x), floor(y)).name + + if replaceableTiles[tileName] then + if throwRocksIntoWater == true then + surface.set_tiles({{name=replaceableTiles[tileName], position={floor(x), floor(y)}}}) + end + else + if floor(random(1, 4)) > 2 then + surface.create_entity({name = "stone", position = {x, y}}).amount = floor(random(13, 27)) + surface.create_entity({name = "explosion", position = {x, y}}) + end + end + end +end diff --git a/data.lua b/data.lua index ae1140a..0d7b6ec 100644 --- a/data.lua +++ b/data.lua @@ -1,4 +1,4 @@ -require("prototypes.entities") -require("prototypes.items") -require("prototypes.recipes") -require("prototypes.projectiles") \ No newline at end of file +require("prototypes.entities") +require("prototypes.items") +require("prototypes.recipes") +require("prototypes.projectiles") diff --git a/graphics/entity/Bomb.png b/graphics/entity/Bomb.png deleted file mode 100644 index 451e3f4536fdc9f89ad6fca17153c803d7ea6048..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5608 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