1
0
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:
Gerkiz 2021-05-01 21:22:10 +02:00
parent 550bef8445
commit 99abacb36e
2 changed files with 163 additions and 43 deletions

View File

@ -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

View File

@ -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)