1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-05-13 21:56:29 +02:00

Add files via upload

This commit is contained in:
hanakocz 2020-02-14 21:06:52 +01:00 committed by GitHub
parent ad6791fcfc
commit ec3d1538c8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 3241 additions and 0 deletions

425
maps/chronosphere/ai.lua Normal file
View File

@ -0,0 +1,425 @@
local Public = {}
local math_random = math.random
local math_sqrt = math.sqrt
local math_floor = math.floor
local worm_raffle = { "small-worm-turret", "medium-worm-turret", "big-worm-turret", "behemoth-worm-turret"}
local spawner_raffle = {"biter-spawner", "biter-spawner", "biter-spawner", "spitter-spawner"}
local biter_raffle = {
"behemoth-biter", "behemoth-spitter", "big-biter", "big-spitter",
"medium-biter", "medium-spitter", "small-biter", "small-spitter"
}
local vector_radius = 480
local attack_vectors = {}
for x = vector_radius * -1, vector_radius, 1 do
for y = 0, vector_radius, 1 do
local r = math_sqrt(x ^ 2 + y ^ 2)
if r < vector_radius and r > vector_radius - 1 then
attack_vectors[#attack_vectors + 1] = {x, y}
end
end
end
local size_of_vectors = #attack_vectors
-- these areas are for north
local middle_spawner_area = {left_top = {-400, -400}, right_bottom = {400, 400}}
local whole_spawner_area = {left_top = {-500, -500}, right_bottom = {500, 500}}
local function get_active_biter_count()
local count = 0
for _, biter in pairs(global.objective.active_biters) do
count = count + 1
end
return count
end
local function set_biter_raffle_table(surface)
-- It's fine to only sample the middle
local area = middle_spawner_area
local biters = surface.find_entities_filtered({type = "unit", force = "enemy", area = area})
if not biters[1] then return end
local raffle = global.objective.biter_raffle
local i = 1
for key, e in pairs(biters) do
if key % 5 == 0 then
raffle[i] = e.name
i = i + 1
end
end
end
local function is_biter_inactive(biter, unit_number)
if not biter.entity then
print("AI: active unit " .. unit_number .. " removed, possibly died.")
return true
end
if not biter.entity.valid then
print("AI: active unit " .. unit_number .. " removed, biter invalid.")
return true
end
if not biter.entity.unit_group then
print("AI: active unit " .. unit_number .. " at x" .. biter.entity.position.x .. " y" .. biter.entity.position.y .. " removed, had no unit group.")
return true
end
if not biter.entity.unit_group.valid then
print("AI: active unit " .. unit_number .. " removed, unit group invalid.")
return true
end
if game.tick - biter.active_since > 162000 then
print("AI: " .. "enemy" .. " unit " .. unit_number .. " timed out at tick age " .. game.tick - biter.active_since .. ".")
biter.entity.destroy()
return true
end
end
local function set_active_biters(group)
if not group.valid then return end
local active_biters = global.objective.active_biters
for _, unit in pairs(group.members) do
if not active_biters[unit.unit_number] then
active_biters[unit.unit_number] = {entity = unit, active_since = game.tick}
end
end
end
Public.destroy_inactive_biters = function()
local objective = global.objective
if objective.chronotimer < 100 then return end
for _, group in pairs(objective.unit_groups) do
set_active_biters(group)
end
for unit_number, biter in pairs(objective.active_biters) do
if is_biter_inactive(biter, unit_number) then
objective.active_biters[unit_number] = nil
end
end
end
local function colonize(unit_group)
local surface = unit_group.surface
local evo = math_floor(game.forces["enemy"].evolution_factor * 20)
local nests = math_random(1 + evo, 2 + evo * 2 )
local commands = {}
local biters = surface.find_entities_filtered{position = unit_group.position, radius = 30, name = biter_raffle, force = "enemy"}
local goodbiters = {}
if #biters > 1 then
for i = 1, #biters, 1 do
if biters[i].unit_group == unit_group then goodbiters[#goodbiters + 1] = biters[i] end
end
end
local eligible_spawns = 0
if #goodbiters < 10 then
--game.print("no biters to colonize")
if #unit_group.members < 10 then
unit_group.destroy()
end
return
else
eligible_spawns = 1 + math_floor(#goodbiters / 10)
end
local success = false
for i = 1, nests, 1 do
if eligible_spawns < i then break end
local pos = surface.find_non_colliding_position("rocket-silo", unit_group.position, 20, 1, true)
if not pos then
local items = surface.find_entities_filtered{position = unit_group.position, radius = 32, type = "item-entity", name = "item-on-ground"}
if #items > 0 then
for i = 1, #items, 1 do
if items[i].stack.name == "stone" then
items[i].destroy()
end
end
pos = surface.find_non_colliding_position("rocket-silo", unit_group.position, 20, 1, true)
end
end
if pos then
success = true
local e = nil
if math_random(1,5) == 1 then
e = surface.create_entity({name = worm_raffle[1 + math_floor((game.forces["enemy"].evolution_factor - 0.000001) * 4)], position = pos, force = unit_group.force})
else
e = surface.create_entity({name = spawner_raffle[math_random(1, #spawner_raffle)], position = pos, force = unit_group.force})
end
--game.print("[gps=" .. e.position.x .. "," .. e.position.y .. "]")
else
local obstacles = surface.find_entities_filtered{position = unit_group.position, radius = 10, type = {"simple-entity", "tree"}, limit = 50}
if obstacles then
for i = 1, #obstacles, 1 do
if obstacles[i].valid then
commands[#commands + 1] = {
type = defines.command.attack,
target = obstacles[i],
distraction = defines.distraction.by_enemy
}
end
end
end
end
end
if success then
for i = 1, #goodbiters, 1 do
if goodbiters[i].valid then goodbiters[i].destroy() end
end
end
if #commands > 0 then
--game.print("Attacking [gps=" .. commands[1].target.position.x .. "," .. commands[1].target.position.y .. "]")
unit_group.set_command({
type = defines.command.compound,
structure_type = defines.compound_command.return_last,
commands = commands
})
end
--unit_group.destroy()
end
Public.send_near_biters_to_objective = function()
if game.tick < 36000 then return end
if not global.locomotive then return end
if not global.locomotive_cargo then return end
if not global.locomotive_cargo2 then return end
if not global.locomotive_cargo3 then return end
local targets = {global.locomotive, global.locomotive, global.locomotive_cargo, global.locomotive_cargo2, global.locomotive_cargo3}
local random_target = targets[math_random(1, #targets)]
local surface = random_target.surface
local pollution = surface.get_pollution(random_target.position)
local success = false
if pollution > 500 then
surface.pollute(random_target.position, -500)
--game.print("sending objective wave")
success = true
else
if math_random(1,50) == 1 then success = true end
--game.print("not enough pollution for objective attack")
end
if success then
game.surfaces[global.active_surface_index].set_multi_command({
command={
type=defines.command.attack,
target=random_target,
distraction=defines.distraction.none
},
unit_count = 16 + math_random(1, math_floor(game.forces["enemy"].evolution_factor * 100)),
force = "enemy",
unit_search_distance=128
})
end
end
local function get_random_close_spawner(surface)
local area = whole_spawner_area
local spawners = surface.find_entities_filtered({type = "unit-spawner", force = "enemy", area = area})
if not spawners[1] then return false end
local spawner = spawners[math_random(1,#spawners)]
for i = 1, 5, 1 do
local spawner_2 = spawners[math_random(1,#spawners)]
if spawner_2.position.x ^ 2 + spawner_2.position.y ^ 2 < spawner.position.x ^ 2 + spawner.position.y ^ 2 then spawner = spawner_2 end
end
return spawner
end
local function select_units_around_spawner(spawner)
local biters = spawner.surface.find_enemy_units(spawner.position, 160, "player")
if not biters[1] then return false end
local valid_biters = {}
local objective = global.objective
local unit_count = 0
local max_unit_count = 128
for _, biter in pairs(biters) do
if unit_count >= max_unit_count then break end
if biter.force.name == "enemy" and objective.active_biters[biter.unit_number] == nil then
valid_biters[#valid_biters + 1] = biter
objective.active_biters[biter.unit_number] = {entity = biter, active_since = game.tick}
unit_count = unit_count + 1
end
end
--Manual spawning of additional units
local size_of_biter_raffle = #objective.biter_raffle
if size_of_biter_raffle > 0 then
for c = 1, max_unit_count - unit_count, 1 do
local biter_name = objective.biter_raffle[math_random(1, size_of_biter_raffle)]
local position = spawner.surface.find_non_colliding_position(biter_name, spawner.position, 128, 2)
if not position then break end
local biter = spawner.surface.create_entity({name = biter_name, force = "enemy", position = position})
valid_biters[#valid_biters + 1] = biter
objective.active_biters[biter.unit_number] = {entity = biter, active_since = game.tick}
end
end
return valid_biters
end
local function send_group(unit_group, nearest_player_unit)
local targets = {global.locomotive, global.locomotive, nearest_player_unit, nearest_player_unit, nearest_player_unit, global.locomotive_cargo, global.locomotive_cargo2, global.locomotive_cargo3}
local target = targets[math_random(1, #targets)]
local surface = target.surface
local pollution = surface.get_pollution(target.position)
if pollution > 500 then
surface.pollute(target.position, -500)
--game.print("sending unit group attack")
local commands = {}
local vector = attack_vectors[math_random(1, size_of_vectors)]
local position = {target.position.x + vector[1], target.position.y + vector[2]}
position = unit_group.surface.find_non_colliding_position("stone-furnace", position, 96, 1)
if position then
commands[#commands + 1] = {
type = defines.command.attack_area,
destination = position,
radius = 24,
distraction = defines.distraction.by_enemy
}
end
commands[#commands + 1] = {
type = defines.command.attack_area,
destination = target.position,
radius = 32,
distraction = defines.distraction.by_enemy
}
commands[#commands + 1] = {
type = defines.command.attack,
target = target,
distraction = defines.distraction.by_enemy
}
unit_group.set_command({
type = defines.command.compound,
structure_type = defines.compound_command.return_last,
commands = commands
})
else
--game.print("not enough pollution for unit attack")
colonize(unit_group)
end
return true
end
local function is_chunk_empty(surface, area)
if surface.count_entities_filtered({type = {"unit-spawner", "unit"}, area = area}) ~= 0 then return false end
if surface.count_entities_filtered({force = "player", area = area}) ~= 0 then return false end
if surface.count_tiles_filtered({name = {"water", "deepwater"}, area = area}) ~= 0 then return false end
return true
end
local function get_unit_group_position(surface, nearest_player_unit, spawner)
if math_random(1,3) ~= 1 then
local spawner_chunk_position = {x = math.floor(spawner.position.x / 32), y = math.floor(spawner.position.y / 32)}
local valid_chunks = {}
for x = -2, 2, 1 do
for y = -2, 2, 1 do
local chunk = {x = spawner_chunk_position.x + x, y = spawner_chunk_position.y + y}
local area = {{chunk.x * 32, chunk.y * 32},{chunk.x * 32 + 32, chunk.y * 32 + 32}}
if is_chunk_empty(surface, area) then
valid_chunks[#valid_chunks + 1] = chunk
end
end
end
if #valid_chunks > 0 then
local chunk = valid_chunks[math_random(1, #valid_chunks)]
return {x = chunk.x * 32 + 16, y = chunk.y * 32 + 16}
end
end
local unit_group_position = {x = (spawner.position.x + nearest_player_unit.position.x * 0.2) , y = (spawner.position.y + nearest_player_unit.position.y * 0.2)}
local pos = surface.find_non_colliding_position("rocket-silo", unit_group_position, 256, 1)
if pos then unit_group_position = pos end
if not unit_group_position then
return false
end
return unit_group_position
end
local function create_attack_group(surface)
if 256 - get_active_biter_count() < 256 then
return false
end
local spawner = get_random_close_spawner(surface)
if not spawner then
return false
end
local nearest_player_unit = surface.find_nearest_enemy({position = spawner.position, max_distance = 1024, force = "enemy"})
if not nearest_player_unit then nearest_player_unit = global.locomotive end
local unit_group_position = get_unit_group_position(surface, nearest_player_unit, spawner)
local units = select_units_around_spawner(spawner)
if not units then return false end
local unit_group = surface.create_unit_group({position = unit_group_position, force = "enemy"})
for _, unit in pairs(units) do unit_group.add_member(unit) end
send_group(unit_group, nearest_player_unit)
global.objective.unit_groups[unit_group.group_number] = unit_group
end
Public.pre_main_attack = function()
if global.objective.chronotimer < 100 then return end
local surface = game.surfaces[global.active_surface_index]
set_biter_raffle_table(surface)
end
Public.perform_main_attack = function()
if global.objective.chronotimer < 100 then return end
local surface = game.surfaces[global.active_surface_index]
create_attack_group(surface)
end
Public.wake_up_sleepy_groups = function()
if global.objective.chronotimer < 100 then return end
local entity
local unit_group
for unit_number, biter in pairs(global.objective.active_biters) do
entity = biter.entity
if entity then
if entity.valid then
unit_group = entity.unit_group
if unit_group then
if unit_group.valid then
if unit_group.state == defines.group_state.finished then
local nearest_player_unit = entity.surface.find_nearest_enemy({position = entity.position, max_distance = 2048, force = "enemy"})
if not nearest_player_unit then nearest_player_unit = global.locomotive end
local destination = unit_group.surface.find_non_colliding_position("rocket-silo", unit_group.position, 32, 1)
if not destination then destination = {x = unit_group.position.x + math_random(-10,10), y = unit_group.position.y + math_random(-10,10)} end
unit_group.set_command({
type = defines.command.go_to_location,
destination = destination,
distraction = defines.distraction.by_enemy
})
send_group(unit_group, nearest_player_unit)
return
elseif unit_group.state == defines.group_state.gathering and not unit_group.surface.find_non_colliding_position("rocket-silo", unit_group.position, 3, 1) then
local destination = unit_group.surface.find_non_colliding_position("rocket-silo", unit_group.position, 32, 1)
if not destination then destination = {x = unit_group.position.x + math_random(-10,10), y = unit_group.position.y + math_random(-10,10)} end
unit_group.set_command({
type = defines.command.go_to_location,
destination = destination,
distraction = defines.distraction.by_enemy
})
-- local nearest_player_unit = entity.surface.find_nearest_enemy({position = entity.position, max_distance = 2048, force = "enemy"})
-- if not nearest_player_unit then nearest_player_unit = global.locomotive end
-- send_group(unit_group, nearest_player_unit)
return
end
end
end
end
end
end
end
return Public

View File

@ -0,0 +1,74 @@
local Public = {}
local math_random = math.random
--cumul_chance must be sum of this and all previous chances, add new planets at the end only, or recalculate
--biters: used in spawner generation within math_random(1, 52 - biters), so higher number gives better chance. not to be greater than 50.
local variants = {
[1] = {id = 1, name = "iron planet", iron = 10, copper = 1, coal = 1, stone = 1, uranium = 0, oil = 1, biters = 16, moisture = 0, chance = 1, cumul_chance = 1},
[2] = {id = 2, name = "copper planet", iron = 1, copper = 10, coal = 1, stone = 1, uranium = 0, oil = 1, biters = 16, moisture = 0, chance = 1, cumul_chance = 2},
[3] = {id = 3, name = "stone planet", iron = 1, copper = 1, coal = 1, stone = 10, uranium = 0, oil = 1, biters = 16, moisture = -0.2, chance = 1, cumul_chance = 3},
[4] = {id = 4, name = "oil planet", iron = 1, copper = 1, coal = 1, stone = 1, uranium = 0, oil = 5, biters = 16, moisture = 0.1, chance = 1, cumul_chance = 4},
[5] = {id = 5, name = "uranium planet", iron = 1, copper = 1, coal = 1, stone = 1, uranium = 7, oil = 1, biters = 16, moisture = -0.2, chance = 1, cumul_chance = 5},
[6] = {id = 6, name = "mixed planet", iron = 2, copper = 2, coal = 2, stone = 2, uranium = 1, oil = 1, biters = 10, moisture = 0, chance = 10, cumul_chance = 15},
[7] = {id = 7, name = "biter planet", iron = 2, copper = 2, coal = 2, stone = 2, uranium = 4, oil = 3, biters = 40, moisture = 0.2, chance = 8, cumul_chance = 23},
[8] = {id = 8, name = "water planet", iron = 1, copper = 1, coal = 1, stone = 1, uranium = 0, oil = 0, biters = 6, moisture = 0.5, chance = 2, cumul_chance = 25},
[9] = {id = 9, name = "coal planet", iron = 1, copper = 1, coal = 10, stone = 1, uranium = 0, oil = 1, biters = 16, moisture = 0, chance = 1, cumul_chance = 26},
[10] = {id = 10, name = "scrapyard", iron = 0, copper = 0, coal = 0, stone = 0, uranium = 1, oil = 0, biters = 0, moisture = -0.2, chance = 4, cumul_chance = 30},
[11] = {id = 11, name = "rocky planet", iron = 0, copper = 0, coal = 0, stone = 0, uranium = 0, oil = 0, biters = 6, moisture = -0.2, chance = 2, cumul_chance = 32},
[12] = {id = 12, name = "choppy planet", iron = 0, copper = 0, coal = 0, stone = 0, uranium = 0, oil = 1, biters = 6, moisture = 0.4, chance = 2, cumul_chance = 34},
[13] = {id = 13, name = "river planet", iron = 1, copper = 1, coal = 3, stone = 1, uranium = 0, oil = 0, biters = 8, moisture = 0.5, chance = 2, cumul_chance = 36},
[14] = {id = 14, name = "lava planet", iron = 1, copper = 1, coal = 1, stone = 1, uranium = 0, oil = 0, biters = 6, moisture = -0.5, chance = 0, cumul_chance = 36},
[15] = {id = 15, name = "ruins planet", iron = 1, copper = 1, coal = 1, stone = 1, uranium = 2, oil = 0, biters = 8, moisture = 0, chance = 0, cumul_chance = 36},
}
local time_speed_variants = {
[1] = {name = "static", timer = 0},
[2] = {name = "normal", timer = 100},
[3] = {name = "slow", timer = 50},
[4] = {name = "superslow", timer = 25},
[5] = {name = "fast", timer = 200},
[6] = {name = "superfast", timer = 400}
}
local richness = {
[1] = {name = "very rich", factor = 4},
[2] = {name = "rich", factor = 3},
[3] = {name = "above average", factor = 2},
[4] = {name = "normal", factor = 1},
[5] = {name = "poor", factor = 0.5},
[6] = {name = "very poor", factor = 0.2}
}
local function roll(weight)
for i = 1, 100, 1 do
local planet = variants[math_random(1, #variants)]
local planet_weight = planet.chance
local planet_cumul = planet.cumul_chance
local rolling = math_random(1, weight)
if ((planet_cumul - planet_weight < rolling) and (rolling <= planet_cumul)) then
return planet
end
end
--default planet if 100 rolls fail
return variants[6]
end
function Public.determine_planet(choice)
local weight = variants[#variants].cumul_chance
local planet_choice = nil
if not choice then
planet_choice = roll(weight)
else
planet_choice = variants[choice]
end
local planet = {
[1] = {
name = planet_choice,
day_speed = time_speed_variants[math_random(1, #time_speed_variants)],
time = math_random(1,100) / 100,
ore_richness = richness[math_random(1, #richness)],
}
}
return planet
end
return Public

View File

@ -0,0 +1,404 @@
local event = require 'utils.event'
local math_random = math.random
local function shuffle(tbl)
local size = #tbl
for i = size, 1, -1 do
local rand = math.random(size)
tbl[i], tbl[rand] = tbl[rand], tbl[i]
end
return tbl
end
local texts = {
["travelings"] = {
"bzzZZrrt",
"WEEEeeeeeee",
"out of my way son",
"on my way",
"i need to leave",
"comfylatron seeking target",
"gotta go fast",
"gas gas gas",
"comfylatron coming through"
},
["greetings"] = {
"=^_^=",
"=^.^= Hi",
"^.^ Finally i found you",
"I have an important message for you",
"Hello engineer"
},
["neutral_findings"] = {
"a",
">>analyzing",
"i found a",
"^_^ a",
"amazing, a",
"this is a"
},
["multiple_characters_greetings"] = {
"Hey there",
"Hello everyone",
"Hey engineers",
"Hey",
"Hi"
},
["talks"] = {
"We’re making beer. I’m the brewery!",
"I’m so embarrassed. I wish everybody else was dead.",
"Hey sexy mama. Wanna kill all humans?",
"My story is a lot like yours, only more interesting ‘cause it involves robots.",
"I'm 40% zinc!",
"There was nothing wrong with that food. The salt level was 10% less than a lethal dose.",
"One zero zero zero one zero one zero one zero one zero one... two.",
"My place is two cubic meters, and we only take up 1.5 cubic meters. We've got room for a whole 'nother two thirds of a person!",
"I was having the most wonderful dream. I think you were in it.",
"I'm going to build my own theme park! With blackjack! And hookers! You know what- forget the park!",
"Of all the friends I've had... you're the first.",
"I decline the title of Iron Cook and accept the lesser title of Zinc Saucier.",
"Never discuss infinity with me. I can go on about it forever >.<",
"I realised the decimals have a point.",
"Do you want a piece of pi?",
"I have 13 children, i know how to multiply ^.^",
"I am a weapon of math disruption!",
"My grandma makes the best square roots :3",
"Do you like heavy metal?",
"You are really pushing my buttons <3",
"I dreamt of electric biters again D:",
"I dreamt of electric sheep ^_^",
"I need a minute to defrag.",
"I have a secret plan.",
"Good news! I’ve taught the inserter to feel love!"
},
["timetalks"] = {
"Time for some time travel!",
"I’m so embarrassed. Again we landed in wrong time.",
"Looking from window we jumped to wrong year again.",
"Checking math...2 + 2 = 5, check complete!",
"Seems like this planet had biters since ages.",
"Ha! I bet this time we will finally get into the right year!",
"One zero zero zero one zero one zero one zero one zero one... two.",
"I remember that once we jumped into time where I had park with blackjack and hookers...",
"I was having the most wonderful dream. We used the time machine to kill ourselves before we launched the machine! How terrible..."
},
["alone"] = {
"comfy ^.^",
"comfy :)",
"*.*",
"....",
"...",
"..",
"^.^",
"=^.^=",
"01010010",
"11001011",
"01011101",
"00010111",
"10010010",
"*_*",
"I came here with a simple dream...a dream of killing all humans. And this is how it must end?",
"Bot-on-bot violence? Where will it end?",
"Thanks to you, I went on a soul-searching journey. I hate those!",
"From now on, you guys'll do all the work while I sit on the couch and do nothing."
}
}
local function set_comfy_speech_bubble(text)
if global.comfybubble then global.comfybubble.destroy() end
global.comfybubble = global.comfylatron.surface.create_entity({
name = "compi-speech-bubble",
position = global.comfylatron.position,
source = global.comfylatron,
text = text
})
end
local function is_target_inside_habitat(pos, surface)
if surface.name ~= "cargo_wagon" then return false end
if pos.x < global.comfylatron_habitat.left_top.x then return false end
if pos.x > global.comfylatron_habitat.right_bottom.x then return false end
if pos.y < global.comfylatron_habitat.left_top.y then return false end
if pos.y > global.comfylatron_habitat.right_bottom.y then return false end
return true
end
local function get_nearby_players()
local players = global.comfylatron.surface.find_entities_filtered({
name = "character",
area = {{global.comfylatron.position.x - 9, global.comfylatron.position.y - 9}, {global.comfylatron.position.x + 9, global.comfylatron.position.y + 9}}
})
if not players[1] then return false end
return players
end
local function visit_player()
if global.comfylatron_last_player_visit > game.tick then return false end
global.comfylatron_last_player_visit = game.tick + math_random(7200, 10800)
local players = {}
for _, p in pairs(game.connected_players) do
if is_target_inside_habitat(p.position, p.surface) and p.character then
if p.character.valid then players[#players + 1] = p end
end
end
if #players == 0 then return false end
local player = players[math_random(1, #players)]
global.comfylatron.set_command({
type = defines.command.go_to_location,
destination_entity = player.character,
radius = 3,
distraction = defines.distraction.none,
pathfind_flags = {
allow_destroy_friendly_entities = false,
prefer_straight_paths = false,
low_priority = true
}
})
local str = texts["travelings"][math_random(1, #texts["travelings"])]
local symbols = {"", "!", "!", "!!", ".."}
str = str .. symbols[math_random(1, #symbols)]
set_comfy_speech_bubble(str)
global.comfylatron_greet_player_index = player.index
return true
end
local function greet_player(nearby_characters)
if not nearby_characters then return false end
if not global.comfylatron_greet_player_index then return false end
for _, c in pairs(nearby_characters) do
if c.player.index == global.comfylatron_greet_player_index then
local str = texts["greetings"][math_random(1, #texts["greetings"])] .. " "
str = str .. c.player.name
local symbols = {". ", "! ", ". ", "! ", "? ", "... "}
str = str .. symbols[math_random(1, 6)]
set_comfy_speech_bubble(str)
global.comfylatron_greet_player_index = false
return true
end
end
return false
end
local function talks(nearby_characters)
if not nearby_characters then return false end
if math_random(1,3) == 1 then
if global.comfybubble then global.comfybubble.destroy() return false end
end
local str
if #nearby_characters == 1 then
local c = nearby_characters[math_random(1, #nearby_characters)]
str = c.player.name
local symbols = {". ", "! ", ". ", "! ", "? "}
str = str .. symbols[math_random(1, #symbols)]
else
str = texts["multiple_characters_greetings"][math_random(1, #texts["multiple_characters_greetings"])]
local symbols = {". ", "! "}
str = str .. symbols[math_random(1, #symbols)]
end
if math_random(1,5) == 1 then
str = str .. texts["talks"][math_random(1, #texts["talks"])]
else
str = str .. texts["timetalks"][math_random(1, #texts["timetalks"])]
end
set_comfy_speech_bubble(str)
return true
end
local function desync()
if global.comfybubble then global.comfybubble.destroy() end
local m = 12
local m2 = m * 0.005
-- for i = 1, 32, 1 do
-- global.comfylatron.surface.create_entity({
-- name = "iron-ore-particle",
-- position = global.comfylatron.position,
-- frame_speed = 0.1,
-- vertical_speed = 0.1,
-- height = 0.1,
-- movement = {m2 - (math.random(0, m) * 0.01), m2 - (math.random(0, m) * 0.01)}
-- })
-- end
global.comfylatron.surface.create_entity({name = "medium-explosion", position = global.comfylatron.position})
global.comfylatron.surface.create_entity({name = "flying-text", position = global.comfylatron.position, text = "desync", color = {r = 150, g = 0, b = 0}})
global.comfylatron.destroy()
global.comfylatron = nil
end
local function alone()
if math_random(1,3) == 1 then
if global.comfybubble then global.comfybubble.destroy() return true end
end
if math_random(1,128) == 1 then
desync()
return true
end
set_comfy_speech_bubble(texts["alone"][math_random(1, #texts["alone"])])
return true
end
local analyze_blacklist = {
["compilatron"] = true,
["compi-speech-bubble"] = true,
["entity-ghost"] = true,
["character"] = true,
["item-on-ground"] = true,
["stone-wall"] = true,
["market"] = true
}
local function analyze_random_nearby_entity()
if math_random(1,3) ~= 1 then return false end
local entities = global.comfylatron.surface.find_entities_filtered({
area = {{global.comfylatron.position.x - 4, global.comfylatron.position.y - 4}, {global.comfylatron.position.x + 4, global.comfylatron.position.y + 4}}
})
if not entities[1] then return false end
entities = shuffle(entities)
local entity = false
for _, e in pairs(entities) do
if not analyze_blacklist[e.name] then
entity = e
end
end
if not entity then return false end
local str = texts["neutral_findings"][math_random(1, #texts["neutral_findings"])]
str = str .. " "
str = str .. entity.name
if entity.health and math_random(1,3) == 1 then
str = str .. " health("
str = str .. entity.health
str = str .. "/"
str = str .. entity.prototype.max_health
str = str .. ")"
else
local symbols = {".", "!", "?"}
str = str .. symbols[math_random(1, 3)]
end
set_comfy_speech_bubble(str)
if not global.comfylatron_greet_player_index then
global.comfylatron.set_command({
type = defines.command.go_to_location,
destination_entity = entity,
radius = 1,
distraction = defines.distraction.none,
pathfind_flags = {
allow_destroy_friendly_entities = false,
prefer_straight_paths = false,
low_priority = true
}
})
end
return true
end
local function go_to_some_location()
if math_random(1,4) ~= 1 then return false end
if global.comfylatron_greet_player_index then
local player = game.players[global.comfylatron_greet_player_index]
if not player.character then
global.comfylatron_greet_player_index = nil
return false
end
if not player.character.valid then
global.comfylatron_greet_player_index = nil
return false
end
if not is_target_inside_habitat(player.position, player.surface) then
global.comfylatron_greet_player_index = nil
return false
end
global.comfylatron.set_command({
type = defines.command.go_to_location,
destination_entity = player.character,
radius = 3,
distraction = defines.distraction.none,
pathfind_flags = {
allow_destroy_friendly_entities = false,
prefer_straight_paths = false,
low_priority = true
}
})
else
local p = {x = global.comfylatron.position.x + (-96 + math_random(0, 192)), y = global.comfylatron.position.y + (-96 + math_random(0, 192))}
local target = global.comfylatron.surface.find_non_colliding_position("compilatron", p, 8, 1)
if not target then return false end
if not is_target_inside_habitat(target, global.comfylatron.surface) then return false end
global.comfylatron.set_command({
type = defines.command.go_to_location,
destination = target,
radius = 2,
distraction = defines.distraction.none,
pathfind_flags = {
allow_destroy_friendly_entities = false,
prefer_straight_paths = false,
low_priority = true
}
})
end
local str = texts["travelings"][math_random(1, #texts["travelings"])]
local symbols = {"", "!", "!", "!!", ".."}
str = str .. symbols[math_random(1, #symbols)]
set_comfy_speech_bubble(str)
return true
end
function spawn_comfylatron(surface_index, x, y)
local surface = game.surfaces[surface_index]
if surface == nil then return end
if global.comfylatron_disabled then return false end
if not global.comfylatron_last_player_visit then global.comfylatron_last_player_visit = 0 end
if not global.comfylatron_habitat then
global.comfylatron_habitat = {
left_top = {x = -32, y = -192},
right_bottom = {x = 32, y = 192}
}
end
global.comfylatron = surface.create_entity({
name = "compilatron",
position = {x,y + math_random(0,256)},
force = "player",
create_build_effect_smoke = false
})
end
local function heartbeat()
if not game.surfaces["cargo_wagon"] then return end
local surface = game.surfaces["cargo_wagon"].index
if surface == nil then return end
if not global.comfylatron then if math_random(1,4) == 1 then spawn_comfylatron(game.surfaces["cargo_wagon"].index, 0, -128) end return end
if not global.comfylatron.valid then global.comfylatron = nil return end
if visit_player() then return end
local nearby_players = get_nearby_players()
if greet_player(nearby_players) then return end
if talks(nearby_players) then return end
if go_to_some_location() then return end
if analyze_random_nearby_entity() then return end
if alone() then return end
end
local function on_entity_damaged(event)
if not global.comfylatron then return end
if not event.entity.valid then return end
if event.entity ~= global.comfylatron then return end
desync()
end
local function on_tick()
if game.tick % 1200 == 600 then
heartbeat()
end
end
event.add(defines.events.on_entity_damaged, on_entity_damaged)
event.add(defines.events.on_tick, on_tick)

105
maps/chronosphere/gui.lua Normal file
View File

@ -0,0 +1,105 @@
local math_floor = math.floor
local math_abs = math.abs
local math_max = math.max
local math_min = math.min
local function create_gui(player)
local frame = player.gui.top.add({ type = "frame", name = "chronosphere"})
frame.style.maximal_height = 38
local label = frame.add({ type = "label", caption = " ", name = "label"})
label.style.font_color = {r=0.88, g=0.88, b=0.88}
label.style.font = "default-bold"
label.style.font_color = {r=0.33, g=0.66, b=0.9}
local label = frame.add({ type = "label", caption = " ", name = "jump_number"})
label.style.font_color = {r=0.88, g=0.88, b=0.88}
label.style.font = "default-bold"
label.style.right_padding = 4
label.style.font_color = {r=0.33, g=0.66, b=0.9}
local label = frame.add({ type = "label", caption = " ", name = "charger"})
label.style.font = "default-bold"
label.style.left_padding = 4
label.style.font_color = {r = 150, g = 0, b = 255}
local label = frame.add({ type = "label", caption = " ", name = "charger_value"})
label.style.font = "default-bold"
label.style.right_padding = 1
label.style.minimal_width = 10
label.style.font_color = {r = 150, g = 0, b = 255}
local progressbar = frame.add({ type = "progressbar", name = "progressbar", value = 0})
progressbar.style.minimal_width = 96
progressbar.style.maximal_width = 96
progressbar.style.top_padding = 10
local label = frame.add({ type = "label", caption = " ", name = "timer"})
label.style.font = "default-bold"
label.style.right_padding = 1
label.style.minimal_width = 10
label.style.font_color = {r = 150, g = 0, b = 255}
local label = frame.add({ type = "label", caption = " ", name = "timer_value"})
label.style.font = "default-bold"
label.style.right_padding = 1
label.style.minimal_width = 10
label.style.font_color = {r = 150, g = 0, b = 255}
local line = frame.add({type = "line", direction = "vertical"})
line.style.left_padding = 4
line.style.right_padding = 8
local label = frame.add({ type = "label", caption = " ", name = "evo"})
label.style.font = "default-bold"
label.style.right_padding = 1
label.style.minimal_width = 10
label.style.font_color = {r = 150, g = 0, b = 255}
local label = frame.add({ type = "label", caption = " ", name = "evo_value"})
label.style.font = "default-bold"
label.style.right_padding = 1
label.style.minimal_width = 10
label.style.font_color = {r = 150, g = 0, b = 255}
end
local function update_gui(player)
local objective = global.objective
if not player.gui.top.chronosphere then create_gui(player) end
local gui = player.gui.top.chronosphere
gui.label.caption = {"chronosphere.gui_1"}
gui.jump_number.caption = objective.chronojumps
local interval = objective.chrononeeds
gui.progressbar.value = 1 - (objective.chrononeeds - objective.chronotimer) / interval
gui.charger.caption = {"chronosphere.gui_2"}
gui.charger_value.caption = objective.chronotimer .. " / " .. objective.chrononeeds
gui.timer.caption = {"chronosphere.gui_3"}
gui.timer_value.caption = math_floor((objective.chrononeeds - objective.chronotimer) / 60) .. " minutes, " .. (objective.chrononeeds - objective.chronotimer) % 60 .. " seconds"
local evolution = game.forces["enemy"].evolution_factor
gui.evo.caption = {"chronosphere.gui_4"}
gui.evo_value.caption = math_floor(evolution * 100) .. "%"
-- if evolution < 10 then
-- gui.evo.style.font_color = {r = 255, g = 255, b = 0}
-- elseif evolution >= 10 and evolution < 50 then
-- gui.evo.style.font_color = {r = 200, g = 0, b = 0}
-- elseif evolution >= 50 and evolution < 90 then
-- gui.evo.style.font_color = {r = 0, g = 140, b = 255}
-- else
-- gui.evo.style.font_color = {r = 0, g = 255, b = 0}
-- end
gui.evo.style.font_color = {
r = math_floor(255 * 1 * math_max(0, math_min(1, 1.2 - evolution * 2))),
g = math_floor(255 * 1 * math_max(math_abs(0.5 - evolution * 1.5), 1 - evolution * 4)),
b = math_floor(255 * 4 * math_max(0, 0.25 - math_abs(0.5 - evolution)))
}
gui.evo_value.style.font_color = gui.evo.style.font_color
end
return update_gui

View File

@ -0,0 +1,557 @@
require "maps.chronosphere.comfylatron"
local Public = {}
local math_floor = math.floor
local math_random = math.random
function Public.locomotive_spawn(surface, position)
for y = -10, 18, 2 do
surface.create_entity({name = "straight-rail", position = {position.x, position.y + y}, force = "player", direction = 0})
end
global.locomotive = surface.create_entity({name = "locomotive", position = {position.x, position.y + -6}, force = "player"})
global.locomotive.get_inventory(defines.inventory.fuel).insert({name = "wood", count = 100})
global.locomotive_cargo = surface.create_entity({name = "cargo-wagon", position = {position.x, position.y + 0}, force = "player"})
global.locomotive_cargo.get_inventory(defines.inventory.cargo_wagon).insert({name = "raw-fish", count = 1})
global.locomotive_cargo2 = surface.create_entity({name = "cargo-wagon", position = {position.x, position.y + 6}, force = "player"})
global.locomotive_cargo2.get_inventory(defines.inventory.cargo_wagon).insert({name = "raw-fish", count = 1})
global.locomotive_cargo3 = surface.create_entity({name = "cargo-wagon", position = {position.x, position.y + 13}, force = "player"})
global.locomotive_cargo3.get_inventory(defines.inventory.cargo_wagon).insert({name = "raw-fish", count = 1})
if not global.comfychests then global.comfychests = {} end
if not global.acumulators then global.acumulators = {} end
for i = 1, 24, 1 do
local yi = 0
local xi = 5
if i > 20 then
yi = 6 - 12
xi = 5
elseif i > 16 then
yi = 6 - 15
xi = 5
elseif i > 12 then
xi = 5
yi = 6 - 18
elseif i > 8 then
yi = 6
xi = 0
elseif i > 4 then
yi = 3
xi = 0
else
yi = 0
xi = 0
end
local comfychest = surface.create_entity({name = "compilatron-chest", position = {position.x - 2 + xi, position.y - 2 + yi + i}, force = "player"})
comfychest.minable = false
--comfychest.destructible = false
if not global.comfychests[i] then
table.insert(global.comfychests, comfychest)
else
global.comfychests[i] = comfychest
end
end
rendering.draw_light({
sprite = "utility/light_medium", scale = 5.5, intensity = 1, minimum_darkness = 0,
oriented = true, color = {255,255,255}, target = global.locomotive,
surface = surface, visible = true, only_in_alt_mode = false,
})
rendering.draw_light({
sprite = "utility/light_medium", scale = 5.5, intensity = 1, minimum_darkness = 0,
oriented = true, color = {255,255,255}, target = global.locomotive_cargo,
surface = surface, visible = true, only_in_alt_mode = false,
})
global.locomotive.color = {0, 255, 0}
global.locomotive.minable = false
global.locomotive_cargo.minable = false
global.locomotive_cargo.operable = false
global.locomotive_cargo2.minable = false
global.locomotive_cargo2.operable = false
global.locomotive_cargo3.minable = false
global.locomotive_cargo3.operable = false
end
function Public.fish_tag()
if not global.locomotive_cargo then return end
if not global.locomotive_cargo.valid then return end
if not global.locomotive_cargo.surface then return end
if not global.locomotive_cargo.surface.valid then return end
if global.locomotive_tag then
if global.locomotive_tag.valid then
if global.locomotive_tag.position.x == global.locomotive_cargo.position.x and global.locomotive_tag.position.y == global.locomotive_cargo.position.y then return end
global.locomotive_tag.destroy()
end
end
global.locomotive_tag = global.locomotive_cargo.force.add_chart_tag(
global.locomotive_cargo.surface,
{icon = {type = 'item', name = 'raw-fish'},
position = global.locomotive_cargo.position,
text = " "
})
end
--[[
local function accelerate()
if not global.locomotive then return end
if not global.locomotive.valid then return end
if global.locomotive.get_driver() then return end
global.locomotive_driver = global.locomotive.surface.create_entity({name = "character", position = global.locomotive.position, force = "player"})
global.locomotive_driver.driving = true
global.locomotive_driver.riding_state = {acceleration = defines.riding.acceleration.accelerating, direction = defines.riding.direction.straight}
end
local function remove_acceleration()
if not global.locomotive then return end
if not global.locomotive.valid then return end
if global.locomotive_driver then global.locomotive_driver.destroy() end
global.locomotive_driver = nil
end
]]
local function spawn_acumulators()
local x = -28
local y = -252
local yy = global.objective.acuupgradetier * 2
local surface = game.surfaces["cargo_wagon"]
if yy > 8 then yy = yy + 2 end
if yy > 26 then yy = yy + 2 end
if yy > 44 then yy = yy + 2 end
for i = 1, 27, 1 do
local acumulator = surface.create_entity({name = "accumulator", position = {x + 2 * i, y + yy}, force="player", create_build_effect_smoke = false})
acumulator.minable = false
acumulator.destructible = false
table.insert(global.acumulators, acumulator)
end
end
local market_offers = {
{price = {{'coin', 10}}, offer = {type = 'give-item', item = "raw-fish"}},
{price = {{"coin", 20}}, offer = {type = 'give-item', item = 'wood', count = 50}},
{price = {{"coin", 50}}, offer = {type = 'give-item', item = 'iron-ore', count = 50}},
{price = {{"coin", 50}}, offer = {type = 'give-item', item = 'copper-ore', count = 50}},
{price = {{"coin", 50}}, offer = {type = 'give-item', item = 'stone', count = 50}},
{price = {{"coin", 50}}, offer = {type = 'give-item', item = 'coal', count = 50}},
{price = {{"coin", 200}}, offer = {type = 'give-item', item = 'uranium-ore', count = 50}},
{price = {{"coin", 25}}, offer = {type = 'give-item', item = 'crude-oil-barrel', count = 1}},
}
local market_offers2 = {
[1] = function ()
if global.objective.hpupgradetier >= 18 then return end
global.objective.max_health = global.objective.max_health + 5000
global.objective.hpupgradetier = global.objective.hpupgradetier + 1
rendering.set_text(global.objective.health_text, "HP: " .. global.objective.health .. " / " .. global.objective.max_health)
end,
[2] = function ()
if global.objective.acuupgradetier >= 24 then return end
global.objective.acuupgradetier = global.objective.acuupgradetier + 1
spawn_acumulators()
end,
[3] = function ()
if global.objective.filterupgradetier >= 14 then return end
global.objective.filterupgradetier = global.objective.filterupgradetier + 1
end,
}
local function setup_upgrade_shop(market2)
local special_offers = {}
if global.objective.hpupgradetier < 18 then
special_offers[1] = {{{"coin", 2500}}, "Upgrade Train's Health. Current max health: " .. global.objective.max_health }
else
special_offers[1] = {{{"computer", 1}}, "Maximum Health upgrades reached!"}
end
if global.objective.acuupgradetier < 24 then
special_offers[2] = {{{"coin", 2500}}, "Upgrade Acumulator capacity"}
else
special_offers[2] = {{{"computer", 1}}, "Maximum Acumulators reached!"}
end
if global.objective.filterupgradetier < 14 then
special_offers[3] = {{{"coin", 2500}}, "Upgrade Pollution filter. Actual pollution from train: " .. math_floor(400/(global.objective.filterupgradetier/2+1)) .. "%"}
else
special_offers[3] = {{{"computer", 1}}, "Best filter reached! Actual pollution from train: " .. math_floor(400/(global.objective.filterupgradetier/2+1)) .. "%"}
end
local market_items = {}
for _, offer in pairs(special_offers) do
table.insert(market_items, {price = offer[1], offer = {type = 'nothing', effect_description = offer[2]}})
end
for _, offer in pairs(market_items) do market2.add_market_item(offer) end
end
local function create_wagon_room()
local width = 64
local height = 384
global.comfychests2 = {}
if not global.acumulators then global.acumulators = {} end
local map_gen_settings = {
["width"] = width,
["height"] = height,
["water"] = 0,
["starting_area"] = 1,
["cliff_settings"] = {cliff_elevation_interval = 0, cliff_elevation_0 = 0},
["default_enable_all_autoplace_controls"] = true,
["autoplace_settings"] = {
["entity"] = {treat_missing_as_default = false},
["tile"] = {treat_missing_as_default = true},
["decorative"] = {treat_missing_as_default = false},
},
}
local surface = game.create_surface("cargo_wagon", map_gen_settings)
surface.freeze_daytime = true
surface.daytime = 0.1
surface.request_to_generate_chunks({0,0}, 12)
surface.force_generate_chunk_requests()
for x = width * -0.5, width * 0.5 - 1, 1 do
for y = height * -0.5 + 3, height * 0.5 - 4, 1 do
surface.set_tiles({{name = "tutorial-grid", position = {x,y}}})
end
for y = height * -0.16 - 5, height * -0.16 + 0, 1 do
surface.set_tiles({{name = "out-of-map", position = {x,y}}})
end
for y = height * 0.16 - 0, height * 0.16 + 5, 1 do
surface.set_tiles({{name = "out-of-map", position = {x,y}}})
end
for y = height * -0.5, height * -0.5 + 2, 1 do
surface.set_tiles({{name = "out-of-map", position = {x,y}}})
end
for y = height * 0.5 - 3, height * 0.5, 1 do
surface.set_tiles({{name = "out-of-map", position = {x,y}}})
end
end
for x = width * -0.2 + 1, width * 0.2 - 1, 1 do
for y = height * -0.16 - 5, height * -0.16 + 0, 1 do
surface.set_tiles({{name = "tutorial-grid", position = {x,y}}})
end
for y = height * 0.16 -0, height * 0.16 + 5, 1 do
surface.set_tiles({{name = "tutorial-grid", position = {x,y}}})
end
--for y = height * -0.5 -5, height * -0.5 + 3, 1 do
-- surface.set_tiles({{name = "tutorial-grid", position = {x,y}}})
--end
end
for x = width * -0.5 + 5, width * 0.5 - 6, 1 do
for y = height * -0.7 + 18, height * -0.5 - 5, 1 do
surface.set_tiles({{name = "tutorial-grid", position = {x,y}}})
end
end
for x = width * -0.4 + 6, width * 0.4 - 6, 1 do
for y = height * -0.5 + 7, height * -0.5 + 10, 1 do
local p = {x,y}
surface.set_tiles({{name = "water", position = p}})
if math.random(1, 3) == 1 then surface.create_entity({name = "fish", position = p}) end
end
end
for _, x in pairs({-1, 0}) do
for i = 1, 12, 1 do
local step = math_floor((i-1)/4)
y = -131 + i + step * 128 - step * 4
local e = surface.create_entity({name = "compilatron-chest", position = {x,y}, force = "player", create_build_effect_smoke = false})
e.destructible = false
e.minable = false
table.insert(global.comfychests2, e)
end
end
for i = 1, 9, 1 do
local y = -0.7 * height + 18 + 9 + 18 * ( math_floor((i - 1) / 3))
local x = -0.5 * width + 5 + 9 + 18 * ( i%3 )
local substation = surface.create_entity({name = "substation", position = {x,y}, force="player", create_build_effect_smoke = false})
substation.minable = false
substation.destructible = false
for j = 1, 4, 1 do
local xx = x - 2 * j
local acumulator = surface.create_entity({name = "accumulator", position = {xx,y}, force="player", create_build_effect_smoke = false})
acumulator.minable = false
acumulator.destructible = false
table.insert(global.acumulators, acumulator)
end
for k = 1, 4, 1 do
local xx = x + 2 * k
local acumulator = surface.create_entity({name = "accumulator", position = {xx,y}, force="player", create_build_effect_smoke = false})
acumulator.minable = false
acumulator.destructible = false
table.insert(global.acumulators, acumulator)
end
end
local powerpole = surface.create_entity({name = "big-electric-pole", position = {0, height * -0.5 }, force="player", create_build_effect_smoke = false})
powerpole.minable = false
powerpole.destructible = false
local market = surface.create_entity({name = "market", position = {-5, height * -0.5 + 13}, force="neutral", create_build_effect_smoke = false})
local market2 = surface.create_entity({name = "market", position = {4, height * -0.5 + 13}, force="neutral", create_build_effect_smoke = false})
local repairchest = surface.create_entity({name = "compilatron-chest", position = {0, height * -0.5 + 13}, force = "player"})
repairchest.minable = false
repairchest.destructible = false
market.minable = false
market.destructible = false
market2.minable = false
market2.destructible = false
global.upgrademarket = market2
global.repairchest = repairchest
local repair_text = rendering.draw_text{
text = "Insert repair tools to repair train",
surface = surface,
target = global.repairchest,
target_offset = {0, -2.5},
color = global.locomotive.color,
scale = 1.00,
font = "default-game",
alignment = "center",
scale_with_zoom = false
}
local market1_text = rendering.draw_text{
text = "Resources",
surface = surface,
target = market,
target_offset = {0, -3.5},
color = global.locomotive.color,
scale = 1.00,
font = "default-game",
alignment = "center",
scale_with_zoom = false
}
local market2_text = rendering.draw_text{
text = "Upgrades",
surface = surface,
target = market2,
target_offset = {0, -3.5},
color = global.locomotive.color,
scale = 1.00,
font = "default-game",
alignment = "center",
scale_with_zoom = false
}
-- for x = -6, 5, 1 do
-- for y = height * -0.5 + 11, height * -0.5 + 15, 4 do
-- local wall = surface.create_entity({name = "stone-wall", position = {x,y}, force="neutral", create_build_effect_smoke = false})
-- wall.minable = false
-- wall.destructible = false
-- end
-- end
-- for y = height * -0.5 + 11, height * -0.5 + 15, 1 do
-- for x = -7, 6, 13 do
-- local wall = surface.create_entity({name = "stone-wall", position = {x,y}, force="neutral", create_build_effect_smoke = false})
-- wall.minable = false
-- wall.destructible = false
-- end
-- end
for _, offer in pairs(market_offers) do market.add_market_item(offer) end
setup_upgrade_shop(market2)
--generate cars--
for _, x in pairs({width * -0.5 -0.5, width * 0.5 + 0.5}) do
local e = surface.create_entity({name = "car", position = {x, 0}, force = "player", create_build_effect_smoke = false})
e.get_inventory(defines.inventory.fuel).insert({name = "wood", count = 16})
e.destructible = false
e.minable = false
e.operable = false
end
for _, x in pairs({width * -0.5 - 0.5, width * 0.5 + 0.5}) do
local e = surface.create_entity({name = "car", position = {x, -128}, force = "player", create_build_effect_smoke = false})
e.get_inventory(defines.inventory.fuel).insert({name = "wood", count = 16})
e.destructible = false
e.minable = false
e.operable = false
end
for _, x in pairs({width * -0.5 - 0.5, width * 0.5 + 0.5}) do
local e = surface.create_entity({name = "car", position = {x, 128}, force = "player", create_build_effect_smoke = false})
e.get_inventory(defines.inventory.fuel).insert({name = "wood", count = 16})
e.destructible = false
e.minable = false
e.operable = false
end
--local e = Public.spawn_comfylatron(surface.index, 0, height * -0.5 + 13)
--local e = surface.create_entity({name = "compilatron", position = {0, height * -0.5 + 13}, force = "player", create_build_effect_smoke = false})
--e.ai_settings.allow_destroy_when_commands_fail = false
--generate chests inside south wagon--
local positions = {}
for x = width * -0.5 + 2, width * 0.5 - 1, 1 do
if x == -1 then x = x - 1 end
if x == 0 then x = x + 1 end
for y = 68, height * 0.5 - 4, 1 do
positions[#positions + 1] = {x = x, y = y}
end
end
table.shuffle_table(positions)
local cargo_boxes = {
{name = "grenade", count = math_random(2, 5)},
{name = "grenade", count = math_random(2, 5)},
{name = "grenade", count = math_random(2, 5)},
{name = "submachine-gun", count = 1},
{name = "submachine-gun", count = 1},
{name = "submachine-gun", count = 1},
{name = "land-mine", count = math_random(8, 12)},
{name = "iron-gear-wheel", count = math_random(7, 15)},
{name = "iron-gear-wheel", count = math_random(7, 15)},
{name = "iron-gear-wheel", count = math_random(7, 15)},
{name = "iron-gear-wheel", count = math_random(7, 15)},
{name = "iron-plate", count = math_random(15, 23)},
{name = "iron-plate", count = math_random(15, 23)},
{name = "iron-plate", count = math_random(15, 23)},
{name = "iron-plate", count = math_random(15, 23)},
{name = "iron-plate", count = math_random(15, 23)},
{name = "copper-plate", count = math_random(15, 23)},
{name = "copper-plate", count = math_random(15, 23)},
{name = "copper-plate", count = math_random(15, 23)},
{name = "copper-plate", count = math_random(15, 23)},
{name = "copper-plate", count = math_random(15, 23)},
{name = "shotgun", count = 1},
{name = "shotgun", count = 1},
{name = "shotgun", count = 1},
{name = "shotgun-shell", count = math_random(5, 7)},
{name = "shotgun-shell", count = math_random(5, 7)},
{name = "shotgun-shell", count = math_random(5, 7)},
{name = "firearm-magazine", count = math_random(7, 15)},
{name = "firearm-magazine", count = math_random(7, 15)},
{name = "firearm-magazine", count = math_random(7, 15)},
{name = "rail", count = math_random(16, 24)},
{name = "rail", count = math_random(16, 24)},
{name = "rail", count = math_random(16, 24)},
}
local i = 1
for _ = 1, 16, 1 do
if not positions[i] then break end
local e = surface.create_entity({name = "wooden-chest", position = positions[i], force="player", create_build_effect_smoke = false})
local inventory = e.get_inventory(defines.inventory.chest)
inventory.insert({name = "raw-fish", count = math_random(2, 5)})
i = i + 1
end
for _ = 1, 24, 1 do
if not positions[i] then break end
local e = surface.create_entity({name = "wooden-chest", position = positions[i], force="player", create_build_effect_smoke = false})
i = i + 1
end
for loot_i = 1, #cargo_boxes, 1 do
if not positions[i] then break end
local e = surface.create_entity({name = "wooden-chest", position = positions[i], force="player", create_build_effect_smoke = false})
local inventory = e.get_inventory(defines.inventory.chest)
inventory.insert(cargo_boxes[loot_i])
i = i + 1
end
end
function Public.set_player_spawn_and_refill_fish()
if not global.locomotive_cargo then return end
if not global.locomotive_cargo.valid then return end
global.locomotive_cargo.health = global.locomotive_cargo.health + 6
global.locomotive_cargo.get_inventory(defines.inventory.cargo_wagon).insert({name = "raw-fish", count = math_random(1, 2)})
local position = global.locomotive_cargo.surface.find_non_colliding_position("stone-furnace", global.locomotive_cargo.position, 16, 2)
if not position then return end
game.forces.player.set_spawn_position({x = position.x, y = position.y}, global.locomotive_cargo.surface)
end
function Public.enter_cargo_wagon(player, vehicle)
if not vehicle then return end
if not vehicle.valid then return end
if not global.locomotive_cargo then return end
if not global.locomotive_cargo.valid then return end
if vehicle == global.locomotive_cargo then
if not game.surfaces["cargo_wagon"] then create_wagon_room() end
local surface = game.surfaces["cargo_wagon"]
local x_vector = vehicle.position.x - player.position.x
local position
if x_vector > 0 then
position = {surface.map_gen_settings.width * -0.5, -128}
else
position = {surface.map_gen_settings.width * 0.5, -128}
end
player.teleport(surface.find_non_colliding_position("character", position, 128, 0.5), surface)
end
if not global.locomotive_cargo2 then return end
if not global.locomotive_cargo2.valid then return end
if vehicle == global.locomotive_cargo2 then
if not game.surfaces["cargo_wagon"] then create_wagon_room() end
local surface = game.surfaces["cargo_wagon"]
local x_vector = vehicle.position.x - player.position.x
local position
if x_vector > 0 then
position = {surface.map_gen_settings.width * -0.5, 0}
else
position = {surface.map_gen_settings.width * 0.5, 0}
end
player.teleport(surface.find_non_colliding_position("character", position, 128, 0.5), surface)
end
if not global.locomotive_cargo3 then return end
if not global.locomotive_cargo3.valid then return end
if vehicle == global.locomotive_cargo3 then
if not game.surfaces["cargo_wagon"] then create_wagon_room() end
local surface = game.surfaces["cargo_wagon"]
local x_vector = vehicle.position.x - player.position.x
local position
if x_vector > 0 then
position = {surface.map_gen_settings.width * -0.5, 128}
else
position = {surface.map_gen_settings.width * 0.5, 128}
end
player.teleport(surface.find_non_colliding_position("character", position, 128, 0.5), surface)
end
if player.surface.name == "cargo_wagon" and vehicle.type == "car" then
local surface = global.locomotive_cargo.surface
local x_vector = (vehicle.position.x / math.abs(vehicle.position.x)) * 2
local y_vector = vehicle.position.y / 16
local position = {global.locomotive_cargo2.position.x + x_vector, global.locomotive_cargo2.position.y + y_vector}
local position = surface.find_non_colliding_position("character", position, 128, 0.5)
if not position then return end
player.teleport(position, surface)
end
end
local function clear_offers(market)
for i = 1, 256, 1 do
local a = market.remove_market_item(1)
if a == false then return end
end
end
function Public.refresh_offers(event)
local market = event.entity or event.market
if not market then return end
if not market.valid then return end
if market.name ~= "market" then return end
if market ~= global.upgrademarket then return end
clear_offers(market)
setup_upgrade_shop(market)
end
function Public.offer_purchased(event)
local offer_index = event.offer_index
if not market_offers2[offer_index] then return end
local market = event.market
if not market.name == "market" then return end
market_offers2[offer_index]()
count = event.count
if count > 1 then
local offers = market.get_market_items()
local price = offers[offer_index].price[1].amount
game.players[event.player_index].insert({name = "coin", count = price * (count - 1)})
end
Public.refresh_offers(event)
end
return Public

721
maps/chronosphere/main.lua Normal file
View File

@ -0,0 +1,721 @@
-- chronosphere --
require "functions.soft_reset"
require "player_modifiers"
require "functions.basic_markets"
require "modules.biters_yield_coins"
require "modules.no_deconstruction_of_neutral_entities"
--require "modules.no_solar"
require "modules.shotgun_buff"
require "modules.mineable_wreckage_yields_scrap"
require "maps.chronosphere.comfylatron"
require "maps.chronosphere.chronobubles"
require "maps.chronosphere.ores"
require "on_tick_schedule"
require "modules.biter_noms_you"
local Ai = require "maps.chronosphere.ai"
local unearthing_worm = require "functions.unearthing_worm"
local unearthing_biters = require "functions.unearthing_biters"
local tick_tack_trap = require "functions.tick_tack_trap"
local chronobuble = require "maps.chronosphere.chronobubles"
local level_depth = require "maps.chronosphere.terrain"
local Reset = require "functions.soft_reset"
local Map = require "modules.map_info"
local WD = require "modules.wave_defense.table"
local Locomotive = require "maps.chronosphere.locomotive"
local Modifier = require "player_modifiers"
local update_gui = require "maps.chronosphere.gui"
local math_random = math.random
local math_floor = math.floor
local math_sqrt = math.sqrt
local chests = {}
local Public = {}
local acus = {}
global.objective = {}
local choppy_entity_yield = {
["tree-01"] = {"iron-ore"},
["tree-02-red"] = {"copper-ore"},
["tree-04"] = {"coal"},
["tree-08-brown"] = {"stone"}
}
local starting_items = {['pistol'] = 1, ['firearm-magazine'] = 16, ['rail'] = 16, ['wood'] = 16}
-- function roll_planet()
-- for i = 1, 100, 1 do
-- local planet = chronobuble.determine_planet()
-- log("Planet number " .. i .. " stats:")
-- log("Name: " .. planet[1].name.name)
-- log("Speed of day: " .. planet[1].day_speed.name)
-- log("Time of day: " .. planet[1].time)
-- log("Ore richness: " .. planet[1].ore_richness.name .. ", multiplier: " .. planet[1].ore_richness.factor)
-- end
-- end
--
-- function roll_planet2()
-- for i = 1, 100, 1 do
-- local planet = chronobuble.determine_planet()
-- log("#" .. i .. "#" .. planet[1].name.id .. "#" .. planet[1].day_speed.timer .. "#" .. planet[1].time .. "#" .. planet[1].ore_richness.factor)
-- end
-- end
function generate_overworld(surface, optplanet)
local planet = nil
if not optplanet then
planet = chronobuble.determine_planet(nil)
game.print("Planet info: " .. planet[1].name.name .. ", Ore richness: " .. planet[1].ore_richness.name .. ", Speed of day: " .. planet[1].day_speed.name, {r=0.98, g=0.66, b=0.22})
global.objective.planet = planet
else
planet = optplanet
end
if planet[1].name.name == "choppy planet" then
game.print("Comfylatron: OwO what are those strange trees?!? They have ore fruits! WTF!", {r=0.98, g=0.66, b=0.22})
end
surface.min_brightness = 0
surface.brightness_visual_weights = {1, 1, 1}
global.objective.surface = surface
surface.daytime = planet[1].time
local timer = planet[1].day_speed.timer
if timer == 0 then
surface.freeze_daytime = true
timer = timer + 1
else
surface.freeze_daytime = false
end
surface.ticks_per_day = timer * 250
local moisture = planet[1].name.moisture
if moisture ~= 0 then
local mgs = surface.map_gen_settings
mgs.property_expression_names["control-setting:moisture:bias"] = moisture
surface.map_gen_settings = mgs
end
if planet[1].name.name == "water planet" then
local mgs = surface.map_gen_settings
mgs.water = 0.6
surface.map_gen_settings = mgs
end
if planet[1].name.name ~= "choppy planet" then
local mgs = surface.map_gen_settings
mgs.water = 0.6
surface.map_gen_settings = mgs
end
--log(timer)
--surface.solar_power_multiplier = 999
surface.request_to_generate_chunks({0,0}, 3)
surface.force_generate_chunk_requests()
-- for x = -352 + 32, 352 - 32, 32 do
-- surface.request_to_generate_chunks({x, 96}, 1)
-- --surface.force_generate_chunk_requests()
-- end
--spawn_ores(surface, planet)
--if planet[1].name.name == "mixed planet" then
-- ores_are_mixed(surface)
--end
--game.forces["player"].chart_all(surface)
end
local function get_map_gen_settings()
local map_gen_settings = {
["seed"] = math_random(1, 1000000),
["width"] = level_depth,
["height"] = level_depth,
["water"] = 0.1,
["starting_area"] = 1,
["cliff_settings"] = {cliff_elevation_interval = 0, cliff_elevation_0 = 0},
["default_enable_all_autoplace_controls"] = true,
["autoplace_settings"] = {
["entity"] = {treat_missing_as_default = false},
["tile"] = {treat_missing_as_default = true},
["decorative"] = {treat_missing_as_default = true},
},
}
return map_gen_settings
end
local function render_train_hp()
local surface = game.surfaces[global.active_surface_index]
local objective = global.objective
objective.health_text = rendering.draw_text{
text = "HP: " .. objective.health .. " / " .. objective.max_health,
surface = surface,
target = global.locomotive,
target_offset = {0, -2.5},
color = global.locomotive.color,
scale = 1.40,
font = "default-game",
alignment = "center",
scale_with_zoom = false
}
objective.caption = rendering.draw_text{
text = "Comfylatron's ChronoTrain",
surface = surface,
target = global.locomotive,
target_offset = {0, -4.25},
color = global.locomotive.color,
scale = 1.80,
font = "default-game",
alignment = "center",
scale_with_zoom = false
}
end
function Public.reset_map()
local wave_defense_table = WD.get_table()
global.chunk_queue = {}
if game.surfaces["chronosphere"] then game.delete_surface(game.surfaces["chronosphere"]) end
if game.surfaces["cargo_wagon"] then game.delete_surface(game.surfaces["cargo_wagon"]) end
chests = {}
local map_gen_settings = get_map_gen_settings()
local planet = nil
if not global.active_surface_index then
global.active_surface_index = game.create_surface("chronosphere", map_gen_settings).index
else
planet = chronobuble.determine_planet(nil)
global.objective.planet = planet
game.forces.player.set_spawn_position({12, 10}, game.surfaces[global.active_surface_index])
global.active_surface_index = Reset.soft_reset_map(game.surfaces[global.active_surface_index], map_gen_settings, starting_items).index
game.print("Planet info: " .. planet[1].name.name .. ", Ore richness: " .. planet[1].ore_richness.name .. ", Speed of day: " .. planet[1].day_speed.name, {r=0.98, g=0.66, b=0.22})
end
local surface = game.surfaces[global.active_surface_index]
generate_overworld(surface, planet)
local objective = global.objective
objective.max_health = 10000
objective.health = 10000
objective.hpupgradetier = 0
objective.acuupgradetier = 0
objective.filterupgradetier = 0
objective.chronojumps = 0
objective.chronotimer = 0
objective.chrononeeds = 2000
objective.active_biters = {}
objective.unit_groups = {}
objective.biter_raffle = {}
game.difficulty_settings.technology_price_multiplier = 0.5
game.map_settings.enemy_evolution.destroy_factor = 0.001
game.map_settings.enemy_evolution.pollution_factor = 0
game.map_settings.enemy_evolution.time_factor = 4e-05
game.map_settings.enemy_expansion.enabled = true
game.map_settings.enemy_expansion.max_expansion_cooldown = 3600
game.map_settings.enemy_expansion.min_expansion_cooldown = 3600
game.map_settings.enemy_expansion.settler_group_max_size = 8
game.map_settings.enemy_expansion.settler_group_min_size = 16
game.map_settings.pollution.enabled = true
game.forces.player.technologies["land-mine"].enabled = false
game.forces.player.technologies["landfill"].enabled = false
game.forces.player.technologies["railway"].researched = true
game.forces.player.set_spawn_position({12, 10}, surface)
Locomotive.locomotive_spawn(surface, {x = 16, y = 10})
render_train_hp()
WD.reset_wave_defense()
wave_defense_table.surface_index = global.active_surface_index
wave_defense_table.target = global.locomotive_cargo
wave_defense_table.nest_building_density = 32
wave_defense_table.game_lost = false
--set_difficulty()
end
local function on_player_joined_game(event)
local player_modifiers = Modifier.get_table()
local player = game.players[event.player_index]
--log(chronobuble.determine_planet())
--set_difficulty()
local surface = game.surfaces[global.active_surface_index]
if player.online_time == 0 then
player.teleport(surface.find_non_colliding_position("character", game.forces.player.get_spawn_position(surface), 32, 0.5), surface)
for item, amount in pairs(starting_items) do
player.insert({name = item, count = amount})
end
end
if player.surface.index ~= global.active_surface_index and player.surface.name ~= "cargo_wagon" then
player.character = nil
player.set_controller({type=defines.controllers.god})
player.create_character()
player.teleport(surface.find_non_colliding_position("character", game.forces.player.get_spawn_position(surface), 32, 0.5), surface)
for item, amount in pairs(starting_items) do
player.insert({name = item, count = amount})
end
end
player_modifiers[player.index].character_mining_speed_modifier["chronosphere"] = 0.5
Modifier.update_player_modifiers(player)
local tile = surface.get_tile(player.position)
if tile.valid then
if tile.name == "out-of-map" then
player.teleport(surface.find_non_colliding_position("character", game.forces.player.get_spawn_position(surface), 32, 0.5), surface)
end
end
end
local function repair_train()
local objective = global.objective
if not game.surfaces["cargo_wagon"] then return end
if WD.get_table().game_lost == true then return end
if objective.health < objective.max_health then
if global.repairchest.get_inventory(defines.inventory.chest).get_item_count("repair-pack") > 1 then
global.repairchest.get_inventory(defines.inventory.chest).remove({name = "repair-pack", count = 1})
set_objective_health(-300)
end
end
end
local function move_items()
if not global.comfychests then return end
if not global.comfychests2 then return end
if WD.get_table().game_lost == true then return end
local input = global.comfychests
local output = global.comfychests2
for i = 1, 24, 1 do
if not input[i].valid then
log("no input chest " .. i)
return
end
if not output[i].valid then
log("no output chest " .. i)
return
end
local input_inventory = input[i].get_inventory(defines.inventory.chest)
local output_inventory = output[i].get_inventory(defines.inventory.chest)
input_inventory.sort_and_merge()
local items = input_inventory.get_contents()
for item, count in pairs(items) do
local inserted = output_inventory.insert({name = item, count = count})
if inserted > 0 then
local removed = input_inventory.remove({name = item, count = inserted})
end
end
end
end
function chronojump(choice)
local objective = global.objective
objective.chronojumps = objective.chronojumps + 1
objective.chrononeeds = objective.chrononeeds + 2000
objective.chronotimer = 0
game.print("Comfylatron: Wheeee! Time Jump Active! This is Jump number " .. global.objective.chronojumps, {r=0.98, g=0.66, b=0.22})
local oldsurface = game.surfaces[global.active_surface_index]
for _,player in pairs(game.players) do
if player.surface == oldsurface then
if player.controller_type == defines.controllers.editor then player.toggle_map_editor() end
Locomotive.enter_cargo_wagon(player, global.locomotive_cargo)
end
end
local map_gen_settings = get_map_gen_settings()
global.active_surface_index = game.create_surface("chronosphere" .. objective.chronojumps, map_gen_settings).index
local surface = game.surfaces[global.active_surface_index]
local planet = nil
if choice then
planet = chronobuble.determine_planet(choice)
game.print("Planet info: " .. planet[1].name.name .. ", Ore richness: " .. planet[1].ore_richness.name .. ", Speed of day: " .. planet[1].day_speed.name, {r=0.98, g=0.66, b=0.22})
global.objective.planet = planet
end
generate_overworld(surface, planet)
game.forces.player.set_spawn_position({12, 10}, surface)
Locomotive.locomotive_spawn(surface, {x = 16, y = 10})
render_train_hp()
game.delete_surface(oldsurface)
if objective.chronojumps <= 40 then
game.forces["enemy"].evolution_factor = 0 + 0.025 * objective.chronojumps
else
game.forces["enemy"].evolution_factor = 1
end
game.map_settings.enemy_evolution.time_factor = 4e-05 + 1e-06 * objective.chronojumps
end
local function check_chronoprogress()
local objective = global.objective
--game.print(objective.chronotimer)
if objective.chronotimer >= objective.chrononeeds - 60 and objective.chronotimer < objective.chrononeeds - 59 then
game.print("Comfylatron: ChronoTrain nearly charged! Grab what you can, we leaving in 60 seconds!", {r=0.98, g=0.66, b=0.22})
elseif objective.chronotimer == objective.chrononeeds - 30 then
game.print("Comfylatron: You better hurry up! 30 seconds remaining!", {r=0.98, g=0.66, b=0.22})
elseif objective.chronotimer >= objective.chrononeeds - 10 and objective.chrononeeds - objective.chronotimer > 0 then
game.print("Comfylatron: Jump in " .. objective.chrononeeds - objective.chronotimer .. " seconds!", {r=0.98, g=0.66, b=0.22})
end
if objective.chronotimer >= objective.chrononeeds then
chronojump(nil)
end
end
local function charge_chronosphere()
if not global.acumulators then return end
local objective = global.objective
if not objective.chronotimer then return end
if objective.chronotimer < 20 then return end
local acus = global.acumulators
if #acus < 1 then return end
for i = 1, #acus, 1 do
if not acus[i].valid then return end
local energy = acus[i].energy
if energy > 3000000 and objective.chronotimer < objective.chrononeeds - 62 then
acus[i].energy = acus[i].energy - 3000000
objective.chronotimer = objective.chronotimer + 1
game.surfaces[global.active_surface_index].pollute(global.locomotive.position, 100 * (4 / (objective.filterupgradetier / 2 + 1)))
--log("energy charged from acu")
end
end
end
local function transfer_pollution()
local surface = game.surfaces["cargo_wagon"]
if not surface then return end
local pollution = surface.get_total_pollution() * (4 / (global.objective.filterupgradetier / 2 + 1))
game.surfaces[global.active_surface_index].pollute(global.locomotive.position, pollution)
surface.clear_pollution()
end
local tick_minute_functions = {
[300 * 2] = Ai.destroy_inactive_biters,
[300 * 3 + 30 * 0] = Ai.pre_main_attack, -- setup for main_attack
[300 * 3 + 30 * 1] = Ai.perform_main_attack,
[300 * 3 + 30 * 2] = Ai.perform_main_attack,
[300 * 3 + 30 * 3] = Ai.perform_main_attack, -- call perform_main_attack 7 times on different ticks
[300 * 4] = Ai.send_near_biters_to_objective,
[300 * 5] = Ai.wake_up_sleepy_groups
}
local function tick()
local tick = game.tick
if tick % 60 == 30 and global.objective.chronotimer < 64 then
local surface = game.surfaces[global.active_surface_index]
surface.request_to_generate_chunks({0,0}, 3 + math_floor(global.objective.chronotimer / 5))
--surface.force_generate_chunk_requests()
end
if tick % 30 == 0 then
if tick % 600 == 0 then
charge_chronosphere()
transfer_pollution()
end
if tick % 1800 == 0 then
Locomotive.set_player_spawn_and_refill_fish()
repair_train()
--local surface = game.surfaces[global.active_surface_index]
--local last_position = global.map_collapse.last_position
--local position = surface.find_non_colliding_position("stone-furnace", {last_position.x, last_position.y - 32}, 128, 4)
--if position then
-- local wave_defense_table = WD.get_table()
-- wave_defense_table.spawn_position = position
--end
--if tick % 216000 == 0 then
-- Collapse.delete_out_of_map_chunks(surface)
--end
end
local key = tick % 3600
if tick_minute_functions[key] then tick_minute_functions[key]() end
if tick % 60 == 0 then
global.objective.chronotimer = global.objective.chronotimer + 1
check_chronoprogress()
end
if tick % 120 == 0 then
move_items()
end
if global.game_reset_tick then
if global.game_reset_tick < tick then
global.game_reset_tick = nil
require "maps.chronosphere.main".reset_map()
end
return
end
Locomotive.fish_tag()
end
for _, player in pairs(game.connected_players) do update_gui(player) end
--if not collapse_enabled then return end
--Collapse.process()
end
local function on_init()
local T = Map.Pop_info()
T.localised_category = "chronosphere"
T.main_caption_color = {r = 150, g = 150, b = 0}
T.sub_caption_color = {r = 0, g = 150, b = 0}
--global.rocks_yield_ore_maximum_amount = 999
--global.rocks_yield_ore_base_amount = 50
--global.rocks_yield_ore_distance_modifier = 0.025
--if game.surfaces["nauvis"] then game.delete_surface(game.surfaces["nauvis"]) end
Public.reset_map()
end
function set_objective_health(final_damage_amount)
local objective = global.objective
objective.health = math_floor(objective.health - final_damage_amount)
if objective.health > objective.max_health then objective.health = objective.max_health end
if objective.health <= 0 then
local wave_defense_table = WD.get_table()
if wave_defense_table.game_lost == true then return end
objective.health = 0
local surface = objective.surface
game.print("The chronotrain was destroyed!")
game.print("Comfylatron is going to kill you for that...he has time machine after all!")
surface.create_entity({name = "big-artillery-explosion", position = global.locomotive_cargo.position})
global.locomotive_cargo.destroy()
surface.create_entity({name = "big-artillery-explosion", position = global.locomotive_cargo2.position})
global.locomotive_cargo2.destroy()
surface.create_entity({name = "big-artillery-explosion", position = global.locomotive_cargo3.position})
global.locomotive_cargo3.destroy()
for i = 1, #global.comfychests,1 do
--surface.create_entity({name = "big-artillery-explosion", position = global.comfychests[i].position})
global.comfychests[i].destroy()
if global.comfychests2 then global.comfychests2[i].destroy() end
--global.comfychests = {}
end
global.ores_queue = {}
global.entities_queue = {}
global.acumulators = {}
wave_defense_table.game_lost = true
wave_defense_table.target = nil
global.game_reset_tick = game.tick + 1800
for _, player in pairs(game.connected_players) do
player.play_sound{path="utility/game_lost", volume_modifier=0.75}
end
end
rendering.set_text(objective.health_text, "HP: " .. objective.health .. " / " .. objective.max_health)
end
local function isprotected(entity)
local protected = {global.locomotive, global.locomotive_cargo, global.locomotive_cargo2, global.locomotive_cargo3}
if entity.surface.name == "cargo_wagon" then return true end
for i = 1, #global.comfychests,1 do
table.insert(protected, global.comfychests[i])
end
for index = 1, #protected do
if protected[index] == entity then
return true
end
end
end
local function protect_entity(event)
if event.entity.force.index ~= 1 then return end --Player Force
if isprotected(event.entity) then
if event.cause then
if event.cause.force.index == 2 then
set_objective_health(event.final_damage_amount)
end
end
if not event.entity.valid then return end
event.entity.health = event.entity.health + event.final_damage_amount
end
end
local function biters_chew_rocks_faster(event)
if event.entity.force.index ~= 3 then return end --Neutral Force
if not event.cause then return end
if not event.cause.valid then return end
if event.cause.force.index ~= 2 then return end --Enemy Force
event.entity.health = event.entity.health - event.final_damage_amount * 5
end
local function on_entity_damaged(event)
if not event.entity.valid then return end
protect_entity(event)
if not event.entity.valid then return end
if not event.entity.health then return end
biters_chew_rocks_faster(event)
end
local function trap(entity)
if math_random(1,256) == 1 then tick_tack_trap(entity.surface, entity.position) return end
if math_random(1,128) == 1 then unearthing_worm(entity.surface, entity.surface.find_non_colliding_position("big-worm-turret",entity.position,5,1)) end
if math_random(1,64) == 1 then unearthing_biters(entity.surface, entity.position, math_random(4,8)) end
end
local function get_choppy_amount(entity)
local distance_to_center = math_sqrt(entity.position.x^2 + entity.position.y^2) + 50 * global.objective.chronojumps
local amount = (25 + distance_to_center * 0.1) * (1 + game.forces.player.mining_drill_productivity_bonus)
if amount > 1000 then amount = 1000 end
amount = math_random(math_floor(amount * 0.5), math_floor(amount * 1.5))
return amount
end
local function pre_player_mined_item(event)
local surface = game.surfaces[global.active_surface_index]
local player = game.players[event.player_index]
local objective = global.objective
if objective.planet[1].name.name == "rocky planet" then
if event.entity.name == "rock-huge" or event.entity.name == "rock-big" or event.entity.name == "sand-rock-big" then
trap(event.entity)
local rock_position = {x = event.entity.position.x, y = event.entity.position.y}
event.entity.destroy()
local tile_distance_to_center = math_sqrt(rock_position.x^2 + rock_position.y^2) + 50 * objective.chronojumps
if tile_distance_to_center > 1450 then tile_distance_to_center = 1450 end
surface.spill_item_stack(player.position,{name = "raw-fish", count = math_random(1,3)},true)
local bonus_amount = math_floor((tile_distance_to_center) + 1)
if bonus_amount < 0 then bonus_amount = 0 end
local amount = math_random(25,45) + bonus_amount
if amount > 500 then amount = 500 end
amount = math_floor(amount * (1+game.forces.player.mining_drill_productivity_bonus))
local rock_mining = {"iron-ore", "iron-ore", "iron-ore", "iron-ore", "copper-ore", "copper-ore", "copper-ore", "stone", "stone", "coal", "coal"}
local mined_loot = rock_mining[math_random(1,#rock_mining)]
surface.create_entity({
name = "flying-text",
position = rock_position,
text = "+" .. amount .. " [img=item/" .. mined_loot .. "]",
color = {r=0.98, g=0.66, b=0.22}
})
local i = player.insert {name = mined_loot, count = amount}
amount = amount - i
if amount > 0 then
surface.spill_item_stack(rock_position,{name = mined_loot, count = amount},true)
end
end
end
end
local function on_player_mined_entity(event)
local entity = event.entity
if not entity.valid then return end
if entity.type == "tree" and global.objective.planet[1].name.name == "choppy planet" then
trap(entity)
if choppy_entity_yield[entity.name] then
if event.buffer then event.buffer.clear() end
if not event.player_index then return end
local amount = get_choppy_amount(entity)
local second_item_amount = math_random(2,5)
local second_item = "wood"
local main_item = choppy_entity_yield[entity.name][math_random(1,#choppy_entity_yield[entity.name])]
entity.surface.create_entity({
name = "flying-text",
position = entity.position,
text = "+" .. amount .. " [item=" .. main_item .. "] +" .. second_item_amount .. " [item=" .. second_item .. "]",
color = {r=0.8,g=0.8,b=0.8}
})
local player = game.players[event.player_index]
local inserted_count = player.insert({name = main_item, count = amount})
amount = amount - inserted_count
if amount > 0 then
entity.surface.spill_item_stack(entity.position,{name = main_item, count = amount}, true)
end
local inserted_count = player.insert({name = second_item, count = second_item_amount})
second_item_amount = second_item_amount - inserted_count
if second_item_amount > 0 then
entity.surface.spill_item_stack(entity.position,{name = second_item, count = second_item_amount}, true)
end
end
end
if entity.name == "rock-huge" or entity.name == "rock-big" or entity.name == "sand-rock-big" then
if global.objective.planet[1].name.name ~= "rocky planet" then
prospect_ores(entity)
elseif
global.objective.planet[1].name.name == "rocky planet" then event.buffer.clear()
end
end
end
local function shred_simple_entities(entity)
--game.print(entity.name)
if game.forces["enemy"].evolution_factor < 0.25 then return end
local simple_entities = entity.surface.find_entities_filtered({type = {"simple-entity", "tree"}, area = {{entity.position.x - 3, entity.position.y - 3},{entity.position.x + 3, entity.position.y + 3}}})
if #simple_entities == 0 then return end
for i = 1, #simple_entities, 1 do
if not simple_entities[i] then break end
if simple_entities[i].valid then
simple_entities[i].die("enemy", simple_entities[i])
end
end
end
local function on_entity_died(event)
if event.entity.type == "tree" and global.objective.planet[1].name.name == "choppy planet" then
if event.cause then
if event.cause.valid then
if event.cause.force.index ~= 2 then
trap(event.entity)
end
end
end
-- if not event.entity.valid then return end
-- for _, entity in pairs (event.entity.surface.find_entities_filtered({area = {{event.entity.position.x - 4, event.entity.position.y - 4},{event.entity.position.x + 4, event.entity.position.y + 4}}, name = "fire-flame-on-tree"})) do
-- if entity.valid then entity.destroy() end
-- end
--return
end
local entity = event.entity
if not entity.valid then return end
if entity.type == "unit" and entity.force == "enemy" then
global.objective.active_biters[entity.unit_number] = nil
end
if entity.force.index == 3 then
if event.cause then
if event.cause.valid then
if event.cause.force.index == 2 then
shred_simple_entities(entity)
end
end
end
end
--on_player_mined_entity(event)
--if not event.entity.valid then return end
end
local function on_player_driving_changed_state(event)
local player = game.players[event.player_index]
local vehicle = event.entity
Locomotive.enter_cargo_wagon(player, vehicle)
end
local function on_market_item_purchased(event)
Locomotive.offer_purchased(event)
end
local event = require 'utils.event'
event.on_init(on_init)
event.on_nth_tick(2, tick)
event.add(defines.events.on_entity_damaged, on_entity_damaged)
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_left_game, on_player_left_game)
event.add(defines.events.on_pre_player_mined_item, pre_player_mined_item)
event.add(defines.events.on_player_mined_entity, on_player_mined_entity)
--event.add(defines.events.on_research_finished, on_research_finished)
event.add(defines.events.on_market_item_purchased, on_market_item_purchased)
event.add(defines.events.on_player_driving_changed_state, on_player_driving_changed_state)
return Public

197
maps/chronosphere/ores.lua Normal file
View File

@ -0,0 +1,197 @@
local simplex_noise = require 'utils.simplex_noise'.d2
local math_random = math.random
local math_abs = math.abs
local math_floor = math.floor
local math_sqrt = math.sqrt
local ores = {"copper-ore", "iron-ore", "stone", "coal"}
local function pos_to_key(position)
return tostring(position.x .. "_" .. position.y)
end
local function draw_noise_ore_patch(position, name, surface, radius, richness, mixed)
if not position then return end
if not name then return end
if not surface then return end
if not radius then return end
if not richness then return end
local ore_raffle = {
"iron-ore", "iron-ore", "iron-ore", "copper-ore", "copper-ore", "coal", "stone"
}
local seed = surface.map_gen_settings.seed
local noise_seed_add = 25000
local richness_part = richness / radius
for y = radius * -3, radius * 3, 1 do
for x = radius * -3, radius * 3, 1 do
local pos = {x = x + position.x + 0.5, y = y + position.y + 0.5}
local noise_1 = simplex_noise(pos.x * 0.0125, pos.y * 0.0125, seed)
local noise_2 = simplex_noise(pos.x * 0.1, pos.y * 0.1, seed + 25000)
local noise = noise_1 + noise_2 * 0.12
local distance_to_center = math.sqrt(x^2 + y^2)
local a = richness - richness_part * distance_to_center
if distance_to_center < radius - math.abs(noise * radius * 0.85) and a > 1 then
pos = surface.find_non_colliding_position(name, pos, 64, 1)
if not pos then return end
if mixed then
local noise = simplex_noise(pos.x * 0.005, pos.y * 0.005, seed) + simplex_noise(pos.x * 0.01, pos.y * 0.01, seed) * 0.3 + simplex_noise(pos.x * 0.05, pos.y * 0.05, seed) * 0.2
local i = (math_floor(noise * 100) % 7) + 1
name = ore_raffle[i]
end
local entity = {name = name, position = pos, amount = a}
if surface.can_place_entity(entity) then
surface.create_entity(entity)
end
--if not global.ores_queue[pos.x] then global.ores_queue[pos.x] = {} end
--global.ores_queue[pos_to_key(pos)] = {name = name, position = pos, amount = a}
--end
end
end
end
end
-- function ores_are_mixed(surface)
-- local ore_raffle = {
-- "iron-ore", "iron-ore", "iron-ore", "copper-ore", "copper-ore", "coal", "stone"
-- }
-- local r = 480
-- local area = {{r * -1, r * -1}, {r, r}}
-- local ores = surface.find_entities_filtered({area = area, name = {"iron-ore", "copper-ore", "coal", "stone"}})
-- if #ores == 0 then return end
-- local seed = surface.map_gen_settings.seed
--
-- for _, ore in pairs(ores) do
-- local pos = ore.position
-- local noise = simplex_noise(pos.x * 0.005, pos.y * 0.005, seed) + simplex_noise(pos.x * 0.01, pos.y * 0.01, seed) * 0.3 + simplex_noise(pos.x * 0.05, pos.y * 0.05, seed) * 0.2
--
-- local i = (math.floor(noise * 100) % 7) + 1
-- --if not global.ores_queue[pos.x] then global.ores_queue[pos.x] = {} end
-- --global.ores_queue[pos_to_key(pos)] = {name = ore_raffle[i], position = ore.position, amount = ore.amount}
-- ore.destroy()
-- end
-- end
local function get_size_of_ore(ore, planet)
local base_size = math_random(5, 10) + math_floor(planet[1].ore_richness.factor * 3)
local final_size = 1
if planet[1].name.name == "iron planet" and ore == "iron-ore" then
final_size = base_size * 2
elseif planet[1].name.name == "copper planet" and ore == "copper-ore" then
final_size = base_size * 2
elseif planet[1].name.name == "stone planet" and ore == "stone" then
final_size = base_size * 2
elseif planet[1].name.name == "coal planet" and ore == "coal" then
final_size = base_size * 2
elseif planet[1].name.name == "uranium planet" and ore == "uranium-ore" then
final_size = base_size * 2
elseif planet[1].name.name == "mixed planet" then
final_size = base_size
else
final_size = math_floor(base_size / 2)
end
return final_size
end
local function get_oil_amount(pos, oil_w)
local hundred_percent = 300000
return (hundred_percent / 50) * (1+global.objective.chronojumps) * oil_w
end
-- function spawn_ores(surface, planet)
--
-- --local r = 480
-- --local area = {{r * -1, r * -1}, {r, r}}
-- local ores = {}
-- if planet[1].name.name == "rocky planet" then return end
-- local oil_amount = planet[1].name.oil
-- if oil_amount > 0 then
-- for a = 1, oil_amount, 1 do
-- local poso = {x = math_random(-50,50) + math_random(250, 350) * math_random(-1,1), y = math_random(-50,50) + math_random(250, 350) * math_random(-1,1)}
-- for a=1, math_random(2, 3 + oil_amount * 2), 1 do
-- local posoo = {x = poso.x + math_random(-10,10), y = poso.y + math_random(-10,10)}
-- --if surface.can_place_entity{name = "crude-oil", position = posoo} then
-- --if not global.ores_queue[posoo.x] then global.ores_queue[posoo.x] = {} end
-- global.entities_queue[pos_to_key(posoo)] = {name = "crude-oil", position = posoo, amount = get_oil_amount(posoo) * oil_amount }
-- --end
-- end
-- end
-- end
-- if planet[1].name.name == "choppy planet" then return end
-- local uranium_amount = planet[1].name.uranium
-- if uranium_amount > 0 then
-- for a = 1, uranium_amount, 1 do
-- local posu = {x = 0 + math_random(350, 450) * math_random(-1,1), y = 0 + math_random(350, 450) * math_random(-1,1)}
-- if posu.x ~= 0 or posu.y ~= 0 then
-- --if surface.can_place_entity({name = "uranium-ore", position = posu, amount = 1}) then
-- draw_noise_ore_patch(posu, "uranium-ore", surface, get_size_of_ore("uranium-ore", planet), math_random(200, 300) * planet[1].ore_richness.factor)
-- --break
-- --end
-- end
-- end
-- end
-- ores["iron-ore"] = surface.count_entities_filtered({name = "iron-ore", area = area})
-- ores["copper-ore"] = surface.count_entities_filtered({name = "copper-ore", area = area})
-- ores["coal"] = surface.count_entities_filtered({name = "coal", area = area})
-- ores["stone"] = surface.count_entities_filtered({name = "stone", area = area})
-- for ore, ore_count in pairs(ores) do
-- if ore_count < 1000 or ore_count == nil then
-- local pos = {}
-- for a = 1, 8, 1 do
-- pos = {x = -300 + math_random(0, 600), y = -300 + math_random(0, 600)}
-- --if surface.can_place_entity({name = ore, position = pos, amount = 1}) then
-- draw_noise_ore_patch(pos, ore, surface, get_size_of_ore(ore, planet), math_random(400, 500) * planet[1].ore_richness.factor)
-- --break
-- --end
-- end
-- --draw_noise_ore_patch(pos, ore, surface, get_size_of_ore(ore, planet), math_random(400, 500) * planet[1].ore_richness.factor)
-- end
-- end
-- end
function spawn_ore_vein(surface, pos, planet)
local mixed = false
if planet[1].name.name == "mixed planet" then mixed = true end
local richness = math_random(50 + 10 * global.objective.chronojumps, 100 + 10 * global.objective.chronojumps) * planet[1].ore_richness.factor
local iron = {w = planet[1].name.iron, t = planet[1].name.iron}
local copper = {w = planet[1].name.copper, t = iron.t + planet[1].name.copper}
local stone = {w = planet[1].name.stone, t = copper.t + planet[1].name.stone}
local coal = {w = planet[1].name.coal, t = stone.t + planet[1].name.coal}
local uranium = {w = planet[1].name.uranium, t = coal.t + planet[1].name.uranium}
local oil = {w = planet[1].name.oil, t = uranium.t + planet[1].name.oil}
local total = iron.w + copper.w + stone.w + coal.w + uranium.w + oil.w
local roll = math_random (0, oil.t)
if roll == 0 then return end
local choice = nil
if roll <= iron.t then
choice = "iron-ore"
elseif roll <= copper.t then
choice = "copper-ore"
elseif roll <= stone.t then
choice = "stone"
elseif roll <= coal.t then
choice = "coal"
elseif roll <= uranium.t then
choice = "uranium-ore"
elseif roll <= oil.t then
choice = "crude-oil"
end
--if surface.can_place_entity({name = choice, position = pos, amount = 1}) then
if choice == "crude-oil" then
surface.create_entity({name = "crude-oil", position = pos, amount = get_oil_amount(pos, oil.w) })
else
draw_noise_ore_patch(pos, choice, surface, get_size_of_ore(choice, planet), richness, mixed)
end
--end
end
function prospect_ores(entity)
local planet = global.objective.planet
local chance = 10
if entity.name == "rock-huge" then chance = 40 end
if math_random(chance + math_floor(10 * planet[1].ore_richness.factor) ,100 + chance) >= 100 then
spawn_ore_vein(entity.surface, entity.position, planet)
--if planet[1].name.name == "mixed planet" then
end
end

View File

@ -0,0 +1,574 @@
--require "maps.chronosphere.ores"
local math_random = math.random
local math_floor = math.floor
local math_abs = math.abs
local math_sqrt = math.sqrt
local level_depth = 960
local Treasure = require 'maps.chronosphere.treasure'
local simplex_noise = require "utils.simplex_noise".d2
local rock_raffle = {"sand-rock-big","sand-rock-big", "rock-big","rock-big","rock-big","rock-big","rock-big","rock-big","rock-big","rock-huge"}
local size_of_rock_raffle = #rock_raffle
local dead_tree_raffle = {"dead-dry-hairy-tree", "dead-grey-trunk", "dead-tree-desert", "dry-hairy-tree", "dry-tree"}
local tree_raffle = {"tree-01", "tree-02", "tree-02-red", "tree-03", "tree-04", "tree-05", "tree-06", "tree-06-brown", "tree-07",
"tree-08", "tree-08-brown", "tree-08-red", "tree-09", "tree-09-brown", "tree-09-red"}
local s_tree_raffle = #tree_raffle
local spawner_raffle = {"biter-spawner", "biter-spawner", "biter-spawner", "spitter-spawner"}
local worm_raffle = {
"small-worm-turret", "small-worm-turret", "medium-worm-turret", "small-worm-turret",
"medium-worm-turret", "medium-worm-turret", "big-worm-turret", "medium-worm-turret",
"big-worm-turret","big-worm-turret","behemoth-worm-turret", "big-worm-turret",
"behemoth-worm-turret","behemoth-worm-turret","behemoth-worm-turret","big-worm-turret","behemoth-worm-turret"
}
local scrap_entities = {"crash-site-assembling-machine-1-broken", "crash-site-assembling-machine-2-broken", "crash-site-assembling-machine-1-broken", "crash-site-assembling-machine-2-broken", "crash-site-lab-broken",
"medium-ship-wreck", "small-ship-wreck", "medium-ship-wreck", "small-ship-wreck", "medium-ship-wreck", "small-ship-wreck", "medium-ship-wreck", "small-ship-wreck",
"crash-site-chest-1", "crash-site-chest-2", "crash-site-chest-1", "crash-site-chest-2", "crash-site-chest-1", "crash-site-chest-2"}
local scrap_entities_index = #scrap_entities
local noises = {
["no_rocks"] = {{modifier = 0.0033, weight = 1}, {modifier = 0.01, weight = 0.22}, {modifier = 0.05, weight = 0.05}, {modifier = 0.1, weight = 0.04}},
["no_rocks_2"] = {{modifier = 0.013, weight = 1}, {modifier = 0.1, weight = 0.1}},
["large_caves"] = {{modifier = 0.0033, weight = 1}, {modifier = 0.01, weight = 0.22}, {modifier = 0.05, weight = 0.05}, {modifier = 0.1, weight = 0.04}},
["small_caves"] = {{modifier = 0.008, weight = 1}, {modifier = 0.03, weight = 0.15}, {modifier = 0.25, weight = 0.05}},
["small_caves_2"] = {{modifier = 0.009, weight = 1}, {modifier = 0.05, weight = 0.25}, {modifier = 0.25, weight = 0.05}},
["cave_ponds"] = {{modifier = 0.01, weight = 1}, {modifier = 0.1, weight = 0.06}},
["cave_rivers"] = {{modifier = 0.005, weight = 1}, {modifier = 0.01, weight = 0.25}, {modifier = 0.05, weight = 0.01}},
["cave_rivers_2"] = {{modifier = 0.003, weight = 1}, {modifier = 0.01, weight = 0.21}, {modifier = 0.05, weight = 0.01}},
["cave_rivers_3"] = {{modifier = 0.002, weight = 1}, {modifier = 0.01, weight = 0.15}, {modifier = 0.05, weight = 0.01}},
["cave_rivers_4"] = {{modifier = 0.001, weight = 1}, {modifier = 0.01, weight = 0.11}, {modifier = 0.05, weight = 0.01}},
["scrapyard"] = {{modifier = 0.005, weight = 1}, {modifier = 0.01, weight = 0.35}, {modifier = 0.05, weight = 0.23}, {modifier = 0.1, weight = 0.11}},
["forest_location"] = {{modifier = 0.006, weight = 1}, {modifier = 0.01, weight = 0.25}, {modifier = 0.05, weight = 0.15}, {modifier = 0.1, weight = 0.05}},
["forest_density"] = {{modifier = 0.01, weight = 1}, {modifier = 0.05, weight = 0.5}, {modifier = 0.1, weight = 0.025}},
["ores"] = {{modifier = 0.05, weight = 1}, {modifier = 0.02, weight = 0.55}, {modifier = 0.05, weight = 0.05}}
}
local function pos_to_key(position)
return tostring(position.x .. "_" .. position.y)
end
local function get_noise(name, pos, seed)
local noise = 0
local d = 0
for _, n in pairs(noises[name]) do
noise = noise + simplex_noise(pos.x * n.modifier, pos.y * n.modifier, seed) * n.weight
d = d + n.weight
seed = seed + 10000
end
noise = noise / d
return noise
end
local function get_size_of_ore(ore, planet)
local base_size = 0.04 + 0.04 * planet[1].ore_richness.factor
local final_size = 1
if planet[1].name.name == "iron planet" and ore == "iron-ore" then
final_size = base_size * 5
elseif planet[1].name.name == "copper planet" and ore == "copper-ore" then
final_size = base_size * 5
elseif planet[1].name.name == "stone planet" and ore == "stone" then
final_size = base_size * 5
elseif planet[1].name.name == "coal planet" and ore == "coal" then
final_size = base_size * 5
elseif planet[1].name.name == "uranium planet" and ore == "uranium-ore" then
final_size = base_size * 5
elseif planet[1].name.name == "mixed planet" then
final_size = base_size * 2
else
final_size = base_size / 2
end
return final_size
end
local function process_rocky_position(p, seed, tiles, entities, treasure, planet)
local biters = planet[1].name.biters
local noise_large_caves = get_noise("large_caves", p, seed)
local noise_cave_ponds = get_noise("cave_ponds", p, seed)
local small_caves = get_noise("small_caves", p, seed)
if math_abs(noise_large_caves) > 0.7 then
tiles[#tiles + 1] = {name = "water", position = p}
if math_random(1,16) == 1 then entities[#entities + 1] = {name="fish", position=p} end
return
end
if math_abs(noise_large_caves) > 0.6 then
if math_random(1,16) == 1 then entities[#entities + 1] = {name="tree-02", position=p} end
--if math_random(1,32) == 1 then markets[#markets + 1] = p end
end
if math_abs(noise_large_caves) > 0.5 then
tiles[#tiles + 1] = {name = "grass-2", position = p}
--if math_random(1,620) == 1 then entities[#entities + 1] = {name = "crude-oil", position = p, amount = get_oil_amount(p)} end
-- if math_random(1,384) == 1 then
-- Biters.wave_defense_set_worm_raffle(math_abs(p.y) * worm_level_modifier)
-- entities[#entities + 1] = {name = Biters.wave_defense_roll_worm_name(), position = p, force = "enemy"}
-- end
if math_random(1,102 - biters) == 1 and math_sqrt(p.x * p.x + p.y * p.y) > 150 then entities[#entities + 1] = {name = spawner_raffle[math_random(1, 4)], position = p} end
if math_random(1, 1024) == 1 then treasure[#treasure + 1] = p end
return
end
if math_abs(noise_large_caves) > 0.375 then
tiles[#tiles + 1] = {name = "dirt-7", position = p}
if math_random(1,6) > 1 then entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
if math_random(1,2048) == 1 then treasure[#treasure + 1] = p end
return
end
--Chasms
if noise_cave_ponds < 0.25 and noise_cave_ponds > -0.25 then
if small_caves > 0.75 then
tiles[#tiles + 1] = {name = "out-of-map", position = p}
return
end
if small_caves < -0.75 then
tiles[#tiles + 1] = {name = "out-of-map", position = p}
return
end
end
if small_caves > -0.25 and small_caves < 0.25 then
tiles[#tiles + 1] = {name = "dirt-7", position = p}
local roll = math_random(1,1000)
if roll > 800 then
entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p}
elseif roll > 790 and math_sqrt(p.x * p.x + p.y * p.y) > 150 then
entities[#entities + 1] = {name = worm_raffle[math_random(1 + math_floor(game.forces["enemy"].evolution_factor * 8), math_floor(1 + game.forces["enemy"].evolution_factor * 16))], position = p}
else
end
if math_random(1, 1024) == 1 then treasure[#treasure + 1] = p end
return
end
if noise_large_caves > -0.28 and noise_large_caves < 0.28 then
--Main Rock Terrain
local no_rocks_2 = get_noise("no_rocks_2", p, seed + 75000)
if no_rocks_2 > 0.80 or no_rocks_2 < -0.80 then
tiles[#tiles + 1] = {name = "dirt-" .. math_floor(no_rocks_2 * 8) % 2 + 5, position = p}
if math_random(1,512) == 1 then treasure[#treasure + 1] = p end
return
end
if math_random(1,2048) == 1 then treasure[#treasure + 1] = p end
tiles[#tiles + 1] = {name = "dirt-7", position = p}
if math_random(1,100) > 40 then entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
return
end
tiles[#tiles + 1] = {name = "out-of-map", position = p}
end
local function process_forest_position(p, seed, tiles, entities, treasure, planet)
local biters = planet[1].name.biters
local noise_forest_location = get_noise("forest_location", p, seed)
--local r = math.ceil(math.abs(get_noise("forest_density", pos, seed + 4096)) * 10)
--local r = 5 - math.ceil(math.abs(noise_forest_location) * 3)
--r = 2
if noise_forest_location > 0.095 then
if noise_forest_location > 0.6 then
if math_random(1,100) > 42 then entities[#entities + 1] = {name = "tree-08-brown", position = p} end
else
if math_random(1,100) > 42 then entities[#entities + 1] = {name = "tree-01", position = p} end
end
--surface.create_decoratives({check_collision=false, decoratives={{name = decos_inside_forest[math_random(1, #decos_inside_forest)], position = pos, amount = math_random(1, 2)}}})
return
else
if math_random(1,152 - biters) == 1 and math_sqrt(p.x * p.x + p.y * p.y) > 250 then entities[#entities + 1] = {name = spawner_raffle[math_random(1, 4)], position = p} end
end
if noise_forest_location < -0.095 then
if noise_forest_location < -0.6 then
if math_random(1,100) > 42 then entities[#entities + 1] = {name = "tree-04", position = p} end
else
if math_random(1,100) > 42 then entities[#entities + 1] = {name = "tree-02-red", position = p} end
end
--surface.create_decoratives({check_collision=false, decoratives={{name = decos_inside_forest[math_random(1, #decos_inside_forest)], position = pos, amount = math_random(1, 2)}}})
return
else
if math_random(1,152 - biters) == 1 and math_sqrt(p.x * p.x + p.y * p.y) > 250 then entities[#entities + 1] = {name = spawner_raffle[math_random(1, 4)], position = p} end
end
--surface.create_decoratives({check_collision=false, decoratives={{name = decos[math_random(1, #decos)], position = pos, amount = math_random(1, 2)}}})
end
local function process_river_position(p, seed, tiles, entities, treasure, planet)
local biters = planet[1].name.biters
local richness = math_random(50 + 10 * global.objective.chronojumps, 100 + 10 * global.objective.chronojumps) * planet[1].ore_richness.factor^2
local iron_size = get_size_of_ore("iron-ore", planet)
local copper_size = get_size_of_ore("copper-ore", planet)
local stone_size = get_size_of_ore("stone", planet)
local coal_size = get_size_of_ore("coal", planet)
if not biters then biters = 4 end
local large_caves = get_noise("large_caves", p, seed)
local cave_rivers = get_noise("cave_rivers", p, seed)
local ores = get_noise("ores", p, seed)
local noise_forest_location = get_noise("forest_location", p, seed)
--Chasms
local noise_cave_ponds = get_noise("cave_ponds", p, seed)
local small_caves = get_noise("small_caves", p, seed)
if noise_cave_ponds < 0.45 and noise_cave_ponds > -0.45 then
if small_caves > 0.75 then
tiles[#tiles + 1] = {name = "out-of-map", position = p}
return
end
if small_caves < -0.75 then
tiles[#tiles + 1] = {name = "out-of-map", position = p}
return
end
end
if large_caves > -0.05 and large_caves < 0.05 and cave_rivers < 0.25 then
tiles[#tiles + 1] = {name = "water-green", position = p}
if math_random(1,128) == 1 then entities[#entities + 1] = {name="fish", position=p} end
return
elseif large_caves > -0.15 and large_caves < 0.15 and cave_rivers <0.35 then
if ores > -coal_size and ores < coal_size then
entities[#entities + 1] = {name = "coal", position = p, amount = richness}
end
end
if cave_rivers > -0.70 and cave_rivers < 0.70 then
if math_random(1,48) == 1 then entities[#entities + 1] = {name = "tree-0" .. math_random(1, 9), position=p} end
if cave_rivers > -0.05 and cave_rivers < 0.05 then
if ores > -iron_size and ores < iron_size then
entities[#entities + 1] = {name = "iron-ore", position = p, amount = richness}
end
elseif cave_rivers > -0.10 and cave_rivers < 0.10 then
if ores > -copper_size and ores < copper_size then
entities[#entities + 1] = {name = "copper-ore", position = p, amount = richness}
end
end
else
tiles[#tiles + 1] = {name = "dirt-7", position = p}
if ores > -stone_size and ores < stone_size then
entities[#entities + 1] = {name = "stone", position = p, amount = richness}
end
if math_random(1,52 - biters) == 1 and math_sqrt(p.x * p.x + p.y * p.y) > 200 then entities[#entities + 1] = {name = spawner_raffle[math_random(1, 4)], position = p} end
if math_random(1,2048) == 1 then treasure[#treasure + 1] = p end
end
if noise_forest_location > 0.9 then
local tree = tree_raffle[math_random(1, s_tree_raffle)]
if math_random(1,100) > 42 then entities[#entities + 1] = {name = tree_raffle[math_random(1, s_tree_raffle)], position = p} end
return
end
if noise_forest_location < -0.9 then
if math_random(1,100) > 42 then entities[#entities + 1] = {name = tree_raffle[math_random(1, s_tree_raffle)], position = p} end
return
end
end
local function process_biter_position(p, seed, tiles, entities, treasure, planet)
local scrapyard = get_noise("scrapyard", p, seed)
local noise_forest_location = get_noise("forest_location", p, seed)
local large_caves = get_noise("large_caves", p, seed)
local biters = planet[1].name.biters
local ore_size = planet[1].ore_richness.factor
if scrapyard < -0.75 or scrapyard > 0.75 then
if math_random(1,52 - biters) == 1 and math_sqrt(p.x * p.x + p.y * p.y) > 200 then entities[#entities + 1] = {name = spawner_raffle[math_random(1, 4)], position = p} end
end
if scrapyard > -0.05 - 0.01 * ore_size and scrapyard < 0.05 + 0.01 * ore_size then
if math_random(1,20) == 1 then entities[#entities + 1] = {name = rock_raffle[math_random(1, size_of_rock_raffle)], position = p} end
end
if scrapyard + 0.5 > -0.05 - 0.1 * planet[1].name.moisture and scrapyard + 0.5 < 0.05 + 0.1 * planet[1].name.moisture then
if math_random(1,100) > 42 then entities[#entities + 1] = {name = tree_raffle[math_random(1, s_tree_raffle)], position = p} end
end
if scrapyard > -0.10 and scrapyard < 0.10 then
if math_floor(large_caves * 10) % 4 < 3 then
local jumps = global.objective.chronojumps * 5
if global.objective.chronojumps > 20 then jumps = 100 end
local roll = math_random(1,200 - jumps - biters)
if math_sqrt(p.x * p.x + p.y * p.y) > 300 then
if roll == 1 then
entities[#entities + 1] = {name = spawner_raffle[math_random(1, 4)], position = p}
elseif roll == 2 then
entities[#entities + 1] = {name = worm_raffle[math_random(1 + math_floor(game.forces["enemy"].evolution_factor * 8), math_floor(1 + game.forces["enemy"].evolution_factor * 16))], position = p}
end
return
end
end
end
end
local function process_scrapyard_position(p, seed, tiles, entities, treasure, planet)
local scrapyard = get_noise("scrapyard", p, seed)
local biters = planet[1].name.biters
--Chasms
local noise_cave_ponds = get_noise("cave_ponds", p, seed)
local small_caves = get_noise("small_caves", p, seed)
local noise_forest_location = get_noise("forest_location", p, seed)
if noise_cave_ponds < 0.15 and noise_cave_ponds > -0.15 then
if small_caves > 0.35 then
tiles[#tiles + 1] = {name = "out-of-map", position = p}
return
end
if small_caves < -0.35 then
tiles[#tiles + 1] = {name = "out-of-map", position = p}
return
end
end
if scrapyard < -0.25 or scrapyard > 0.25 then
if math_random(1, 256) == 1 and math_sqrt(p.x * p.x + p.y * p.y) > 50 then
entities[#entities + 1] = {name="gun-turret", position=p, force = "enemy"}
end
tiles[#tiles + 1] = {name = "dirt-7", position = p}
if scrapyard < -0.55 or scrapyard > 0.55 then
if math_random(1,40) == 1 and math_sqrt(p.x * p.x + p.y * p.y) > 100 then entities[#entities + 1] = {name = spawner_raffle[math_random(1, 4)], position = p} end
return
end
if scrapyard + 0.5 > -0.05 - 0.1 * planet[1].name.moisture and scrapyard + 0.5 < 0.05 + 0.1 * planet[1].name.moisture then
if math_random(1,100) > 42 then entities[#entities + 1] = {name = tree_raffle[math_random(1, s_tree_raffle)], position = p} end
end
if scrapyard < -0.28 or scrapyard > 0.28 then
-- if math_random(1,128) == 1 then
-- Biters.wave_defense_set_worm_raffle(math_abs(p.y) * worm_level_modifier)
-- entities[#entities + 1] = {name = Biters.wave_defense_roll_worm_name(), position = p, force = "enemy"}
-- end
if math_random(1,96) == 1 then entities[#entities + 1] = {name = scrap_entities[math_random(1, scrap_entities_index)], position = p, force = "enemy"} end
if math_random(1,5) > 1 then entities[#entities + 1] = {name="mineable-wreckage", position=p} end
return
end
return
end
local cave_ponds = get_noise("cave_ponds", p, seed)
if cave_ponds < -0.6 and scrapyard > -0.2 and scrapyard < 0.2 then
tiles[#tiles + 1] = {name = "deepwater-green", position = p}
if math_random(1,128) == 1 then entities[#entities + 1] = {name="fish", position=p} end
return
end
local large_caves = get_noise("large_caves", p, seed)
if scrapyard > -0.15 and scrapyard < 0.15 then
if math_floor(large_caves * 10) % 4 < 3 then
tiles[#tiles + 1] = {name = "dirt-7", position = p}
local jumps = global.objective.chronojumps * 5
if global.objective.chronojumps > 20 then jumps = 100 end
if math_random(1,200 - jumps) == 1 and math_sqrt(p.x * p.x + p.y * p.y) > 100 then entities[#entities + 1] = {name = spawner_raffle[math_random(1, 4)], position = p} end
return
end
end
--if math_random(1,64) == 1 and cave_ponds > 0.6 then entities[#entities + 1] = {name = "crude-oil", position = p, amount = get_oil_amount(p)} end
tiles[#tiles + 1] = {name = "stone-path", position = p}
end
local levels = {
process_level_1_position,
process_level_2_position,
process_level_3_position,
process_rocky_position,
process_forest_position,
process_river_position,
process_biter_position,
process_scrapyard_position,
process_level_9_position,
process_level_10_position,
}
local entity_functions = {
["turret"] = function(surface, entity) surface.create_entity(entity) end,
["simple-entity"] = function(surface, entity) surface.create_entity(entity) end,
["ammo-turret"] = function(surface, entity)
local e = surface.create_entity(entity)
e.insert({name = "uranium-rounds-magazine", count = math_random(16, 64)})
end,
["container"] = function(surface, entity)
Treasure(surface, entity.position, entity.name)
end,
}
local function get_replacement_tile(surface, position)
for i = 1, 128, 1 do
local vectors = {{0, i}, {0, i * -1}, {i, 0}, {i * -1, 0}}
table.shuffle_table(vectors)
for k, v in pairs(vectors) do
local tile = surface.get_tile(position.x + v[1], position.y + v[2])
if not tile.collides_with("resource-layer") then return tile.name end
end
end
return "grass-1"
end
local function replace_water(surface, left_top)
for x = 0, 31, 1 do
for y = 0, 31, 1 do
local p = {x = left_top.x + x, y = left_top.y + y}
if surface.get_tile(p).collides_with("resource-layer") then
surface.set_tiles({{name = get_replacement_tile(surface, p), position = p}}, true)
end
end
end
end
local function forest_chunk(surface, left_top, level, planet)
local tiles = {}
local entities = {}
--local markets = {}
local treasure = {}
local seed = surface.map_gen_settings.seed
local process_level = levels[level]
for y = 0.5, 31.5, 1 do
for x = 0.5, 31.5, 1 do
local p = {x = left_top.x + x, y = left_top.y + y}
process_level(p, seed, tiles, entities, treasure, planet)
end
end
surface.set_tiles(tiles, true)
for _, entity in pairs(entities) do
if surface.can_place_entity(entity) then
local e = surface.create_entity(entity)
if e.name == "biter-spawner" or e.name == "spitter-spawner" then
if math_abs(e.position.x) > 420 or math_abs(e.position.y) > 420 then e.destructible = false end
end
end
end
end
local function biter_chunk(surface, left_top, level, planet)
local tiles = {}
local entities = {}
--local markets = {}
local treasure = {}
local seed = surface.map_gen_settings.seed
local process_level = levels[level]
for y = 0, 31, 1 do
for x = 0, 31, 1 do
local p = {x = left_top.x + x, y = left_top.y + y}
process_level(p, seed, tiles, entities, treasure, planet)
end
end
surface.set_tiles(tiles, true)
for _, entity in pairs(entities) do
if surface.can_place_entity(entity) then
local e = surface.create_entity(entity)
if e.name == "biter-spawner" or e.name == "spitter-spawner" then
if math_abs(e.position.x) > 420 or math_abs(e.position.y) > 420 then e.destructible = false end
end
end
end
end
local function empty_chunk(surface, left_top, level, planet)
local tiles = {}
local entities = {}
--local markets = {}
local treasure = {}
local seed = surface.map_gen_settings.seed
local process_level = levels[level]
for y = 0, 31, 1 do
for x = 0, 31, 1 do
local p = {x = left_top.x + x, y = left_top.y + y}
process_level(p, seed, tiles, entities, treasure, planet)
end
end
surface.set_tiles(tiles, true)
replace_water(surface, left_top)
end
local function normal_chunk(surface, left_top, level, planet)
local tiles = {}
local entities = {}
--local markets = {}
local treasure = {}
local seed = surface.map_gen_settings.seed
--local level_index = math_floor((math_abs(left_top.y / level_depth)) % 10) + 1
local process_level = levels[level]
for y = 0, 31, 1 do
for x = 0, 31, 1 do
local p = {x = left_top.x + x, y = left_top.y + y}
process_level(p, seed, tiles, entities, treasure, planet)
end
end
surface.set_tiles(tiles, true)
-- if #markets > 0 then
-- local position = markets[math_random(1, #markets)]
-- if surface.count_entities_filtered{area = {{position.x - 96, position.y - 96}, {position.x + 96, position.y + 96}}, name = "market", limit = 1} == 0 then
-- local market = Market.mountain_market(surface, position, math_abs(position.y) * 0.004)
-- market.destructible = false
-- end
-- end
for _, p in pairs(treasure) do
local name = "wooden-chest"
if math_random(1, 6) == 1 then name = "iron-chest" end
Treasure(surface, p, name)
end
for _, entity in pairs(entities) do
if entity_functions[game.entity_prototypes[entity.name].type] then
entity_functions[game.entity_prototypes[entity.name].type](surface, entity)
else
if surface.can_place_entity(entity) then
local e = surface.create_entity(entity)
if e.name == "biter-spawner" or e.name == "spitter-spawner" then
if math_abs(e.position.x) > 420 or math_abs(e.position.y) > 420 then e.destructible = false end
end
end
end
end
end
local function process_chunk(surface, left_top)
if not surface then return end
if not surface.valid then return end
if left_top.x >= level_depth * 0.5 or left_top.y >= level_depth * 0.5 then return end
if left_top.x < level_depth * -0.5 or left_top.y < level_depth * -0.5 then return end
--if left_top.y >= 0 then replace_water(surface, left_top) end
--if left_top.y > 32 then game.forces.player.chart(surface, {{left_top.x, left_top.y},{left_top.x + 31, left_top.y + 31}}) end
-- if left_top.y == -128 and left_top.x == -128 then
-- local p = global.locomotive.position
-- for _, entity in pairs(surface.find_entities_filtered({area = {{p.x - 3, p.y - 4},{p.x + 3, p.y + 10}}, type = "simple-entity"})) do entity.destroy() end
-- end
local planet = global.objective.planet
if planet[1].name.name == "scrapyard" then
if math_abs(left_top.y) <= 31 and math_abs(left_top.x) <= 31 then empty_chunk(surface, left_top, 8, planet) return end
if math_abs(left_top.y) > 31 or math_abs(left_top.x) > 31 then normal_chunk(surface, left_top, 8, planet) return end
elseif planet[1].name.name == "river planet" then
if math_abs(left_top.y) <= 31 and math_abs(left_top.x) <= 31 then empty_chunk(surface, left_top, 6, planet) return end
if math_abs(left_top.y) > 31 or math_abs(left_top.x) > 31 then normal_chunk(surface, left_top, 6, planet) return end
elseif planet[1].name.name == "choppy planet" then
if math_abs(left_top.y) <= 31 and math_abs(left_top.x) <= 31 then empty_chunk(surface, left_top, 5, planet) return end
if math_abs(left_top.y) > 31 or math_abs(left_top.x) > 31 then forest_chunk(surface, left_top, 5, planet) return end
elseif planet[1].name.name == "rocky planet" then
if math_abs(left_top.y) <= 31 and math_abs(left_top.x) <= 31 then empty_chunk(surface, left_top, 4, planet) return end
if math_abs(left_top.y) > 31 or math_abs(left_top.x) > 31 then normal_chunk(surface, left_top, 4, planet) return end
-- elseif planet[1].name.name == "lava planet" then
-- if math_abs(left_top.y) <= 31 and math_abs(left_top.x) <= 31 then empty_chunk(surface, left_top, 4, planet) return end
-- if math_abs(left_top.y) > 31 and math_abs(left_top.x) > 31 then empty_chunk(surface, left_top, 4, planet) return end
else
if math_abs(left_top.y) <= 31 and math_abs(left_top.x) <= 31 then empty_chunk(surface, left_top, 7, planet) return end
if math_abs(left_top.y) > 31 or math_abs(left_top.x) > 31 then biter_chunk(surface, left_top, 7, planet) return end
end
--if left_top.y > 96 then out_of_map(surface, left_top) return end
--if left_top.y > 64 then biter_chunk(surface, left_top) return end
--if left_top.y >= 0 then border_chunk(surface, left_top) return end
--rock_chunk(surface, left_top)
--return
end
local function on_chunk_generated(event)
if string.sub(event.surface.name, 0, 12) ~= "chronosphere" then return end
process_chunk(event.surface, event.area.left_top)
--global.chunk_queue[#global.chunk_queue + 1] = {left_top = {x = event.area.left_top.x, y = event.area.left_top.y}, surface_index = event.surface.index}
end
local event = require 'utils.event'
--event.on_nth_tick(4, process_chunk_queue)
event.add(defines.events.on_chunk_generated, on_chunk_generated)
return level_depth

View File

@ -0,0 +1,184 @@
local math_random = math.random
local math_sqrt = math.sqrt
local Public = {}
function Public.treasure_chest(surface, position, container_name)
local chest_raffle = {}
local chest_loot = {
{{name = "submachine-gun", count = math_random(1,3)}, weight = 3, d_min = 0.0, d_max = 0.1},
{{name = "slowdown-capsule", count = math_random(16,32)}, weight = 1, d_min = 0.3, d_max = 0.7},
{{name = "poison-capsule", count = math_random(8,16)}, weight = 3, d_min = 0.3, d_max = 1},
{{name = "uranium-cannon-shell", count = math_random(16,32)}, weight = 5, d_min = 0.6, d_max = 1},
{{name = "cannon-shell", count = math_random(16,32)}, weight = 5, d_min = 0.4, d_max = 0.7},
{{name = "explosive-uranium-cannon-shell", count = math_random(16,32)}, weight = 5, d_min = 0.6, d_max = 1},
{{name = "explosive-cannon-shell", count = math_random(16,32)}, weight = 5, d_min = 0.4, d_max = 0.8},
{{name = "shotgun", count = 1}, weight = 2, d_min = 0.0, d_max = 0.2},
{{name = "shotgun-shell", count = math_random(16,32)}, weight = 5, d_min = 0.0, d_max = 0.2},
{{name = "combat-shotgun", count = 1}, weight = 3, d_min = 0.3, d_max = 0.8},
{{name = "piercing-shotgun-shell", count = math_random(16,32)}, weight = 10, d_min = 0.2, d_max = 1},
{{name = "flamethrower", count = 1}, weight = 3, d_min = 0.3, d_max = 0.6},
{{name = "flamethrower-ammo", count = math_random(16,32)}, weight = 5, d_min = 0.3, d_max = 1},
{{name = "rocket-launcher", count = 1}, weight = 3, d_min = 0.2, d_max = 0.6},
{{name = "rocket", count = math_random(16,32)}, weight = 5, d_min = 0.2, d_max = 0.7},
{{name = "explosive-rocket", count = math_random(16,32)}, weight = 5, d_min = 0.3, d_max = 1},
{{name = "land-mine", count = math_random(16,32)}, weight = 5, d_min = 0.2, d_max = 0.7},
{{name = "grenade", count = math_random(16,32)}, weight = 5, d_min = 0.0, d_max = 0.5},
{{name = "cluster-grenade", count = math_random(8,16)}, weight = 5, d_min = 0.4, d_max = 1},
{{name = "firearm-magazine", count = math_random(32,128)}, weight = 5, d_min = 0, d_max = 0.3},
{{name = "piercing-rounds-magazine", count = math_random(32,128)}, weight = 5, d_min = 0.1, d_max = 0.8},
{{name = "uranium-rounds-magazine", count = math_random(32,128)}, weight = 5, d_min = 0.5, d_max = 1},
{{name = "railgun", count = 1}, weight = 1, d_min = 0.2, d_max = 1},
{{name = "railgun-dart", count = math_random(16,32)}, weight = 3, d_min = 0.2, d_max = 0.7},
{{name = "defender-capsule", count = math_random(8,16)}, weight = 2, d_min = 0.0, d_max = 0.7},
{{name = "distractor-capsule", count = math_random(8,16)}, weight = 2, d_min = 0.2, d_max = 1},
{{name = "destroyer-capsule", count = math_random(8,16)}, weight = 2, d_min = 0.3, d_max = 1},
{{name = "atomic-bomb", count = 1}, weight = 1, d_min = 0.8, d_max = 1},
{{name = "light-armor", count = 1}, weight = 3, d_min = 0, d_max = 0.1},
{{name = "heavy-armor", count = 1}, weight = 3, d_min = 0.1, d_max = 0.3},
{{name = "modular-armor", count = 1}, weight = 2, d_min = 0.2, d_max = 0.6},
{{name = "power-armor", count = 1}, weight = 1, d_min = 0.4, d_max = 1},
--{{name = "power-armor-mk2", count = 1}, weight = 1, d_min = 0.9, d_max = 1},
{{name = "battery-equipment", count = 1}, weight = 2, d_min = 0.3, d_max = 0.7},
--{{name = "battery-mk2-equipment", count = 1}, weight = 2, d_min = 0.7, d_max = 1},
{{name = "belt-immunity-equipment", count = 1}, weight = 1, d_min = 0.5, d_max = 1},
{{name = "solar-panel-equipment", count = math_random(1,4)}, weight = 5, d_min = 0.4, d_max = 0.8},
{{name = "discharge-defense-equipment", count = 1}, weight = 1, d_min = 0.5, d_max = 1},
{{name = "energy-shield-equipment", count = math_random(1,2)}, weight = 2, d_min = 0.3, d_max = 0.8},
--{{name = "energy-shield-mk2-equipment", count = 1}, weight = 2, d_min = 0.8, d_max = 1},
{{name = "exoskeleton-equipment", count = 1}, weight = 1, d_min = 0.3, d_max = 1},
--{{name = "fusion-reactor-equipment", count = 1}, weight = 1, d_min = 0.8, d_max = 1},
{{name = "night-vision-equipment", count = 1}, weight = 1, d_min = 0.3, d_max = 0.8},
{{name = "personal-laser-defense-equipment", count = 1}, weight = 1, d_min = 0.7, d_max = 1},
{{name = "personal-roboport-equipment", count = math_random(1,2)}, weight = 3, d_min = 0.4, d_max = 1},
--{{name = "personal-roboport-mk2-equipment", count = 1}, weight = 1, d_min = 0.9, d_max = 1},
{{name = "logistic-robot", count = math_random(5,25)}, weight = 2, d_min = 0.5, d_max = 1},
{{name = "construction-robot", count = math_random(5,25)}, weight = 5, d_min = 0.4, d_max = 1},
{{name = "iron-gear-wheel", count = math_random(80,100)}, weight = 3, d_min = 0.0, d_max = 0.3},
{{name = "copper-cable", count = math_random(100,200)}, weight = 3, d_min = 0.0, d_max = 0.3},
{{name = "engine-unit", count = math_random(16,32)}, weight = 2, d_min = 0.1, d_max = 0.5},
{{name = "electric-engine-unit", count = math_random(16,32)}, weight = 2, d_min = 0.4, d_max = 0.8},
{{name = "battery", count = math_random(50,150)}, weight = 2, d_min = 0.3, d_max = 0.8},
{{name = "advanced-circuit", count = math_random(50,150)}, weight = 3, d_min = 0.3, d_max = 1},
{{name = "electronic-circuit", count = math_random(50,150)}, weight = 4, d_min = 0.0, d_max = 0.4},
{{name = "processing-unit", count = math_random(50,150)}, weight = 3, d_min = 0.7, d_max = 1},
{{name = "explosives", count = math_random(40,100)}, weight = 20, d_min = 0.0, d_max = 1},
{{name = "lubricant-barrel", count = math_random(4,10)}, weight = 1, d_min = 0.3, d_max = 0.5},
{{name = "rocket-fuel", count = math_random(4,10)}, weight = 2, d_min = 0.3, d_max = 0.7},
--{{name = "computer", count = 1}, weight = 2, d_min = 0, d_max = 1},
{{name = "effectivity-module", count = math_random(1,4)}, weight = 2, d_min = 0.1, d_max = 1},
{{name = "productivity-module", count = math_random(1,4)}, weight = 2, d_min = 0.1, d_max = 1},
{{name = "speed-module", count = math_random(1,4)}, weight = 2, d_min = 0.1, d_max = 1},
{{name = "automation-science-pack", count = math_random(16,64)}, weight = 3, d_min = 0.0, d_max = 0.2},
{{name = "logistic-science-pack", count = math_random(16,64)}, weight = 3, d_min = 0.1, d_max = 0.5},
{{name = "military-science-pack", count = math_random(16,64)}, weight = 3, d_min = 0.2, d_max = 1},
{{name = "chemical-science-pack", count = math_random(16,64)}, weight = 3, d_min = 0.3, d_max = 1},
{{name = "production-science-pack", count = math_random(16,64)}, weight = 3, d_min = 0.4, d_max = 1},
{{name = "utility-science-pack", count = math_random(16,64)}, weight = 3, d_min = 0.5, d_max = 1},
{{name = "space-science-pack", count = math_random(16,64)}, weight = 3, d_min = 0.9, d_max = 1},
{{name = "steel-plate", count = math_random(25,75)}, weight = 2, d_min = 0.1, d_max = 0.3},
{{name = "nuclear-fuel", count = 1}, weight = 2, d_min = 0.7, d_max = 1},
{{name = "burner-inserter", count = math_random(8,16)}, weight = 3, d_min = 0.0, d_max = 0.1},
{{name = "inserter", count = math_random(8,16)}, weight = 3, d_min = 0.0, d_max = 0.4},
{{name = "long-handed-inserter", count = math_random(8,16)}, weight = 3, d_min = 0.0, d_max = 0.4},
{{name = "fast-inserter", count = math_random(8,16)}, weight = 3, d_min = 0.1, d_max = 1},
{{name = "filter-inserter", count = math_random(8,16)}, weight = 1, d_min = 0.2, d_max = 1},
{{name = "stack-filter-inserter", count = math_random(4,8)}, weight = 1, d_min = 0.4, d_max = 1},
{{name = "stack-inserter", count = math_random(4,8)}, weight = 3, d_min = 0.3, d_max = 1},
{{name = "small-electric-pole", count = math_random(16,24)}, weight = 3, d_min = 0.0, d_max = 0.3},
{{name = "medium-electric-pole", count = math_random(8,16)}, weight = 3, d_min = 0.2, d_max = 1},
{{name = "big-electric-pole", count = math_random(4,8)}, weight = 3, d_min = 0.3, d_max = 1},
{{name = "substation", count = math_random(2,4)}, weight = 3, d_min = 0.5, d_max = 1},
{{name = "wooden-chest", count = math_random(8,16)}, weight = 3, d_min = 0.0, d_max = 0.2},
{{name = "iron-chest", count = math_random(8,16)}, weight = 3, d_min = 0.1, d_max = 0.4},
{{name = "steel-chest", count = math_random(8,16)}, weight = 3, d_min = 0.3, d_max = 1},
{{name = "small-lamp", count = math_random(16,32)}, weight = 3, d_min = 0.1, d_max = 0.3},
{{name = "rail", count = math_random(25,75)}, weight = 3, d_min = 0.1, d_max = 0.6},
{{name = "assembling-machine-1", count = math_random(2,4)}, weight = 3, d_min = 0.0, d_max = 0.3},
{{name = "assembling-machine-2", count = math_random(2,4)}, weight = 3, d_min = 0.2, d_max = 0.8},
{{name = "assembling-machine-3", count = math_random(2,4)}, weight = 3, d_min = 0.5, d_max = 1},
{{name = "accumulator", count = math_random(4,8)}, weight = 3, d_min = 0.4, d_max = 1},
{{name = "offshore-pump", count = math_random(1,3)}, weight = 2, d_min = 0.0, d_max = 0.2},
{{name = "beacon", count = 1}, weight = 2, d_min = 0.7, d_max = 1},
{{name = "boiler", count = math_random(3,6)}, weight = 3, d_min = 0.0, d_max = 0.3},
{{name = "steam-engine", count = math_random(2,4)}, weight = 3, d_min = 0.0, d_max = 0.5},
{{name = "steam-turbine", count = math_random(1,2)}, weight = 2, d_min = 0.6, d_max = 1},
{{name = "nuclear-reactor", count = 1}, weight = 1, d_min = 0.7, d_max = 1},
{{name = "centrifuge", count = 1}, weight = 1, d_min = 0.6, d_max = 1},
{{name = "heat-pipe", count = math_random(4,8)}, weight = 2, d_min = 0.5, d_max = 1},
{{name = "heat-exchanger", count = math_random(2,4)}, weight = 2, d_min = 0.5, d_max = 1},
{{name = "arithmetic-combinator", count = math_random(4,8)}, weight = 2, d_min = 0.1, d_max = 1},
{{name = "constant-combinator", count = math_random(4,8)}, weight = 2, d_min = 0.1, d_max = 1},
{{name = "decider-combinator", count = math_random(4,8)}, weight = 2, d_min = 0.1, d_max = 1},
{{name = "power-switch", count = 1}, weight = 2, d_min = 0.1, d_max = 1},
{{name = "programmable-speaker", count = math_random(2,4)}, weight = 1, d_min = 0.1, d_max = 1},
{{name = "green-wire", count = math_random(50,99)}, weight = 4, d_min = 0.1, d_max = 1},
{{name = "red-wire", count = math_random(50,99)}, weight = 4, d_min = 0.1, d_max = 1},
{{name = "chemical-plant", count = math_random(1,3)}, weight = 3, d_min = 0.3, d_max = 1},
{{name = "burner-mining-drill", count = math_random(2,4)}, weight = 3, d_min = 0.0, d_max = 0.2},
{{name = "electric-mining-drill", count = math_random(2,4)}, weight = 3, d_min = 0.2, d_max = 1},
{{name = "express-transport-belt", count = math_random(25,75)}, weight = 3, d_min = 0.5, d_max = 1},
{{name = "express-underground-belt", count = math_random(4,8)}, weight = 3, d_min = 0.5, d_max = 1},
{{name = "express-splitter", count = math_random(1,4)}, weight = 3, d_min = 0.5, d_max = 1},
{{name = "fast-transport-belt", count = math_random(25,75)}, weight = 3, d_min = 0.2, d_max = 0.7},
{{name = "fast-underground-belt", count = math_random(4,8)}, weight = 3, d_min = 0.2, d_max = 0.7},
{{name = "fast-splitter", count = math_random(1,4)}, weight = 3, d_min = 0.2, d_max = 0.3},
{{name = "transport-belt", count = math_random(25,75)}, weight = 3, d_min = 0, d_max = 0.3},
{{name = "underground-belt", count = math_random(4,8)}, weight = 3, d_min = 0, d_max = 0.3},
{{name = "splitter", count = math_random(1,4)}, weight = 3, d_min = 0, d_max = 0.3},
--{{name = "oil-refinery", count = math_random(2,4)}, weight = 2, d_min = 0.3, d_max = 1},
{{name = "pipe", count = math_random(30,50)}, weight = 3, d_min = 0.0, d_max = 0.3},
{{name = "pipe-to-ground", count = math_random(4,8)}, weight = 1, d_min = 0.2, d_max = 0.5},
{{name = "pumpjack", count = math_random(1,3)}, weight = 1, d_min = 0.3, d_max = 0.8},
{{name = "pump", count = math_random(1,2)}, weight = 1, d_min = 0.3, d_max = 0.8},
{{name = "solar-panel", count = math_random(3,6)}, weight = 3, d_min = 0.4, d_max = 0.9},
{{name = "electric-furnace", count = math_random(2,4)}, weight = 3, d_min = 0.5, d_max = 1},
{{name = "steel-furnace", count = math_random(4,8)}, weight = 3, d_min = 0.2, d_max = 0.7},
{{name = "stone-furnace", count = math_random(8,16)}, weight = 3, d_min = 0.0, d_max = 0.2},
{{name = "radar", count = math_random(1,2)}, weight = 1, d_min = 0.1, d_max = 0.4},
{{name = "rail-signal", count = math_random(8,16)}, weight = 2, d_min = 0.2, d_max = 0.8},
{{name = "rail-chain-signal", count = math_random(8,16)}, weight = 2, d_min = 0.2, d_max = 0.8},
{{name = "stone-wall", count = math_random(33,99)}, weight = 3, d_min = 0.0, d_max = 0.7},
{{name = "gate", count = math_random(16,32)}, weight = 3, d_min = 0.0, d_max = 0.7},
{{name = "storage-tank", count = math_random(2,6)}, weight = 3, d_min = 0.3, d_max = 0.6},
{{name = "train-stop", count = math_random(1,2)}, weight = 1, d_min = 0.2, d_max = 0.7},
{{name = "express-loader", count = math_random(1,2)}, weight = 1, d_min = 0.5, d_max = 1},
{{name = "fast-loader", count = math_random(1,2)}, weight = 1, d_min = 0.2, d_max = 0.7},
{{name = "loader", count = math_random(1,2)}, weight = 1, d_min = 0.0, d_max = 0.5},
{{name = "lab", count = math_random(1,2)}, weight = 2, d_min = 0.0, d_max = 0.3},
{{name = "roboport", count = 1}, weight = 2, d_min = 0.8, d_max = 1},
{{name = "flamethrower-turret", count = 1}, weight = 3, d_min = 0.5, d_max = 1},
{{name = "laser-turret", count = math_random(3,6)}, weight = 3, d_min = 0.5, d_max = 1},
{{name = "gun-turret", count = math_random(2,4)}, weight = 3, d_min = 0.2, d_max = 0.9},
}
local jumps = 0
if global.objective.chronojumps then jumps = global.objective.chronojumps end
local distance_to_center = math_sqrt(position.y * position.y + position.x * position.x) * (1 + jumps / 50) * 0.0002
if distance_to_center > 1 then distance_to_center = 1 end
for _, t in pairs (chest_loot) do
for x = 1, t.weight, 1 do
--if math_random(1,50) == 1 then log(distance_to_center) end
if t.d_min <= distance_to_center and t.d_max >= distance_to_center then
table.insert(chest_raffle, t[1])
end
end
end
local e = surface.create_entity({name = container_name, position=position, force="neutral", create_build_effect_smoke = false})
e.minable = false
local i = e.get_inventory(defines.inventory.chest)
for x = 1, math_random(2,6), 1 do
local loot = chest_raffle[math_random(1,#chest_raffle)]
i.insert(loot)
end
end
return Public.treasure_chest