mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2025-01-10 00:43:27 +02:00
378 lines
14 KiB
Lua
378 lines
14 KiB
Lua
require "modules.no_turrets"
|
|
local RPG = require "modules.rpg"
|
|
local unit_raffle = require "maps.biter_hatchery.raffle_tables"
|
|
local map_functions = require "tools.map_functions"
|
|
local Terrain = require "maps.biter_hatchery.terrain"
|
|
local Gui = require "maps.biter_hatchery.gui"
|
|
local Team = require "maps.biter_hatchery.team"
|
|
local Reset = require "functions.soft_reset"
|
|
local Map = require "modules.map_info"
|
|
local math_random = math.random
|
|
local Public = {}
|
|
|
|
local worm_turret_spawn_radius = 18
|
|
local worm_turret_vectors = {}
|
|
worm_turret_vectors.west = {}
|
|
for x = 0, worm_turret_spawn_radius, 1 do
|
|
for y = worm_turret_spawn_radius * -1, worm_turret_spawn_radius, 1 do
|
|
if math.sqrt(x ^ 2 + y ^ 2) <= worm_turret_spawn_radius then table.insert(worm_turret_vectors.west, {x, y}) end
|
|
end
|
|
end
|
|
worm_turret_vectors.east = {}
|
|
for x = worm_turret_spawn_radius * -1, 0, 1 do
|
|
for y = worm_turret_spawn_radius * -1, worm_turret_spawn_radius, 1 do
|
|
if math.sqrt(x ^ 2 + y ^ 2) <= worm_turret_spawn_radius then table.insert(worm_turret_vectors.east, {x, y}) end
|
|
end
|
|
end
|
|
|
|
local function draw_spawn_ores(surface)
|
|
local x = global.map_forces.west.hatchery.position.x - 64
|
|
map_functions.draw_smoothed_out_ore_circle({x = x, y = 32}, "iron-ore", surface, 15, 2500)
|
|
map_functions.draw_smoothed_out_ore_circle({x = x, y = -32}, "copper-ore", surface, 15, 2500)
|
|
map_functions.draw_smoothed_out_ore_circle({x = x, y = 0}, "coal", surface, 15, 1500)
|
|
map_functions.draw_smoothed_out_ore_circle({x = x, y = 64}, "stone", surface, 15, 1500)
|
|
|
|
local x = global.map_forces.east.hatchery.position.x + 64
|
|
map_functions.draw_smoothed_out_ore_circle({x = x, y = 32}, "copper-ore", surface, 15, 2500)
|
|
map_functions.draw_smoothed_out_ore_circle({x = x, y = -32}, "iron-ore", surface, 15, 2500)
|
|
map_functions.draw_smoothed_out_ore_circle({x = x, y = 0}, "coal", surface, 15, 1500)
|
|
map_functions.draw_smoothed_out_ore_circle({x = x, y = -64}, "stone", surface, 15, 1500)
|
|
end
|
|
|
|
function Public.reset_map()
|
|
local map_gen_settings = {}
|
|
map_gen_settings.seed = math_random(1, 10000000)
|
|
map_gen_settings.water = 0.2
|
|
map_gen_settings.starting_area = 1
|
|
map_gen_settings.terrain_segmentation = 10
|
|
map_gen_settings.cliff_settings = {cliff_elevation_interval = math_random(16, 48), cliff_elevation_0 = math_random(16, 48)}
|
|
map_gen_settings.autoplace_controls = {
|
|
["coal"] = {frequency = 100, size = 0.5, richness = 0.5,},
|
|
["stone"] = {frequency = 100, size = 0.5, richness = 0.5,},
|
|
["copper-ore"] = {frequency = 100, size = 0.5, richness = 0.5,},
|
|
["iron-ore"] = {frequency = 100, size = 0.5, richness = 0.5,},
|
|
["uranium-ore"] = {frequency = 50, size = 0.5, richness = 0.5,},
|
|
["crude-oil"] = {frequency = 50, size = 0.5, richness = 0.5,},
|
|
["trees"] = {frequency = math_random(5, 10) * 0.1, size = math_random(5, 10) * 0.1, richness = math_random(3, 10) * 0.1},
|
|
["enemy-base"] = {frequency = 0, size = 0, richness = 0}
|
|
}
|
|
|
|
if not global.active_surface_index then
|
|
global.active_surface_index = game.create_surface("biter_hatchery", map_gen_settings).index
|
|
else
|
|
global.active_surface_index = Reset.soft_reset_map(game.surfaces[global.active_surface_index], map_gen_settings, Team.starting_items).index
|
|
end
|
|
|
|
local surface = game.surfaces[global.active_surface_index]
|
|
surface.request_to_generate_chunks({0,0}, 10)
|
|
surface.force_generate_chunk_requests()
|
|
|
|
game.forces.west.set_spawn_position({-160, 0}, surface)
|
|
game.forces.east.set_spawn_position({160, 0}, surface)
|
|
|
|
local e = surface.create_entity({name = "biter-spawner", position = {-160, 0}, force = "west"})
|
|
e.active = false
|
|
global.map_forces.west.hatchery = e
|
|
global.map_forces.east.target = e
|
|
|
|
local e = surface.create_entity({name = "biter-spawner", position = {160, 0}, force = "east"})
|
|
e.active = false
|
|
global.map_forces.east.hatchery = e
|
|
global.map_forces.west.target = e
|
|
|
|
draw_spawn_ores(surface)
|
|
|
|
RPG.rpg_reset_all_players()
|
|
|
|
Team.set_force_attributes()
|
|
Team.assign_random_force_to_active_players()
|
|
|
|
for _, player in pairs(game.connected_players) do
|
|
if player.gui.left.biter_hatchery_game_won then player.gui.left.biter_hatchery_game_won.destroy() end
|
|
Team.teleport_player_to_active_surface(player)
|
|
end
|
|
|
|
for _, player in pairs(game.forces.spectator.connected_players) do
|
|
player.character.destroy()
|
|
Team.set_player_to_spectator(player)
|
|
end
|
|
for _, player in pairs(game.forces.spectator.players) do
|
|
Gui.rejoin_question(player)
|
|
end
|
|
end
|
|
|
|
local function spawn_worm_turret(surface, force_name, food_item)
|
|
local r_max = surface.count_entities_filtered({type = "turret", force = force_name}) + 1
|
|
if math_random(1, r_max) ~= 1 then return end
|
|
local vectors = worm_turret_vectors[force_name]
|
|
local vector = vectors[math_random(1, #vectors)]
|
|
local worm = "small-worm-turret"
|
|
local position = global.map_forces[force_name].hatchery.position
|
|
position.x = position.x + vector[1]
|
|
position.y = position.y + vector[2]
|
|
position = surface.find_non_colliding_position("biter-spawner", position, 16, 1)
|
|
if not position then return end
|
|
surface.create_entity({name = worm, position = position, force = force_name})
|
|
surface.create_entity({name = "blood-explosion-huge", position = position})
|
|
end
|
|
|
|
local function spawn_units(belt, food_item, removed_item_count)
|
|
local count_per_flask = unit_raffle[food_item][2]
|
|
local raffle = unit_raffle[food_item][1]
|
|
for _ = 1, removed_item_count, 1 do
|
|
for _ = 1, count_per_flask, 1 do
|
|
local unit = belt.surface.create_entity({name = raffle[math_random(1, #raffle)], position = belt.position, force = belt.force})
|
|
unit.ai_settings.allow_destroy_when_commands_fail = false
|
|
unit.ai_settings.allow_try_return_to_spawner = false
|
|
end
|
|
end
|
|
if math_random(1, 32) == 1 then spawn_worm_turret(belt.surface, belt.force.name, food_item) end
|
|
end
|
|
|
|
local function get_belts(spawner)
|
|
local belts = spawner.surface.find_entities_filtered({
|
|
type = "transport-belt",
|
|
area = {{spawner.position.x - 5, spawner.position.y - 3},{spawner.position.x + 4, spawner.position.y + 3}},
|
|
force = spawner.force,
|
|
})
|
|
return belts
|
|
end
|
|
|
|
local nom_msg = {"munch", "munch", "yum", "nom"}
|
|
|
|
local function feed_floaty_text(entity)
|
|
entity.surface.create_entity({name = "flying-text", position = entity.position, text = nom_msg[math_random(1, #nom_msg)], color = {math_random(50, 100), 0, 255}})
|
|
local position = {x = entity.position.x - 0.75, y = entity.position.y - 1}
|
|
local b = 1.35
|
|
for a = 1, math_random(0, 2), 1 do
|
|
local p = {(position.x + 0.4) + (b * -1 + math_random(0, b * 20) * 0.1), position.y + (b * -1 + math_random(0, b * 20) * 0.1)}
|
|
entity.surface.create_entity({name = "flying-text", position = p, text = "♥", color = {math_random(150, 255), 0, 255}})
|
|
end
|
|
end
|
|
|
|
local function eat_food_from_belt(belt)
|
|
for i = 1, 2, 1 do
|
|
local line = belt.get_transport_line(i)
|
|
for food_item, raffle in pairs(unit_raffle) do
|
|
local removed_item_count = line.remove_item({name = food_item, count = math_random(1, 2)})
|
|
if removed_item_count > 0 then
|
|
feed_floaty_text(belt)
|
|
spawn_units(belt, food_item, removed_item_count)
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function nom()
|
|
local surface = game.surfaces[global.active_surface_index]
|
|
for key, force in pairs(global.map_forces) do
|
|
force.hatchery.health = force.hatchery.health + 1
|
|
local belts = get_belts(force.hatchery)
|
|
for _, belt in pairs(belts) do
|
|
eat_food_from_belt(belt)
|
|
end
|
|
end
|
|
end
|
|
|
|
local function send_unit_groups()
|
|
local surface = game.surfaces[global.active_surface_index]
|
|
for key, force in pairs(global.map_forces) do
|
|
local units = {}
|
|
for _, unit in pairs(surface.find_entities_filtered({type = "unit", force = key})) do
|
|
if not unit.unit_group then
|
|
units[#units + 1] = unit
|
|
end
|
|
end
|
|
if #units > 0 then
|
|
local unit_group = surface.create_unit_group({position = force.hatchery.position, force = key})
|
|
for _, unit in pairs(units) do unit_group.add_member(unit) end
|
|
unit_group.set_command({
|
|
type = defines.command.compound,
|
|
structure_type = defines.compound_command.return_last,
|
|
commands = {
|
|
{
|
|
type = defines.command.attack_area,
|
|
destination = {x = force.target.position.x, y = force.target.position.y},
|
|
radius = 8,
|
|
distraction = defines.distraction.by_enemy
|
|
},
|
|
{
|
|
type = defines.command.attack,
|
|
target = force.target,
|
|
distraction = defines.distraction.by_enemy,
|
|
},
|
|
}
|
|
})
|
|
end
|
|
end
|
|
end
|
|
|
|
local border_teleport = {
|
|
["east"] = 2,
|
|
["west"] = -2,
|
|
}
|
|
|
|
local function on_player_changed_position(event)
|
|
local player = game.players[event.player_index]
|
|
if not player.character then return end
|
|
if not player.character.valid then return end
|
|
if player.position.x >= -4 and player.position.x <= 4 then
|
|
if not border_teleport[player.force.name] then return end
|
|
if player.character.driving then player.character.driving = false end
|
|
player.teleport({player.position.x + border_teleport[player.force.name], player.position.y}, game.surfaces[global.active_surface_index])
|
|
end
|
|
end
|
|
|
|
local function on_entity_died(event)
|
|
if not event.entity.valid then return end
|
|
if global.game_reset_tick then return end
|
|
if event.entity.type ~= "unit-spawner" then return end
|
|
|
|
local gui_str
|
|
if event.entity.force.name == "east" then
|
|
game.print("East lost their Hatchery.", {100, 100, 100})
|
|
gui_str = ">>>> West team has won the game!!! <<<<"
|
|
for _, player in pairs(game.forces.east.connected_players) do
|
|
player.play_sound{path="utility/game_lost", volume_modifier=0.85}
|
|
end
|
|
for _, player in pairs(game.forces.west.connected_players) do
|
|
player.play_sound{path="utility/game_won", volume_modifier=0.85}
|
|
end
|
|
else
|
|
game.print("West lost their Hatchery.", {100, 100, 100})
|
|
gui_str = ">>>> East team has won the game!!! <<<<"
|
|
for _, player in pairs(game.forces.west.connected_players) do
|
|
player.play_sound{path="utility/game_lost", volume_modifier=0.85}
|
|
end
|
|
for _, player in pairs(game.forces.east.connected_players) do
|
|
player.play_sound{path="utility/game_won", volume_modifier=0.85}
|
|
end
|
|
end
|
|
|
|
game.print("Next round starting in 30 seconds..", {150, 150, 150})
|
|
|
|
for _, player in pairs(game.forces.player.connected_players) do
|
|
player.play_sound{path="utility/game_won", volume_modifier=0.85}
|
|
end
|
|
global.game_reset_tick = game.tick + 1800
|
|
|
|
for _, player in pairs(game.connected_players) do
|
|
for _, child in pairs(player.gui.left.children) do child.destroy() end
|
|
player.gui.left.add({type = "frame", name = "biter_hatchery_game_won", caption = gui_str})
|
|
end
|
|
end
|
|
|
|
local function on_player_joined_game(event)
|
|
local player = game.players[event.player_index]
|
|
local surface = game.surfaces[global.active_surface_index]
|
|
|
|
Gui.spectate_button(player)
|
|
|
|
if player.gui.left.biter_hatchery_game_won then player.gui.left.biter_hatchery_game_won.destroy() end
|
|
|
|
if player.surface.index ~= global.active_surface_index then
|
|
if player.force.name == "spectator" then
|
|
Team.set_player_to_spectator(player)
|
|
Team.teleport_player_to_active_surface(player)
|
|
return
|
|
end
|
|
Team.assign_force_to_player(player)
|
|
Team.teleport_player_to_active_surface(player)
|
|
Team.put_player_into_random_team(player)
|
|
end
|
|
end
|
|
|
|
local function tick()
|
|
local game_tick = game.tick
|
|
if game_tick % 240 == 0 then
|
|
local area = {{-256, -97}, {255, 96}}
|
|
game.forces.west.chart(game.surfaces[global.active_surface_index], area)
|
|
game.forces.east.chart(game.surfaces[global.active_surface_index], area)
|
|
end
|
|
if game_tick % 1200 == 0 then send_unit_groups() end
|
|
if global.game_reset_tick then
|
|
if global.game_reset_tick < game_tick then
|
|
global.game_reset_tick = nil
|
|
Public.reset_map()
|
|
end
|
|
return
|
|
end
|
|
nom()
|
|
end
|
|
|
|
--Construction Robot Restriction
|
|
local robot_build_restriction = {
|
|
["east"] = function(x)
|
|
if x < 0 then return true end
|
|
end,
|
|
["west"] = function(x)
|
|
if x > 0 then return true end
|
|
end
|
|
}
|
|
|
|
local function on_robot_built_entity(event)
|
|
if not robot_build_restriction[event.robot.force.name] then return end
|
|
if not robot_build_restriction[event.robot.force.name](event.created_entity.position.x) then return end
|
|
local inventory = event.robot.get_inventory(defines.inventory.robot_cargo)
|
|
inventory.insert({name = event.created_entity.name, count = 1})
|
|
event.robot.surface.create_entity({name = "explosion", position = event.created_entity.position})
|
|
game.print("Team " .. event.robot.force.name .. "'s construction drone had an accident.", {r = 200, g = 50, b = 100})
|
|
event.created_entity.destroy()
|
|
end
|
|
|
|
local function on_entity_damaged(event)
|
|
local entity = event.entity
|
|
if not entity.valid then return end
|
|
if entity.type ~= "unit-spawner" then return end
|
|
local cause = event.cause
|
|
if cause then
|
|
if cause.valid then
|
|
if cause.type == "unit" then return end
|
|
end
|
|
end
|
|
entity.health = entity.health + event.final_damage_amount
|
|
end
|
|
|
|
local function on_init()
|
|
game.difficulty_settings.technology_price_multiplier = 0.5
|
|
game.map_settings.enemy_evolution.destroy_factor = 0
|
|
game.map_settings.enemy_evolution.pollution_factor = 0
|
|
game.map_settings.enemy_evolution.time_factor = 0
|
|
game.map_settings.enemy_expansion.enabled = false
|
|
game.map_settings.pollution.enabled = false
|
|
global.map_forces = {
|
|
["west"] = {},
|
|
["east"] = {},
|
|
}
|
|
|
|
local T = Map.Pop_info()
|
|
T.main_caption = "Biter Hatchery"
|
|
T.sub_caption = "..nibble nibble nom nom.."
|
|
T.text = table.concat({
|
|
"Defeat the enemy teams nest.\n",
|
|
"Feed your hatchery science flasks to breed biters!\n",
|
|
"They will soon after swarm to the opposing teams nest!\n",
|
|
"\n",
|
|
"Lay transport belts to your hatchery and they will happily nom the juice off the conveyor.\n",
|
|
"Higher tier flasks will breed stronger biters!\n",
|
|
"\n",
|
|
"Player turrets are disabled.\n",
|
|
"Feeding may spawn friendly worm turrets.\n",
|
|
"The center river may not be crossed.\n",
|
|
"Construction robots may not build over the river.\n",
|
|
})
|
|
T.main_caption_color = {r = 150, g = 0, b = 255}
|
|
T.sub_caption_color = {r = 0, g = 250, b = 150}
|
|
|
|
Team.create_forces()
|
|
Public.reset_map()
|
|
end
|
|
|
|
local event = require 'utils.event'
|
|
event.on_init(on_init)
|
|
event.on_nth_tick(60, tick)
|
|
event.add(defines.events.on_robot_built_entity, on_robot_built_entity)
|
|
event.add(defines.events.on_entity_died, on_entity_died)
|
|
event.add(defines.events.on_player_joined_game, on_player_joined_game)
|
|
event.add(defines.events.on_player_changed_position, on_player_changed_position)
|
|
event.add(defines.events.on_entity_damaged, on_entity_damaged) |