diff --git a/maps/minesweeper/functions.lua b/maps/minesweeper/functions.lua index 46258b13..80310559 100644 --- a/maps/minesweeper/functions.lua +++ b/maps/minesweeper/functions.lua @@ -1,3 +1,4 @@ +--luacheck: ignore local Public = {} local LootRaffle = require "functions.loot_raffle" local Get_noise = require "utils.get_noise" @@ -28,8 +29,8 @@ function Public.is_minefield_tile(position, search_cell) end end return - end - + 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 @@ -48,17 +49,17 @@ 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 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 - + 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 @@ -66,18 +67,18 @@ 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) @@ -86,7 +87,7 @@ function Public.disarm_reward(position) container.minable = false return end - + local a, b = string.find(tile_name, "grass", 1, true) local ore if a then @@ -94,7 +95,7 @@ function Public.disarm_reward(position) 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 @@ -108,7 +109,7 @@ function Public.disarm_reward(position) surface.create_entity({name = ore, position = p, amount = 1000 + distance_to_center * 2}) end end - end + end end function Public.uncover_terrain(position) @@ -132,4 +133,4 @@ function Public.uncover_terrain(position) end end -return Public \ No newline at end of file +return Public diff --git a/maps/minesweeper/main.lua b/maps/minesweeper/main.lua index 31521ab9..ca075d85 100644 --- a/maps/minesweeper/main.lua +++ b/maps/minesweeper/main.lua @@ -1,15 +1,16 @@ +--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 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 = {} @@ -21,319 +22,358 @@ Global.register( ) 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}, + [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"}, + ['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 + 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 + 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 + 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 + 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 + 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 + 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} + 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 + 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 + 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 + local score_change = 0 - if not cell then minesweeper.cells[key] = {} end - local cell = minesweeper.cells[key] - - cell[1] = get_adjacent_mine_count(position) + if not Functions.is_minefield_tile(position, true) then + return score_change + end - 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 + 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 + 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 + 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 + 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} - }) + 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 - 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 + --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 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 - --[[ + 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) @@ -341,171 +381,191 @@ local function add_mines_to_chunk(left_top) if cell then update_rendering(cell, position) end 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) + 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) + 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 + 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) + deny_building(event) end local function on_robot_built_entity(event) - deny_building(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 + 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) + 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) + 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}) + 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"}) + 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() + 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 + 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") + game.create_force('minesweeper') - global.custom_highscore.description = "Minesweep rank:" + 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) + 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} + 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' @@ -519,4 +579,4 @@ 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) \ No newline at end of file +Event.add(defines.events.on_player_built_tile, on_player_built_tile)