mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2025-01-16 02:47:48 +02:00
push latest minesweeper
This commit is contained in:
parent
550bef8445
commit
99abacb36e
@ -1,8 +1,11 @@
|
||||
--luacheck: ignore
|
||||
|
||||
local Public = {}
|
||||
local LootRaffle = require "functions.loot_raffle"
|
||||
local Get_noise = require "utils.get_noise"
|
||||
|
||||
local safe_zone_radius = 16
|
||||
|
||||
local ores = {}
|
||||
ores[1] = {}
|
||||
ores[2] = {}
|
||||
@ -13,17 +16,35 @@ 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
|
||||
|
||||
local function unstuck_players_around_position(surface, position)
|
||||
local area = {{position.x - 2, position.y - 2}, {position.x + 2, position.y + 2}}
|
||||
local characters = surface.find_entities_filtered({name = "character", area = area})
|
||||
for _, character in pairs(characters) do
|
||||
if character.player then
|
||||
local player = character.player
|
||||
local p = surface.find_non_colliding_position('character', player.position, 32, 0.5)
|
||||
if not p then
|
||||
return
|
||||
end
|
||||
player.teleport(p, surface)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Public.kaboom(position)
|
||||
local surface = game.surfaces[1]
|
||||
local count = surface.count_entities_filtered({name = {"atomic-bomb-ground-zero-projectile", "atomic-bomb-wave", "atomic-bomb-wave-spawns-cluster-nuke-explosion", "atomic-bomb-wave-spawns-fire-smoke-explosion","atomic-bomb-wave-spawns-nuclear-smoke", "atomic-bomb-wave-spawns-nuke-shockwave-explosion", "atomic-rocket"}, area = {{position.x - 4, position.y - 4}, {position.x + 4, position.y + 4}}, limit = 1})
|
||||
if count > 0 then return end
|
||||
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)
|
||||
local surface = game.surfaces.nauvis
|
||||
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)
|
||||
local tile = surface.get_tile(p)
|
||||
if tile.name == "nuclear-ground" then return true end
|
||||
if tile.hidden_tile == "nuclear-ground" then return true end
|
||||
end
|
||||
@ -31,11 +52,23 @@ function Public.is_minefield_tile(position, search_cell)
|
||||
return
|
||||
end
|
||||
|
||||
local tile = game.surfaces.nauvis.get_tile(position)
|
||||
local tile = surface.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.is_spawn(position)
|
||||
if math.abs(position.x) > safe_zone_radius then return false end
|
||||
if math.abs(position.y) > safe_zone_radius then return false end
|
||||
local p = {x = position.x, y = position.y}
|
||||
if p.x > 0 then p.x = p.x + 1 end
|
||||
if p.y > 0 then p.y = p.y + 1 end
|
||||
local d = math.sqrt(p.x ^ 2 + p.y ^ 2)
|
||||
if d < safe_zone_radius then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
function Public.position_to_string(p)
|
||||
return p.x .. "_" .. p.y
|
||||
end
|
||||
@ -48,6 +81,8 @@ function Public.position_to_cell_position(p)
|
||||
end
|
||||
|
||||
function Public.get_terrain_tile(surface, position)
|
||||
if Public.is_spawn(position) then return 'black-refined-concrete' end
|
||||
|
||||
local seed = surface.map_gen_settings.seed
|
||||
|
||||
local noise_1 = Get_noise("smol_areas", position, seed)
|
||||
@ -82,9 +117,11 @@ function Public.disarm_reward(position)
|
||||
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"})
|
||||
local p = {x = position.x + math.random(0, 1), y = position.y + math.random(0, 1)}
|
||||
local container = surface.create_entity({name = "crash-site-chest-" .. math.random(1, 2), position = p, force = "neutral"})
|
||||
for _, item_stack in pairs(item_stacks) do container.insert(item_stack) end
|
||||
container.minable = false
|
||||
unstuck_players_around_position(surface, p)
|
||||
return
|
||||
end
|
||||
|
||||
@ -106,7 +143,7 @@ function Public.disarm_reward(position)
|
||||
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})
|
||||
surface.create_entity({name = ore, position = p, amount = 1000 + distance_to_center * 3})
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -128,7 +165,7 @@ function Public.uncover_terrain(position)
|
||||
surface.create_entity({name = "fish", position = p})
|
||||
end
|
||||
|
||||
if mineable_tile_name then surface.set_tiles({{name = mineable_tile_name, position = p}}, true) end
|
||||
if mineable_tile_name and tile_name ~= "water-shallow" then surface.set_tiles({{name = mineable_tile_name, position = p}}, true) end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -1,9 +1,13 @@
|
||||
--luacheck: ignore
|
||||
--[[
|
||||
It's a Minesweeper thingy - MewMew
|
||||
-- 1 to 9 = adjacent mines
|
||||
-- 10 = mine
|
||||
-- 11 = marked mine
|
||||
|
||||
Cell Values:
|
||||
-- 1 to 8 = adjacent mines
|
||||
-- 9 = empty cell with grid
|
||||
-- 10 = mine
|
||||
-- 11 = marked mine
|
||||
|
||||
]] --
|
||||
|
||||
require 'modules.satellite_score'
|
||||
@ -35,7 +39,8 @@ local number_colors = {
|
||||
|
||||
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'},
|
||||
--['stone-path'] = {offset = {0.54, -0.27}, zoom = 3, font = 'default-large'},
|
||||
['stone-path'] = {offset = {0.52, -0.28}, zoom = 3, font = 'default-large-bold'},
|
||||
['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'},
|
||||
@ -90,7 +95,8 @@ 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 surface = game.surfaces[1]
|
||||
local tile = surface.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'}
|
||||
@ -99,6 +105,9 @@ local function update_rendering(cell, position)
|
||||
if cell[2] then
|
||||
rendering.destroy(cell[2])
|
||||
end
|
||||
if cell[3] then
|
||||
rendering.destroy(cell[3])
|
||||
end
|
||||
|
||||
local cell_value = cell[1]
|
||||
|
||||
@ -111,6 +120,9 @@ local function update_rendering(cell, position)
|
||||
|
||||
local p = {position.x + tile_values.offset[1], position.y + tile_values.offset[2]}
|
||||
local text = cell_value
|
||||
if cell_value == 10 or cell_value == 9 then
|
||||
text = ' '
|
||||
end
|
||||
if cell_value == 11 then
|
||||
text = 'X'
|
||||
end
|
||||
@ -118,7 +130,7 @@ local function update_rendering(cell, position)
|
||||
cell[2] =
|
||||
rendering.draw_text {
|
||||
text = text,
|
||||
surface = game.surfaces[1],
|
||||
surface = surface,
|
||||
target = p,
|
||||
color = color,
|
||||
scale = tile_values.zoom,
|
||||
@ -127,6 +139,25 @@ local function update_rendering(cell, position)
|
||||
scale_with_zoom = false,
|
||||
only_in_alt_mode = false
|
||||
}
|
||||
|
||||
if not tile.hidden_tile then
|
||||
return
|
||||
end
|
||||
if tile.hidden_tile ~= 'nuclear-ground' then
|
||||
return
|
||||
end
|
||||
|
||||
cell[3] =
|
||||
rendering.draw_rectangle {
|
||||
width = 2,
|
||||
filled = false,
|
||||
surface = surface,
|
||||
left_top = position,
|
||||
right_bottom = {position.x + 2, position.y + 2},
|
||||
color = {0, 0, 0},
|
||||
draw_on_ground = true,
|
||||
only_in_alt_mode = false
|
||||
}
|
||||
end
|
||||
|
||||
local function get_adjacent_mine_count(position)
|
||||
@ -145,9 +176,15 @@ end
|
||||
local function kill_cell(position)
|
||||
local key = Functions.position_to_string(position)
|
||||
local cell = minesweeper.cells[key]
|
||||
if cell and cell[2] then
|
||||
if not cell then
|
||||
return
|
||||
end
|
||||
if cell[2] then
|
||||
rendering.destroy(cell[2])
|
||||
end
|
||||
if cell[3] then
|
||||
rendering.destroy(cell[3])
|
||||
end
|
||||
minesweeper.cells[key] = nil
|
||||
end
|
||||
|
||||
@ -178,6 +215,7 @@ local function visit_cell(position)
|
||||
end
|
||||
|
||||
if cell[1] == 11 then
|
||||
update_rendering(cell, position)
|
||||
return score_change
|
||||
end
|
||||
|
||||
@ -334,8 +372,7 @@ local function mark_mine(entity, player)
|
||||
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 function add_mines_to_chunk(left_top, distance_to_center)
|
||||
local base_mine_count = 40
|
||||
local max_mine_count = 128
|
||||
local mine_count = distance_to_center * 0.043 + base_mine_count
|
||||
@ -350,12 +387,24 @@ local function add_mines_to_chunk(left_top)
|
||||
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
|
||||
if distance_to_center < 128 then
|
||||
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]}
|
||||
if not Functions.is_spawn(position) then
|
||||
local key = Functions.position_to_string(position)
|
||||
minesweeper.cells[key] = {10}
|
||||
minesweeper.active_mines = minesweeper.active_mines + 1
|
||||
end
|
||||
end
|
||||
else
|
||||
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
|
||||
end
|
||||
|
||||
-- remove mines that would form a 3x3 block
|
||||
@ -386,18 +435,35 @@ end
|
||||
|
||||
local function on_chunk_generated(event)
|
||||
local left_top = event.area.left_top
|
||||
if event.surface.index ~= 1 then
|
||||
local surface = event.surface
|
||||
if surface.index ~= 1 then
|
||||
return
|
||||
end
|
||||
|
||||
local distance_to_center = math.sqrt((left_top.x + 16) ^ 2 + (left_top.y + 16) ^ 2)
|
||||
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}})
|
||||
|
||||
if distance_to_center < 128 then
|
||||
for x = 0, 31, 1 do
|
||||
for y = 0, 31, 1 do
|
||||
local position = {x = left_top.x + x, y = left_top.y + y}
|
||||
if Functions.is_spawn(position) then
|
||||
table.insert(tiles, {name = Functions.get_terrain_tile(surface, position), position = position})
|
||||
else
|
||||
table.insert(tiles, {name = 'nuclear-ground', position = position})
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
for x = 0, 31, 1 do
|
||||
for y = 0, 31, 1 do
|
||||
local position = {x = left_top.x + x, y = left_top.y + y}
|
||||
table.insert(tiles, {name = 'nuclear-ground', position = position})
|
||||
--table.insert(tiles, {name = Functions.get_terrain_tile(surface, position), position = position})
|
||||
end
|
||||
end
|
||||
end
|
||||
event.surface.set_tiles(tiles, true)
|
||||
surface.set_tiles(tiles, true)
|
||||
|
||||
--surface.clear() will cause to trigger on_chunk_generated twice
|
||||
local key = Functions.position_to_string(left_top)
|
||||
@ -406,7 +472,7 @@ local function on_chunk_generated(event)
|
||||
end
|
||||
minesweeper.chunks[key] = true
|
||||
|
||||
add_mines_to_chunk(left_top)
|
||||
add_mines_to_chunk(left_top, distance_to_center)
|
||||
end
|
||||
|
||||
local function on_player_changed_position(event)
|
||||
@ -427,24 +493,27 @@ local function deny_building(event)
|
||||
if not entity.valid then
|
||||
return
|
||||
end
|
||||
if entity.name == 'entity-ghost' then
|
||||
|
||||
if not game.item_prototypes[entity.name] 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()
|
||||
if not Functions.is_minefield_tile(entity.position, true) then
|
||||
return
|
||||
end
|
||||
|
||||
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 function on_built_entity(event)
|
||||
@ -460,7 +529,11 @@ local function update_built_tiles(surface, tiles)
|
||||
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
|
||||
if not cell and Functions.is_minefield_tile(placed_tile.position) then
|
||||
minesweeper.cells[key] = {9}
|
||||
end
|
||||
local cell = minesweeper.cells[key]
|
||||
if cell then
|
||||
update_rendering(cell, cell_position)
|
||||
end
|
||||
end
|
||||
@ -474,6 +547,14 @@ local function on_robot_built_tile(event)
|
||||
update_built_tiles(event.robot.surface, event.tiles)
|
||||
end
|
||||
|
||||
local function on_player_mined_tile(event)
|
||||
update_built_tiles(game.surfaces[event.surface_index], event.tiles)
|
||||
end
|
||||
|
||||
local function on_robot_mined_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})
|
||||
@ -580,3 +661,5 @@ 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)
|
||||
Event.add(defines.events.on_robot_mined_tile, on_robot_mined_tile)
|
||||
Event.add(defines.events.on_player_mined_tile, on_player_mined_tile)
|
||||
|
Loading…
Reference in New Issue
Block a user