mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2024-12-26 22:56:43 +02:00
485 lines
18 KiB
Lua
485 lines
18 KiB
Lua
local Public = {}
|
|
|
|
local GetNoise = require "utils.get_noise"
|
|
local Constants = require 'maps.cave_miner_v2.constants'
|
|
local BiterRaffle = require "functions.biter_raffle"
|
|
local LootRaffle = require "functions.loot_raffle"
|
|
local Esq = require "modules.entity_spawn_queue"
|
|
local Pets = require "modules.biter_pets"
|
|
|
|
local math_sqrt = math.sqrt
|
|
local math_random = math.random
|
|
local math_floor = math.floor
|
|
|
|
local spawn_amount_rolls = {}
|
|
for a = 48, 1, -1 do table.insert(spawn_amount_rolls, math_floor(a ^ 5)) end
|
|
|
|
function Public.get_difficulty_modifier(position)
|
|
local difficulty = math_sqrt(position.x ^ 2 + position.y ^ 2) * 0.0001
|
|
return difficulty
|
|
end
|
|
|
|
function Public.get_colored_name(player_index)
|
|
local player = game.players[player_index]
|
|
local colored_name = table.concat({"[color=", player.chat_color.r, ",", player.chat_color.g, ",", player.chat_color.b, "]", player.name, "[/color]"})
|
|
return colored_name
|
|
end
|
|
|
|
function Public.unstuck_player(player_index)
|
|
local player = game.players[player_index]
|
|
local surface = player.surface
|
|
local position = surface.find_non_colliding_position("character", player.position, 32, 0.5)
|
|
if not position then return end
|
|
player.teleport(position, surface)
|
|
end
|
|
|
|
function Public.roll_biter_amount()
|
|
local max_chance = 0
|
|
for k, v in pairs(spawn_amount_rolls) do
|
|
max_chance = max_chance + v
|
|
end
|
|
local r = math_random(0, max_chance)
|
|
local current_chance = 0
|
|
for k, v in pairs(spawn_amount_rolls) do
|
|
current_chance = current_chance + v
|
|
if r <= current_chance then return k end
|
|
end
|
|
end
|
|
|
|
--lab-dark-1 > position has been copied
|
|
--lab-dark-2 > position has been visited
|
|
function Public.reveal(cave_miner, surface, source_surface, position, brushsize)
|
|
local tile = source_surface.get_tile(position)
|
|
if tile.name == "lab-dark-2" then return end
|
|
local tiles = {}
|
|
local copied_tiles = {}
|
|
local i = 0
|
|
local brushsize_square = brushsize ^ 2
|
|
for _, tile in pairs(source_surface.find_tiles_filtered({area = {{position.x - brushsize, position.y - brushsize}, {position.x + brushsize, position.y + brushsize}}})) do
|
|
local tile_position = tile.position
|
|
if tile.name ~= "lab-dark-2" and tile.name ~= "lab-dark-1" and (position.x - tile_position.x) ^ 2 + (position.y - tile_position.y) ^ 2 < brushsize_square then
|
|
i = i + 1
|
|
copied_tiles[i] = {name = "lab-dark-1", position = tile.position}
|
|
tiles[i] = {name = tile.name, position = tile.position}
|
|
end
|
|
end
|
|
surface.set_tiles(tiles, true, false, false, false)
|
|
source_surface.set_tiles(copied_tiles, false, false, false, false)
|
|
|
|
for _, entity in pairs(source_surface.find_entities_filtered({area = {{position.x - brushsize, position.y - brushsize}, {position.x + brushsize, position.y + brushsize}}})) do
|
|
local entity_position = entity.position
|
|
if (position.x - entity_position.x) ^ 2 + (position.y - entity_position.y) ^ 2 < brushsize_square then
|
|
local e = entity.clone({position = entity_position, surface = surface})
|
|
if entity.force.index == 2 then
|
|
e.active = true
|
|
table.insert(cave_miner.reveal_queue, {entity.type, entity.position.x, entity.position.y})
|
|
end
|
|
entity.destroy()
|
|
end
|
|
end
|
|
|
|
source_surface.set_tiles({{name = "lab-dark-2", position = position}}, false)
|
|
source_surface.request_to_generate_chunks(position, 3)
|
|
end
|
|
|
|
function Public.get_base_ground_tile(position, seed)
|
|
local noise = GetNoise("large_caves", position, seed)
|
|
local name
|
|
if noise < 0.1 then
|
|
name = "dirt-7"
|
|
else
|
|
name = "nuclear-ground"
|
|
end
|
|
return name
|
|
end
|
|
|
|
function Public.spawn_player(player)
|
|
if not player.character then
|
|
player.create_character()
|
|
end
|
|
|
|
local surface = player.surface
|
|
local position
|
|
position = surface.find_non_colliding_position("character", player.force.get_spawn_position(surface), 48, 1)
|
|
if not position then position = player.force.get_spawn_position(surface) end
|
|
player.teleport(position, surface)
|
|
|
|
for name, count in pairs(Constants.starting_items) do
|
|
player.insert({name = name, count = count})
|
|
end
|
|
end
|
|
|
|
function Public.set_mining_speed(cave_miner, force)
|
|
force.manual_mining_speed_modifier = -0.60 + cave_miner.pickaxe_tier * 0.40
|
|
return force.manual_mining_speed_modifier
|
|
end
|
|
|
|
function Public.place_worm(surface, position, multiplier)
|
|
local e = surface.create_entity({name = BiterRaffle.roll("worm", Public.get_difficulty_modifier(position) * multiplier), position = position, force = "enemy"})
|
|
return e
|
|
end
|
|
|
|
function Public.spawn_random_biter(surface, position, multiplier)
|
|
local name = BiterRaffle.roll("mixed", Public.get_difficulty_modifier(position) * multiplier)
|
|
local non_colliding_position = surface.find_non_colliding_position(name, position, 16, 1)
|
|
local unit
|
|
if non_colliding_position then
|
|
unit = surface.create_entity({name = name, position = non_colliding_position, force = "enemy"})
|
|
else
|
|
unit = surface.create_entity({name = name, position = position, force = "enemy"})
|
|
end
|
|
unit.ai_settings.allow_try_return_to_spawner = false
|
|
unit.ai_settings.allow_destroy_when_commands_fail = false
|
|
return unit
|
|
end
|
|
|
|
function Public.rock_spawns_biters(cave_miner, position)
|
|
local amount = Public.roll_biter_amount()
|
|
local surface = game.surfaces.nauvis
|
|
local difficulty_modifier = Public.get_difficulty_modifier(position)
|
|
local tick = game.tick
|
|
for c = 1, amount, 1 do
|
|
Esq.add_to_queue(tick + c * 25, surface, {name = BiterRaffle.roll("mixed", difficulty_modifier), position = position, force = "enemy"}, 8)
|
|
end
|
|
end
|
|
|
|
function Public.loot_crate(surface, position, container_name, player_index)
|
|
local amount_multiplier = Constants.treasures[container_name].amount_multiplier
|
|
local base_amount = 16 * amount_multiplier
|
|
local difficulty_modifier = Public.get_difficulty_modifier(position)
|
|
local slots = game.entity_prototypes[container_name].get_inventory_size(defines.inventory.chest)
|
|
local tech_bonus = Constants.treasures[container_name].tech_bonus
|
|
local description = Constants.treasures[container_name].description
|
|
|
|
local blacklist = LootRaffle.get_tech_blacklist(difficulty_modifier + tech_bonus)
|
|
|
|
local item_stacks = LootRaffle.roll(base_amount + difficulty_modifier * amount_multiplier * 5000, slots, blacklist)
|
|
local container = surface.create_entity({name = container_name, position = position, force = "neutral"})
|
|
for _, item_stack in pairs(item_stacks) do container.insert(item_stack) end
|
|
container.minable = false
|
|
|
|
if not description then return end
|
|
if not player_index then return end
|
|
local player = game.players[player_index]
|
|
local text
|
|
if math_random(1, 2) == 1 then
|
|
text = player.name .. " found " .. description
|
|
else
|
|
text = player.name .. " uncovered " .. description
|
|
end
|
|
|
|
for _, player in pairs(game.forces.player.connected_players) do
|
|
player.add_custom_alert(container, {type = "item", name = "wooden-chest"}, text, true)
|
|
end
|
|
end
|
|
|
|
function Public.place_crude_oil(surface, position, multiplier)
|
|
if not surface.can_place_entity({name = "crude-oil", position = position, amount = 1}) then return end
|
|
local d = math_sqrt(position.x ^ 2 + position.y ^ 2)
|
|
local amount = math_random(50000, 100000) + d * 100 * multiplier
|
|
surface.create_entity({name = "crude-oil", position = position, amount = amount})
|
|
end
|
|
|
|
function Public.create_top_gui(player)
|
|
local frame = player.gui.top.cave_miner
|
|
if frame then return end
|
|
frame = player.gui.top.add({type = "frame", name = "cave_miner", direction = "horizontal"})
|
|
frame.style.maximal_height = 38
|
|
|
|
local label = frame.add({type = "label", caption = "Loading..."})
|
|
label.style.font = "heading-2"
|
|
label.style.font_color = {225, 225, 225}
|
|
label.style.margin = 0
|
|
label.style.padding = 0
|
|
|
|
local label = frame.add({type = "label", caption = "Loading..."})
|
|
label.style.font = "heading-2"
|
|
label.style.font_color = {225, 225, 225}
|
|
label.style.margin = 0
|
|
label.style.padding = 0
|
|
end
|
|
|
|
function Public.update_top_gui(cave_miner)
|
|
local pickaxe_tiers = Constants.pickaxe_tiers
|
|
for _, player in pairs(game.connected_players) do
|
|
local element = player.gui.top.cave_miner
|
|
if element and element.valid then
|
|
element.children[1].caption = pickaxe_tiers[cave_miner.pickaxe_tier] .. " Pickaxe | "
|
|
element.children[1].tooltip = "Mining speed " .. (1 + game.forces.player.manual_mining_speed_modifier) * 100 .. "%"
|
|
element.children[2].caption = "Rocks broken: " .. cave_miner.rocks_broken
|
|
end
|
|
end
|
|
end
|
|
|
|
local function is_entity_in_darkness(entity)
|
|
if not entity then return end
|
|
if not entity.valid then return end
|
|
local position = entity.position
|
|
|
|
local d = position.x ^ 2 + position.y ^ 2
|
|
if d < 512 then return false end
|
|
|
|
for _, lamp in pairs(entity.surface.find_entities_filtered({area={{position.x - 16, position.y - 16},{position.x + 16, position.y + 16}}, name = "small-lamp"})) do
|
|
local circuit = lamp.get_or_create_control_behavior()
|
|
if circuit then
|
|
if lamp.energy > 25 and circuit.disabled == false then
|
|
return
|
|
end
|
|
else
|
|
if lamp.energy > 25 then
|
|
return
|
|
end
|
|
end
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
local function darkness_event(cave_miner, entity)
|
|
local index = tostring(entity.unit_number)
|
|
local darkness = cave_miner.darkness
|
|
|
|
if darkness[index] then
|
|
darkness[index] = darkness[index] + 1
|
|
else
|
|
darkness[index] = -3
|
|
end
|
|
|
|
if darkness[index] <= 0 then return end
|
|
|
|
local position = entity.position
|
|
local difficulty_modifier = Public.get_difficulty_modifier(position)
|
|
|
|
local count = math_floor(darkness[index] * 0.33) + 1
|
|
if count > 16 then count = 16 end
|
|
for c = 1, count, 1 do
|
|
Esq.add_to_queue(game.tick + math_random(5, 45) * c, entity.surface, {name = BiterRaffle.roll("mixed", difficulty_modifier), position = position, force = "enemy"}, 8)
|
|
end
|
|
|
|
entity.damage(darkness[index] * 2, "neutral", "poison")
|
|
end
|
|
|
|
function Public.darkness(cave_miner)
|
|
for _, player in pairs(game.connected_players) do
|
|
local character = player.character
|
|
if character and character.valid and not character.driving then
|
|
character.disable_flashlight()
|
|
if is_entity_in_darkness(character) then
|
|
darkness_event(cave_miner, character)
|
|
else
|
|
cave_miner.darkness[tostring(character.unit_number)] = nil
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
Public.mining_events = {
|
|
{function(cave_miner, entity, player_index)
|
|
if math.random(1, 8) == 1 then
|
|
entity.surface.spill_item_stack(entity.position, {name = "raw-fish", count = 1}, true)
|
|
end
|
|
end, 350000, "Nothing"},
|
|
|
|
{function(cave_miner, entity, player_index)
|
|
local amount = Public.roll_biter_amount()
|
|
local position = entity.position
|
|
local surface = entity.surface
|
|
local difficulty_modifier = Public.get_difficulty_modifier(position)
|
|
local tick = game.tick
|
|
for c = 1, amount, 1 do
|
|
Esq.add_to_queue(tick + c * 25, surface, {name = BiterRaffle.roll("mixed", difficulty_modifier), position = position, force = "enemy"}, 8)
|
|
end
|
|
end, 16384, "Mixed_Biters"},
|
|
|
|
{function(cave_miner, entity, player_index)
|
|
local amount = Public.roll_biter_amount()
|
|
local position = entity.position
|
|
local surface = entity.surface
|
|
local difficulty_modifier = Public.get_difficulty_modifier(position)
|
|
local tick = game.tick
|
|
for c = 1, amount, 1 do
|
|
Esq.add_to_queue(tick + c * 25, surface, {name = BiterRaffle.roll("biter", difficulty_modifier), position = position, force = "enemy"}, 8)
|
|
end
|
|
end, 2048, "Biters"},
|
|
|
|
{function(cave_miner, entity, player_index)
|
|
local amount = Public.roll_biter_amount()
|
|
local position = entity.position
|
|
local surface = entity.surface
|
|
local difficulty_modifier = Public.get_difficulty_modifier(position)
|
|
local tick = game.tick
|
|
for c = 1, amount, 1 do
|
|
Esq.add_to_queue(tick + c * 25, surface, {name = BiterRaffle.roll("spitter", difficulty_modifier), position = position, force = "enemy"}, 8)
|
|
end
|
|
end, 2048, "Spitters"},
|
|
|
|
{function(cave_miner, entity, player_index)
|
|
local position = entity.position
|
|
local surface = entity.surface
|
|
Public.loot_crate(surface, position, "wooden-chest", player_index)
|
|
end, 1024, "Treasure_Tier_1"},
|
|
|
|
{function(cave_miner, entity, player_index)
|
|
local position = entity.position
|
|
local surface = entity.surface
|
|
Public.loot_crate(surface, position, "iron-chest", player_index)
|
|
end, 512, "Treasure_Tier_2"},
|
|
|
|
{function(cave_miner, entity, player_index)
|
|
local position = entity.position
|
|
local surface = entity.surface
|
|
Public.loot_crate(surface, position, "steel-chest", player_index)
|
|
end, 256, "Treasure_Tier_3"},
|
|
|
|
{function(cave_miner, entity, player_index)
|
|
local position = entity.position
|
|
local surface = entity.surface
|
|
Public.loot_crate(surface, position, "crash-site-spaceship-wreck-medium-" .. math_random(1,3), player_index)
|
|
end, 128, "Treasure_Tier_4"},
|
|
|
|
{function(cave_miner, entity, player_index)
|
|
local position = entity.position
|
|
local surface = entity.surface
|
|
Public.loot_crate(surface, position, "crash-site-spaceship-wreck-big-" .. math_random(1,2), player_index)
|
|
end, 64, "Treasure_Tier_5"},
|
|
|
|
{function(cave_miner, entity, player_index)
|
|
local position = entity.position
|
|
local surface = entity.surface
|
|
Public.loot_crate(surface, position, "big-ship-wreck-" .. math_random(1,3), player_index)
|
|
end, 32, "Treasure_Tier_6"},
|
|
|
|
{function(cave_miner, entity, player_index)
|
|
local position = entity.position
|
|
local surface = entity.surface
|
|
Public.loot_crate(surface, position, "crash-site-chest-" .. math_random(1,2), player_index)
|
|
end, 16, "Treasure_Tier_7"},
|
|
|
|
{function(cave_miner, entity, player_index)
|
|
local position = entity.position
|
|
local surface = entity.surface
|
|
Public.loot_crate(surface, position, "crash-site-spaceship", player_index)
|
|
Public.unstuck_player(player_index)
|
|
end, 8, "Treasure_Tier_8"},
|
|
|
|
{function(cave_miner, entity, player_index)
|
|
local position = entity.position
|
|
local surface = entity.surface
|
|
local unit = Public.spawn_random_biter(surface, position, 2)
|
|
Pets.biter_pets_tame_unit(game.players[player_index], unit, true)
|
|
end, 256, "Pet"},
|
|
|
|
{function(cave_miner, entity, player_index)
|
|
local position = entity.position
|
|
local surface = entity.surface
|
|
surface.create_entity({name = "biter-spawner", position = position, force = "enemy"})
|
|
Public.unstuck_player(player_index)
|
|
end, 1024, "Nest"},
|
|
|
|
{function(cave_miner, entity, player_index)
|
|
local position = entity.position
|
|
local surface = entity.surface
|
|
Public.place_worm(surface, position, 1)
|
|
Public.unstuck_player(player_index)
|
|
end, 1024, "Worm"},
|
|
|
|
{function(cave_miner, entity, player_index)
|
|
local position = entity.position
|
|
if position.x ^ 2 + position.y ^ 2 < 8000 then return end
|
|
local surface = entity.surface
|
|
Public.place_worm(surface, position, 1)
|
|
Public.unstuck_player(player_index)
|
|
local difficulty_modifier = Public.get_difficulty_modifier(position)
|
|
local tick = game.tick
|
|
for c = 1, math_random(1, 7), 1 do
|
|
Esq.add_to_queue(
|
|
tick + c * 90 + math_random(0, 90),
|
|
surface,
|
|
{name = BiterRaffle.roll("worm", difficulty_modifier), position = {position.x + (-4 + math_random(0, 8)), position.y + (-4 + math_random(0, 8))}, force = "enemy"},
|
|
16
|
|
)
|
|
end
|
|
end, 128, "Worms"},
|
|
|
|
{function(cave_miner, entity, player_index)
|
|
local position = entity.position
|
|
local surface = entity.surface
|
|
surface.create_entity({name = "compilatron", position = position, force = "player"})
|
|
end, 64, "Friendly Compilatron"},
|
|
|
|
{function(cave_miner, entity, player_index)
|
|
local position = entity.position
|
|
local surface = entity.surface
|
|
surface.create_entity({name = "compilatron", position = position, force = "enemy"})
|
|
end, 128, "Enemy Compilatron"},
|
|
|
|
{function(cave_miner, entity, player_index)
|
|
local position = entity.position
|
|
local surface = entity.surface
|
|
local entity = surface.create_entity({name = cave_miner.buildings_raffle[math_random(1, #cave_miner.buildings_raffle)], position = position, force = "player"})
|
|
entity.health = math_random(1, entity.prototype.max_health)
|
|
local player = game.players[player_index]
|
|
game.print(Public.get_colored_name(player_index) .. " discovered an abandoned building", Constants.chat_color)
|
|
end, 128, "Abandoned Building"},
|
|
|
|
{function(cave_miner, entity, player_index)
|
|
local position = entity.position
|
|
local surface = entity.surface
|
|
surface.create_entity({name = "car", position = position, force = "player"})
|
|
Public.unstuck_player(player_index)
|
|
local player = game.players[player_index]
|
|
game.print(player.name .. " has finally found their car!!", Constants.chat_color)
|
|
end, 32, "Car"},
|
|
|
|
{function(cave_miner, entity, player_index)
|
|
local position = entity.position
|
|
local surface = entity.surface
|
|
local tick = game.tick
|
|
|
|
local trees = {}
|
|
for k, prototype in pairs(game.entity_prototypes) do
|
|
if prototype.type == "tree" then table.insert(trees, k) end
|
|
end
|
|
table.shuffle_table(trees)
|
|
local tree = game.entity_prototypes[trees[1]].name
|
|
|
|
for c = 1, math_random(4, 96), 1 do
|
|
Esq.add_to_queue(tick + c * 5, surface, {name = tree, position = position, force = "neutral"}, 64)
|
|
end
|
|
local player = game.players[player_index]
|
|
game.print(player.name .. " found a whole forest!", Constants.chat_color)
|
|
end, 64, "Forest"},
|
|
}
|
|
|
|
Public.on_entity_died = {
|
|
["unit"] = function(cave_miner, entity)
|
|
local position = entity.position
|
|
local surface = entity.surface
|
|
if math.random(1, 8) == 1 then
|
|
surface.spill_item_stack(position, {name = "raw-fish", count = 1}, true)
|
|
end
|
|
end,
|
|
["unit-spawner"] = function(cave_miner, entity)
|
|
local position = entity.position
|
|
local surface = entity.surface
|
|
local a = 64 * 0.0001
|
|
local b = math.sqrt(position.x ^ 2 + position.y ^ 2)
|
|
local c = math_floor(a * b) + 1
|
|
for _ = 1, c, 1 do
|
|
Public.spawn_random_biter(surface, position, 1)
|
|
end
|
|
end,
|
|
["simple-entity"] = function(cave_miner, entity)
|
|
local position = entity.position
|
|
cave_miner.rocks_broken = cave_miner.rocks_broken + 1
|
|
if math.random(1, 6) == 1 then
|
|
Public.rock_spawns_biters(cave_miner, position)
|
|
end
|
|
end,
|
|
["container"] = function(cave_miner, entity)
|
|
local position = entity.position
|
|
Public.reveal(cave_miner, game.surfaces.nauvis, game.surfaces.cave_miner_source, position, 20)
|
|
end,
|
|
}
|
|
|
|
return Public |