mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2025-03-17 20:58:13 +02:00
mountain map update WIP
This commit is contained in:
parent
e2562068c3
commit
30b2519a2d
@ -1,6 +1,7 @@
|
||||
-- Cave Defender, protect the locomotive! -- by MewMew
|
||||
|
||||
require "modules.wave_defense"
|
||||
--require "modules.dense_rocks"
|
||||
|
||||
require "maps.mountain_fortress.terrain"
|
||||
require "maps.mountain_fortress.locomotive"
|
||||
@ -21,24 +22,33 @@ local function init_surface()
|
||||
game.create_surface("mountain_fortress", map)
|
||||
end
|
||||
|
||||
local function on_entity_died(event)
|
||||
if not event.entity.valid then return end
|
||||
if event.entity == global.locomotive_cargo then
|
||||
game.print("Game Over!")
|
||||
global.wave_defense.game_lost = true
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local function on_player_joined_game(event)
|
||||
local surface = game.surfaces["mountain_fortress"]
|
||||
local player = game.players[event.player_index]
|
||||
|
||||
if player.online_time == 0 then
|
||||
player.teleport(surface.find_non_colliding_position("character", {0,0}, 3, 0.5), surface)
|
||||
player.teleport(surface.find_non_colliding_position("character", game.forces.player.get_spawn_position(surface), 3, 0.5), surface)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_init(surface)
|
||||
global.chunk_queue = {}
|
||||
|
||||
init_surface()
|
||||
|
||||
local surface = game.surfaces["mountain_fortress"]
|
||||
surface.request_to_generate_chunks({0,0}, 6)
|
||||
surface.force_generate_chunk_requests()
|
||||
|
||||
global.wave_defense.surface = surface
|
||||
|
||||
game.map_settings.enemy_evolution.destroy_factor = 0
|
||||
game.map_settings.enemy_evolution.pollution_factor = 0
|
||||
game.map_settings.enemy_evolution.time_factor = 0
|
||||
@ -49,9 +59,15 @@ local function on_init(surface)
|
||||
game.map_settings.enemy_expansion.settler_group_min_size = 16
|
||||
game.map_settings.pollution.enabled = false
|
||||
|
||||
locomotive_spawn(surface, {x = 0, y = -10})
|
||||
game.forces.player.set_spawn_position({-2, 16}, surface)
|
||||
|
||||
locomotive_spawn(surface, {x = 0, y = 16})
|
||||
|
||||
global.wave_defense.surface = surface
|
||||
global.wave_defense.target = global.locomotive_cargo
|
||||
end
|
||||
|
||||
local event = require 'utils.event'
|
||||
event.on_init(on_init)
|
||||
event.add(defines.events.on_entity_died, on_entity_died)
|
||||
event.add(defines.events.on_player_joined_game, on_player_joined_game)
|
@ -1,3 +1,7 @@
|
||||
local math_random = math.random
|
||||
local rock_raffle = {"sand-rock-big","sand-rock-big","rock-big","rock-big","rock-big","rock-big","rock-big","rock-big","rock-huge"}
|
||||
local spawner_raffle = {"biter-spawner", "biter-spawner", "biter-spawner", "spitter-spawner"}
|
||||
|
||||
local function process_position(surface, p)
|
||||
local distance_to_center = math.sqrt(p.x^2 + p.y^2)
|
||||
local index = math.floor((distance_to_center / 16) % 18) + 1
|
||||
@ -12,18 +16,121 @@ local function process_position(surface, p)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_chunk_generated(event)
|
||||
local left_top = event.area.left_top
|
||||
local surface = event.surface
|
||||
|
||||
for x = 0.5, 31.5, 1 do
|
||||
for y = 0.5, 31.5, 1 do
|
||||
p = {x = left_top.x + x, y = left_top.y + y}
|
||||
--process_position(surface, p)
|
||||
|
||||
local function rock_chunk(surface, left_top)
|
||||
for x = 0, 31, 1 do
|
||||
for y = 0, 31, 1 do
|
||||
surface.set_tiles({{name = "dirt-7", position = {x = left_top.x + x, y = left_top.y + y}}})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function border_chunk(surface, left_top)
|
||||
for x = 0, 31, 1 do
|
||||
for y = 0, 31, 1 do
|
||||
surface.set_tiles({{name = "dirt-3", position = {x = left_top.x + x, y = left_top.y + y}}})
|
||||
end
|
||||
end
|
||||
|
||||
local trees = {"dead-grey-trunk", "dead-grey-trunk", "dry-tree"}
|
||||
for x = 0, 31, 1 do
|
||||
for y = 5, 31, 1 do
|
||||
local pos = {x = left_top.x + x, y = left_top.y + y}
|
||||
if math_random(1, math.ceil(pos.y + pos.y) + 64) == 1 then
|
||||
surface.create_entity({name = trees[math_random(1, #trees)], position = pos})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
for x = 0, 31, 1 do
|
||||
for y = 0, 31, 1 do
|
||||
local pos = {x = left_top.x + x, y = left_top.y + y}
|
||||
if math_random(1, pos.y + 2) == 1 then
|
||||
surface.create_decoratives{
|
||||
check_collision=false,
|
||||
decoratives={
|
||||
{name = "rock-medium", position = pos, amount = math_random(1, 1 + math.ceil(20 - y / 2))}
|
||||
}
|
||||
}
|
||||
end
|
||||
if math_random(1, pos.y + 2) == 1 then
|
||||
surface.create_decoratives{
|
||||
check_collision=false,
|
||||
decoratives={
|
||||
{name = "rock-small", position = pos, amount = math_random(1, 1 + math.ceil(20 - y / 2))}
|
||||
}
|
||||
}
|
||||
end
|
||||
if math_random(1, pos.y + 2) == 1 then
|
||||
surface.create_decoratives{
|
||||
check_collision=false,
|
||||
decoratives={
|
||||
{name = "rock-tiny", position = pos, amount = math_random(1, 1 + math.ceil(20 - y / 2))}
|
||||
}
|
||||
}
|
||||
end
|
||||
if math_random(1, math.ceil(pos.y + pos.y) + 2) == 1 then
|
||||
surface.create_entity({name = rock_raffle[math_random(1, #rock_raffle)], position = pos})
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function biter_chunk(surface, left_top)
|
||||
local tile_positions = {}
|
||||
for x = 0, 31, 1 do
|
||||
for y = 0, 31, 1 do
|
||||
local p = {x = left_top.x + x, y = left_top.y + y}
|
||||
surface.set_tiles({{name = "sand-3", position = p}})
|
||||
tile_positions[#tile_positions + 1] = p
|
||||
end
|
||||
end
|
||||
for i = 1, 4, 1 do
|
||||
local position = surface.find_non_colliding_position("biter-spawner", tile_positions[math_random(1, #tile_positions)], 16, 2)
|
||||
if position then
|
||||
surface.create_entity({name = spawner_raffle[math_random(1, #spawner_raffle)], position = position})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function out_of_map(surface, left_top)
|
||||
for x = 0, 31, 1 do
|
||||
for y = 0, 31, 1 do
|
||||
surface.set_tiles({{name = "out-of-map", position = {x = left_top.x + x, y = left_top.y + y}}})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function process_chunk(left_top)
|
||||
local surface = game.surfaces["mountain_fortress"]
|
||||
if left_top.y == 96 and left_top.x == 96 then
|
||||
local p = global.locomotive.position
|
||||
for _, entity in pairs(surface.find_entities_filtered({area = {{p.x - 3, p.y - 4},{p.x + 3, p.y + 8}}, force = "neutral"})) do entity.destroy() end
|
||||
end
|
||||
if left_top.y < 0 then rock_chunk(surface, left_top) return end
|
||||
if left_top.y > 128 then out_of_map(surface, left_top) return end
|
||||
if left_top.y > 64 then biter_chunk(surface, left_top) return end
|
||||
if left_top.y >= 0 then border_chunk(surface, left_top) return end
|
||||
end
|
||||
|
||||
local function process_chunk_queue()
|
||||
for k, left_top in pairs(global.chunk_queue) do
|
||||
process_chunk(left_top)
|
||||
global.chunk_queue[k] = nil
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local function on_chunk_generated(event)
|
||||
if game.surfaces["mountain_fortress"].index ~= event.surface.index then return end
|
||||
local left_top = event.area.left_top
|
||||
|
||||
if game.tick == 0 then
|
||||
process_chunk(left_top)
|
||||
else
|
||||
global.chunk_queue[#global.chunk_queue + 1] = {x = left_top.x, y = left_top.y}
|
||||
end
|
||||
end
|
||||
|
||||
local event = require 'utils.event'
|
||||
event.on_nth_tick(60, process_chunk_queue)
|
||||
event.add(defines.events.on_chunk_generated, on_chunk_generated)
|
@ -27,8 +27,8 @@ function set_biter_raffle(level)
|
||||
global.wave_defense.biter_raffle = {
|
||||
["small-biter"] = 1000 - level * 2,
|
||||
["small-spitter"] = 1000 - level * 2,
|
||||
["medium-biter"] = level * 2,
|
||||
["medium-spitter"] = level * 2,
|
||||
["medium-biter"] = level,
|
||||
["medium-spitter"] = level,
|
||||
["big-biter"] = 0,
|
||||
["big-spitter"] = 0,
|
||||
["behemoth-biter"] = 0,
|
||||
@ -47,6 +47,16 @@ function set_biter_raffle(level)
|
||||
end
|
||||
end
|
||||
|
||||
local function time_out_biters()
|
||||
for k, biter in pairs(global.wave_defense.active_biters) do
|
||||
if biter.spawn_tick + global.wave_defense.max_biter_age < game.tick then
|
||||
global.wave_defense.threat = global.wave_defense.threat + threat_values[biter.entity.name]
|
||||
biter.entity.destroy()
|
||||
global.wave_defense.active_biters[k] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function get_random_close_spawner()
|
||||
local spawners = global.wave_defense.surface.find_entities_filtered({type = "unit-spawner"})
|
||||
if not spawners[1] then return false end
|
||||
@ -77,7 +87,7 @@ end
|
||||
local function set_group_spawn_position()
|
||||
local spawner = get_random_close_spawner()
|
||||
if not spawner then return end
|
||||
local position = global.wave_defense.surface.find_non_colliding_position("rocket-silo", spawner.position, 32, 1)
|
||||
local position = global.wave_defense.surface.find_non_colliding_position("rocket-silo", spawner.position, 48, 1)
|
||||
if not position then return end
|
||||
global.wave_defense.spawn_position = position
|
||||
end
|
||||
@ -113,16 +123,16 @@ local function spawn_unit_group()
|
||||
if not biter then break end
|
||||
unit_group.add_member(biter)
|
||||
end
|
||||
global.wave_defense.unit_groups[#global.wave_defense.unit_groups + 1] = unit_group
|
||||
return true
|
||||
end
|
||||
|
||||
local function spawn_wave()
|
||||
if game.tick < global.wave_defense.next_wave then return end
|
||||
global.wave_defense.next_wave = game.tick + global.wave_defense.wave_interval
|
||||
if global.wave_defense.active_biter_count >= global.wave_defense.max_active_biters then return false end
|
||||
global.wave_defense.wave_number = global.wave_defense.wave_number + 1
|
||||
global.wave_defense.group_size = global.wave_defense.wave_number * 4
|
||||
global.wave_defense.group_size = global.wave_defense.wave_number * 2
|
||||
if global.wave_defense.group_size > global.wave_defense.max_group_size then global.wave_defense.group_size = global.wave_defense.max_group_size end
|
||||
global.wave_defense.threat = global.wave_defense.threat + global.wave_defense.wave_number * 4
|
||||
global.wave_defense.threat = global.wave_defense.threat + global.wave_defense.wave_number * 2
|
||||
set_enemy_evolution()
|
||||
set_biter_raffle(global.wave_defense.wave_number)
|
||||
for a = 1, 16, 1 do
|
||||
@ -130,6 +140,60 @@ local function spawn_wave()
|
||||
end
|
||||
end
|
||||
|
||||
local function give_commands_to_unit_groups()
|
||||
if #global.wave_defense.unit_groups == 0 then return end
|
||||
if not global.wave_defense.target then return end
|
||||
if not global.wave_defense.target.valid then return end
|
||||
for k, group in pairs(global.wave_defense.unit_groups) do
|
||||
if group.valid then
|
||||
group.set_command({
|
||||
type = defines.command.compound,
|
||||
structure_type = defines.compound_command.return_last,
|
||||
commands = {
|
||||
{
|
||||
type = defines.command.attack_area,
|
||||
destination = global.wave_defense.target.position,
|
||||
radius = 16,
|
||||
distraction = defines.distraction.by_enemy
|
||||
},
|
||||
{
|
||||
type = defines.command.attack,
|
||||
target = global.wave_defense.target,
|
||||
distraction = defines.distraction.by_enemy
|
||||
}
|
||||
}
|
||||
})
|
||||
else
|
||||
global.wave_defense.unit_groups[k] = nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function create_gui(player)
|
||||
local frame = player.gui.top.add({ type = "frame", name = "wave_defense", tooltip = "Click to show map info"})
|
||||
frame.style.maximal_height = 38
|
||||
|
||||
local label = frame.add({ type = "label", caption = " ", name = "label"})
|
||||
label.style.font_color = {r=0.88, g=0.88, b=0.88}
|
||||
label.style.font = "default-listbox"
|
||||
label.style.left_padding = 4
|
||||
label.style.right_padding = 4
|
||||
label.style.minimal_width = 68
|
||||
label.style.font_color = {r=0.33, g=0.66, b=0.9}
|
||||
|
||||
local progressbar = frame.add({ type = "progressbar", name = "progressbar", value = 0})
|
||||
progressbar.style.minimal_width = 128
|
||||
progressbar.style.maximal_width = 128
|
||||
progressbar.style.top_padding = 10
|
||||
end
|
||||
|
||||
local function update_gui(player)
|
||||
if not player.gui.top.wave_defense then create_gui(player) end
|
||||
player.gui.top.wave_defense.label.caption = "Wave: " .. global.wave_defense.wave_number
|
||||
if global.wave_defense.wave_number == 0 then player.gui.top.wave_defense.label.caption = "First wave in " .. math.floor((global.wave_defense.next_wave - game.tick) / 60) + 1 end
|
||||
player.gui.top.wave_defense.progressbar.value = 1 - math.round((global.wave_defense.next_wave - game.tick) / global.wave_defense.wave_interval, 3)
|
||||
end
|
||||
|
||||
local function on_entity_died(event)
|
||||
if not event.entity.valid then return end
|
||||
if event.entity.type ~= "unit" then return end
|
||||
@ -139,30 +203,48 @@ local function on_entity_died(event)
|
||||
end
|
||||
|
||||
local function on_tick()
|
||||
if game.tick % 60 == 0 then
|
||||
if global.wave_defense.game_lost then return end
|
||||
|
||||
for _, player in pairs(game.connected_players) do update_gui(player) end
|
||||
|
||||
if game.tick < global.wave_defense.next_wave then return end
|
||||
|
||||
if global.wave_defense.active_biter_count < global.wave_defense.max_active_biters then
|
||||
global.wave_defense.next_wave = game.tick + global.wave_defense.wave_interval
|
||||
time_out_biters()
|
||||
set_target()
|
||||
spawn_wave()
|
||||
end
|
||||
give_commands_to_unit_groups()
|
||||
return
|
||||
end
|
||||
|
||||
if game.tick % 3600 == 0 then
|
||||
time_out_biters()
|
||||
set_target()
|
||||
give_commands_to_unit_groups()
|
||||
end
|
||||
end
|
||||
|
||||
local function on_init()
|
||||
global.wave_defense = {
|
||||
surface = game.surfaces["nauvis"],
|
||||
active_biters = {},
|
||||
max_active_biters = 2048,
|
||||
unit_groups = {},
|
||||
max_active_biters = 1024,
|
||||
max_group_size = 256,
|
||||
max_biter_age = 3600 * 30,
|
||||
active_biter_count = 0,
|
||||
spawn_position = {x = 0, y = 48},
|
||||
--next_wave = 3600 * 15,
|
||||
next_wave = 60,
|
||||
wave_interval = 60,
|
||||
next_wave = 3600 * 0.15,
|
||||
wave_interval = 1800,
|
||||
wave_number = 0,
|
||||
game_lost = false,
|
||||
threat = 0,
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
local event = require 'utils.event'
|
||||
event.on_nth_tick(60, on_tick)
|
||||
event.on_nth_tick(30, on_tick)
|
||||
event.on_init(on_init)
|
||||
event.add(defines.events.on_entity_died, on_entity_died)
|
Loading…
x
Reference in New Issue
Block a user