Aleksei-bird 7c9c708c92 Первый фикс
Пачки некоторых позиций увеличены
2024-03-01 20:54:33 +03:00

2699 lines
96 KiB
Lua

-- ENEMIES v.1.1.x
-- Make remote interface for "Lua API global Variable Viewer (gvv)" by x2605.
-- (https://mods.factorio.com/mod/gvv)
-- If that mod is active, you can inspect your mod's global table at runtime.
if script.active_mods["gvv"] then
require("__gvv__.gvv")()
end
if not NE_Enemies then NE_Enemies = {} end
if not NE_Enemies.Settings then NE_Enemies.Settings = {} end
NE_Enemies.Settings.NE_Difficulty = settings.startup["NE_Difficulty"].value
NE_Enemies.Settings.NE_Starting_Evolution = settings.startup["NE_Starting_Evolution"].value
NE_Enemies.Settings.NE_Alien_Artifact_Eggs = settings.startup["NE_Alien_Artifact_Eggs"].value and settings.startup["NE_Alien_Artifacts"].value
NE_Enemies.Settings.NE_Spawners_Blue = settings.startup["NE_Blue_Spawners"].value
NE_Enemies.Settings.NE_Biter_Breeder = settings.startup["NE_Biter_Breeder"].value
NE_Enemies.Settings.NE_Spitter_Breeder = settings.startup["NE_Spitter_Breeder"].value
NE_Enemies.Settings.NE_Spawners_Red = settings.startup["NE_Red_Spawners"].value
NE_Enemies.Settings.NE_Biter_Fire = settings.startup["NE_Biter_Fire"].value
NE_Enemies.Settings.NE_Spitter_Fire = settings.startup["NE_Spitter_Fire"].value
NE_Enemies.Settings.NE_Spawners_Green = settings.startup["NE_Green_Spawners"].value
NE_Enemies.Settings.NE_Biter_Fast = settings.startup["NE_Biter_Fast"].value
NE_Enemies.Settings.NE_Spitter_Ulaunch = settings.startup["NE_Spitter_Ulaunch"].value
NE_Enemies.Settings.NE_Spawners_Yellow = settings.startup["NE_Yellow_Spawners"].value
NE_Enemies.Settings.NE_Biter_Wallbreaker = settings.startup["NE_Biter_Wallbreaker"].value
NE_Enemies.Settings.NE_Spitter_Webshooter = settings.startup["NE_Spitter_Webshooter"].value
NE_Enemies.Settings.NE_Spawners_Pink = settings.startup["NE_Pink_Spawners"].value
NE_Enemies.Settings.NE_Biter_Tank = settings.startup["NE_Biter_Tank"].value
NE_Enemies.Settings.NE_Spitter_Mine = settings.startup["NE_Spitter_Mine"].value
NE_Enemies.Settings.NE_QC_Mode = settings.global["NE_QC_Mode"].value
if NE_Enemies.Settings.NE_QC_Mode == true then
QC_Mod = true
else
QC_Mod = false
end
require("util")
require("prototypes.NE_Units.Unit_Launcher")
--- Milestone Stuff
if script.active_mods["Milestones"] then
require("prototypes.Compatibility.Milestones")
end
---************** Used for Testing -----
if NE_Enemies.Settings.NE_QC_Mode == true then
require ("Test_Spawn")
---*************
end
--- Scorched Earth
local replaceableTiles_alien = {
-- vanilla
["grass-1"] = "vegetation-green-grass-3",
["grass-3"] = "vegetation-green-grass-2",
["grass-2"] = "vegetation-green-grass-4",
["grass-4"] = "vegetation-green-grass-4",
["dirt-1"] = "mineral-beige-dirt-1",
["dirt-2"] = "mineral-beige-dirt-1",
["dirt-3"] = "mineral-beige-dirt-1",
["dirt-5"] = "mineral-beige-dirt-1",
["dirt-6"] = "mineral-beige-dirt-1",
["dirt-7"] = "mineral-beige-dirt-1",
["dirt-4"] = "mineral-beige-dirt-1",
["dry-dirt"] = "mineral-beige-dirt-1",
["sand-3"] = "mineral-beige-dirt-1",
["sand-2"] = "mineral-beige-dirt-1",
["sand-1"] = "mineral-beige-dirt-1",
["red-desert-0"] = "mineral-beige-dirt-1",
["red-desert-1"] = "mineral-beige-dirt-1",
["red-desert-2"] = "mineral-beige-dirt-1",
["red-desert-3"] = "mineral-beige-dirt-1",
-- alien biomes
["frozen-snow-0"] = "frozen-snow-1",
["frozen-snow-1"] = "frozen-snow-2",
["frozen-snow-2"] = "frozen-snow-3",
["frozen-snow-3"] = "frozen-snow-4",
["frozen-snow-4"] = "frozen-snow-5",
["frozen-snow-5"] = "frozen-snow-6",
["frozen-snow-6"] = "frozen-snow-7",
["frozen-snow-7"] = "frozen-snow-8",
["frozen-snow-8"] = "frozen-snow-9",
["frozen-snow-9"] = "volcanic-orange-heat-1",
["mineral-aubergine-dirt-1"] = "mineral-aubergine-dirt-2",
["mineral-aubergine-dirt-2"] = "mineral-aubergine-dirt-3",
["mineral-aubergine-dirt-3"] = "mineral-aubergine-dirt-4",
["mineral-aubergine-dirt-4"] = "mineral-aubergine-dirt-5",
["mineral-aubergine-dirt-5"] = "mineral-aubergine-dirt-6",
["mineral-aubergine-dirt-6"] = "mineral-aubergine-sand-1",
["mineral-aubergine-sand-1"] = "mineral-aubergine-sand-2",
["mineral-aubergine-sand-2"] = "mineral-aubergine-sand-3",
["mineral-aubergine-sand-3"] = "volcanic-orange-heat-1",
["mineral-beige-dirt-1"] = "mineral-beige-dirt-2",
["mineral-beige-dirt-2"] = "mineral-beige-dirt-3",
["mineral-beige-dirt-3"] = "mineral-beige-dirt-4",
["mineral-beige-dirt-4"] = "mineral-beige-dirt-5",
["mineral-beige-dirt-5"] = "mineral-beige-dirt-6",
["mineral-beige-dirt-6"] = "mineral-beige-sand-1",
["mineral-beige-sand-1"] = "mineral-beige-sand-2",
["mineral-beige-sand-2"] = "mineral-beige-sand-3",
["mineral-beige-sand-3"] = "volcanic-orange-heat-1",
["mineral-black-dirt-1"] = "mineral-black-dirt-2",
["mineral-black-dirt-2"] = "mineral-black-dirt-3",
["mineral-black-dirt-3"] = "mineral-black-dirt-4",
["mineral-black-dirt-4"] = "mineral-black-dirt-5",
["mineral-black-dirt-5"] = "mineral-black-dirt-6",
["mineral-black-dirt-6"] = "mineral-black-sand-1",
["mineral-black-sand-1"] = "mineral-black-sand-2",
["mineral-black-sand-2"] = "mineral-black-sand-3",
["mineral-black-sand-3"] = "volcanic-orange-heat-1",
["mineral-brown-dirt-1"] = "mineral-brown-dirt-2",
["mineral-brown-dirt-2"] = "mineral-brown-dirt-3",
["mineral-brown-dirt-3"] = "mineral-brown-dirt-4",
["mineral-brown-dirt-4"] = "mineral-brown-dirt-5",
["mineral-brown-dirt-5"] = "mineral-brown-dirt-6",
["mineral-brown-dirt-6"] = "mineral-brown-sand-1",
["mineral-brown-sand-1"] = "mineral-brown-sand-2",
["mineral-brown-sand-2"] = "mineral-brown-sand-3",
["mineral-brown-sand-3"] = "volcanic-orange-heat-1",
["mineral-cream-dirt-1"] = "mineral-cream-dirt-2",
["mineral-cream-dirt-2"] = "mineral-cream-dirt-3",
["mineral-cream-dirt-3"] = "mineral-cream-dirt-4",
["mineral-cream-dirt-4"] = "mineral-cream-dirt-5",
["mineral-cream-dirt-5"] = "mineral-cream-dirt-6",
["mineral-cream-dirt-6"] = "mineral-cream-sand-1",
["mineral-cream-sand-1"] = "mineral-cream-sand-2",
["mineral-cream-sand-2"] = "mineral-cream-sand-3",
["mineral-cream-sand-3"] = "volcanic-orange-heat-1",
["mineral-dustyrose-dirt-1"] = "mineral-dustyrose-dirt-2",
["mineral-dustyrose-dirt-2"] = "mineral-dustyrose-dirt-3",
["mineral-dustyrose-dirt-3"] = "mineral-dustyrose-dirt-4",
["mineral-dustyrose-dirt-4"] = "mineral-dustyrose-dirt-5",
["mineral-dustyrose-dirt-5"] = "mineral-dustyrose-dirt-6",
["mineral-dustyrose-dirt-6"] = "mineral-dustyrose-sand-1",
["mineral-dustyrose-sand-1"] = "mineral-dustyrose-sand-2",
["mineral-dustyrose-sand-2"] = "mineral-dustyrose-sand-3",
["mineral-dustyrose-sand-3"] = "volcanic-orange-heat-1",
["mineral-grey-dirt-1"] = "mineral-grey-dirt-2",
["mineral-grey-dirt-2"] = "mineral-grey-dirt-3",
["mineral-grey-dirt-3"] = "mineral-grey-dirt-4",
["mineral-grey-dirt-4"] = "mineral-grey-dirt-5",
["mineral-grey-dirt-5"] = "mineral-grey-dirt-6",
["mineral-grey-dirt-6"] = "mineral-grey-sand-1",
["mineral-grey-sand-1"] = "mineral-grey-sand-2",
["mineral-grey-sand-2"] = "mineral-grey-sand-3",
["mineral-grey-sand-3"] = "volcanic-orange-heat-1",
["mineral-purple-dirt-1"] = "mineral-purple-dirt-2",
["mineral-purple-dirt-2"] = "mineral-purple-dirt-3",
["mineral-purple-dirt-3"] = "mineral-purple-dirt-4",
["mineral-purple-dirt-4"] = "mineral-purple-dirt-5",
["mineral-purple-dirt-5"] = "mineral-purple-dirt-6",
["mineral-purple-dirt-6"] = "mineral-purple-sand-1",
["mineral-purple-sand-1"] = "mineral-purple-sand-2",
["mineral-purple-sand-2"] = "mineral-purple-sand-3",
["mineral-purple-sand-3"] = "volcanic-orange-heat-1",
["mineral-red-dirt-1"] = "mineral-red-dirt-2",
["mineral-red-dirt-2"] = "mineral-red-dirt-3",
["mineral-red-dirt-3"] = "mineral-red-dirt-4",
["mineral-red-dirt-4"] = "mineral-red-dirt-5",
["mineral-red-dirt-5"] = "mineral-red-dirt-6",
["mineral-red-dirt-6"] = "mineral-red-sand-1",
["mineral-red-sand-1"] = "mineral-red-sand-2",
["mineral-red-sand-2"] = "mineral-red-sand-3",
["mineral-red-sand-3"] = "volcanic-orange-heat-1",
["mineral-tan-dirt-1"] = "mineral-tan-dirt-2",
["mineral-tan-dirt-2"] = "mineral-tan-dirt-3",
["mineral-tan-dirt-3"] = "mineral-tan-dirt-4",
["mineral-tan-dirt-4"] = "mineral-tan-dirt-5",
["mineral-tan-dirt-5"] = "mineral-tan-dirt-6",
["mineral-tan-dirt-6"] = "mineral-tan-sand-1",
["mineral-tan-sand-1"] = "mineral-tan-sand-2",
["mineral-tan-sand-2"] = "mineral-tan-sand-3",
["mineral-tan-sand-3"] = "volcanic-orange-heat-1",
["mineral-violet-dirt-1"] = "mineral-violet-dirt-2",
["mineral-violet-dirt-2"] = "mineral-violet-dirt-3",
["mineral-violet-dirt-3"] = "mineral-violet-dirt-4",
["mineral-violet-dirt-4"] = "mineral-violet-dirt-5",
["mineral-violet-dirt-5"] = "mineral-violet-dirt-6",
["mineral-violet-dirt-6"] = "mineral-violet-sand-1",
["mineral-violet-sand-1"] = "mineral-violet-sand-2",
["mineral-violet-sand-2"] = "mineral-violet-sand-3",
["mineral-violet-sand-3"] = "volcanic-orange-heat-1",
["mineral-white-dirt-1"] = "mineral-white-dirt-2",
["mineral-white-dirt-2"] = "mineral-white-dirt-3",
["mineral-white-dirt-3"] = "mineral-white-dirt-4",
["mineral-white-dirt-4"] = "mineral-white-dirt-5",
["mineral-white-dirt-5"] = "mineral-white-dirt-6",
["mineral-white-dirt-6"] = "mineral-white-sand-1",
["mineral-white-sand-1"] = "mineral-white-sand-2",
["mineral-white-sand-2"] = "mineral-white-sand-3",
["mineral-white-sand-3"] = "volcanic-orange-heat-1",
["vegetation-blue-grass-1"] = "vegetation-blue-grass-2",
["vegetation-blue-grass-2"] = "mineral-beige-dirt-1",
["vegetation-green-grass-1"] = "vegetation-green-grass-2",
["vegetation-green-grass-2"] = "vegetation-green-grass-3",
["vegetation-green-grass-3"] = "vegetation-green-grass-4",
["vegetation-green-grass-4"] = "mineral-beige-dirt-1",
["vegetation-mauve-grass-1"] = "vegetation-mauve-grass-2",
["vegetation-mauve-grass-2"] = "mineral-beige-dirt-1",
["vegetation-olive-grass-1"] = "vegetation-olive-grass-2",
["vegetation-olive-grass-2"] = "mineral-beige-dirt-1",
["vegetation-orange-grass-1"] = "vegetation-orange-grass-2",
["vegetation-orange-grass-2"] = "mineral-beige-dirt-1",
["vegetation-purple-grass-1"] = "vegetation-purple-grass-2",
["vegetation-purple-grass-2"] = "mineral-beige-dirt-1",
["vegetation-red-grass-1"] = "vegetation-red-grass-2",
["vegetation-red-grass-2"] = "mineral-beige-dirt-1",
["vegetation-turquoise-grass-1"] = "vegetation-turquoise-grass-2",
["vegetation-turquoise-grass-2"] = "mineral-beige-dirt-1",
["vegetation-violet-grass-1"] = "vegetation-violet-grass-2",
["vegetation-violet-grass-2"] = "mineral-beige-dirt-1",
["vegetation-yellow-grass-1"] = "vegetation-yellow-grass-2",
["vegetation-yellow-grass-2"] = "mineral-beige-dirt-1",
["volcanic-blue-heat-1"] = "volcanic-blue-heat-2",
["volcanic-blue-heat-2"] = "volcanic-blue-heat-3",
["volcanic-blue-heat-3"] = "volcanic-blue-heat-4",
["volcanic-blue-heat-4"] = "volcanic-orange-heat-1",
["volcanic-green-heat-1"] = "volcanic-green-heat-2",
["volcanic-green-heat-2"] = "volcanic-green-heat-3",
["volcanic-green-heat-3"] = "volcanic-green-heat-4",
["volcanic-green-heat-4"] = "volcanic-orange-heat-1",
["volcanic-orange-heat-1"] = "volcanic-orange-heat-2",
["volcanic-orange-heat-2"] = "volcanic-orange-heat-3",
["volcanic-orange-heat-3"] = "volcanic-orange-heat-4",
["volcanic-purple-heat-1"] = "volcanic-purple-heat-2",
["volcanic-purple-heat-2"] = "volcanic-purple-heat-3",
["volcanic-purple-heat-3"] = "volcanic-purple-heat-4",
["volcanic-purple-heat-4"] = "volcanic-orange-heat-1"
}
local replaceableTiles = {
-- vanilla
["grass-1"] = "grass-3",
["grass-3"] = "grass-2",
["grass-2"] = "grass-4",
["grass-4"] = "red-desert-0",
["red-desert-0"] = "dirt-3",
["dirt-3"] = "dirt-5",
["dirt-5"] = "dirt-6",
["dirt-6"] = "dirt-7",
["dirt-7"] = "dirt-4",
["dirt-4"] = "dry-dirt",
["dry-dirt"] = "dirt-2",
["dirt-2"] = "dirt-1",
["dirt-1"] = "red-desert-2",
["red-desert-2"] = "red-desert-3",
["red-desert-3"] = "sand-3",
["sand-3"] = "sand-2",
["sand-2"] = "sand-1",
["sand-1"] = "red-desert-1"
}
local waterTiles = {
["deepwater"] = true,
["deepwater-green"] = true,
["water"] = true,
["water-green"] = true,
["water-shallow"] = true,
["water-mud"] = true
}
-- Auto repair items
local autoRepairType = {
["straight-rail"] = true,
["curved-rail"] = true,
["rail-signal"] = true,
["rail-chain-signal"] = true
}
---- List of entities that will auto repair
local autoRepairName = {
["bi-big-wooden-pole"] = true,
["bi-huge-wooden-pole"] = true
}
-- List of Entities Types that can catch fire if destoyed
local catchFire = {
["furnace"] = true,
["transport-belt"] = false,
["boiler"] = false,
["container"] = false,
["electric-pole"] = false,
["generator"] = true,
["offshore-pump"] = true,
["inserter"] = true,
["radar"] = true,
["lamp"] = false,
["pipe-to-ground"] = false,
["assembling-machine"] = true,
["wall"] = false,
["underground-belt"] = false,
["loader"] = true,
["splitter"] = false,
["car"] = true,
["solar-panel"] = true,
["locomotive"] = true,
["cargo-wagon"] = true,
["fluid-wagon"] = true,
["artillery-wagon"] = true,
["gate"] = false,
["lab"] = true,
["rocket-silo"] = true,
["roboport"] = true,
["storage-tank"] = true,
["pump"] = true,
["market"] = true,
["accumulator"] = true,
["beacon"] = true,
["mining-drill"] = true,
["electric-turret"] = true,
["ammo-turret"] = true,
["turret"] = false,
["straight-rail"] = false,
["curved-rail"] = false,
["rail-signal"] = false,
["rail-chain-signal"] = false,
["reactor"] = true
}
-- Corpse Size = Fire Size
local corpseSize = {
["furnace"] = "medium-remnants",
["transport-belt"] = "small-remnants",
["boiler"] = "small-remnants",
["container"] = "small-remnants",
["electric-pole"] = "small-remnants",
["generator"] = "big-remnants",
["offshore-pump"] = "small-remnants",
["inserter"] = "small-remnants",
["radar"] = "big-remnants",
["lamp"] = "small-remnants",
["pipe-to-ground"] = "small-remnants",
["assembling-machine"] = "big-remnants",
["wall"] = "small-remnants",
["underground-belt"] = "small-remnants",
["loader"] = "small-remnants",
["splitter"] = "medium-remnants",
["car"] = "medium-remnants",
["solar-panel"] = "big-remnants",
["locomotive"] = "big-remnants",
["cargo-wagon"] = "medium-remnants",
["fluid-wagon"] = "medium-remnants",
["artillery-wagon"] = "big-remnants",
["gate"] = "small-remnants",
["lab"] = "big-remnants",
["rocket-silo"] = "big-remnants",
["roboport"] = "big-remnants",
["storage-tank"] = "medium-remnants",
["pump"] = "small-remnants",
["market"] = "big-remnants",
["accumulator"] = "medium-remnants",
["beacon"] = "big-remnants",
["mining-drill"] = "big-remnants",
["electric-turret"] = "big-remnants",
["ammo-turret"] = "big-remnants",
["turret"] = "big-remnants",
["straight-rail"] = "small-remnants",
["curved-rail"] = "small-remnants",
["rail-signal"] = "small-remnants",
["rail-chain-signal"] = "small-remnants",
["reactor"] = "big-remnants"
}
--------- Achievements
function Achievements_Init()
-- Enemy Counts
--- Biters
if not global.Breeder_Biter_Count then global.Breeder_Biter_Count = 0 end
if not global.Fire_Biter_Count then global.Fire_Biter_Count = 0 end
if not global.Fast_Biter_Count then global.Fast_Biter_Count = 0 end
if not global.Wallbreaker_Biter_Count then
global.Wallbreaker_Biter_Count = 0
end
if not global.Tank_Biter_Count then global.Tank_Biter_Count = 0 end
--- Spitters
if not global.Breeder_Spitter_Count then global.Breeder_Spitter_Count = 0 end
if not global.Fire_Spitter_Count then global.Fire_Spitter_Count = 0 end
if not global.Ulaunch_Spitter_Count then global.Ulaunch_Spitter_Count = 0 end
if not global.Webshooter_Spitter_Count then
global.Webshooter_Spitter_Count = 0
end
if not global.Mine_Spitter_Count then global.Mine_Spitter_Count = 0 end
--- Spawners
if not global.Blue_Spawner_Count then global.Blue_Spawner_Count = 0 end
if not global.Red_Spawner_Count then global.Blue_Spawner_Count = 0 end
if not global.Green_Spawner_Count then global.Blue_Spawner_Count = 0 end
if not global.Yellow_Spawner_Count then global.Blue_Spawner_Count = 0 end
if not global.Pink_Spawner_Count then global.Blue_Spawner_Count = 0 end
end
---- Expansion Initialization ----
function Expansion_Initialization()
local enemy_expansion = game.map_settings.enemy_expansion
if not global.max_expansion_distance_NE then
global.max_expansion_distance_NE =
enemy_expansion.max_expansion_distance -- Vanilla 7
end
if not global.friendly_base_influence_radius_NE then
global.friendly_base_influence_radius_NE =
enemy_expansion.friendly_base_influence_radius -- Vanilla 2
end
if not global.enemy_building_influence_radius_NE then
global.enemy_building_influence_radius_NE =
enemy_expansion.enemy_building_influence_radius -- Vanilla 2
end
if not global.settler_Group_min_size_NE then
global.settler_Group_min_size_NE =
enemy_expansion.settler_group_min_size -- Vanilla 5
end
if not global.settler_Group_max_size_NE then
global.settler_Group_max_size_NE =
enemy_expansion.settler_group_max_size -- Vanilla 20
end
if not global.building_coefficient_NE then
global.building_coefficient_NE = enemy_expansion.building_coefficient -- vanilla 0.1
end
if not global.other_base_coefficient_NE then
global.other_base_coefficient_NE =
enemy_expansion.other_base_coefficient -- vanilla 2.0
end
if not global.neighbouring_chunk_coefficient_NE then
global.neighbouring_chunk_coefficient_NE =
enemy_expansion.neighbouring_chunk_coefficient -- vanilla 0.5
end
if not global.neighbouring_base_chunk_coefficient_NE then
global.neighbouring_base_chunk_coefficient_NE =
enemy_expansion.neighbouring_base_chunk_coefficient -- vanilla 0.4
end
local unit_group = game.map_settings.unit_group
if not global.min_Group_radius_NE then
global.min_Group_radius_NE = unit_group.min_group_radius -- Vanilla 5
end
if not global.max_Group_radius_NE then
global.max_Group_radius_NE = unit_group.max_group_radius -- Vanilla 30
end
if not global.max_Speed_up_NE then
global.max_Speed_up_NE = unit_group.max_member_speedup_when_behind -- Vanilla 1.4
end
local path_finder = game.map_settings.path_finder
if not global.max_Steps_NE then
global.max_Steps_NE = path_finder.max_steps_worked_per_tick -- Vanilla 100
end
end
---------------------------------------------
local function On_Init()
--- Set Initial Evolution Factor
if NE_Enemies.Settings.NE_Starting_Evolution then
game.forces.enemy.evolution_factor =
(NE_Enemies.Settings.NE_Starting_Evolution / 100)
if game.forces.enemy.evolution_factor > 1 then
game.forces.enemy.evolution_factor = 1
end
end
--- Used for Unit Turrets
if not global.tick then global.tick = game.tick end
if not global.evoFactorFloor then
if game.forces.enemy.evolution_factor > 0.995 then
global.evoFactorFloor = 10
else
global.evoFactorFloor = math.floor(game.forces.enemy
.evolution_factor * 10)
end
global.tick = global.tick + 1800
end
---- Used for Cliff Explosion Trigger
global.cliff_explosive = {}
global.cliff_explosive["ground-explosion"] = "ground-explosion"
--- Used for Mine Laying attackes
if global.deployed_mine == nil then global.deployed_mine = {} end
--- Used for Alien Artifact record keeping
if global.small_alien_artifact_created == nil then
global.small_alien_artifact_created = {}
end
if global.big_alien_artifact_created == nil then
global.big_alien_artifact_created = {}
end
--- Total Spawner Counter
if global.Total_Number_of_Spawners_Killed == nil then
global.Total_Number_of_Spawners_Killed = 0
end
--- Spawner Counter
if global.Recent_Number_of_Spawners_Killed == nil then
global.Recent_Number_of_Spawners_Killed = 0
end
--- Tech Level counter
if global.tech_level == nil then global.tech_level = 0 end
--- Number of Rocket Silos
if global.number_or_rocketsilos == nil then
global.number_or_rocketsilos = 0
end
--- Rocket Silos
if global.rocketsilos == nil then global.rocketsilos = {} end
--- Expansion Initialization ----
Expansion_Initialization()
--------- Achievements --
Achievements_Init()
--------
if QC_Mod == true then
---*************
local surface = game.surfaces['nauvis']
Test_Spawn()
---*************
end
IsAlienBiomeActive = game.active_mods["alien-biomes"]
SEARCH_RADIUS_onDeath = 5 + (math.floor(game.forces.enemy.evolution_factor * 10))
end
---------------------------------------------
local function On_Config_Change()
--- Used for Unit Turrets
if not global.tick then global.tick = game.tick end
if not global.evoFactorFloor then
if game.forces.enemy.evolution_factor > 0.995 then
global.evoFactorFloor = 10
else
global.evoFactorFloor = math.floor(game.forces.enemy
.evolution_factor * 10)
end
global.tick = global.tick + 1800
end
---- Used for Cliff Explosion Trigger
global.cliff_explosive = {}
global.cliff_explosive["ground-explosion"] = "ground-explosion"
--- Used for Mine Laying attackes
if global.deployed_mine == nil then global.deployed_mine = {} end
--- Used for Alien Artifact record keeping
if global.small_alien_artifact_created == nil then
global.small_alien_artifact_created = {}
end
if global.big_alien_artifact_created == nil then
global.big_alien_artifact_created = {}
end
--- Total Spawner Counter
if global.Total_Number_of_Spawners_Killed == nil then
global.Total_Number_of_Spawners_Killed = 0
end
--- Spawner Counter
if global.Recent_Number_of_Spawners_Killed == nil then
global.Recent_Number_of_Spawners_Killed = 0
end
--- Tech Level counter
if global.tech_level == nil then global.tech_level = 0 end
--- Number of Rocket Silos
if global.number_or_rocketsilos == nil then
global.number_or_rocketsilos = 0
end
--- Rocket Silos
if global.rocketsilos == nil then global.rocketsilos = {} end
--- Expansion Initialization ----
Expansion_Initialization()
--------- Achievements --
Achievements_Init()
-- enable researched recipes
for i, force in pairs(game.forces) do
for _, tech in pairs(force.technologies) do
if tech.researched then
for _, effect in pairs(tech.effects) do
if effect.type == "unlock-recipe" then
force.recipes[effect.recipe].enabled = true
end
end
end
end
end
end
---------------------------------------------
local function Look_and_Attack(entity, factor)
local surface = entity.surface
local force = entity.force
local radius = 15 * NE_Enemies.Settings.NE_Difficulty
local pos = entity.position
local area = {
{pos.x - radius, pos.y - radius}, {pos.x + radius, pos.y + radius}
}
local attack_chance = math.random(100) +
(6 - NE_Enemies.Settings.NE_Difficulty)
------writeDebug("Attack Chance: "..attack_chance)
------writeDebug("Evo Factor: "..math.floor(game.forces.enemy.evolution_factor*100))
if attack_chance < math.floor(game.forces.enemy.evolution_factor * 100) then
-- find nearby players
local players = surface.find_entities_filtered {
area = area,
type = "player"
}
local s_radius = math.floor((100 *
math.floor(
game.forces.enemy.evolution_factor *
10) + 600 *
NE_Enemies.Settings.NE_Difficulty) *
factor)
local nr_counts = math.floor((2 * NE_Enemies.Settings.NE_Difficulty +
math.floor(
game.forces.enemy.evolution_factor *
30)) * factor)
----writeDebug("Search Radius is: ".. s_radius)
----writeDebug("Number of units is: ".. nr_counts)
-- send attacks to all nearby players
for i, player in pairs(players) do
player.surface.set_multi_command {
command = {
type = defines.command.attack,
target = player,
distraction = defines.distraction.by_enemy
},
unit_count = nr_counts,
unit_search_distance = s_radius
}
end
end
end
---------------------------------------------
local function Look_and_Burn(entity, radius)
local surface = entity.surface
local force = entity.force
local radius = radius
local pos = entity.position
local area = {
{pos.x - radius, pos.y - radius}, {pos.x + radius, pos.y + radius}
}
local items = {}
local items = surface.find_entities_filtered({
area = area,
name = "item-on-ground"
})
-- writeDebug("# of Items on ground found: ".. #items)
if (#items > 0) and settings.startup["NE_Challenge_Mode"].value then
for i, item in pairs(items) do
if item and item.valid then item.destroy() end
end
end
end
---------------------------------------------
local function Remove_Decal(surface, pos, radius, limit)
-- game.print("Decal Script running")
local radius = radius
local area = {
{pos.x - radius, pos.y - radius}, {pos.x + radius, pos.y + radius}
}
surface.destroy_decoratives {
area = area,
type = "optimized-decorative",
limit = limit
}
end
--- Remove Trees
local function Remove_Trees(entity)
local surface = entity.surface
local radius = 1.5
local pos = entity.position
local area = {
{pos.x - radius, pos.y - radius}, {pos.x + radius, pos.y + radius}
}
-- find nearby trees
local trees = {}
local trees = surface.find_entities_filtered {area = area, type = "tree"}
-- Remove Trees
if #trees > 0 then
----writeDebug("Tree Found")
for i, tree in pairs(trees) do
if tree and tree.valid then tree.die() end
end
end
end
--- Remove Rocks
local function Remove_Rocks(entity)
local surface = entity.surface
local radius = 1.5
local pos = entity.position
local area = {
{pos.x - radius, pos.y - radius}, {pos.x + radius, pos.y + radius}
}
-- find nearby rocks
local rocks = {}
local rocks = surface.find_entities_filtered {
area = area,
type = "simple-entity"
} -- Rocks are simple entities...
-- Remove Rocks
if #rocks > 0 then
writeDebug("Rock Found")
for i, rock in pairs(rocks) do
if rock and rock.valid then rock.die() end
end
end
end
--------------------------------------------------------------------
local function On_Built(event)
local entity = event.created_entity
local surface = entity.surface
local force = entity.force
local position = entity.position
--- If you build a rocket silo, the tech levle rises.
if entity.valid and entity.type == "rocket-silo" and
settings.startup["NE_Challenge_Mode"].value then
----writeDebug("Tech Level: "..global.tech_level)
global.tech_level = global.tech_level + 1000
global.number_or_rocketsilos = global.number_or_rocketsilos + 1
----writeDebug("Number of Rocket Silos: "..global.number_or_rocketsilos)
--- Add silo to table
global.rocketsilos[entity.unit_number] = {silo = entity}
-- Biters will attack the newly built Rocket Silo
if not settings.global["NE_Remove_Biter_Search"].value then
surface.set_multi_command {
command = {
type = defines.command.attack,
target = entity,
distraction = defines.distraction.by_enemy
},
unit_count = math.floor(4000 *
game.forces.enemy.evolution_factor),
unit_search_distance = 2500 * NE_Enemies.Settings.NE_Difficulty
}
end
end
end
--------------------------------------------------------------------
local function On_Remove(event)
local entity = event.entity
local surface = entity.surface
local force = entity.force
local position = entity.position
------writeDebug("Tech Level: "..global.tech_level)
--- If you remove a rocket silo, the tech levle lowers again.
if entity.valid and entity.type == "rocket-silo" and
settings.startup["NE_Challenge_Mode"].value then
global.tech_level = global.tech_level - 1000
if global.tech_level <= 0 then global.tech_level = 0 end
global.number_or_rocketsilos = global.number_or_rocketsilos - 1
if global.number_or_rocketsilos <= 0 then
global.number_or_rocketsilos = 0
end
--- Remove silo from table
if global.rocketsilos[entity.unit_number] then
global.rocketsilos[entity.unit_number] = nil
end
------writeDebug("Tech Level: "..global.tech_level)
end
--------- Did you really just kill that tree...
if entity.valid and settings.startup["NE_Challenge_Mode"].value and
(entity.type == "tree") then
----writeDebug("Tree Mined")
----writeDebug("Tech_level: "..global.tech_level)
Look_and_Attack(entity, 1)
---- Sometimes there are small biters in trees...
local spawn_chance = math.random(420 -
(20 *
NE_Enemies.Settings
.NE_Difficulty))
if spawn_chance < math.floor(game.forces.enemy.evolution_factor * 100) then
local monkey_lvl = math.floor(
game.forces.enemy.evolution_factor * 10)
-- writeDebug("Evo Factor Lvl: "..monkey_lvl)
if monkey_lvl <= 1 then monkey_lvl = 1 end
local tree_monkey_name = "ne-biter-breeder-" .. monkey_lvl
-- writeDebug("Tree Monkey Name: "..tree_monkey_name)
--- Spawn Monkey
local tree_monkey = surface.create_entity({
name = tree_monkey_name,
position = entity.position,
force = game.forces.enemy
})
end
end
end
--- Check if the entity was a spawner
function isSpawner(enemy)
if enemy.type == "unit-spawner" then
return 2
else
return 0
end
end
--[[
--- Return Class
function UnitClass(entity)
_, _, mod, spiecies, class, number = string.find(entity.name, "(%a+)-(%a+)-(%a+)-(%d+)")
return class
end
]]
--- Count Killed NE Unit
local function NE_Unit_Count(entity)
--- Biters
if string.find(entity.name, "ne%-biter%-breeder%-") then
global.Breeder_Biter_Count = global.Breeder_Biter_Count + 1
elseif string.find(entity.name, "ne%-biter%-fire%-") then
global.Fire_Biter_Count = global.Fire_Biter_Count + 1
elseif string.find(entity.name, "ne%-biter%-fast%-") then
global.Fast_Biter_Count = global.Fast_Biter_Count + 1
elseif string.find(entity.name, "ne%-biter%-fastL%-") then -- Launched units
global.Fast_Biter_Count = global.Fast_Biter_Count + 1
elseif string.find(entity.name, "ne%-biter%-wallbreaker%-") then
global.Wallbreaker_Biter_Count = global.Wallbreaker_Biter_Count + 1
elseif string.find(entity.name, "ne%-biter%-tank%-") then
global.Tank_Biter_Count = global.Tank_Biter_Count + 1
-- Spitters
elseif string.find(entity.name, "ne%-spitter%-breeder%-") then
global.Breeder_Spitter_Count = global.Breeder_Spitter_Count + 1
elseif string.find(entity.name, "ne%-spitter%-fire%-") then
global.Fire_Spitter_Count = global.Fire_Spitter_Count + 1
elseif string.find(entity.name, "ne%-spitter%-ulaunch%-") then
global.Ulaunch_Spitter_Count = global.Ulaunch_Spitter_Count + 1
elseif string.find(entity.name, "ne%-spitter%-webshooter%-") then
global.Webshooter_Spitter_Count = global.Webshooter_Spitter_Count + 1
elseif string.find(entity.name, "ne%-spitter%-mine%-") then
global.Mine_Spitter_Count = global.Mine_Spitter_Count + 1
end
end
--- Check for Fire Biter
function isFireBiter(entity)
return (string.find(entity.name, "ne%-biter%-fire%-") or
string.find(entity.name, "ne%-spitter%-fire%-"))
end
--- Check for Breeder Biter
function isBreeder(entity)
return (string.find(entity.name, "ne%-biter%-breeder%-") or
string.find(entity.name, "ne%-spitter%-breeder%-"))
end
--- Return Unit#
function UnitNumber(entity)
_, _, mod, spiecies, class, number =
string.find(entity.name, "(%a+)-(%a+)-(%a+)-(%d+)")
return number
end
--- Return Spiecies
function UnitSpiecies(entity)
_, _, mod, spiecies, class, number =
string.find(entity.name, "(%a+)-(%a+)-(%a+)-(%d+)")
return spiecies
end
--- Return NE Land mine
function NELandmine(entity)
-- "ne-spitter-land-mine-"..i
_, _, ne, spiecies, land, mine, number =
string.find(entity.name, "(%a+)-(%a+)-(%a+)-(%a+)-(%d+)")
if land and mine then return land .. mine end
end
---- Spawn Babies from Breeders Units
function SpawnBreederBabies(entity)
local NumberOfBabies = math.floor(math.floor(UnitNumber(entity)) +
math.floor(
math.sqrt(UnitNumber(entity))) +
math.floor(
NE_Enemies.Settings.NE_Difficulty *
2)) / 3 -- Number of Babies, 3 to 8 at level 20 on Diff 1 and 5 to 11 at level 20 on Diff 5
local BabyLvl = math.floor(math.sqrt((UnitNumber(entity)) * 2) +
(NE_Enemies.Settings.NE_Difficulty / 3)) -- Baby Level, 4 to 9 at level 20 on Diff 1 and 6 to 10 at level 20 on Diff 5
local BabyName
if BabyLvl <= 0 then BabyLvl = 1 end
if UnitSpiecies(entity) then
BabyName = "ne-" .. UnitSpiecies(entity) .. "-breeder-" .. BabyLvl
else
BabyName = "ne-biter-breeder-" .. BabyLvl
end
------writeDebug(BabyName)
------writeDebug(BabyLvl)
--- Only start breeding at Lvl 5 & if there are 10 or less units in the area. - Prevents over-crowding...
local radius = 20
local pos = entity.position
local area = {
{pos.x - radius, pos.y - radius}, {pos.x + radius, pos.y + radius}
}
local unit_names = {
"ne-biter-breeder-1", "ne-biter-breeder-2", "ne-biter-breeder-3",
"ne-biter-breeder-4", "ne-biter-breeder-5", "ne-biter-breeder-6",
"ne-biter-breeder-7", "ne-biter-breeder-8", "ne-biter-breeder-9",
"ne-biter-breeder-10", "ne-biter-breeder-11", "ne-biter-breeder-12",
"ne-biter-breeder-13", "ne-biter-breeder-14", "ne-biter-breeder-15",
"ne-biter-breeder-16", "ne-biter-breeder-17", "ne-biter-breeder-18",
"ne-biter-breeder-19", "ne-biter-breeder-20", "ne-spitter-breeder-1",
"ne-spitter-breeder-2", "ne-spitter-breeder-3", "ne-spitter-breeder-4",
"ne-spitter-breeder-5", "ne-spitter-breeder-6", "ne-spitter-breeder-7",
"ne-spitter-breeder-8", "ne-spitter-breeder-9", "ne-spitter-breeder-10",
"ne-spitter-breeder-11", "ne-spitter-breeder-12",
"ne-spitter-breeder-13", "ne-spitter-breeder-14",
"ne-spitter-breeder-15", "ne-spitter-breeder-16",
"ne-spitter-breeder-17", "ne-spitter-breeder-18",
"ne-spitter-breeder-19", "ne-spitter-breeder-20"
}
local blue_units = entity.surface.count_entities_filtered {
area = area,
name = unit_names
}
-- writeDebug("Blue Unit count is: "..blue_units)
if math.floor(UnitNumber(entity)) >= 5 and blue_units <=
(9 + NE_Enemies.Settings.NE_Difficulty) then
for i = 1, NumberOfBabies do
local PositionValid = entity.surface.find_non_colliding_position(
BabyName, entity.position, 4, 0.5)
if PositionValid then
spawn_unit = entity.surface.create_entity({
name = BabyName,
position = PositionValid,
force = entity.force
})
--- Remove trees around mines, to prevent units from getting stuck
Remove_Trees(spawn_unit)
Remove_Rocks(spawn_unit)
end
end
end
end
---- Spawn Babies from Breeders Spawners
function SpawnBreederBabies_Spawner(entity)
local NumberOfBabies = math.floor(2 * NE_Enemies.Settings.NE_Difficulty +
math.floor(
game.forces.enemy.evolution_factor *
30))
local BabyNumber = math.floor(NE_Enemies.Settings.NE_Difficulty +
math.floor(
game.forces.enemy.evolution_factor *
10))
if BabyNumber <= 0 then BabyNumber = 1 end
local BabyName = "ne-biter-breeder-" .. BabyNumber
-- No spawn for first 5% of Evo & if there are 15 or less units in the area. - Prevents over-crowding...
local radius = 8
local pos = entity.position
local area = {
{pos.x - radius, pos.y - radius}, {pos.x + radius, pos.y + radius}
}
local unit_names = {
"ne-biter-breeder-1", "ne-biter-breeder-2", "ne-biter-breeder-3",
"ne-biter-breeder-4", "ne-biter-breeder-5", "ne-biter-breeder-6",
"ne-biter-breeder-7", "ne-biter-breeder-8", "ne-biter-breeder-9",
"ne-biter-breeder-10", "ne-biter-breeder-11", "ne-biter-breeder-12",
"ne-biter-breeder-13", "ne-biter-breeder-14", "ne-biter-breeder-15",
"ne-biter-breeder-16", "ne-biter-breeder-17", "ne-biter-breeder-18",
"ne-biter-breeder-19", "ne-biter-breeder-20", "ne-spitter-breeder-1",
"ne-spitter-breeder-2", "ne-spitter-breeder-3", "ne-spitter-breeder-4",
"ne-spitter-breeder-5", "ne-spitter-breeder-6", "ne-spitter-breeder-7",
"ne-spitter-breeder-8", "ne-spitter-breeder-9", "ne-spitter-breeder-10",
"ne-spitter-breeder-11", "ne-spitter-breeder-12",
"ne-spitter-breeder-13", "ne-spitter-breeder-14",
"ne-spitter-breeder-15", "ne-spitter-breeder-16",
"ne-spitter-breeder-17", "ne-spitter-breeder-18",
"ne-spitter-breeder-19", "ne-spitter-breeder-20"
}
local blue_units = entity.surface.count_entities_filtered {
area = area,
name = unit_names
}
-- writeDebug("Blue Unit count is: "..blue_units)
if math.floor(game.forces.enemy.evolution_factor * 10) >= 5 and blue_units <=
(14 + NE_Enemies.Settings.NE_Difficulty) then
for i = 1, NumberOfBabies + 2 do
local PositionValid = entity.surface.find_non_colliding_position(
BabyName, entity.position, 8, 0.5)
if PositionValid then
spawn_unit = entity.surface.create_entity({
name = BabyName,
position = PositionValid,
force = entity.force
})
Remove_Trees(spawn_unit)
Remove_Rocks(spawn_unit)
end
end
end
end
--------------------------------------------------------------------
function Achievement_Check()
----writeDebug("Achievement Check Pont")
---- Unit Kill Check
if (global.Breeder_Biter_Count >= 100 and global.Fire_Biter_Count >= 100 and
global.Fast_Biter_Count >= 100 and global.Wallbreaker_Biter_Count >= 100 and
global.Tank_Biter_Count >= 100 and global.Breeder_Spitter_Count >= 100 and
global.Fire_Spitter_Count >= 100 and global.Ulaunch_Spitter_Count >= 100 and
global.Webshooter_Spitter_Count >= 100 and global.Mine_Spitter_Count >=
100) then
----writeDebug("Achievement #1 PASSED")
for index, player in pairs(game.players) do -- give the achievement to every player
player.unlock_achievement("killed-all-NE-1")
end
elseif (global.Breeder_Biter_Count >= 10000 and global.Fire_Biter_Count >=
10000 and global.Fast_Biter_Count >= 10000 and
global.Wallbreaker_Biter_Count >= 10000 and global.Tank_Biter_Count >=
10000 and global.Breeder_Spitter_Count >= 10000 and
global.Fire_Spitter_Count >= 10000 and global.Ulaunch_Spitter_Count >=
10000 and global.Webshooter_Spitter_Count >= 10000 and
global.Mine_Spitter_Count >= 10000) then
----writeDebug("Achievement #2 PASSED")
for index, player in pairs(game.players) do -- give the achievement to every player
player.unlock_achievement("killed-all-NE-2")
end
elseif (global.Breeder_Biter_Count >= 100000 and global.Fire_Biter_Count >=
100000 and global.Fast_Biter_Count >= 100000 and
global.Wallbreaker_Biter_Count >= 100000 and global.Tank_Biter_Count >=
100000 and global.Breeder_Spitter_Count >= 100000 and
global.Fire_Spitter_Count >= 100000 and global.Ulaunch_Spitter_Count >=
100000 and global.Webshooter_Spitter_Count >= 100000 and
global.Mine_Spitter_Count >= 100000) then
----writeDebug("Achievement #3 PASSED")
for index, player in pairs(game.players) do -- give the achievement to every player
player.unlock_achievement("killed-all-NE-3")
end
else
----writeDebug("Achievement-Unique FAIL")
end
---- Total Count Achievement
if (global.Breeder_Biter_Count + global.Fire_Biter_Count +
global.Fast_Biter_Count + global.Wallbreaker_Biter_Count +
global.Tank_Biter_Count + global.Breeder_Spitter_Count +
global.Fire_Spitter_Count + global.Ulaunch_Spitter_Count +
global.Webshooter_Spitter_Count + global.Mine_Spitter_Count) >= 10000 then
----writeDebug("Achievement #4 PASSED")
for index, player in pairs(game.players) do -- give the achievement to every player
player.unlock_achievement("killed-total-NE-1")
end
elseif (global.Breeder_Biter_Count + global.Fire_Biter_Count +
global.Fast_Biter_Count + global.Wallbreaker_Biter_Count +
global.Tank_Biter_Count + global.Breeder_Spitter_Count +
global.Fire_Spitter_Count + global.Ulaunch_Spitter_Count +
global.Webshooter_Spitter_Count + global.Mine_Spitter_Count) >= 100000 then
----writeDebug("Achievement #5 PASSED")
for index, player in pairs(game.players) do -- give the achievement to every player
player.unlock_achievement("killed-total-NE-2")
end
elseif (global.Breeder_Biter_Count + global.Fire_Biter_Count +
global.Fast_Biter_Count + global.Wallbreaker_Biter_Count +
global.Tank_Biter_Count + global.Breeder_Spitter_Count +
global.Fire_Spitter_Count + global.Ulaunch_Spitter_Count +
global.Webshooter_Spitter_Count + global.Mine_Spitter_Count) >= 1000000 then
----writeDebug("Achievement #6 PASSED")
for index, player in pairs(game.players) do -- give the achievement to every player
player.unlock_achievement("killed-total-NE-3")
end
else
----writeDebug("Achievement-Total FAIL")
end
end
--[[
function check_kill_count()
function isBiter_Breeder(entity)
return string.find(entity, "ne%-biter%-breeder%-")
end
for entity_name, kill_count in pairs(game.forces.player.kill_count_statistics.input_counts) do
----writeDebug("Entity Name: "..entity_name)
----writeDebug("Kill Count: "..kill_count)
--for 1 to kill_count do
for i = 1, kill_count do
if isBiter_Breeder(entity_name) then
global.Breeder_Biter_Count = global.Breeder_Biter_Count + 1
----writeDebug("The Number of Breeders Killed is: "..global.Breeder_Biter_Count)
end
end
end
end
]]
local reverse_events = {}
for e_name, e in pairs(defines.events) do
reverse_events[e] = e_name
end
if NE_Enemies.Settings.NE_QC_Mode == true then
LOOT_EXPIRE_TICKS = (60 * 60 * 1) -- Testing
else
LOOT_EXPIRE_TICKS = (60 * 60 * 30) -- 30 min, start spawning worms :)
end
--------------------------------------------------------------------
local function On_Death(event)
local post_event = (event.name == defines.events.on_post_entity_died)
-- Exists only in on_entity_died!
local entity = event.entity
-- on_post_entity_died provides surface_index
local surface = post_event and game.surfaces[event.surface_index] or
entity.surface
-- on_post_entity_died provides position
local pos = post_event and event.position or entity.position
if NE_Enemies.Settings.NE_Alien_Artifact_Eggs == true then
-- writeDebug(string.format("Entered handler for event %s: %s", reverse_events[event.name], serpent.line(event)))
local loot_expires_on_tick = event.tick + LOOT_EXPIRE_TICKS
-- Code for on_post_entity_died
if post_event then
local tick = loot_expires_on_tick
-- Tables have been created in on_entity_died if artifacts were found in loot!
if global.small_alien_artifact_created[tick] or
global.big_alien_artifact_created[tick] then
-- Look for items on ground around position where entity died
local loot_entities = surface.find_entities_filtered({
position = pos,
name = {"small-alien-artifact", "alien-artifact"},
--~ type = "item-entity",
radius = SEARCH_RADIUS_onDeath
})
--log("loot_entities: "..serpent.block(loot_entities))
-- Look for the items on ground that contain artifacts
for e, entity in pairs(loot_entities) do
--log(string.format("e: %s\titem in entity: %s (%s)", e, entity.stack.name, entity.stack.count))
if entity.stack.valid and entity.stack.valid_for_read then
-- Add small artifacts to table
if entity.stack.name == "small-alien-artifact" and
global.small_alien_artifact_created[tick] then
--writeDebug("Loot Trigger is Small Artifact")
--log("entity: "..serpent.line(entity and entity.valid and entity.name))
table.insert(global.small_alien_artifact_created[tick], entity)
-- Add big artifacts to table
elseif entity.stack.name == "alien-artifact" and
global.big_alien_artifact_created[tick] then
-- writeDebug("Loot Trigger is Big Artifact")
table.insert(global.big_alien_artifact_created[tick], entity)
end
end
end
--[[
writeDebug(string.format("Added %s small and %s big artifacts!",
global.small_alien_artifact_created[tick] and
#global.small_alien_artifact_created[tick] or 0,
global.big_alien_artifact_created[tick] and
#global.big_alien_artifact_created[tick] or 0))
]]
end
-- Nothing more to do for on_post_entity_died!
return
end
--------------------------------------------------------------------
-- Code for on_entity_died
--- Look for Alien Artifacts from Loot Drops
local loot = event.loot.get_contents()
--for i_name, i_count in pairs(loot) do
--log(string.format("name: %s\tcount: %s", i_name, i_count))
--end
-- Create tables
if loot["small-alien-artifact"] then
global.small_alien_artifact_created[loot_expires_on_tick] = {}
end
if loot["alien-artifact"] then
global.big_alien_artifact_created[loot_expires_on_tick] = {}
end
end
--- End if post event
if post_event then
return
end
--- If you remove a rocket silo, the tech levle lowers again.
if entity.valid and entity.type == "rocket-silo" and
settings.startup["NE_Challenge_Mode"].value then
global.tech_level = global.tech_level - 1000
if global.tech_level <= 0 then global.tech_level = 0 end
global.number_or_rocketsilos = global.number_or_rocketsilos + 1
if global.number_or_rocketsilos <= 0 then
global.number_or_rocketsilos = 0
end
--- Remove silo from table
if global.rocketsilos[entity.unit_number] then
global.rocketsilos[entity.unit_number] = nil
end
end
--- Unit Launcher Mine Detinated
if entity.valid and NELandmine(entity) == "landmine" then
------writeDebug("Land Mine has been Detinated")
if global.deployed_mine[entity.unit_number] then
global.deployed_mine[entity.unit_number] = nil
end
end
--- If you remove a rocket silo, the tech levle lowers again.
if entity.valid and entity.type == "rocket-silo" and
settings.startup["NE_Challenge_Mode"].value then
global.tech_level = global.tech_level - 1000
if global.tech_level <= 0 then global.tech_level = 0 end
global.number_or_rocketsilos = global.number_or_rocketsilos - 1
if global.number_or_rocketsilos <= 0 then
global.number_or_rocketsilos = 0
end
--- Remove silo from table
if global.rocketsilos[entity.unit_number] then
global.rocketsilos[entity.unit_number] = nil
end
------writeDebug("Tech Level: "..global.tech_level)
end
--- Spawn Breeder Units
if isBreeder(entity) and entity.type == "unit" and UnitNumber(entity) ~= nil then
------writeDebug("Was a Breeder")
SpawnBreederBabies(entity)
end
if isFireBiter(entity) and entity.type == "unit" and UnitNumber(entity) ~=
nil then
------writeDebug("Fire Unit killed")
----This causes some LAG, so removed for now.
if math.floor(UnitNumber(entity)) < 5 then
-- local spawn_fire = surface.create_entity({name="ne-fire-flame-0", position = pos, force = "enemy"})
-- writeDebug("Smaller than 5")
-- Look_and_Burn(spawn_fire, 0.25)
elseif math.floor(UnitNumber(entity)) < 10 then
-- local spawn_fire = surface.create_entity({name="ne-fire-flame-1", position = pos, force = "enemy"})
-- writeDebug("Smaller than 10")
-- Look_and_Burn(spawn_fire, 0.25)
elseif math.floor(UnitNumber(entity)) < 15 then
-- local spawn_fire = surface.create_entity({name="ne-fire-flame-2", position = pos, force = "enemy"})
-- writeDebug("Smaller than 15")
-- Look_and_Burn(spawn_fire, 0.375)
else
-- local spawn_fire = surface.create_entity({name="ne-fire-flame-3", position = pos, force = "enemy"})
-- writeDebug("Bigger than 15")
-- Look_and_Burn(spawn_fire, 0.5)
end
end
--[[
This causes some LAG, so removed for now.
--- Buildings catch fire if destroyed.
if entity.valid and settings.startup["NE_Burning_Buildings"].value and catchFire[entity.type] then
local e_corpse = corpseSize[entity.type]
----writeDebug("Corpse Size: "..e_corpse)
if (force == game.forces.enemy) then
-- do nothing
elseif e_corpse == "medium-remnants" then
--surface.create_entity({name="ne-fire-flame-2", position = pos, force = "enemy"})
elseif e_corpse == "big-remnants" then
--surface.create_entity({name="ne-fire-flame-3", position = pos, force = "enemy"})
else
--surface.create_entity({name="ne-fire-flame-1", position = pos, force = "enemy"})
end
end
]]
--------- If you kill a spawner, enemies will attach you.
if entity.valid and (entity.type == "unit-spawner") then
if entity.force == game.forces.enemy then
----writeDebug("Enemy Spawner Killed")
global.Total_Number_of_Spawners_Killed =
global.Total_Number_of_Spawners_Killed + 1
global.Recent_Number_of_Spawners_Killed =
global.Recent_Number_of_Spawners_Killed + 1
--- First 20 nests are free of danger
if settings.startup["NE_Challenge_Mode"].value and
global.Total_Number_of_Spawners_Killed >
(21 - NE_Enemies.Settings.NE_Difficulty) then
Spawn_Megalodon(event, entity)
end
Look_and_Attack(entity, 1.5)
--- Spawn Breeder Units
if entity.name == "ne-spawner-blue" then
----writeDebug("Was a Breeder Spawner")
SpawnBreederBabies_Spawner(entity)
end
--- Cause Fire
if entity.name == "ne-spawner-red" then
----writeDebug("Was a Fire Spawner")
local size = 3
for xxx = -size, size do
for yyy = -size, size do
local new_position = {x = pos.x + xxx, y = pos.y + yyy}
surface.create_entity({
name = "ne-fire-flame-3",
position = new_position,
force = "enemy"
})
end
end
end
if settings.startup["NE_Scorched_Earth"].value then
Scorched_Earth(surface, pos, 6)
end
else
----writeDebug("Friendly Spawner")
end
end
--------- An Enemy Unit Died
if entity.valid and entity.force == game.forces.enemy and
(entity.type == "unit") and event.force ~= nil and event.cause then -- and event.cause.name == "character" then
--- add to the NE unit counter
NE_Unit_Count(entity)
if settings.startup["NE_Scorched_Earth"].value then
Scorched_Earth(surface, pos, 2)
end
end
--------- Did you really just kill that tree...
if entity.valid and settings.startup["NE_Challenge_Mode"].value and
(entity.type == "tree") and event.force ~= nil and event.cause and
event.cause.name == "character" then
----writeDebug("a Tree was Killed")
Look_and_Attack(entity, 0.5)
---- Sometimes there are small biters in trees...
local spawn_chance = math.random(620 -
(20 *
NE_Enemies.Settings
.NE_Difficulty))
if spawn_chance < math.floor(game.forces.enemy.evolution_factor * 100) then
local tree_monkey = surface.create_entity({
name = "ne-biter-breeder-1",
position = entity.position,
force = game.forces.enemy
})
end
end
-- auto repair things like rails, and signals. Also by destroying the entity the enemy retargets.
if entity.valid and (event.force == game.forces.enemy) and
(autoRepairType[entity.type] or autoRepairName[entity.name]) then
local repairPosition = entity.position
local repairName = entity.name
local repairForce = entity.force
local repairDirection = entity.direction
local wires
if (entity.type == "electric-pole") then
wires = entity.neighbours
end
entity.destroy()
local entityRepaired = surface.create_entity({
position = repairPosition,
name = repairName,
direction = repairDirection,
force = repairForce
})
if wires then
for connectType, neighbourGroup in pairs(wires) do
if connectType == "copper" then
for _, v in pairs(neighbourGroup) do
entityRepaired.connect_neighbour(v);
end
elseif connectType == "red" then
for _, v in pairs(neighbourGroup) do
entityRepaired.connect_neighbour({
wire = defines.wire_type.red,
target_entity = v
});
end
elseif connectType == "green" then
for _, v in pairs(neighbourGroup) do
entityRepaired.connect_neighbour({
wire = defines.wire_type.green,
target_entity = v
});
end
end
end
end
local enemies = surface.find_entities_filtered({
area = {
{x = repairPosition.x - 20, y = repairPosition.y - 20},
{x = repairPosition.x + 20, y = repairPosition.y + 20}
},
type = "unit",
force = game.forces.enemy
})
for i = 1, #enemies do
local enemy = enemies[i]
enemy.set_command({
type = defines.command.wander,
distraction = defines.distraction.by_enemy
})
end
end
end
--------------------------------------------
function Natural_Evolution_Expansion_Settings()
---- Expansion Initialization ----
local enemy_expansion = game.map_settings.enemy_expansion
local unit_group = game.map_settings.unit_group
local path_finder = game.map_settings.path_finder
local NE_multiplier_plus =
((game.forces.enemy.evolution_factor * 100) + 50) /
(77 - NE_Enemies.Settings.NE_Difficulty * 2)
local NE_multiplier_minus =
(((1 - game.forces.enemy.evolution_factor) * 100) + 50) /
(73 + NE_Enemies.Settings.NE_Difficulty * 2)
-----
enemy_expansion.max_expansion_distance =
global.max_expansion_distance_NE * NE_multiplier_plus
-- limit Expansion distance to always we 20 or less. https://forums.factorio.com/viewtopic.php?f=23&t=64381
if enemy_expansion.max_expansion_distance > 20 then
enemy_expansion.max_expansion_distance = 20
end
enemy_expansion.friendly_base_influence_radius =
global.friendly_base_influence_radius_NE * NE_multiplier_minus
enemy_expansion.enemy_building_influence_radius =
global.enemy_building_influence_radius_NE * NE_multiplier_minus
enemy_expansion.building_coefficient =
global.building_coefficient_NE * NE_multiplier_minus
enemy_expansion.other_base_coefficient =
global.other_base_coefficient_NE * NE_multiplier_minus
enemy_expansion.neighbouring_chunk_coefficient =
global.neighbouring_chunk_coefficient_NE * NE_multiplier_minus
enemy_expansion.neighbouring_base_chunk_coefficient =
global.neighbouring_base_chunk_coefficient_NE * NE_multiplier_minus
enemy_expansion.settler_group_min_size =
global.settler_Group_min_size_NE * NE_multiplier_plus
if enemy_expansion.settler_group_min_size < 1 then
enemy_expansion.settler_group_min_size = 1
end
enemy_expansion.settler_group_max_size =
global.settler_Group_max_size_NE * NE_multiplier_plus
if enemy_expansion.settler_group_max_size > 50 then
enemy_expansion.settler_group_max_size = 50
end
unit_group.max_group_radius = global.max_Group_radius_NE *
NE_multiplier_plus
if unit_group.max_group_radius > 60 then unit_group.max_group_radius = 60 end
unit_group.min_group_radius = global.min_Group_radius_NE *
NE_multiplier_plus
if unit_group.min_group_radius > unit_group.max_group_radius then
unit_group.min_group_radius =
math.floor(unit_group.max_group_radius - 1)
elseif unit_group.min_group_radius < 1 then
unit_group.min_group_radius = 1
end
unit_group.max_member_speedup_when_behind =
global.max_Speed_up_NE * NE_multiplier_plus
path_finder.max_steps_worked_per_tick = 20 +
(global.max_Steps_NE *
NE_multiplier_plus)
if path_finder.max_steps_worked_per_tick > 2000 then
path_finder.max_steps_worked_per_tick = 200
end
----writeDebug("The PLUS multiplier is: " .. NE_multiplier_plus)
----writeDebug("The MINUS multiplier is: " .. NE_multiplier_minus)
----writeDebug("The max Expansion distance is (Vanilla): " .. global.max_expansion_distance_NE)
----writeDebug("Changed to due to Evo Factor : " .. enemy_expansion.max_expansion_distance)
------writeDebug("The max other_base_coefficient factore is (Vanilla): " .. global.other_base_oefficient_NE)
------writeDebug("Changed to due to Evo Factor : " .. enemy_expansion.other_base_coefficient)
end
------------------------
function Spawn_Megalodon(event, entity)
--- 100 to 500 0 to 2,000 0 to 4,410 0 to 1,000
local spawn_chance = math.random(math.max(20,
6500 -
((100 *
NE_Enemies.Settings
.NE_Difficulty) +
math.floor(
game.forces.enemy
.evolution_factor *
2000) +
(global.tech_level * 2) +
(global.Recent_Number_of_Spawners_Killed *
50))))
local surface = entity.surface
local health = (100 * NE_Enemies.Settings.NE_Difficulty) +
math.floor(game.forces.enemy.evolution_factor * 1000) +
(global.tech_level * 10)
local force = entity.force
local pos = entity.position
------writeDebug("Health: "..health)
if spawn_chance < (math.floor(game.forces.enemy.evolution_factor * 100) +
NE_Enemies.Settings.NE_Difficulty) then
local megalodon_position = surface.find_non_colliding_position(
"ne-biter-megalodon", entity.position, 5,
0.5)
-- writeDebug("megalodon_position is : "..megalodon_position)
-- writeDebug("entity.position is : "..entity.position.x)
if megalodon_position then
local megalodon = surface.create_entity({
name = "ne-biter-megalodon",
position = megalodon_position,
force = entity.force
})
megalodon.health = health
global.Recent_Number_of_Spawners_Killed = 0
end
end
if event.force ~= nil and event.cause then
if event.cause.type == "artillery-turret" or event.cause.type ==
"artillery-wagon" then
local megalodon_position = surface.find_non_colliding_position(
"ne-biter-megalodon",
entity.position, 5, 0.5)
if megalodon_position then
local megalodon = surface.create_entity({
name = "ne-biter-megalodon",
position = megalodon_position,
force = game.forces.enemy
})
megalodon.health = health * 2
end
------writeDebug("megalodon spawned")
local enemies = surface.find_enemy_units(pos, 50)
local attack_group = surface.create_unit_group({
position = pos,
force = "enemy"
})
----writeDebug("Number of Enemies: "..#enemies)
if #enemies > 0 then
for i = 1, #enemies do
----writeDebug("Enemy "..i.." added to group")
attack_group.add_member(enemies[i])
end
end
surface.set_multi_command {
command = {
type = defines.command.attack,
target = event.cause,
distraction = defines.distraction.by_enemy
},
unit_count = #enemies,
unit_search_distance = 50
}
----writeDebug("Group sent to attack")
end
end
end
---------------------------------------------
-- Spawn Launched Units
function SpawnLaunchedUnits(enemy, unit_to_spawn)
--[[
local test = subEnemyNumberTable[enemy.name][global.evoFactorFloor]
writeDebug("subEnemyNumberTable is: "..subEnemyNumberTable[enemy.name][global.evoFactorFloor])
]]
local subEnemyName = subEnemyNameTable[enemy.name]
if not subEnemyName then
writeDebug("Got kicked out")
return
end
-- writeDebug("Got HERE")
if subEnemyNameTable[enemy.name][global.evoFactorFloor] then
if enemy.name == "ne_green_splash_1" then
subEnemyName = subEnemyNameTable[enemy.name][global.evoFactorFloor]
else
subEnemyName = unit_to_spawn.spawn ..
subEnemyNumberTable[enemy.name][global.evoFactorFloor]
end
end
if game.entity_prototypes[subEnemyName] then
local number = subEnemyNumberTable[enemy.name][global.evoFactorFloor]
-- writeDebug("The Evo Factor is: " .. global.evoFactorFloor)
-- writeDebug("The FLAG Name is: " .. enemy.name)
-- writeDebug("The Enemy Name is: " .. subEnemyName)
-- writeDebug("The NUMBER is: " .. number)
for i = 1, number do
local subEnemyPosition = enemy.surface.find_non_colliding_position(
subEnemyName, enemy.position, 2, 0.5)
if subEnemyPosition then
-- writeDebug("The ne_green_splash_1 force is: " .. enemy.force.name)
create_unit = enemy.surface.create_entity({
name = subEnemyName,
position = subEnemyPosition
})
-- writeDebug("The Created Unit's force is: " .. create_unit.force.name)
-- create_unit = enemy.surface.create_entity({name = subEnemyName, position = subEnemyPosition, force = game.forces.enemy})
create_unit.health = create_unit.health * .95
Remove_Trees(create_unit)
Remove_Rocks(create_unit)
end
end
end
end
function does_tile_exists(tile_name)
local found = false
for _, tile_prototype in pairs(game.tile_prototypes) do
if (tile_prototype.name == tile_name) then found = true end
end
-- game.print("FOUND") -- it does not get here now!
return found
end
----------------------------------------------
function Scorched_Earth(surface, pos, size)
--- Turn the terrain into desert
local New_tiles = {}
local Scorch_test = false
for xxx = -size, size do
for yyy = -size, size do
local new_position = {x = pos.x + xxx, y = pos.y + yyy}
local currentTilename = surface.get_tile(new_position.x,
new_position.y).name
------writeDebug("The current tile is: " .. currentTilename)
if IsAlienBiomeActive then
if currentTilename == "volcanic-orange-heat-4" then
local spawn_fire = surface.create_entity({
name = "ne-fire-flame-0",
position = pos,
force = "enemy"
})
Look_and_Burn(spawn_fire, 0.25)
Remove_Decal(surface, new_position, 1.5, 5)
elseif replaceableTiles_alien[currentTilename] then
if does_tile_exists(replaceableTiles_alien[currentTilename]) then
table.insert(New_tiles, {
name = replaceableTiles_alien[currentTilename],
position = new_position
})
Scorch_test = true
end
Remove_Decal(surface, new_position, 0.5, 1)
end
else
if currentTilename == "red-desert-1" then
local spawn_fire = surface.create_entity({
name = "ne-fire-flame-0",
position = pos,
force = "enemy"
})
Look_and_Burn(spawn_fire, 0.25)
Remove_Decal(surface, new_position, 1.5, 5)
elseif replaceableTiles[currentTilename] then
if does_tile_exists(replaceableTiles[currentTilename]) then
table.insert(New_tiles, {
name = replaceableTiles[currentTilename],
position = new_position
})
Scorch_test = true
end
Remove_Decal(surface, new_position, 0.5, 1)
end
end
end
end
if Scorch_test then surface.set_tiles(New_tiles) end
end
-- Randomly choose a worm to shoot - weighted
function get_worm_to_spawn()
local spawn_options = {
{spawn = "ne-larva-worm-1", weight = 50},
{spawn = "ne-larva-worm-2", weight = 50}
}
local calculate_odds = {}
for k, spawn in ipairs(spawn_options) do
for i = 1, spawn.weight do
calculate_odds[#calculate_odds + 1] = k
end
end
local random_num = #calculate_odds
return spawn_options[calculate_odds[math.random(random_num)]]
end
function Spawn_Worm_Larva(entity)
if not NE_Enemies.Settings.NE_Alien_Artifact_Eggs then
return
end
--- Prevents over-crowding...
local radius = 11 - (math.floor(game.forces.enemy.evolution_factor * 10))
local pos = entity.position
local area = {
{pos.x - radius, pos.y - radius}, {pos.x + radius, pos.y + radius}
}
local worm_names = {
"ne-base-larva-worm", "ne-larva-worm-1", "ne-larva-worm-2", "small-worm-turret", "medium-worm-turret", "big-worm-turret", "behemoth-worm-turret"
}
local worm_count = entity.surface.count_entities_filtered {
area = area,
name = worm_names
}
-- writeDebug("Worm Count is:" .. worm_count)
-- writeDebug("Check Number:" .. (10 + (math.floor(game.forces.enemy.evolution_factor * 10))))
local Worm_Name = get_worm_to_spawn()
--writeDebug("Worm Name is:" .. Worm_Name.spawn)
--local Worm_Name = "ne-base-larva-worm"
local PositionValid = entity.surface.find_non_colliding_position(
Worm_Name.spawn, entity.position, 2, 0.5, 0.01)
if PositionValid and worm_count < (10 + (math.floor(game.forces.enemy.evolution_factor * 10))) then
local worm_larva = entity.surface.create_entity({
name = Worm_Name.spawn,
position = PositionValid,
force = game.forces.enemy
})
if Worm_Name.spawn == "ne-larva-worm-1" then
worm_larva.health = 1 + 5 * (math.floor(game.forces.enemy.evolution_factor * 10))
end
Remove_Trees(worm_larva)
Remove_Rocks(worm_larva)
end
end
function Spawn_Worm(entity)
if not NE_Enemies.Settings.NE_Alien_Artifact_Eggs then
return
end
if (math.floor(game.forces.enemy.evolution_factor * 10)) < 2 then
if NE_Enemies.Settings.NE_Alien_Artifact_Eggs then
Spawn_Worm_Name = "ne-base-larva-worm"
PositionValid = entity.surface.find_non_colliding_position(Spawn_Worm_Name, entity.position, 1, 1, 0.02)
end
elseif
(math.floor(game.forces.enemy.evolution_factor * 10)) < 4 then
Spawn_Worm_Name = "small-worm-turret"
PositionValid = entity.surface.find_non_colliding_position(Spawn_Worm_Name, entity.position, 1.5, 1.4, 0.02)
elseif
(math.floor(game.forces.enemy.evolution_factor * 10)) < 6 then
Spawn_Worm_Name = "medium-worm-turret"
PositionValid = entity.surface.find_non_colliding_position(Spawn_Worm_Name, entity.position, 1.5, 1.6, 0.02)
elseif
(math.floor(game.forces.enemy.evolution_factor * 10)) < 8 then
Spawn_Worm_Name = "big-worm-turret"
PositionValid = entity.surface.find_non_colliding_position(Spawn_Worm_Name, entity.position, 2, 1.8, 0.02)
else
Spawn_Worm_Name = "behemoth-worm-turret"
PositionValid = entity.surface.find_non_colliding_position(Spawn_Worm_Name, entity.position, 2.5, 2, 0.02)
end
if PositionValid then
local worm_spawn = entity.surface.create_entity({
name = Spawn_Worm_Name,
position = PositionValid,
force = game.forces.enemy
})
worm_spawn.health = 1 + 15 * (math.floor(game.forces.enemy.evolution_factor * 10))
Remove_Trees(worm_spawn)
Remove_Rocks(worm_spawn)
end
end
-------------------------------------------------------------------------------
--[[EVENTS]] --
-------------------------------------------------------------------------------
local function on_tick()
if game.tick % (60 * 60 * 5) == 0 then -- Check every 5 min for Achievements
Achievement_Check()
end
--[[
if game.tick % (60 * 60 * 1) == 0 then -- Check every 5 min for Achievements
writeDebug("Whatis the Loot Tick Exp:" .. LOOT_EXPIRE_TICKS)
end
]]
--------------------------------------------------------
if global.big_alien_artifact_created[game.tick] then
local cnt = 0
for e, entity in pairs(global.big_alien_artifact_created[game.tick]) do
if entity.valid then
cnt = cnt + 1
Spawn_Worm(entity)
entity.destroy()
end
end
global.big_alien_artifact_created[game.tick] = nil
--log(string.format("Removed %s big artifacts!", cnt))
end
if global.small_alien_artifact_created[game.tick] then
local cnt = 0
for e, entity in pairs(global.small_alien_artifact_created[game.tick] or {}) do
if entity.valid then
cnt = cnt + 1
Spawn_Worm_Larva(entity)
entity.destroy()
end
end
global.small_alien_artifact_created[game.tick] = nil
--log(string.format("Removed %s small artifacts!", cnt))
end
-----------------------------------------
if game.tick % (60 * 60 * 10) == 0 then -- Check every 10 min for old mines, Expansion settings
--- Check for Old Mines
if global.deployed_mine ~= nil then
for k, Old_Mines in pairs(global.deployed_mine) do
if Old_Mines.time and Old_Mines.time + (3600 * 30) < game.tick then -- 3600 is 1 min, remove mines older than 30min
Old_Mines.mine.destroy()
Old_Mines.time = nil
Old_Mines.mine = nil
end
end
end
-----------------------------------------------------------
--- Every 10min, increase the evo factor by 5% of remaining evo, if a silo is build.
if global.number_or_rocketsilos >= 1 and
settings.startup["NE_Challenge_Mode"].value then
-- game.forces.enemy.evolution_factor = game.forces.enemy.evolution_factor + (1 - game.forces.enemy.evolution_factor)/5
if game.forces.enemy.evolution_factor > 1 then
game.forces.enemy.evolution_factor = 1
end
----writeDebug("Increase Evo")
-- Biters will attack Rocket Silo and Player(s)
if not settings.global["NE_Remove_Biter_Search"].value then
----writeDebug("Search and attack Rocket Silo and Player(s)")
---- Attack the player, since you have a silo built
for _, player in pairs(game.players) do
if player.connected and player.valid and player.character and
player.character.valid then
player.surface.set_multi_command {
command = {
type = defines.command.attack,
target = player.character,
distraction = defines.distraction.by_enemy
},
unit_count = math.floor(4000 *
game.forces.enemy
.evolution_factor),
unit_search_distance = 2500 *
NE_Enemies.Settings.NE_Difficulty
}
end
end
---- Attack the player, since you have a silo built
if table_size(global.rocketsilos) >= 1 then
for _, silo in pairs(global.rocketsilos) do
----writeDebug("Silo Valid, attack")
silo.silo.surface.set_multi_command {
command = {
type = defines.command.attack,
target = silo.silo,
distraction = defines.distraction.by_enemy
},
unit_count = math.floor(4000 *
game.forces.enemy
.evolution_factor),
unit_search_distance = 2500 *
NE_Enemies.Settings.NE_Difficulty
}
end
end
end
end
if game.active_mods["Natural_Evolution_Expansion"] then
----writeDebug("NE Expansion Installled - Do Nothing")
elseif settings.startup["NE_Expansion_Management"].value then
----writeDebug("Pass - Will execute Expansion settings")
Natural_Evolution_Expansion_Settings()
end
end
end
------------------------ TRIGGERS -----------------------------------------
script.on_event(defines.events.on_trigger_created_entity, function(event)
local entity = event.entity
--- Land Mine Created
if entity.valid and NELandmine(entity) == "landmine" then
global.deployed_mine[entity.unit_number] = {
mine = entity,
time = event.tick
}
--- Remove trees around mines, to prevent units from getting stuck
Remove_Trees(entity)
Remove_Rocks(entity)
-- writeDebug(table_size(global.deployed_mine) )
end
--- Unit Launcher Projectile Trigger
if entity.valid and entity.name == "ne_green_splash_1" then
if global.tick < event.tick then
if game.forces.enemy.evolution_factor > 0.995 then
global.evoFactorFloor = 10
else
global.evoFactorFloor = math.floor(game.forces.enemy
.evolution_factor * 10)
end
global.tick = global.tick + 1800
end
local radius = 13 - NE_Enemies.Settings.NE_Difficulty
local pos = entity.position
local area = {
{pos.x - radius, pos.y - radius}, {pos.x + radius, pos.y + radius}
}
local unit_names = {
"ne-biter-fast-1", "ne-biter-fast-2", "ne-biter-fast-3",
"ne-biter-fast-4", "ne-biter-fast-5", "ne-biter-fast-6",
"ne-biter-fast-7", "ne-biter-fast-8", "ne-biter-fast-9",
"ne-biter-fast-10", "ne-biter-fast-11", "ne-biter-fast-12",
"ne-biter-fast-13", "ne-biter-fast-14", "ne-biter-fast-15",
"ne-biter-fast-16", "ne-biter-fast-17", "ne-biter-fast-18",
"ne-biter-fast-19", "ne-biter-fast-20", "ne-biter-fastL-1",
"ne-biter-fastL-2", "ne-biter-fastL-3", "ne-biter-fastL-4",
"ne-biter-fastL-5", "ne-biter-fastL-6", "ne-biter-fastL-7",
"ne-biter-fastL-8", "ne-biter-fastL-9", "ne-biter-fastL-10",
"ne-biter-fastL-11", "ne-biter-fastL-12", "ne-biter-fastL-13",
"ne-biter-fastL-14", "ne-biter-fastL-15", "ne-biter-fastL-16",
"ne-biter-fastL-17", "ne-biter-fastL-18", "ne-biter-fastL-19",
"ne-biter-fastL-20"
}
local green_units = entity.surface.count_entities_filtered {
area = area,
name = unit_names
}
-- writeDebug("Count is: "..green_units)
-- Only spawn new units if there are 10 or less units in the area. - Prevents over-crowding...
if green_units <= (10 + NE_Enemies.Settings.NE_Difficulty * 2) then
SpawnLaunchedUnits(entity)
end
end
--- WORM Launcher Projectile Trigger (This should spawn the units from the BIG Worm attack)
if entity.valid and entity.name == "ne_green_splash_2" then
-- writeDebug("Entity Name Created: "..entity.name)
if global.tick < event.tick then
if game.forces.enemy.evolution_factor > 0.995 then
global.evoFactorFloor = 10
else
global.evoFactorFloor = math.floor(game.forces.enemy
.evolution_factor * 10)
end
global.tick = global.tick + 1800
end
-- Randomly choose a unit to shoot - weighted
function get_unit_to_spawn()
local spawn_options = {
{spawn = "ne-biter-breeder-", weight = 20},
{spawn = "ne-biter-fire-", weight = 30},
{spawn = "ne-biter-fast-", weight = 60},
{spawn = "ne-biter-wallbreaker-", weight = 50},
{spawn = "ne-biter-tank-", weight = 20},
{spawn = "ne-spitter-breeder-", weight = 8},
{spawn = "ne-spitter-fire-", weight = 3},
{spawn = "ne-spitter-ulaunch-", weight = 2},
{spawn = "ne-spitter-webshooter-", weight = 10},
{spawn = "ne-spitter-mine-", weight = 10}
}
--[[
local spawn_options = {
NE_Enemies.Settings.NE_Biter_Breeder and
{spawn = "ne-biter-breeder-", weight = 20} or nil,
NE_Enemies.Settings.NE_Biter_Fire and
{spawn = "ne-biter-fire-", weight = 30} or nil,
NE_Enemies.Settings.NE_Biter_Fast and
{spawn = "ne-biter-fast-", weight = 60} or nil,
NE_Enemies.Settings.NE_Biter_Wallbreaker and
{spawn = "ne-biter-wallbreaker-", weight = 50} or nil,
NE_Enemies.Settings.NE_Biter_Tank and
{spawn = "ne-biter-tank-", weight = 20} or nil,
NE_Enemies.Settings.NE_Spitter_Breeder and
{spawn = "ne-spitter-breeder-", weight = 8} or nil,
NE_Enemies.Settings.NE_Spitter_Fire and
{spawn = "ne-spitter-fire-", weight = 3} or nil,
NE_Enemies.Settings.NE_Spitter_Ulaunch and
{spawn = "ne-spitter-ulaunch-", weight = 2} or nil,
NE_Enemies.Settings.NE_Spitter_Webshooter and
{spawn = "ne-spitter-webshooter-", weight = 10} or nil,
NE_Enemies.Settings.NE_Spitter_Mine and
{spawn = "ne-spitter-mine-", weight = 10} or nil
}
]]
local calculate_odds = {}
for k, spawn in ipairs(spawn_options) do
for i = 1, spawn.weight do
calculate_odds[#calculate_odds + 1] = k
end
end
local random_num = #calculate_odds
return spawn_options[calculate_odds[math.random(random_num)]]
end
local unit_to_spawn = get_unit_to_spawn()
-- writeDebug("#2: spawn name: "..unit_to_spawn.spawn.. "1")
if game.entity_prototypes[unit_to_spawn.spawn.. "1"] then
SpawnLaunchedUnits(entity, unit_to_spawn)
else
writeDebug("Entity does not exist")
end
end
--- A cliff got bombed
if entity.valid and NE_Enemies.Settings.Tree_Hugger and
global.cliff_explosive[entity.name] then
----writeDebug("Cliff Bombed")
Look_and_Attack(entity, 2)
end
--- If Fire then destroy stuff on ground
if entity.valid and entity.name == "ne-fire-flame-2" then
-- writeDebug("Fire Trigger")
Look_and_Burn(entity, 0.25)
end
--- If Fire then destroy stuff on ground
if entity.valid and entity.name == "fire-flame" then
-- writeDebug("Fire Trigger: fire-flame")
Look_and_Burn(entity, 0.5)
end
end)
-------------------------------------------------------------------------------
script.on_event(defines.events.on_research_finished, function(event)
local research = event.research.name
if research == "military-science-pack" then
global.tech_level = global.tech_level + 10
end
if research == "military" then global.tech_level = global.tech_level + 5 end
if research == "military-2" then
global.tech_level = global.tech_level + 5
end
if research == "military-3" then
global.tech_level = global.tech_level + 5
end
if research == "military-4" then
global.tech_level = global.tech_level + 5
end
if research == "uranium-ammo" then
global.tech_level = global.tech_level + 10
end
if research == "atomic-bomb" then
global.tech_level = global.tech_level + 500
end
if research == "explosives" then
global.tech_level = global.tech_level + 50
end
if research == "flammables" then
global.tech_level = global.tech_level + 5
end
if research == "land-mine" then global.tech_level = global.tech_level + 5 end
if research == "flamethrower" then
global.tech_level = global.tech_level + 10
end
if research == "laser" then global.tech_level = global.tech_level + 15 end
if research == "tanks" then global.tech_level = global.tech_level + 15 end
if research == "rocketry" then global.tech_level = global.tech_level + 5 end
if research == "explosive-rocketry" then
global.tech_level = global.tech_level + 50
end
if research == "heavy-armor" then
global.tech_level = global.tech_level + 10
end
if research == "modular-armor" then
global.tech_level = global.tech_level + 20
end
if research == "power-armor" then
global.tech_level = global.tech_level + 25
end
if research == "power-armor-2" then
global.tech_level = global.tech_level + 25
end
if research == "turrets" then global.tech_level = global.tech_level + 5 end
if research == "laser-turrets" then
global.tech_level = global.tech_level + 15
end
if research == "stone-walls" then
global.tech_level = global.tech_level + 5
end
if research == "rocket-silo" then
global.tech_level = global.tech_level + 500
end
if research == "combat-robotics" then
global.tech_level = global.tech_level + 15
end
if research == "combat-robotics-2" then
global.tech_level = global.tech_level + 15
end
if research == "combat-robotics-3" then
global.tech_level = global.tech_level + 15
end
if research == "artillery" then
global.tech_level = global.tech_level + 500
end
if research == "energy-shield-equipment" then
global.tech_level = global.tech_level + 50
end
if research == "energy-shield-mk2-equipment" then
global.tech_level = global.tech_level + 50
end
if research == "personal-laser-defense-equipment" then
global.tech_level = global.tech_level + 10
end
if research == "discharge-defense-equipment" then
global.tech_level = global.tech_level + 10
end
---- Military Tech Upgrades
if research == "physical-projectile-damage-1" then
global.tech_level = global.tech_level + 10
end
if research == "physical-projectile-damage-2" then
global.tech_level = global.tech_level + 20
end
if research == "physical-projectile-damage-3" then
global.tech_level = global.tech_level + 30
end
if research == "physical-projectile-damage-4" then
global.tech_level = global.tech_level + 40
end
if research == "physical-projectile-damage-5" then
global.tech_level = global.tech_level + 50
end
if research == "physical-projectile-damage-6" then
global.tech_level = global.tech_level + 100
end
if research == "physical-projectile-damage-7" then
global.tech_level = global.tech_level + 150
end
if research == "stronger-explosives-1" then
global.tech_level = global.tech_level + 10
end
if research == "stronger-explosives-2" then
global.tech_level = global.tech_level + 20
end
if research == "stronger-explosives-3" then
global.tech_level = global.tech_level + 30
end
if research == "stronger-explosives-4" then
global.tech_level = global.tech_level + 40
end
if research == "stronger-explosives-5" then
global.tech_level = global.tech_level + 50
end
if research == "stronger-explosives-6" then
global.tech_level = global.tech_level + 100
end
if research == "stronger-explosives-7" then
global.tech_level = global.tech_level + 150
end
if research == "refined-flammables-1" then
global.tech_level = global.tech_level + 10
end
if research == "refined-flammables-2" then
global.tech_level = global.tech_level + 20
end
if research == "refined-flammables-3" then
global.tech_level = global.tech_level + 30
end
if research == "refined-flammables-4" then
global.tech_level = global.tech_level + 40
end
if research == "refined-flammables-5" then
global.tech_level = global.tech_level + 50
end
if research == "refined-flammables-6" then
global.tech_level = global.tech_level + 100
end
if research == "refined-flammables-7" then
global.tech_level = global.tech_level + 150
end
if research == "energy-weapons-damage-1" then
global.tech_level = global.tech_level + 50
end
if research == "energy-weapons-damage-2" then
global.tech_level = global.tech_level + 50
end
if research == "energy-weapons-damage-3" then
global.tech_level = global.tech_level + 50
end
if research == "energy-weapons-damage-4" then
global.tech_level = global.tech_level + 50
end
if research == "energy-weapons-damage-5" then
global.tech_level = global.tech_level + 100
end
if research == "energy-weapons-damage-6" then
global.tech_level = global.tech_level + 200
end
if research == "energy-weapons-damage-7" then
global.tech_level = global.tech_level + 500
end
if research == "weapon-shooting-speed-1" then
global.tech_level = global.tech_level + 5
end
if research == "weapon-shooting-speed-2" then
global.tech_level = global.tech_level + 15
end
if research == "weapon-shooting-speed-3" then
global.tech_level = global.tech_level + 25
end
if research == "weapon-shooting-speed-4" then
global.tech_level = global.tech_level + 50
end
if research == "weapon-shooting-speed-5" then
global.tech_level = global.tech_level + 100
end
if research == "weapon-shooting-speed-6" then
global.tech_level = global.tech_level + 150
end
if research == "laser-turret-speed-1" then
global.tech_level = global.tech_level + 50
end
if research == "laser-turret-speed-2" then
global.tech_level = global.tech_level + 60
end
if research == "laser-turret-speed-3" then
global.tech_level = global.tech_level + 80
end
if research == "laser-turret-speed-4" then
global.tech_level = global.tech_level + 90
end
if research == "laser-turret-speed-5" then
global.tech_level = global.tech_level + 100
end
if research == "laser-turret-speed-6" then
global.tech_level = global.tech_level + 150
end
if research == "laser-turret-speed-7" then
global.tech_level = global.tech_level + 200
end
--
if research == "artillery-shell-range-1" then
global.tech_level = global.tech_level + 300
end
--
if research == "artillery-shell-speed-1" then
global.tech_level = global.tech_level + 300
end
--
if research == "follower-robot-count-1" then
global.tech_level = global.tech_level + 100
end
if research == "follower-robot-count-2" then
global.tech_level = global.tech_level + 100
end
if research == "follower-robot-count-3" then
global.tech_level = global.tech_level + 100
end
if research == "follower-robot-count-4" then
global.tech_level = global.tech_level + 100
end
if research == "follower-robot-count-5" then
global.tech_level = global.tech_level + 100
end
if research == "follower-robot-count-6" then
global.tech_level = global.tech_level + 100
end
if research == "follower-robot-count-7" then
global.tech_level = global.tech_level + 100
end
end)
-------------------------------------------------------------------------------
--[[EVENTS]] --
-------------------------------------------------------------------------------
script.on_configuration_changed(On_Config_Change)
script.on_init(On_Init)
script.on_event(defines.events.on_tick, on_tick)
local build_events = {
defines.events.on_built_entity, defines.events.on_robot_built_entity
}
script.on_event(build_events, On_Built)
local pre_remove_events = {
defines.events.on_pre_player_mined_item, defines.events.on_robot_pre_mined
}
script.on_event(pre_remove_events, On_Remove)
local death_events = {defines.events.on_entity_died, defines.events.on_post_entity_died}
script.on_event(death_events, On_Death)
script.on_nth_tick(60, function()
--updates each second instead of each onDeath
SEARCH_RADIUS_onDeath = 5 + (math.floor(game.forces.enemy.evolution_factor * 10))
end)
-------------------------------------------------------------------------------
--- DeBug Messages
function writeDebug(message)
if QC_Mod == true then
for i, player in pairs(game.players) do
player.print(tostring(message))
end
end
end