mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2025-03-17 20:58:13 +02:00
Merge branch 'develop' into patch-1
This commit is contained in:
commit
b1d67a367b
@ -113,6 +113,9 @@ require 'modules.autostash'
|
||||
--require 'maps.choppy'
|
||||
--require 'maps.choppy_dx'
|
||||
|
||||
--![[Minesweeper?]]--
|
||||
--require 'maps.minesweeper.main'
|
||||
|
||||
--![[Infinite random dungeon with RPG]]--
|
||||
--require 'maps.dungeons.main'
|
||||
--require 'maps.dungeons.tiered_dungeon'
|
||||
|
136
maps/minesweeper/functions.lua
Normal file
136
maps/minesweeper/functions.lua
Normal file
@ -0,0 +1,136 @@
|
||||
--luacheck: ignore
|
||||
local Public = {}
|
||||
local LootRaffle = require "functions.loot_raffle"
|
||||
local Get_noise = require "utils.get_noise"
|
||||
|
||||
local ores = {}
|
||||
ores[1] = {}
|
||||
ores[2] = {}
|
||||
for _ = 1, 15, 1 do table.insert(ores[1], "iron-ore") end
|
||||
for _ = 1, 9, 1 do table.insert(ores[1], "coal") end
|
||||
for _ = 1, 1, 1 do table.insert(ores[1], "crude-oil") end
|
||||
for _ = 1, 6, 1 do table.insert(ores[2], "copper-ore") end
|
||||
for _ = 1, 4, 1 do table.insert(ores[2], "stone") end
|
||||
for _ = 1, 1, 1 do table.insert(ores[2], "uranium-ore") end
|
||||
|
||||
function Public.kaboom(position)
|
||||
local surface = game.surfaces[1]
|
||||
surface.create_entity({name = "atomic-rocket", position = {position.x + 1, position.y + 1}, target = {position.x + 1, position.y + 1}, speed = 1, force = "minesweeper"})
|
||||
end
|
||||
|
||||
function Public.is_minefield_tile(position, search_cell)
|
||||
if search_cell then
|
||||
for x = 0, 1, 1 do
|
||||
for y = 0, 1, 1 do
|
||||
local p = {x = position.x + x, y = position.y + y}
|
||||
local tile = game.surfaces.nauvis.get_tile(p)
|
||||
if tile.name == "nuclear-ground" then return true end
|
||||
if tile.hidden_tile == "nuclear-ground" then return true end
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
local tile = game.surfaces.nauvis.get_tile(position)
|
||||
if tile.name == "nuclear-ground" then return true end
|
||||
if tile.hidden_tile == "nuclear-ground" then return true end
|
||||
end
|
||||
|
||||
function Public.position_to_string(p)
|
||||
return p.x .. "_" .. p.y
|
||||
end
|
||||
|
||||
function Public.position_to_cell_position(p)
|
||||
local cell_position = {}
|
||||
cell_position.x = math.floor(p.x * 0.5) * 2
|
||||
cell_position.y = math.floor(p.y * 0.5) * 2
|
||||
return cell_position
|
||||
end
|
||||
|
||||
function Public.get_terrain_tile(surface, position)
|
||||
local seed = surface.map_gen_settings.seed
|
||||
|
||||
local noise_1 = Get_noise("smol_areas", position, seed)
|
||||
local noise_2 = Get_noise("cave_rivers", position, seed)
|
||||
|
||||
local a = 0.08
|
||||
if math.floor((noise_1 * 8) % 5) ~= 0 then
|
||||
if math.abs(noise_2) < a then
|
||||
return "water-shallow"
|
||||
end
|
||||
end
|
||||
|
||||
if noise_2 > 0 then return "sand-" .. math.floor((noise_2 * 10) % 3 + 1) end
|
||||
return "grass-" .. math.floor((noise_2 * 10) % 3 + 1)
|
||||
end
|
||||
|
||||
function Public.disarm_reward(position)
|
||||
local surface = game.surfaces[1]
|
||||
local distance_to_center = math.sqrt(position.x ^ 2 + position.y ^ 2)
|
||||
|
||||
surface.create_entity({
|
||||
name = "flying-text",
|
||||
position = {position.x + 1, position.y + 1},
|
||||
text = "Mine disarmed!",
|
||||
color = {r=0.98, g=0.66, b=0.22}
|
||||
})
|
||||
|
||||
local tile_name = Public.get_terrain_tile(surface, position)
|
||||
|
||||
if math.random(1, 3) ~= 1 or tile_name == "water-shallow" then return end
|
||||
|
||||
if math.random(1, 8) == 1 then
|
||||
local blacklist = LootRaffle.get_tech_blacklist(0.05 + distance_to_center * 0.00025) --max loot tier at ~4000 tiles
|
||||
local item_stacks = LootRaffle.roll(math.random(16, 48) + math.floor(distance_to_center * 0.2), 16, blacklist)
|
||||
local container = surface.create_entity({name = "crash-site-chest-" .. math.random(1, 2), position = {position.x + math.random(0, 1), position.y + math.random(0, 1)}, force = "neutral"})
|
||||
for _, item_stack in pairs(item_stacks) do container.insert(item_stack) end
|
||||
container.minable = false
|
||||
return
|
||||
end
|
||||
|
||||
local a, b = string.find(tile_name, "grass", 1, true)
|
||||
local ore
|
||||
if a then
|
||||
ore = ores[1][math.random(1, #ores[1])]
|
||||
else
|
||||
ore = ores[2][math.random(1, #ores[2])]
|
||||
end
|
||||
|
||||
if ore == "crude-oil" then
|
||||
surface.create_entity({name = "crude-oil", position = {position.x + 1, position.y + 1}, amount = 301000 + distance_to_center * 600})
|
||||
return
|
||||
end
|
||||
|
||||
for x = 0, 1, 1 do
|
||||
for y = 0, 1, 1 do
|
||||
local p = {x = position.x + x, y = position.y + y}
|
||||
local tile_name = Public.get_terrain_tile(surface, p)
|
||||
if tile_name ~= "water-shallow" then
|
||||
surface.create_entity({name = ore, position = p, amount = 1000 + distance_to_center * 2})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Public.uncover_terrain(position)
|
||||
local surface = game.surfaces[1]
|
||||
for x = 0, 1, 1 do
|
||||
for y = 0, 1, 1 do
|
||||
local p = {x = position.x + x, y = position.y + y}
|
||||
local tile_name = Public.get_terrain_tile(surface, p)
|
||||
local tile = surface.get_tile(p)
|
||||
local mineable_tile_name = false
|
||||
if tile.prototype.mineable_properties.minable then mineable_tile_name = tile.name end
|
||||
|
||||
surface.set_hidden_tile(p, nil)
|
||||
surface.set_tiles({{name = tile_name, position = p}}, true)
|
||||
if math.random(1, 16) == 1 and tile_name == "water-shallow" then
|
||||
surface.create_entity({name = "fish", position = p})
|
||||
end
|
||||
|
||||
if mineable_tile_name then surface.set_tiles({{name = mineable_tile_name, position = p}}, true) end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return Public
|
582
maps/minesweeper/main.lua
Normal file
582
maps/minesweeper/main.lua
Normal file
@ -0,0 +1,582 @@
|
||||
--luacheck: ignore
|
||||
--[[
|
||||
It's a Minesweeper thingy - MewMew
|
||||
-- 1 to 9 = adjacent mines
|
||||
-- 10 = mine
|
||||
-- 11 = marked mine
|
||||
]] --
|
||||
|
||||
require 'modules.satellite_score'
|
||||
|
||||
local Functions = require 'maps.minesweeper.functions'
|
||||
local Map_score = require 'comfy_panel.map_score'
|
||||
local Map = require 'modules.map_info'
|
||||
local Global = require 'utils.global'
|
||||
|
||||
local minesweeper = {}
|
||||
Global.register(
|
||||
minesweeper,
|
||||
function(tbl)
|
||||
minesweeper = tbl
|
||||
end
|
||||
)
|
||||
|
||||
local number_colors = {
|
||||
[1] = {0, 0, 210},
|
||||
[2] = {0, 100, 0},
|
||||
[3] = {180, 0, 0},
|
||||
[4] = {0, 0, 120},
|
||||
[5] = {120, 0, 0},
|
||||
[6] = {0, 110, 110},
|
||||
[7] = {0, 0, 0},
|
||||
[8] = {125, 125, 125},
|
||||
[11] = {185, 0, 255}
|
||||
}
|
||||
|
||||
local rendering_tile_values = {
|
||||
['nuclear-ground'] = {offset = {0.6, -0.2}, zoom = 3, font = 'scenario-message-dialog'},
|
||||
['stone-path'] = {offset = {0.54, -0.27}, zoom = 3, font = 'default-large'},
|
||||
['concrete'] = {offset = {0.52, -0.28}, zoom = 3, font = 'default-large-bold'},
|
||||
['hazard-concrete-left'] = {offset = {0.52, -0.28}, zoom = 3, font = 'default-large-bold'},
|
||||
['hazard-concrete-right'] = {offset = {0.52, -0.28}, zoom = 3, font = 'default-large-bold'},
|
||||
['refined-concrete'] = {offset = {0.54, -0.26}, zoom = 3, font = 'default-game'},
|
||||
['refined-hazard-concrete-left'] = {offset = {0.54, -0.26}, zoom = 3, font = 'default-game'},
|
||||
['refined-hazard-concrete-right'] = {offset = {0.54, -0.26}, zoom = 3, font = 'default-game'}
|
||||
}
|
||||
|
||||
local chunk_divide_vectors = {}
|
||||
for x = 0, 30, 2 do
|
||||
for y = 0, 30, 2 do
|
||||
table.insert(chunk_divide_vectors, {x, y})
|
||||
end
|
||||
end
|
||||
local size_of_chunk_divide_vectors = #chunk_divide_vectors
|
||||
|
||||
local chunk_vectors = {}
|
||||
for x = -32, 32, 32 do
|
||||
for y = -32, 32, 32 do
|
||||
table.insert(chunk_vectors, {x, y})
|
||||
end
|
||||
end
|
||||
|
||||
local cell_update_vectors = {}
|
||||
for x = -2, 2, 2 do
|
||||
for y = -2, 2, 2 do
|
||||
table.insert(cell_update_vectors, {x, y})
|
||||
end
|
||||
end
|
||||
|
||||
local cell_adjacent_vectors = {}
|
||||
for x = -2, 2, 2 do
|
||||
for y = -2, 2, 2 do
|
||||
if x == 0 and y == 0 then
|
||||
else
|
||||
table.insert(cell_adjacent_vectors, {x, y})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local solving_vector_tables = {}
|
||||
local i = 1
|
||||
for r = 3, 10, 1 do
|
||||
solving_vector_tables[i] = {}
|
||||
for x = r * -2, r * 2, 2 do
|
||||
for y = r * -2, r * 2, 2 do
|
||||
table.insert(solving_vector_tables[i], {x, y})
|
||||
end
|
||||
end
|
||||
i = i + 1
|
||||
end
|
||||
local size_of_solving_vector_tables = #solving_vector_tables
|
||||
|
||||
local function update_rendering(cell, position)
|
||||
local tile = game.surfaces.nauvis.get_tile(position)
|
||||
local tile_values = rendering_tile_values[tile.name]
|
||||
if not tile_values then
|
||||
tile_values = {offset = {0.6, -0.2}, zoom = 3, font = 'scenario-message-dialog'}
|
||||
end
|
||||
|
||||
if cell[2] then
|
||||
rendering.destroy(cell[2])
|
||||
end
|
||||
|
||||
local cell_value = cell[1]
|
||||
|
||||
local color
|
||||
if number_colors[cell_value] then
|
||||
color = number_colors[cell_value]
|
||||
else
|
||||
color = {125, 125, 125}
|
||||
end
|
||||
|
||||
local p = {position.x + tile_values.offset[1], position.y + tile_values.offset[2]}
|
||||
local text = cell_value
|
||||
if cell_value == 11 then
|
||||
text = 'X'
|
||||
end
|
||||
|
||||
cell[2] =
|
||||
rendering.draw_text {
|
||||
text = text,
|
||||
surface = game.surfaces[1],
|
||||
target = p,
|
||||
color = color,
|
||||
scale = tile_values.zoom,
|
||||
font = tile_values.font,
|
||||
draw_on_ground = true,
|
||||
scale_with_zoom = false,
|
||||
only_in_alt_mode = false
|
||||
}
|
||||
end
|
||||
|
||||
local function get_adjacent_mine_count(position)
|
||||
local count = 0
|
||||
for _, vector in pairs(cell_adjacent_vectors) do
|
||||
local p = {x = position.x + vector[1], y = position.y + vector[2]}
|
||||
local key = Functions.position_to_string(p)
|
||||
local cell = minesweeper.cells[key]
|
||||
if cell and cell[1] >= 10 then
|
||||
count = count + 1
|
||||
end
|
||||
end
|
||||
return count
|
||||
end
|
||||
|
||||
local function kill_cell(position)
|
||||
local key = Functions.position_to_string(position)
|
||||
local cell = minesweeper.cells[key]
|
||||
if cell and cell[2] then
|
||||
rendering.destroy(cell[2])
|
||||
end
|
||||
minesweeper.cells[key] = nil
|
||||
end
|
||||
|
||||
local function visit_cell(position)
|
||||
local score_change = 0
|
||||
|
||||
if not Functions.is_minefield_tile(position, true) then
|
||||
return score_change
|
||||
end
|
||||
|
||||
local key = Functions.position_to_string(position)
|
||||
local cell = minesweeper.cells[key]
|
||||
local cell_value_before_visit = false
|
||||
|
||||
if cell then
|
||||
if cell[1] == 10 then
|
||||
Functions.kaboom(position)
|
||||
score_change = -8
|
||||
cell[1] = -1
|
||||
for _, vector in pairs(cell_update_vectors) do
|
||||
local p = {x = position.x + vector[1], y = position.y + vector[2]}
|
||||
local key = Functions.position_to_string(p)
|
||||
if minesweeper.cells[key] and minesweeper.cells[key][1] < 10 then
|
||||
table.insert(minesweeper.visit_queue, {x = p.x, y = p.y})
|
||||
end
|
||||
end
|
||||
return score_change
|
||||
end
|
||||
|
||||
if cell[1] == 11 then
|
||||
return score_change
|
||||
end
|
||||
|
||||
cell_value_before_visit = cell[1]
|
||||
end
|
||||
|
||||
if not cell then
|
||||
minesweeper.cells[key] = {}
|
||||
end
|
||||
local cell = minesweeper.cells[key]
|
||||
|
||||
cell[1] = get_adjacent_mine_count(position)
|
||||
|
||||
if cell[1] == 0 then
|
||||
for _, vector in pairs(cell_adjacent_vectors) do
|
||||
local adjacent_position = {x = position.x + vector[1], y = position.y + vector[2]}
|
||||
if Functions.is_minefield_tile(adjacent_position, true) then
|
||||
local adjacent_key = Functions.position_to_string(adjacent_position)
|
||||
if not minesweeper.cells[adjacent_key] then
|
||||
minesweeper.cells[adjacent_key] = {}
|
||||
end
|
||||
local adjacent_cell = minesweeper.cells[adjacent_key]
|
||||
local mine_count = get_adjacent_mine_count(adjacent_position)
|
||||
adjacent_cell[1] = mine_count
|
||||
update_rendering(adjacent_cell, adjacent_position)
|
||||
if mine_count == 0 then
|
||||
table.insert(minesweeper.visit_queue, {x = adjacent_position.x, y = adjacent_position.y})
|
||||
end
|
||||
end
|
||||
end
|
||||
Functions.uncover_terrain(position)
|
||||
kill_cell(position)
|
||||
return score_change
|
||||
end
|
||||
|
||||
if cell_value_before_visit and cell_value_before_visit ~= cell[1] then
|
||||
for _, vector in pairs(cell_adjacent_vectors) do
|
||||
local adjacent_position = {x = position.x + vector[1], y = position.y + vector[2]}
|
||||
local adjacent_key = Functions.position_to_string(adjacent_position)
|
||||
local adjacent_cell = minesweeper.cells[adjacent_key]
|
||||
if adjacent_cell and adjacent_cell[1] < 9 then
|
||||
table.insert(minesweeper.visit_queue, {x = adjacent_position.x, y = adjacent_position.y})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
update_rendering(cell, position)
|
||||
|
||||
return score_change
|
||||
end
|
||||
|
||||
local function get_solving_vectors(position)
|
||||
local distance_to_center = math.sqrt(position.x ^ 2 + position.y ^ 2)
|
||||
local key = math.floor(distance_to_center * 0.005) + 1
|
||||
if key > size_of_solving_vector_tables then
|
||||
key = size_of_solving_vector_tables
|
||||
end
|
||||
local solving_vectors = solving_vector_tables[key]
|
||||
return solving_vectors
|
||||
end
|
||||
|
||||
local function are_mines_marked_around_target(position)
|
||||
local marked_positions = {}
|
||||
for _, vector in pairs(get_solving_vectors(position)) do
|
||||
local p = {x = position.x + vector[1], y = position.y + vector[2]}
|
||||
local key = Functions.position_to_string(p)
|
||||
local cell = minesweeper.cells[key]
|
||||
if cell then
|
||||
if cell[1] == 10 then
|
||||
return
|
||||
end
|
||||
if cell[1] == 11 then
|
||||
table.insert(marked_positions, p)
|
||||
end
|
||||
end
|
||||
end
|
||||
return marked_positions
|
||||
end
|
||||
|
||||
local function solve_attempt(position)
|
||||
local solved = false
|
||||
for _, vector in pairs(get_solving_vectors(position)) do
|
||||
local p = {x = position.x + vector[1], y = position.y + vector[2]}
|
||||
local key = Functions.position_to_string(p)
|
||||
local cell = minesweeper.cells[key]
|
||||
if cell and cell[1] > 10 then
|
||||
local marked_positions = are_mines_marked_around_target(p)
|
||||
if marked_positions then
|
||||
solved = true
|
||||
for _, p in pairs(marked_positions) do
|
||||
minesweeper.cells[Functions.position_to_string(p)][1] = -1
|
||||
visit_cell(p)
|
||||
Functions.disarm_reward(p)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return solved
|
||||
end
|
||||
|
||||
local function mark_mine(entity, player)
|
||||
local position = Functions.position_to_cell_position(entity.position)
|
||||
local key = Functions.position_to_string(position)
|
||||
local cell = minesweeper.cells[key]
|
||||
local score_change = 0
|
||||
|
||||
--Success
|
||||
if cell and cell[1] > 9 then
|
||||
local surface = game.surfaces.nauvis
|
||||
|
||||
if cell[1] == 10 then
|
||||
score_change = 1
|
||||
end
|
||||
|
||||
surface.create_entity(
|
||||
{
|
||||
name = 'flying-text',
|
||||
position = entity.position,
|
||||
text = 'Mine marked.',
|
||||
color = {r = 0.98, g = 0.66, b = 0.22}
|
||||
}
|
||||
)
|
||||
|
||||
cell[1] = 11
|
||||
update_rendering(cell, position)
|
||||
entity.destroy()
|
||||
|
||||
local solved = solve_attempt(position)
|
||||
if solved then
|
||||
player.insert({name = 'stone-furnace', count = 1})
|
||||
return score_change
|
||||
end
|
||||
|
||||
local e = surface.create_entity({name = 'item-on-ground', position = {position.x + 1, position.y + 1}, stack = {name = 'stone-furnace', count = 1}})
|
||||
if e and e.valid then
|
||||
e.to_be_looted = true
|
||||
end
|
||||
|
||||
return score_change
|
||||
end
|
||||
|
||||
--Trigger all adjacent mines when missplacing a disarming furnace.
|
||||
for _, vector in pairs(cell_update_vectors) do
|
||||
local p = {x = position.x + vector[1], y = position.y + vector[2]}
|
||||
local key = Functions.position_to_string(p)
|
||||
if minesweeper.cells[key] and minesweeper.cells[key][1] == 10 then
|
||||
Functions.kaboom(p)
|
||||
score_change = score_change - 8
|
||||
minesweeper.cells[key][1] = -1
|
||||
solve_attempt(p)
|
||||
table.insert(minesweeper.visit_queue, {x = p.x, y = p.y})
|
||||
end
|
||||
end
|
||||
return score_change
|
||||
end
|
||||
|
||||
local function add_mines_to_chunk(left_top)
|
||||
local distance_to_center = math.sqrt((left_top.x + 16) ^ 2 + (left_top.y + 16) ^ 2)
|
||||
local base_mine_count = 40
|
||||
local max_mine_count = 128
|
||||
local mine_count = distance_to_center * 0.043 + base_mine_count
|
||||
if mine_count > max_mine_count then
|
||||
mine_count = max_mine_count
|
||||
end
|
||||
|
||||
local shuffle_index = {}
|
||||
for i = 1, size_of_chunk_divide_vectors, 1 do
|
||||
table.insert(shuffle_index, i)
|
||||
end
|
||||
table.shuffle_table(shuffle_index)
|
||||
|
||||
-- place shuffled mines
|
||||
for i = 1, mine_count, 1 do
|
||||
local vector = chunk_divide_vectors[shuffle_index[i]]
|
||||
local position = {x = left_top.x + vector[1], y = left_top.y + vector[2]}
|
||||
local key = Functions.position_to_string(position)
|
||||
minesweeper.cells[key] = {10}
|
||||
minesweeper.active_mines = minesweeper.active_mines + 1
|
||||
end
|
||||
|
||||
-- remove mines that would form a 3x3 block
|
||||
for _, chunk_vector in pairs(chunk_vectors) do
|
||||
local left_top_2 = {x = left_top.x + chunk_vector[1], y = left_top.y + chunk_vector[2]}
|
||||
|
||||
for _, vector in pairs(chunk_divide_vectors) do
|
||||
local position = {x = left_top_2.x + vector[1], y = left_top_2.y + vector[2]}
|
||||
local key = Functions.position_to_string(position)
|
||||
local cell = minesweeper.cells[key]
|
||||
if cell and cell[1] == 10 then
|
||||
if get_adjacent_mine_count(position) == 8 then
|
||||
--if cell[2] then rendering.destroy(cell[2]) end
|
||||
minesweeper.cells[key] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
--[[
|
||||
for _, vector in pairs(chunk_divide_vectors) do
|
||||
local position = {x = left_top_2.x + vector[1], y = left_top_2.y + vector[2]}
|
||||
local key = Functions.position_to_string(position)
|
||||
local cell = minesweeper.cells[key]
|
||||
if cell then update_rendering(cell, position) end
|
||||
end
|
||||
]]
|
||||
end
|
||||
end
|
||||
|
||||
local function on_chunk_generated(event)
|
||||
local left_top = event.area.left_top
|
||||
if event.surface.index ~= 1 then
|
||||
return
|
||||
end
|
||||
|
||||
local tiles = {}
|
||||
for x = 0, 31, 1 do
|
||||
for y = 0, 31, 1 do
|
||||
table.insert(tiles, {name = 'nuclear-ground', position = {x = left_top.x + x, y = left_top.y + y}})
|
||||
--table.insert(tiles, {name = Functions.get_terrain_tile(event.surface, {x = left_top.x + x, y = left_top.y + y}), position = {x = left_top.x + x, y = left_top.y + y}})
|
||||
end
|
||||
end
|
||||
event.surface.set_tiles(tiles, true)
|
||||
|
||||
--surface.clear() will cause to trigger on_chunk_generated twice
|
||||
local key = Functions.position_to_string(left_top)
|
||||
if minesweeper.chunks[key] then
|
||||
return
|
||||
end
|
||||
minesweeper.chunks[key] = true
|
||||
|
||||
add_mines_to_chunk(left_top)
|
||||
end
|
||||
|
||||
local function on_player_changed_position(event)
|
||||
local player = game.players[event.player_index]
|
||||
if not Functions.is_minefield_tile(player.position) then
|
||||
return
|
||||
end
|
||||
local cell_position = Functions.position_to_cell_position(player.position)
|
||||
local score_change = visit_cell(cell_position)
|
||||
if score_change < 0 then
|
||||
solve_attempt(cell_position)
|
||||
end
|
||||
Map_score.set_score(player, Map_score.get_score(player) + score_change)
|
||||
end
|
||||
|
||||
local function deny_building(event)
|
||||
local entity = event.created_entity
|
||||
if not entity.valid then
|
||||
return
|
||||
end
|
||||
if entity.name == 'entity-ghost' then
|
||||
return
|
||||
end
|
||||
if Functions.is_minefield_tile(entity.position, true) then
|
||||
if event.player_index then
|
||||
local player = game.players[event.player_index]
|
||||
if entity.position.x % 2 == 1 and entity.position.y % 2 == 1 and entity.name == 'stone-furnace' then
|
||||
local score_change = mark_mine(entity, player)
|
||||
Map_score.set_score(player, Map_score.get_score(player) + score_change)
|
||||
return
|
||||
end
|
||||
player.insert({name = entity.name, count = 1})
|
||||
else
|
||||
local inventory = event.robot.get_inventory(defines.inventory.robot_cargo)
|
||||
inventory.insert({name = entity.name, count = 1})
|
||||
end
|
||||
entity.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
local function on_built_entity(event)
|
||||
deny_building(event)
|
||||
end
|
||||
|
||||
local function on_robot_built_entity(event)
|
||||
deny_building(event)
|
||||
end
|
||||
|
||||
local function update_built_tiles(surface, tiles)
|
||||
for _, placed_tile in pairs(tiles) do
|
||||
local cell_position = Functions.position_to_cell_position(placed_tile.position)
|
||||
local key = Functions.position_to_string(cell_position)
|
||||
local cell = minesweeper.cells[key]
|
||||
if cell and cell[1] ~= 10 then
|
||||
update_rendering(cell, cell_position)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function on_player_built_tile(event)
|
||||
update_built_tiles(game.surfaces[event.surface_index], event.tiles)
|
||||
end
|
||||
|
||||
local function on_robot_built_tile(event)
|
||||
update_built_tiles(event.robot.surface, event.tiles)
|
||||
end
|
||||
|
||||
local function on_player_created(event)
|
||||
local player = game.players[event.player_index]
|
||||
player.insert({name = 'stone-furnace', count = 1})
|
||||
end
|
||||
|
||||
local function on_player_respawned(event)
|
||||
local player = game.players[event.player_index]
|
||||
player.insert({name = 'stone-furnace', count = 1})
|
||||
|
||||
game.surfaces.nauvis.destroy_decoratives({name = 'nuclear-ground-patch'})
|
||||
end
|
||||
|
||||
local function on_entity_died(event)
|
||||
local entity = event.entity
|
||||
if not entity.valid then
|
||||
return
|
||||
end
|
||||
if entity.force.index ~= 2 then
|
||||
return
|
||||
end
|
||||
local force = event.force
|
||||
if not force then
|
||||
return
|
||||
end
|
||||
if force.name ~= 'minesweeper' then
|
||||
return
|
||||
end
|
||||
local revived_entity = entity.clone({position = entity.position})
|
||||
revived_entity.health = entity.prototype.max_health
|
||||
entity.destroy()
|
||||
end
|
||||
|
||||
local function on_nth_tick()
|
||||
for k, position in pairs(minesweeper.visit_queue) do
|
||||
visit_cell(position)
|
||||
table.remove(minesweeper.visit_queue, k)
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
local function on_init()
|
||||
game.create_force('minesweeper')
|
||||
|
||||
global.custom_highscore.description = 'Minesweep rank:'
|
||||
|
||||
local surface = game.surfaces[1]
|
||||
local mgs = surface.map_gen_settings
|
||||
mgs.water = 0
|
||||
mgs.cliff_settings = {cliff_elevation_interval = 0, cliff_elevation_0 = 0}
|
||||
mgs.autoplace_controls = {
|
||||
['coal'] = {frequency = 0, size = 0, richness = 0},
|
||||
['stone'] = {frequency = 0, size = 0, richness = 0},
|
||||
['copper-ore'] = {frequency = 0, size = 0, richness = 0},
|
||||
['iron-ore'] = {frequency = 0, size = 0, richness = 0},
|
||||
['uranium-ore'] = {frequency = 0, size = 0, richness = 0},
|
||||
['crude-oil'] = {frequency = 0, size = 0, richness = 0},
|
||||
['trees'] = {frequency = 4, size = 0.5, richness = 0.1}
|
||||
}
|
||||
surface.map_gen_settings = mgs
|
||||
surface.clear(true)
|
||||
|
||||
minesweeper.chunks = {}
|
||||
minesweeper.cells = {}
|
||||
minesweeper.visit_queue = {}
|
||||
minesweeper.player_data = {}
|
||||
minesweeper.active_mines = 0
|
||||
minesweeper.disarmed_mines = 0
|
||||
minesweeper.triggered_mines = 0
|
||||
|
||||
local T = Map.Pop_info()
|
||||
T.main_caption = 'Minesweeper'
|
||||
T.sub_caption = ''
|
||||
T.text =
|
||||
table.concat(
|
||||
{
|
||||
'Mechanical lifeforms once dominated this world.\n',
|
||||
'They have left long ago, leaving an inhabitable wasteland.\n',
|
||||
'It also seems riddled with buried explosives.\n\n',
|
||||
'Mark mines with your stone furnace.\n',
|
||||
'Marked mines are save to walk on.\n',
|
||||
'When enough mines in an area are marked,\n',
|
||||
'they will disarm and yield rewards!\n',
|
||||
'Faulty marking may trigger surrounding mines!!\n\n',
|
||||
'As you move away from spawn,\n',
|
||||
'mine density and radius required to disarm will increase.\n',
|
||||
'Crates will contain more loot and ore will have higher yield.\n\n',
|
||||
'The paint for the numerics does not work very well with the dirt.\n',
|
||||
'Laying some stone bricks or better may help.\n'
|
||||
}
|
||||
)
|
||||
T.main_caption_color = {r = 255, g = 125, b = 55}
|
||||
T.sub_caption_color = {r = 0, g = 250, b = 150}
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.on_init(on_init)
|
||||
Event.on_nth_tick(2, on_nth_tick)
|
||||
Event.add(defines.events.on_chunk_generated, on_chunk_generated)
|
||||
Event.add(defines.events.on_player_changed_position, on_player_changed_position)
|
||||
Event.add(defines.events.on_built_entity, on_built_entity)
|
||||
Event.add(defines.events.on_entity_died, on_entity_died)
|
||||
Event.add(defines.events.on_robot_built_entity, on_robot_built_entity)
|
||||
Event.add(defines.events.on_player_created, on_player_created)
|
||||
Event.add(defines.events.on_player_respawned, on_player_respawned)
|
||||
Event.add(defines.events.on_robot_built_tile, on_robot_built_tile)
|
||||
Event.add(defines.events.on_player_built_tile, on_player_built_tile)
|
Loading…
x
Reference in New Issue
Block a user