1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-03-17 20:58:13 +02:00

Merge pull request #17 from M3wM3w/master

on par with main
This commit is contained in:
hanakocz 2020-04-19 14:14:49 +02:00 committed by GitHub
commit bbcd006e5b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 1444 additions and 1375 deletions

268
functions/basic_markets.lua Normal file
View File

@ -0,0 +1,268 @@
local Public = {}
local market = {}
market.weapons = {
["pistol"] = {value = 10, rarity = 1},
["submachine-gun"] = {value = 50, rarity = 2},
["shotgun"] = {value = 40, rarity = 2},
["combat-shotgun"] = {value = 400, rarity = 5},
["rocket-launcher"] = {value = 250, rarity = 4},
["flamethrower"] = {value = 750, rarity = 6},
["land-mine"] = {value = 3, rarity = 5},
}
market.ammo = {
["firearm-magazine"] = {value = 3, rarity = 1},
["piercing-rounds-magazine"] = {value = 6, rarity = 4},
["uranium-rounds-magazine"] = {value = 20, rarity = 8},
["shotgun-shell"] = {value = 3, rarity = 1},
["piercing-shotgun-shell"] = {value = 8, rarity = 5},
["cannon-shell"] = {value = 8, rarity = 4},
["explosive-cannon-shell"] = {value = 12, rarity = 5},
["uranium-cannon-shell"] = {value = 16, rarity = 7},
["explosive-uranium-cannon-shell"] = {value = 20, rarity = 8},
["artillery-shell"] = {value = 64, rarity = 7},
["rocket"] = {value = 4, rarity = 3},
["explosive-rocket"] = {value = 12, rarity = 5},
["atomic-bomb"] = {value = 9000, rarity = 10},
["flamethrower-ammo"] = {value = 20, rarity = 6},
["explosives"] = {value = 3, rarity = 1},
}
market.caspules = {
["grenade"] = {value = 16, rarity = 2},
["cluster-grenade"] = {value = 32, rarity = 5},
["poison-capsule"] = {value = 32, rarity = 6},
["slowdown-capsule"] = {value = 8, rarity = 1},
["defender-capsule"] = {value = 8, rarity = 1},
["distractor-capsule"] = {value = 20, rarity = 5},
["destroyer-capsule"] = {value = 32, rarity = 7},
["discharge-defense-remote"] = {value = 64, rarity = 6},
["artillery-targeting-remote"] = {value = 32, rarity = 7},
["raw-fish"] = {value = 6, rarity = 1},
}
market.armor = {
["light-armor"] = {value = 25, rarity = 1},
["heavy-armor"] = {value = 250, rarity = 4},
["modular-armor"] = {value = 750, rarity = 5},
["power-armor"] = {value = 2500, rarity = 6},
["power-armor-mk2"] = {value = 20000, rarity = 10},
}
market.equipment = {
["solar-panel-equipment"] = {value = 240, rarity = 3},
["fusion-reactor-equipment"] = {value = 9000, rarity = 7},
["energy-shield-equipment"] = {value = 400, rarity = 6},
["energy-shield-mk2-equipment"] = {value = 4000, rarity = 8},
["battery-equipment"] = {value = 160, rarity = 2},
["battery-mk2-equipment"] = {value = 2000, rarity = 8},
["personal-laser-defense-equipment"] = {value = 2500, rarity = 7},
["discharge-defense-equipment"] = {value = 2000, rarity = 5},
["belt-immunity-equipment"] = {value = 200, rarity = 1},
["exoskeleton-equipment"] = {value = 800, rarity = 3},
["personal-roboport-equipment"] = {value = 500, rarity = 3},
["personal-roboport-mk2-equipment"] = {value = 5000, rarity = 8},
["night-vision-equipment"] = {value = 250, rarity = 1},
}
market.defense = {
["stone-wall"] = {value = 4, rarity = 1},
["gate"] = {value = 8, rarity = 1},
["repair-pack"] = {value = 8, rarity = 1},
["gun-turret"] = {value = 64, rarity = 1},
["laser-turret"] = {value = 1024, rarity = 6},
["flamethrower-turret"] = {value = 2048, rarity = 6},
["flamethrower-turret"] = {value = 2048, rarity = 6},
["artillery-turret"] = {value = 8192, rarity = 8},
["rocket-silo"] = {value = 64000, rarity = 10},
}
market.logistic = {
["wooden-chest"] = {value = 3, rarity = 1},
["iron-chest"] = {value = 10, rarity = 2},
["steel-chest"] = {value = 24, rarity = 3},
["storage-tank"] = {value = 32, rarity = 4},
["transport-belt"] = {value = 4, rarity = 1},
["fast-transport-belt"] = {value = 8, rarity = 4},
["express-transport-belt"] = {value = 24, rarity = 7},
["underground-belt"] = {value = 8, rarity = 1},
["fast-underground-belt"] = {value = 32, rarity = 4},
["express-underground-belt"] = {value = 64, rarity = 7},
["splitter"] = {value = 16, rarity = 1},
["fast-splitter"] = {value = 48, rarity = 4},
["express-splitter"] = {value = 128, rarity = 7},
["loader"] = {value = 256, rarity = 2},
["fast-loader"] = {value = 512, rarity = 5},
["express-loader"] = {value = 768, rarity = 8},
["burner-inserter"] = {value = 4, rarity = 1},
["inserter"] = {value = 8, rarity = 1},
["long-handed-inserter"] = {value = 12, rarity = 2},
["fast-inserter"] = {value = 16, rarity = 4},
["filter-inserter"] = {value = 24, rarity = 5},
["stack-inserter"] = {value = 96, rarity = 6},
["stack-filter-inserter"] = {value = 128, rarity = 7},
["small-electric-pole"] = {value = 2, rarity = 1},
["medium-electric-pole"] = {value = 12, rarity = 4},
["big-electric-pole"] = {value = 24, rarity = 5},
["substation"] = {value = 96, rarity = 8},
["pipe"] = {value = 2, rarity = 1},
["pipe-to-ground"] = {value = 8, rarity = 1},
["pump"] = {value = 16, rarity = 4},
["logistic-robot"] = {value = 28, rarity = 5},
["construction-robot"] = {value = 28, rarity = 3},
["logistic-chest-active-provider"] = {value = 128, rarity = 7},
["logistic-chest-passive-provider"] = {value = 128, rarity = 6},
["logistic-chest-storage"] = {value = 128, rarity = 6},
["logistic-chest-buffer"] = {value = 128, rarity = 7},
["logistic-chest-requester"] = {value = 128, rarity = 7},
["roboport"] = {value = 4096, rarity = 8},
}
market.vehicles = {
["rail"] = {value = 4, rarity = 1},
["train-stop"] = {value = 32, rarity = 3},
["rail-signal"] = {value = 8, rarity = 5},
["rail-chain-signal"] = {value = 8, rarity = 5},
["locomotive"] = {value = 400, rarity = 4},
["cargo-wagon"] = {value = 200, rarity = 4},
["fluid-wagon"] = {value = 300, rarity = 5},
["artillery-wagon"] = {value = 8192, rarity = 8},
["car"] = {value = 80, rarity = 1},
["tank"] = {value = 1800, rarity = 5},
}
market.wire = {
["small-lamp"] = {value = 4, rarity = 1},
["red-wire"] = {value = 4, rarity = 1},
["green-wire"] = {value = 4, rarity = 1},
["arithmetic-combinator"] = {value = 16, rarity = 1},
["decider-combinator"] = {value = 16, rarity = 1},
["constant-combinator"] = {value = 16, rarity = 1},
["power-switch"] = {value = 16, rarity = 1},
["programmable-speaker"] = {value = 24, rarity = 1},
}
local function get_types()
local types = {}
for k, v in pairs(market) do
types[#types + 1] = k
end
return types
end
local function get_resource_market_sells()
local sells = {
{price = {{"coin", math.random(5,10)}}, offer = {type = 'give-item', item = 'wood', count = 50}},
{price = {{"coin", math.random(5,10)}}, offer = {type = 'give-item', item = 'iron-ore', count = 50}},
{price = {{"coin", math.random(5,10)}}, offer = {type = 'give-item', item = 'copper-ore', count = 50}},
{price = {{"coin", math.random(5,10)}}, offer = {type = 'give-item', item = 'stone', count = 50}},
{price = {{"coin", math.random(5,10)}}, offer = {type = 'give-item', item = 'coal', count = 50}},
{price = {{"coin", math.random(8,16)}}, offer = {type = 'give-item', item = 'uranium-ore', count = 50}},
{price = {{"coin", math.random(2,4)}}, offer = {type = 'give-item', item = 'crude-oil-barrel', count = 1}},
}
table.shuffle_table(sells)
return sells
end
local function get_resource_market_buys()
local buys = {
{price = {{'wood', math.random(10,12)}}, offer = {type = 'give-item', item = "coin"}},
{price = {{'iron-ore', math.random(10,12)}}, offer = {type = 'give-item', item = "coin"}},
{price = {{'copper-ore', math.random(10,12)}}, offer = {type = 'give-item', item = "coin"}},
{price = {{'stone', math.random(10,12)}}, offer = {type = 'give-item', item = "coin"}},
{price = {{'coal', math.random(10,12)}}, offer = {type = 'give-item', item = "coin"}},
{price = {{'uranium-ore', math.random(8,10)}}, offer = {type = 'give-item', item = "coin"}},
{price = {{'water-barrel', 1}}, offer = {type = 'give-item', item = "coin", count = math.random(1,2)}},
{price = {{'lubricant-barrel', 1}}, offer = {type = 'give-item', item = "coin", count = math.random(3,6)}},
{price = {{'sulfuric-acid-barrel', 1}}, offer = {type = 'give-item', item = "coin", count = math.random(4,8)}},
{price = {{'light-oil-barrel', 1}}, offer = {type = 'give-item', item = "coin", count = math.random(2,4)}},
{price = {{'heavy-oil-barrel', 1}}, offer = {type = 'give-item', item = "coin", count = math.random(2,4)}},
{price = {{'petroleum-gas-barrel', 1}}, offer = {type = 'give-item', item = "coin", count = math.random(3,5)}},
}
table.shuffle_table(buys)
return buys
end
local function get_market_item_list(market_types, rarity)
if rarity < 1 then rarity = 1 end
if rarity > 10 then rarity = 10 end
local list = {}
for _, market_type in pairs(market_types) do
for k, item in pairs(market[market_type]) do
--if item.rarity <= rarity and item.rarity + 7 >= rarity then
if item.rarity <= rarity then
local price = math.random(math.floor(item.value * 0.75), math.floor(item.value * 1.25))
if price < 1 then price = 1 end
if price > 64000 then price = 64000 end
list[#list + 1] = {price = {{"coin", price}}, offer = {type = 'give-item', item = k}}
end
end
end
if #list == 0 then return false end
return list
end
local function get_random_market_item_list(rarity)
local types = get_types()
table.shuffle_table(types)
for i = 1, #types, 1 do
local items = get_market_item_list({types[i]}, rarity)
if items then return items end
end
return false
end
function Public.mountain_market(surface, position, rarity)
local types = get_types()
table.shuffle_table(types)
local items = get_market_item_list({types[1], types[2], types[3]}, rarity)
if not items then return end
if #items > 0 then table.shuffle_table(items) end
local market = surface.create_entity({name = "market", position = position, force="neutral"})
for i = 1, math.random(5, 10), 1 do
if not items[i] then break end
market.add_market_item(items[i])
end
local sells = get_resource_market_sells()
for i = 1, math.random(1, 3), 1 do
market.add_market_item(sells[i])
end
local buys = get_resource_market_buys()
for i = 1, math.random(1, 3), 1 do
market.add_market_item(buys[i])
end
return market
end
function Public.super_market(surface, position, rarity)
local items = get_market_item_list(get_types(), rarity)
if not items then return end
if #items > 0 then table.shuffle_table(items) end
local market = surface.create_entity({name = "market", position = position, force="neutral"})
market.minable = false
market.destructible = false
for i = 1, math.random(6, 12), 1 do
if not items[i] then break end
market.add_market_item(items[i])
end
local sells = get_resource_market_sells()
for i = 1, math.random(1, 3), 1 do
market.add_market_item(sells[i])
end
local buys = get_resource_market_buys()
for i = 1, math.random(1, 3), 1 do
market.add_market_item(buys[i])
end
return market
end
return Public

View File

@ -13,7 +13,7 @@ local math_floor = math.floor
local function get_biter_raffle_table(level)
local raffle = {
["small-biter"] = 1000 - level * 1.75,
["medium-biter"] = level,
["medium-biter"] = -250 + level * 1.5,
["big-biter"] = 0,
["behemoth-biter"] = 0,
}
@ -48,7 +48,7 @@ end
local function get_spitter_raffle_table(level)
local raffle = {
["small-spitter"] = 1000 - level * 1.75,
["medium-spitter"] = level,
["medium-spitter"] = -250 + level * 1.5,
["big-spitter"] = 0,
["behemoth-spitter"] = 0,
}

View File

@ -1,3 +1,9 @@
--[[
roll(budget, max_slots) returns a table with item-stacks
budget - the total value of the item stacks combined
max_slots - the maximum amount of item stacks to return
]]
local Public = {}
local table_shuffle_table = table.shuffle_table
@ -188,6 +194,7 @@ local item_worths = {
["battery-mk2-equipment"] = 2048,
["personal-laser-defense-equipment"] = 2048,
["discharge-defense-equipment"] = 2048,
["discharge-defense-remote"] = 32,
["belt-immunity-equipment"] = 256,
["exoskeleton-equipment"] = 1024,
["personal-roboport-equipment"] = 512,
@ -262,6 +269,9 @@ function Public.roll(budget, max_slots)
if not budget then return end
if not max_slots then return end
budget = math_floor(budget)
if budget == 0 then return end
local final_stack_set
local final_stack_set_worth = 0

View File

@ -239,3 +239,8 @@ tooltip_2=gain / minute
[native_war]
map_info= - - N A T I V E W A R - -\n\n Defeat the enemy team Market !\n\nFeed your market with science to spawn waves of native biters and spitters !\nThey will soon after swarm to the opposing team Market !\n\nThe corridor is stewn with worms.\nRebuy dead worms and upgrade them to stem the opposing waves !\n\nExcess energy will activate a beam.\nBeam will progress with more excess energy.\nNatives will spawn according to the beam position.\n\nUse radars to spy opponent's base.\nUse your experience to improve damage and resistance of your biters.\nSpace science packs give extra life to your biters.\nConstruction robots may not build over the wall.\n
[territorial_control]
map_info_main_caption=T E R R I T O R I A L C O N T R O L
map_info_sub_caption= ..alone in the darkness..
map_info_text=Citizen Log #468-2A-3287, Freelancer Trent. \n\nTo whoever is reading this message, \nAny natural resources are rare and the ones worth while are too hard for me to reach. \nLuckily, the wrecks yield all kinds of useful scraps, but also various dangers. \nAlmost lost half a leg some days ago while digging out some scrap. \nThe wildlife is extremely aggressive, especially at the time of night. \nMost of these insect appearing like creatures seem to live underground. \nStay near your light sources, if you want to have a chance of surviving here! \n\n###Log End###

View File

@ -1,8 +1,11 @@
local Public = {}
local BiterRaffle = require "functions.biter_raffle"
local Functions = require "maps.biter_battles_v2.functions"
local bb_config = require "maps.biter_battles_v2.config"
local math_random = math.random
local math_abs = math.abs
local vector_radius = 256
local vector_radius = 512
local attack_vectors = {}
attack_vectors.north = {}
attack_vectors.south = {}
@ -17,6 +20,8 @@ for x = vector_radius * -1, vector_radius, 1 do
end
local size_of_vectors = #attack_vectors.north
local unit_type_raffle = {"biter", "biter", "biter", "mixed", "mixed", "spitter"}
local size_of_unit_type_raffle = #unit_type_raffle
local threat_values = {
["small-spitter"] = 1.5,
@ -35,10 +40,6 @@ local threat_values = {
["spitter-spawner"] = 16
}
-- these areas are for north
local middle_spawner_area = {left_top = {-600, -1000}, right_bottom = {600, -400}}
local whole_spawner_area = {left_top = {-2048, -1400}, right_bottom = {2048, -400}}
local function get_active_biter_count(biter_force_name)
local count = 0
for _, biter in pairs(global.active_biters[biter_force_name]) do
@ -47,44 +48,19 @@ local function get_active_biter_count(biter_force_name)
return count
end
local unit_evo_limits = {
["small-spitter"] = 0.6,
["small-biter"] = 0.6,
["medium-spitter"] = 0.8,
["medium-biter"] = 0.8,
["big-spitter"] = 2,
["big-biter"] = 2,
}
local function set_biter_raffle_table(surface, biter_force_name)
-- It's fine to only sample the middle
local area = middle_spawner_area
-- If south_biters: Mirror area along x-axis
if biter_force_name == "south_biters" then
area = {left_top = {area.left_top[1], -1*area.right_bottom[2]}, right_bottom = {area.right_bottom[1], -1*area.left_top[2]}}
end
local biters = surface.find_entities_filtered({type = "unit", force = biter_force_name, area = area})
if not biters[1] then return end
global.biter_raffle[biter_force_name] = {}
local raffle = global.biter_raffle[biter_force_name]
local i = 1
local evolution_factor = global.bb_evolution[biter_force_name]
for key, e in pairs(biters) do
if key % 5 == 0 then
if unit_evo_limits[e.name] then
if evolution_factor < unit_evo_limits[e.name] then
raffle[i] = e.name
i = i + 1
end
else
raffle[i] = e.name
i = i + 1
end
local function get_target_entity(force_name)
local force_index = game.forces[force_name].index
local target_entity = Functions.get_random_target_entity(force_index)
if not target_entity then print("Unable to get target entity for " .. force_name .. ".") return end
for _ = 1, 3, 1 do
local e = Functions.get_random_target_entity(force_index)
if math_abs(e.position.x) < math_abs(target_entity.position.x) then
target_entity = e
end
end
end
if not target_entity then print("Unable to get target entity for " .. force_name .. ".") return end
print("Target entity for " .. force_name .. ": " .. target_entity.name .. " at x=" .. target_entity.position.x .. " y=" .. target_entity.position.y)
return target_entity
end
local function get_threat_ratio(biter_force_name)
@ -159,9 +135,9 @@ Public.send_near_biters_to_silo = function()
target=global.rocket_silo["north"],
distraction=defines.distraction.none
},
unit_count = 16,
unit_count = 8,
force = "north_biters",
unit_search_distance=128
unit_search_distance = 64
})
game.surfaces["biter_battles"].set_multi_command({
@ -170,9 +146,9 @@ Public.send_near_biters_to_silo = function()
target=global.rocket_silo["south"],
distraction=defines.distraction.none
},
unit_count = 16,
unit_count = 8,
force = "south_biters",
unit_search_distance=128
unit_search_distance = 64
})
end
@ -193,79 +169,85 @@ local function get_random_spawner(biter_force_name)
end
end
local function get_random_close_spawner(surface, biter_force_name)
local nearest_spawner = get_random_spawner(biter_force_name)
if not nearest_spawner then return end
for _ = 1, 16, 1 do
local spawner = get_random_spawner(biter_force_name)
if spawner.position.x ^ 2 + spawner.position.y ^ 2 < nearest_spawner.position.x ^ 2 + nearest_spawner.position.y ^ 2 then
nearest_spawner = spawner
end
end
local function select_units_around_spawner(spawner, force_name, side_target)
local biter_force_name = spawner.force.name
return nearest_spawner
end
local function select_units_around_spawner(spawner, force_name, biter_force_name)
local biters = spawner.surface.find_enemy_units(spawner.position, 160, force_name)
if not biters[1] then return false end
local valid_biters = {}
local i = 0
local threat = global.bb_threat[biter_force_name] * math_random(11,22) * 0.01
local threat = global.bb_threat[biter_force_name] * math_random(8, 32) * 0.01
--threat modifier for outposts
local m = math_abs(side_target.position.x) - 512
if m < 0 then m = 0 end
m = 1 - m * 0.001
if m < 0.5 then m = 0.5 end
threat = threat * m
local unit_count = 0
local max_unit_count = math.ceil(global.bb_threat[biter_force_name] * 0.25) + math_random(6,12)
local max_unit_count = math.floor(global.bb_threat[biter_force_name] * 0.25) + math_random(6,12)
if max_unit_count > bb_config.max_group_size then max_unit_count = bb_config.max_group_size end
for _, biter in pairs(biters) do
if unit_count >= max_unit_count then break end
if biter.force.name == biter_force_name and global.active_biters[biter.force.name][biter.unit_number] == nil then
valid_biters[#valid_biters + 1] = biter
global.active_biters[biter.force.name][biter.unit_number] = {entity = biter, active_since = game.tick}
unit_count = unit_count + 1
threat = threat - threat_values[biter.name]
end
if threat < 0 then break end
end
--Manual spawning of additional units
local size_of_biter_raffle = #global.biter_raffle[biter_force_name]
if size_of_biter_raffle > 0 then
for c = 1, max_unit_count - unit_count, 1 do
if threat < 0 then break end
local biter_name = global.biter_raffle[biter_force_name][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 = biter_force_name, position = position})
threat = threat - threat_values[biter.name]
valid_biters[#valid_biters + 1] = biter
global.active_biters[biter.force.name][biter.unit_number] = {entity = biter, active_since = game.tick}
--Collect biters around spawners
if math_random(1, 2) == 1 then
local biters = spawner.surface.find_enemy_units(spawner.position, 160, force_name)
if biters[1] then
for _, biter in pairs(biters) do
if unit_count >= max_unit_count then break end
if biter.force.name == biter_force_name and global.active_biters[biter.force.name][biter.unit_number] == nil then
i = i + 1
valid_biters[i] = biter
global.active_biters[biter.force.name][biter.unit_number] = {entity = biter, active_since = game.tick}
unit_count = unit_count + 1
threat = threat - threat_values[biter.name]
end
if threat < 0 then break end
end
end
end
--Manual spawning of units
local roll_type = unit_type_raffle[math_random(1, size_of_unit_type_raffle)]
for c = 1, max_unit_count - unit_count, 1 do
if threat < 0 then break end
local unit_name = BiterRaffle.roll(roll_type, global.bb_evolution[biter_force_name])
local position = spawner.surface.find_non_colliding_position(unit_name, spawner.position, 128, 2)
if not position then break end
local biter = spawner.surface.create_entity({name = unit_name, force = biter_force_name, position = position})
threat = threat - threat_values[biter.name]
i = i + 1
valid_biters[i] = biter
global.active_biters[biter.force.name][biter.unit_number] = {entity = biter, active_since = game.tick}
end
if global.bb_debug then game.print(get_active_biter_count(biter_force_name) .. " active units for " .. biter_force_name) end
return valid_biters
end
local function send_group(unit_group, force_name, nearest_player_unit)
local target = nearest_player_unit.position
if math_random(1,2) == 1 then target = global.rocket_silo[force_name].position end
local function send_group(unit_group, force_name, side_target)
local target
if side_target then
target = side_target
else
target = get_target_entity(force_name)
end
if not target then print("No target for " .. force_name .. " biters.") return end
local commands = {}
target = target.position
local commands = {}
local vector = attack_vectors[force_name][math_random(1, size_of_vectors)]
local position = {target.x + vector[1], target.y + vector[2]}
local distance_modifier = math_random(25, 100) * 0.01
local position = {target.x + (vector[1] * distance_modifier), target.y + (vector[2] * distance_modifier)}
position = unit_group.surface.find_non_colliding_position("stone-furnace", position, 96, 1)
if position then
if math.abs(position.y) < math.abs(unit_group.position.y) then
commands[#commands + 1] = {
type = defines.command.attack_area,
destination = position,
radius = 24,
radius = 16,
distraction = defines.distraction.by_enemy
}
end
@ -286,50 +268,25 @@ local function send_group(unit_group, force_name, nearest_player_unit)
unit_group.set_command({
type = defines.command.compound,
structure_type = defines.compound_command.return_last,
structure_type = defines.compound_command.logical_and,
commands = commands
})
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 = {"north", "south"}, 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
local function get_unit_group_position(spawner)
local p
if spawner.force.name == "north_biters" then
p = {x = spawner.position.x, y = spawner.position.y + 4}
else
p = {x = spawner.position.x, y = spawner.position.y - 4}
end
local unit_group_position = {x = (spawner.position.x + nearest_player_unit.position.x) * 0.5, y = (spawner.position.y + nearest_player_unit.position.y) * 0.5}
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
if global.bb_debug then game.print("No unit_group_position found for team " .. force_name) end
return false
p = spawner.surface.find_non_colliding_position("electric-furnace", p, 512, 1)
if not p then
if global.bb_debug then game.print("No unit_group_position found for team " .. spawner.force.name) end
return
end
return unit_group_position
return p
end
local function get_active_threat(biter_force_name)
@ -344,6 +301,27 @@ local function get_active_threat(biter_force_name)
return active_threat
end
local function get_nearby_biter_nest(target_entity)
local center = target_entity.position
local biter_force_name = target_entity.force.name .. "_biters"
local spawner = get_random_spawner(biter_force_name)
if not spawner then return end
local best_distance = (center.x - spawner.position.x) ^ 2 + (center.y - spawner.position.y) ^ 2
for i = 1, 16, 1 do
local new_spawner = get_random_spawner(biter_force_name)
local new_distance = (center.x - new_spawner.position.x) ^ 2 + (center.y - new_spawner.position.y) ^ 2
if new_distance < best_distance then
spawner = new_spawner
best_distance = new_distance
end
end
if not spawner then return end
print("Nearby biter nest found at x=" .. spawner.position.x .. " y=" .. spawner.position.y .. ".")
return spawner
end
local function create_attack_group(surface, force_name, biter_force_name)
local threat = global.bb_threat[biter_force_name]
if get_active_threat(biter_force_name) > threat * 1.20 then return end
@ -354,22 +332,28 @@ local function create_attack_group(surface, force_name, biter_force_name)
return false
end
local spawner = get_random_close_spawner(surface, biter_force_name)
if not spawner then
if global.bb_debug then game.print("No spawner found for team " .. force_name) end
return false
local side_target = get_target_entity(force_name)
if not side_target then
print("No side target found for " .. force_name .. ".")
return
end
local nearest_player_unit = surface.find_nearest_enemy({position = spawner.position, max_distance = 2048, force = biter_force_name})
if not nearest_player_unit then nearest_player_unit = global.rocket_silo[force_name] end
local unit_group_position = get_unit_group_position(surface, nearest_player_unit, spawner)
local spawner = get_nearby_biter_nest(side_target)
if not spawner then
print("No spawner found for " .. force_name .. ".")
return
end
local unit_group_position = get_unit_group_position(spawner)
if not unit_group_position then return end
local units = select_units_around_spawner(spawner, force_name, side_target)
if not units then return end
local units = select_units_around_spawner(spawner, force_name, biter_force_name)
if not units then return false end
local unit_group = surface.create_unit_group({position = unit_group_position, force = biter_force_name})
for _, unit in pairs(units) do unit_group.add_member(unit) end
send_group(unit_group, force_name, nearest_player_unit)
send_group(unit_group, force_name, side_target)
global.unit_groups[unit_group.group_number] = unit_group
end
@ -382,8 +366,6 @@ Public.pre_main_attack = function()
local biter_force_name = force_name .. "_biters"
global.main_attack_wave_amount = math.ceil(get_threat_ratio(biter_force_name) * 7)
set_biter_raffle_table(surface, biter_force_name)
if global.bb_debug then game.print(global.main_attack_wave_amount .. " unit groups designated for " .. force_name .. " biters.") end
else
global.main_attack_wave_amount = 0
@ -424,9 +406,7 @@ Public.wake_up_sleepy_groups = function()
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 = biter_force_name})
if not nearest_player_unit then nearest_player_unit = global.rocket_silo[force_name] end
send_group(unit_group, force_name, nearest_player_unit)
send_group(unit_group, force_name)
print("BiterBattles: Woke up Unit Group at x" .. unit_group.position.x .. " y" .. unit_group.position.y .. ".")
return
end

View File

@ -1,42 +0,0 @@
-- biters will landfill tiles on death within a tiny radius
local Public = {}
local vectors = {{0,0}, {1,0}, {0,1}, {-1,0}, {0,-1}}
local math_random = math.random
local math_abs = math.abs
local whitelist = {
["big-biter"] = true,
["behemoth-biter"] = true,
}
local function create_particles(surface, position)
local m = math_random(8, 12)
local m2 = m * 0.005
for i = 1, 75, 1 do
surface.create_particle({
name = "stone-particle",
position = 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
end
function Public.entity_died(entity)
if not whitelist[entity.name] then return end
local position = entity.position
if math_abs(position.y) < 8 then return true end
local surface = entity.surface
for _, vector in pairs(vectors) do
local tile = surface.get_tile({position.x + vector[1], position.y + vector[2]})
if tile.collides_with("resource-layer") then
--create_particles(surface, tile.position)
surface.set_tiles({{name = "landfill", position = tile.position}})
end
end
return true
end
return Public

View File

@ -1,33 +0,0 @@
local Public = {}
----------share chat with player and spectator force-------------------
function Public.share(event)
if not event.message then return end
if not event.player_index then return end
local player = game.players[event.player_index]
local color = player.chat_color
if player.force.name == "north" then
game.forces.spectator.print(player.name .. " (north): ".. event.message, color)
game.forces.player.print(player.name .. " (north): ".. event.message, color)
end
if player.force.name == "south" then
game.forces.spectator.print(player.name .. " (south): ".. event.message, color)
game.forces.player.print(player.name .. " (south): ".. event.message, color)
end
if global.tournament_mode then return end
if player.force.name == "player" then
game.forces.north.print(player.name .. " (spawn): ".. event.message, color)
game.forces.south.print(player.name .. " (spawn): ".. event.message, color)
game.forces.spectator.print(player.name .. " (spawn): ".. event.message, color)
end
if player.force.name == "spectator" then
game.forces.north.print(player.name .. " (spectator): ".. event.message, color)
game.forces.south.print(player.name .. " (spectator): ".. event.message, color)
game.forces.player.print(player.name .. " (spectator): ".. event.message, color)
end
end
return Public

View File

@ -1,45 +0,0 @@
local Public = {}
local string_sub = string.sub
local balance_functions = {
["flamethrower"] = function(force_name)
global.combat_balance[force_name].flamethrower_damage = -0.6
game.forces[force_name].set_turret_attack_modifier("flamethrower-turret", global.combat_balance[force_name].flamethrower_damage)
game.forces[force_name].set_ammo_damage_modifier("flamethrower", global.combat_balance[force_name].flamethrower_damage)
end,
["refined-flammables"] = function(force_name)
global.combat_balance[force_name].flamethrower_damage = global.combat_balance[force_name].flamethrower_damage + 0.05
game.forces[force_name].set_turret_attack_modifier("flamethrower-turret", global.combat_balance[force_name].flamethrower_damage)
game.forces[force_name].set_ammo_damage_modifier("flamethrower", global.combat_balance[force_name].flamethrower_damage)
end,
["land-mine"] = function(force_name)
if not global.combat_balance[force_name].land_mine then global.combat_balance[force_name].land_mine = -0.75 end
game.forces[force_name].set_ammo_damage_modifier("landmine", global.combat_balance[force_name].land_mine)
end,
["stronger-explosives"] = function(force_name)
if not global.combat_balance[force_name].land_mine then global.combat_balance[force_name].land_mine = -0.75 end
global.combat_balance[force_name].land_mine = global.combat_balance[force_name].land_mine + 0.05
game.forces[force_name].set_ammo_damage_modifier("landmine", global.combat_balance[force_name].land_mine)
end,
["military"] = function(force_name)
global.combat_balance[force_name].shotgun = 1
game.forces[force_name].set_ammo_damage_modifier("shotgun-shell", global.combat_balance[force_name].shotgun)
end,
}
function Public.research_finished(event)
local research_name = event.research.name
local force_name = event.research.force.name
local key
for b = 1, string.len(research_name), 1 do
key = string_sub(research_name, 0, b)
if balance_functions[key] then
if not global.combat_balance[force_name] then global.combat_balance[force_name] = {} end
balance_functions[key](force_name)
return
end
end
end
return Public

View File

@ -12,7 +12,7 @@ local bb_config = {
--BITER SETTINGS--
["max_active_biters"] = 2000, --Maximum total amount of attacking units per side.
["max_group_size"] = 256, --Maximum unit group size.
["max_group_size"] = 288, --Maximum unit group size.
["biter_timeout"] = 162000, --Time it takes in ticks for an attacking unit to be deleted. This prevents perma stuck units.
["bitera_area_distance"] = 512 --Distance to the biter area.
}

View File

@ -0,0 +1,254 @@
local string_sub = string.sub
local math_random = math.random
local math_abs = math.abs
local table_insert = table.insert
local table_remove = table.remove
local balance_functions = {
["flamethrower"] = function(force_name)
global.combat_balance[force_name].flamethrower_damage = -0.6
game.forces[force_name].set_turret_attack_modifier("flamethrower-turret", global.combat_balance[force_name].flamethrower_damage)
game.forces[force_name].set_ammo_damage_modifier("flamethrower", global.combat_balance[force_name].flamethrower_damage)
end,
["refined-flammables"] = function(force_name)
global.combat_balance[force_name].flamethrower_damage = global.combat_balance[force_name].flamethrower_damage + 0.05
game.forces[force_name].set_turret_attack_modifier("flamethrower-turret", global.combat_balance[force_name].flamethrower_damage)
game.forces[force_name].set_ammo_damage_modifier("flamethrower", global.combat_balance[force_name].flamethrower_damage)
end,
["land-mine"] = function(force_name)
if not global.combat_balance[force_name].land_mine then global.combat_balance[force_name].land_mine = -0.75 end
game.forces[force_name].set_ammo_damage_modifier("landmine", global.combat_balance[force_name].land_mine)
end,
["stronger-explosives"] = function(force_name)
if not global.combat_balance[force_name].land_mine then global.combat_balance[force_name].land_mine = -0.75 end
global.combat_balance[force_name].land_mine = global.combat_balance[force_name].land_mine + 0.05
game.forces[force_name].set_ammo_damage_modifier("landmine", global.combat_balance[force_name].land_mine)
end,
["military"] = function(force_name)
global.combat_balance[force_name].shotgun = 1
game.forces[force_name].set_ammo_damage_modifier("shotgun-shell", global.combat_balance[force_name].shotgun)
end,
}
local no_turret_blacklist = {
["ammo-turret"] = true,
["artillery-turret"] = true,
["electric-turret"] = true,
["fluid-turret"] = true
}
local landfill_biters_vectors = {{0,0}, {1,0}, {0,1}, {-1,0}, {0,-1}}
local landfill_biters = {
["big-biter"] = true,
["big-spitter"] = true,
["behemoth-biter"] = true,
["behemoth-spitter"] = true,
}
local target_entity_types = {
["assembling-machine"] = true,
["boiler"] = true,
["furnace"] = true,
["generator"] = true,
["lab"] = true,
["mining-drill"] = true,
["radar"] = true,
["reactor"] = true,
["roboport"] = true,
["rocket-silo"] = true,
["ammo-turret"] = true,
["artillery-turret"] = true,
["beacon"] = true,
["electric-turret"] = true,
["fluid-turret"] = true,
}
local Public = {}
function Public.add_target_entity(entity)
if not entity then return end
if not entity.valid then return end
if not target_entity_types[entity.type] then return end
table_insert(global.target_entities[entity.force.index], entity)
end
function Public.get_random_target_entity(force_index)
local target_entities = global.target_entities[force_index]
local size_of_target_entities = #target_entities
if size_of_target_entities == 0 then return end
for _ = 1, size_of_target_entities, 1 do
local i = math_random(1, size_of_target_entities)
local entity = target_entities[i]
if entity and entity.valid then
return entity
else
table_remove(target_entities, i)
size_of_target_entities = size_of_target_entities - 1
if size_of_target_entities == 0 then return end
end
end
end
function Public.biters_landfill(entity)
if not landfill_biters[entity.name] then return end
local position = entity.position
if math_abs(position.y) < 8 then return true end
local surface = entity.surface
for _, vector in pairs(landfill_biters_vectors) do
local tile = surface.get_tile({position.x + vector[1], position.y + vector[2]})
if tile.collides_with("resource-layer") then
surface.set_tiles({{name = "landfill", position = tile.position}})
local particle_pos = {tile.position.x + 0.5, tile.position.y + 0.5}
for i = 1, 50, 1 do
surface.create_particle({
name = "stone-particle",
position = particle_pos,
frame_speed = 0.1,
vertical_speed = 0.12,
height = 0.01,
movement = {-0.05 + math_random(0, 100) * 0.001, -0.05 + math_random(0, 100) * 0.001}
})
end
end
end
return true
end
function Public.combat_balance(event)
local research_name = event.research.name
local force_name = event.research.force.name
local key
for b = 1, string.len(research_name), 1 do
key = string_sub(research_name, 0, b)
if balance_functions[key] then
if not global.combat_balance[force_name] then global.combat_balance[force_name] = {} end
balance_functions[key](force_name)
return
end
end
end
function Public.no_turret_creep(event)
local entity = event.created_entity
if not entity.valid then return end
if not no_turret_blacklist[event.created_entity.type] then return end
local surface = event.created_entity.surface
local spawners = surface.find_entities_filtered({type = "unit-spawner", area = {{entity.position.x - 70, entity.position.y - 70}, {entity.position.x + 70, entity.position.y + 70}}})
if #spawners == 0 then return end
local allowed_to_build = true
for _, e in pairs(spawners) do
if (e.position.x - entity.position.x)^2 + (e.position.y - entity.position.y)^2 < 4096 then
allowed_to_build = false
break
end
end
if allowed_to_build then return end
if event.player_index then
game.players[event.player_index].insert({name = entity.name, count = 1})
else
local inventory = event.robot.get_inventory(defines.inventory.robot_cargo)
inventory.insert({name = entity.name, count = 1})
end
surface.create_entity({
name = "flying-text",
position = entity.position,
text = "Turret too close to spawner!",
color = {r=0.98, g=0.66, b=0.22}
})
entity.destroy()
end
--share chat with player and spectator force
function Public.share_chat(event)
if not event.message then return end
if not event.player_index then return end
local player = game.players[event.player_index]
local color = player.chat_color
if player.force.name == "north" then
game.forces.spectator.print(player.name .. " (north): ".. event.message, color)
game.forces.player.print(player.name .. " (north): ".. event.message, color)
end
if player.force.name == "south" then
game.forces.spectator.print(player.name .. " (south): ".. event.message, color)
game.forces.player.print(player.name .. " (south): ".. event.message, color)
end
if global.tournament_mode then return end
if player.force.name == "player" then
game.forces.north.print(player.name .. " (spawn): ".. event.message, color)
game.forces.south.print(player.name .. " (spawn): ".. event.message, color)
game.forces.spectator.print(player.name .. " (spawn): ".. event.message, color)
end
if player.force.name == "spectator" then
game.forces.north.print(player.name .. " (spectator): ".. event.message, color)
game.forces.south.print(player.name .. " (spectator): ".. event.message, color)
game.forces.player.print(player.name .. " (spectator): ".. event.message, color)
end
end
function Public.spy_fish(player)
if not player.character then return end
local duration_per_unit = 2700
local i2 = player.get_inventory(defines.inventory.character_main)
if not i2 then return end
local owned_fishes = i2.get_item_count("raw-fish")
owned_fishes = owned_fishes + i2.get_item_count("raw-fish")
if owned_fishes == 0 then
player.print("You have no fish in your inventory.",{ r=0.98, g=0.66, b=0.22})
else
local x = i2.remove({name="raw-fish", count=1})
if x == 0 then i2.remove({name="raw-fish", count=1}) end
local enemy_team = "south"
if player.force.name == "south" then enemy_team = "north" end
if global.spy_fish_timeout[player.force.name] - game.tick > 0 then
global.spy_fish_timeout[player.force.name] = global.spy_fish_timeout[player.force.name] + duration_per_unit
player.print(math.ceil((global.spy_fish_timeout[player.force.name] - game.tick) / 60) .. " seconds of enemy vision left.", { r=0.98, g=0.66, b=0.22})
else
game.print(player.name .. " sent a fish to spy on " .. enemy_team .. " team!", {r=0.98, g=0.66, b=0.22})
global.spy_fish_timeout[player.force.name] = game.tick + duration_per_unit
end
end
end
function Public.create_map_intro_button(player)
if player.gui.top["map_intro_button"] then return end
local b = player.gui.top.add({type = "sprite-button", caption = "?", name = "map_intro_button", tooltip = "Map Info"})
b.style.font_color = {r=0.5, g=0.3, b=0.99}
b.style.font = "heading-1"
b.style.minimal_height = 38
b.style.minimal_width = 38
b.style.top_padding = 1
b.style.left_padding = 1
b.style.right_padding = 1
b.style.bottom_padding = 1
end
function Public.map_intro_click(player, element)
if element.name == "close_map_intro_frame" then player.gui.center["map_intro_frame"].destroy() return true end
if element.name == "biter_battles_map_intro" then player.gui.center["map_intro_frame"].destroy() return true end
if element.name == "map_intro_button" then
if player.gui.center["map_intro_frame"] then
player.gui.center["map_intro_frame"].destroy()
return true
else
if player.gui.center["map_intro_frame"] then player.gui.center["map_intro_frame"].destroy() end
local frame = player.gui.center.add {type = "frame", name = "map_intro_frame", direction = "vertical"}
local frame = frame.add {type = "frame"}
local l = frame.add {type = "label", caption = {"biter_battles.map_info"}, name = "biter_battles_map_intro"}
l.style.single_line = false
l.style.font = "heading-2"
l.style.font_color = {r=0.7, g=0.6, b=0.99}
return true
end
end
end
return Public

View File

@ -336,6 +336,11 @@ local function set_victory_time()
global.victory_time = global.victory_time .. " minutes"
end
local function freeze_all_biters(surface)
for _, e in pairs(surface.find_entities_filtered({force = "north_biters"})) do e.active = false end
for _, e in pairs(surface.find_entities_filtered({force = "south_biters"})) do e.active = false end
end
function Public.silo_death(event)
if not event.entity.valid then return end
if event.entity.name ~= "rocket-silo" then return end
@ -351,11 +356,7 @@ function Public.silo_death(event)
create_victory_gui(player)
show_mvps(player)
end
game.forces["north_biters"].set_friend("north", true)
game.forces["north"].set_friend("north_biters", true)
game.forces["south_biters"].set_friend("south", true)
game.forces["south"].set_friend("south_biters", true)
global.spy_fish_timeout["north"] = game.tick + 999999
global.spy_fish_timeout["south"] = game.tick + 999999
global.server_restart_timer = 180
@ -368,6 +369,8 @@ function Public.silo_death(event)
fireworks(event.entity.surface)
annihilate_base_v2(event.entity.position, event.entity.surface, event.entity.force.name)
freeze_all_biters(event.entity.surface)
end
end

View File

@ -3,7 +3,7 @@ local Server = require 'utils.server'
local bb_config = require "maps.biter_battles_v2.config"
local event = require 'utils.event'
local spy_fish = require "maps.biter_battles_v2.spy_fish"
local Functions = require "maps.biter_battles_v2.functions"
local feed_the_biters = require "maps.biter_battles_v2.feeding"
local Tables = require "maps.biter_battles_v2.tables"
@ -404,7 +404,7 @@ local function on_gui_click(event)
if name == "join_north_button" then join_gui_click(name, player) return end
if name == "join_south_button" then join_gui_click(name, player) return end
if name == "raw-fish" then spy_fish(player) return end
if name == "raw-fish" then Functions.spy_fish(player) return end
if food_names[name] then feed_the_biters(player, name) return end

View File

@ -18,7 +18,9 @@ function Public.settings()
end
function Public.surface()
--Terrain Source Surface
local map_gen_settings = {}
map_gen_settings.seed = math.random(1, 99999999)
map_gen_settings.water = math.random(15, 65) * 0.01
map_gen_settings.starting_area = 2.5
map_gen_settings.terrain_segmentation = math.random(30, 40) * 0.1
@ -30,16 +32,52 @@ function Public.surface()
["iron-ore"] = {frequency = 3.5, size = 0.65, richness = 0.5},
["uranium-ore"] = {frequency = 2, size = 1, richness = 1},
["crude-oil"] = {frequency = 3, size = 1, richness = 0.75},
["trees"] = {frequency = math.random(8, 24) * 0.1, size = math.random(8, 24) * 0.1, richness = math.random(1, 10) * 0.1},
["trees"] = {frequency = math.random(7, 22) * 0.1, size = math.random(7, 22) * 0.1, richness = math.random(1, 10) * 0.1},
["enemy-base"] = {frequency = 0, size = 0, richness = 0}
}
game.create_surface("biter_battles", map_gen_settings)
game.create_surface("bb_source", map_gen_settings)
game.map_settings.enemy_evolution.time_factor = 0
game.map_settings.enemy_evolution.destroy_factor = 0
game.map_settings.enemy_evolution.pollution_factor = 0
game.map_settings.pollution.enabled = false
game.map_settings.enemy_expansion.enabled = false
--Playground Surface
local map_gen_settings = {
["water"] = 0,
["starting_area"] = 1,
["cliff_settings"] = {cliff_elevation_interval = 0, cliff_elevation_0 = 0},
["default_enable_all_autoplace_controls"] = false,
["autoplace_settings"] = {
["entity"] = {treat_missing_as_default = false},
["tile"] = {treat_missing_as_default = false},
["decorative"] = {treat_missing_as_default = false},
},
autoplace_controls = {
["coal"] = {frequency = 0, size = 0, richness = 0},
["stone"] = {frequency = 0, size = 0, richness = 0},
["copper-ore"] = {frequency = 0, size = 0, richness = 0},
["iron-ore"] = {frequency = 0, size = 0, richness = 0},
["uranium-ore"] = {frequency = 0, size = 0, richness = 0},
["crude-oil"] = {frequency = 0, size = 0, richness = 0},
["trees"] = {frequency = 0, size = 0, richness = 0},
["enemy-base"] = {frequency = 0, size = 0, richness = 0}
},
}
local surface = game.create_surface("biter_battles", map_gen_settings)
surface.request_to_generate_chunks({0,0}, 2)
surface.force_generate_chunk_requests()
--Disable Nauvis
local surface = game.surfaces[1]
local map_gen_settings = surface.map_gen_settings
map_gen_settings.height = 3
map_gen_settings.width = 3
surface.map_gen_settings = map_gen_settings
for chunk in surface.get_chunks() do
surface.delete_chunk({chunk.x, chunk.y})
end
end
function Public.forces()
@ -136,6 +174,7 @@ function Public.forces()
for _, d in pairs(defs) do p.set_allows_action(d, true) end
global.target_entities = {}
global.rocket_silo = {}
global.spectator_rejoin_delay = {}
global.spy_fish_timeout = {}
@ -145,14 +184,20 @@ function Public.forces()
global.unit_spawners.south_biters = {}
global.active_biters = {}
global.unit_groups = {}
global.biter_raffle = {}
global.evo_raise_counter = 1
global.next_attack = "north"
if math.random(1,2) == 1 then global.next_attack = "south" end
global.bb_evolution = {}
global.bb_threat_income = {}
global.bb_threat = {}
global.chunks_mirrored = {}
global.terrain_gen = {}
global.terrain_gen.counter = 0
global.terrain_gen.chunk_mirror = {}
global.terrain_gen.size_of_chunk_mirror = 0
global.terrain_gen.chunk_copy = {}
global.terrain_gen.size_of_chunk_copy = 0
global.map_pregen_message_counter = {}
for _, force in pairs(game.forces) do
@ -161,9 +206,9 @@ function Public.forces()
game.forces[force.name].technologies["artillery-shell-speed-1"].enabled = false
game.forces[force.name].technologies["atomic-bomb"].enabled = false
game.forces[force.name].research_queue_enabled = true
global.target_entities[force.index] = {}
global.spy_fish_timeout[force.name] = 0
global.active_biters[force.name] = {}
global.biter_raffle[force.name] = {}
global.bb_evolution[force.name] = 0
global.bb_threat_income[force.name] = 0
global.bb_threat[force.name] = 0

View File

@ -3,15 +3,11 @@
require "on_tick_schedule"
local Biter_health_booster = require "modules.biter_health_booster"
local Ai = require "maps.biter_battles_v2.ai"
local Biters_landfill = require "maps.biter_battles_v2.biters_landfill"
local Chat = require "maps.biter_battles_v2.chat"
local Combat_balance = require "maps.biter_battles_v2.combat_balance"
local Functions = require "maps.biter_battles_v2.functions"
local Game_over = require "maps.biter_battles_v2.game_over"
local Gui = require "maps.biter_battles_v2.gui"
local Init = require "maps.biter_battles_v2.init"
local Map_info = require "maps.biter_battles_v2.map_info"
local Mirror_terrain = require "maps.biter_battles_v2.mirror_terrain"
local No_turret_creep = require "maps.biter_battles_v2.no_turret_creep"
local Team_manager = require "maps.biter_battles_v2.team_manager"
local Terrain = require "maps.biter_battles_v2.terrain"
@ -37,7 +33,7 @@ local function on_player_joined_game(event)
game.permissions.get_group("spectator").add_player(player)
end
Map_info.player_joined_game(player)
Functions.create_map_intro_button(player)
Team_manager.draw_top_toggle_button(player)
end
@ -47,32 +43,34 @@ local function on_gui_click(event)
if not element then return end
if not element.valid then return end
if Map_info.gui_click(player, element) then return end
if Functions.map_intro_click(player, element) then return end
Team_manager.gui_click(event)
end
local function on_research_finished(event)
Combat_balance.research_finished(event)
Functions.combat_balance(event)
end
local function on_console_chat(event)
Chat.share(event)
Functions.share_chat(event)
end
local function on_built_entity(event)
No_turret_creep.deny_building(event)
Functions.no_turret_creep(event)
Functions.add_target_entity(event.created_entity)
end
local function on_robot_built_entity(event)
No_turret_creep.deny_building(event)
Functions.no_turret_creep(event)
Terrain.deny_construction_bots(event)
Functions.add_target_entity(event.created_entity)
end
local function on_entity_died(event)
local entity = event.entity
if not entity.valid then return end
if Ai.subtract_threat(entity) then Gui.refresh_threat() end
if Biters_landfill.entity_died(entity) then return end
if Functions.biters_landfill(entity) then return end
Game_over.silo_death(event)
end
@ -152,7 +150,7 @@ end
local function on_chunk_generated(event)
Terrain.generate(event)
Mirror_terrain.add_chunks(event)
Mirror_terrain.add_chunk(event)
end
local function on_init()
@ -162,9 +160,35 @@ local function on_init()
Team_manager.init()
local surface = game.surfaces["biter_battles"]
surface.request_to_generate_chunks({x = 0, y = 0}, 1)
surface.force_generate_chunk_requests()
for y = 0, 576, 32 do
surface.request_to_generate_chunks({x = 80, y = y + 16}, 0)
surface.request_to_generate_chunks({x = 48, y = y + 16}, 0)
surface.request_to_generate_chunks({x = 16, y = y + 16}, 0)
surface.request_to_generate_chunks({x = -16, y = y - 16}, 0)
surface.request_to_generate_chunks({x = -48, y = y - 16}, 0)
surface.request_to_generate_chunks({x = -80, y = y - 16}, 0)
surface.request_to_generate_chunks({x = 80, y = y * -1 + 16}, 0)
surface.request_to_generate_chunks({x = 48, y = y * -1 + 16}, 0)
surface.request_to_generate_chunks({x = 16, y = y * -1 + 16}, 0)
surface.request_to_generate_chunks({x = -16, y = y * -1 - 16}, 0)
surface.request_to_generate_chunks({x = -48, y = y * -1 - 16}, 0)
surface.request_to_generate_chunks({x = -80, y = y * -1 - 16}, 0)
end
local surface = game.surfaces["bb_source"]
surface.request_to_generate_chunks({x = 0, y = 0}, 2)
surface.force_generate_chunk_requests()
surface.request_to_generate_chunks({x = 0, y = -256}, 8)
surface.force_generate_chunk_requests()
Terrain.generate_north_silo(surface)
Terrain.draw_spawn_area(surface)
Terrain.generate_additional_spawn_ore(surface)
Terrain.generate_silo(surface)
Terrain.draw_spawn_circle(surface)
end
local Event = require 'utils.event'

View File

@ -1,47 +0,0 @@
local Public = {}
local function create_map_intro_button(player)
if player.gui.top["map_intro_button"] then return end
local b = player.gui.top.add({type = "sprite-button", caption = "?", name = "map_intro_button", tooltip = "Map Info"})
b.style.font_color = {r=0.5, g=0.3, b=0.99}
b.style.font = "heading-1"
b.style.minimal_height = 38
b.style.minimal_width = 38
b.style.top_padding = 1
b.style.left_padding = 1
b.style.right_padding = 1
b.style.bottom_padding = 1
end
local function create_map_intro(player)
if player.gui.center["map_intro_frame"] then player.gui.center["map_intro_frame"].destroy() end
local frame = player.gui.center.add {type = "frame", name = "map_intro_frame", direction = "vertical"}
local frame = frame.add {type = "frame"}
local l = frame.add {type = "label", caption = {"biter_battles.map_info"}, name = "biter_battles_map_intro"}
l.style.single_line = false
l.style.font = "heading-2"
l.style.font_color = {r=0.7, g=0.6, b=0.99}
end
function Public.player_joined_game(player)
create_map_intro_button(player)
if player.online_time == 0 then
--create_map_intro(player)
end
end
function Public.gui_click(player, element)
if element.name == "close_map_intro_frame" then player.gui.center["map_intro_frame"].destroy() return true end
if element.name == "biter_battles_map_intro" then player.gui.center["map_intro_frame"].destroy() return true end
if element.name == "map_intro_button" then
if player.gui.center["map_intro_frame"] then
player.gui.center["map_intro_frame"].destroy()
return true
else
create_map_intro(player)
return true
end
end
end
return Public

View File

@ -3,22 +3,6 @@
local Tabs = require 'comfy_panel.main'
local functions = {
["map_settings_blueprint_toggle"] = function(event)
if event.element.switch_state == "left" then
game.permissions.get_group("Default").set_allows_action(defines.input_action.grab_blueprint_record, true)
game.permissions.get_group("Default").set_allows_action(defines.input_action.import_blueprint_string, true)
game.permissions.get_group("Default").set_allows_action(defines.input_action.import_blueprint, true)
global.bb_settings.blueprint_library_importing = true
game.print("The blueprint library has been enabled!")
else
game.permissions.get_group("Default").set_allows_action(defines.input_action.grab_blueprint_record, false)
game.permissions.get_group("Default").set_allows_action(defines.input_action.import_blueprint_string, false)
game.permissions.get_group("Default").set_allows_action(defines.input_action.import_blueprint, false)
global.bb_settings.blueprint_library_importing = false
game.print("The blueprint library has been disabled!")
end
end,
["map_settings_team_balancing_toggle"] = function(event)
if event.element.switch_state == "left" then
global.bb_settings.team_balancing = true
@ -80,13 +64,6 @@ local build_config_gui = (function (player, frame)
local switch_label_elements = {}
local label_elements = {}
line_elements[#line_elements + 1] = frame.add({type = "line"})
local switch_state = "right"
if global.bb_settings.blueprint_library_importing then switch_state = "left" end
local switch = add_switch(frame, switch_state, "map_settings_blueprint_toggle", "Blueprints", "Enables or disables the usage of blueprint strings and the library.")
if not admin then switch.ignored_by_interaction = true end
line_elements[#line_elements + 1] = frame.add({type = "line"})
local switch_state = "right"

View File

@ -1,6 +1,9 @@
-- Mirrored Terrain for Biter Battles -- by MewMew and Serennie
local Public = {}
local Functions = require "maps.biter_battles_v2.functions"
local table_remove = table.remove
local table_insert = table.insert
local direction_translation = {
[0] = 4,
[1] = 5,
@ -36,262 +39,251 @@ local cliff_orientation_translation = {
}
local entity_copy_functions = {
["tree"] = function(surface, entity, mirror_position)
if not surface.can_place_entity({name = entity.name, position = mirror_position}) then return end
entity.clone({position = mirror_position, surface = surface, force = "neutral"})
["tree"] = function(surface, entity, target_position, force_name)
if not surface.can_place_entity({name = entity.name, position = target_position}) then return end
entity.clone({position = target_position, surface = surface, force = "neutral"})
end,
["simple-entity"] = function(surface, entity, mirror_position)
local mirror_entity = {name = entity.name, position = mirror_position, direction = direction_translation[entity.direction]}
["simple-entity"] = function(surface, entity, target_position, force_name)
local mirror_entity = {name = entity.name, position = target_position, direction = direction_translation[entity.direction]}
if not surface.can_place_entity(mirror_entity) then return end
local mirror_entity = surface.create_entity(mirror_entity)
mirror_entity.graphics_variation = entity.graphics_variation
end,
["cliff"] = function(surface, entity, mirror_position)
local mirror_entity = {name = entity.name, position = mirror_position, cliff_orientation = cliff_orientation_translation[entity.cliff_orientation]}
["cliff"] = function(surface, entity, target_position, force_name)
local mirror_entity = {name = entity.name, position = target_position, cliff_orientation = cliff_orientation_translation[entity.cliff_orientation]}
if not surface.can_place_entity(mirror_entity) then return end
surface.create_entity(mirror_entity)
return
end,
["resource"] = function(surface, entity, mirror_position)
surface.create_entity({name = entity.name, position = mirror_position, amount = entity.amount})
["resource"] = function(surface, entity, target_position, force_name)
surface.create_entity({name = entity.name, position = target_position, amount = entity.amount})
end,
["corpse"] = function(surface, entity, mirror_position)
if game.tick > 900 then return end
surface.create_entity({name = entity.name, position = mirror_position})
["corpse"] = function(surface, entity, target_position, force_name)
surface.create_entity({name = entity.name, position = target_position})
end,
["unit-spawner"] = function(surface, entity, mirror_position)
local mirror_entity = {name = entity.name, position = mirror_position, direction = direction_translation[entity.direction], force = "south_biters"}
["unit-spawner"] = function(surface, entity, target_position, force_name)
local mirror_entity = {name = entity.name, position = target_position, direction = direction_translation[entity.direction], force = force_name .. "_biters"}
if not surface.can_place_entity(mirror_entity) then return end
table.insert(global.unit_spawners.south_biters, surface.create_entity(mirror_entity))
table_insert(global.unit_spawners[force_name .. "_biters"], surface.create_entity(mirror_entity))
end,
["turret"] = function(surface, entity, mirror_position)
local mirror_entity = {name = entity.name, position = mirror_position, direction = direction_translation[entity.direction], force = "south_biters"}
["turret"] = function(surface, entity, target_position, force_name)
local mirror_entity = {name = entity.name, position = target_position, direction = direction_translation[entity.direction], force = force_name .. "_biters"}
if not surface.can_place_entity(mirror_entity) then return end
surface.create_entity(mirror_entity)
end,
["rocket-silo"] = function(surface, entity, mirror_position)
if game.tick > 900 then return end
if surface.count_entities_filtered({name = "rocket-silo", area = {{mirror_position.x - 8, mirror_position.y - 8},{mirror_position.x + 8, mirror_position.y + 8}}}) > 0 then return end
global.rocket_silo["south"] = surface.create_entity({name = entity.name, position = mirror_position, direction = direction_translation[entity.direction], force = "south"})
global.rocket_silo["south"].minable = false
["rocket-silo"] = function(surface, entity, target_position, force_name)
if surface.count_entities_filtered({name = "rocket-silo", area = {{target_position.x - 8, target_position.y - 8},{target_position.x + 8, target_position.y + 8}}}) > 0 then return end
global.rocket_silo[force_name] = surface.create_entity({name = entity.name, position = target_position, direction = direction_translation[entity.direction], force = force_name})
global.rocket_silo[force_name].minable = false
Functions.add_target_entity(global.rocket_silo[force_name])
end,
["ammo-turret"] = function(surface, entity, mirror_position)
if game.tick > 900 then return end
if not surface.can_place_entity({name = entity.name, position = mirror_position, force = "south"}) then return end
entity.clone({position = mirror_position, surface = surface, force="south"})
["ammo-turret"] = function(surface, entity, target_position, force_name)
local direction = 0
if force_name == "south" then direction = 4 end
local mirror_entity = {name = entity.name, position = target_position, force = force_name, direction = direction}
if not surface.can_place_entity(mirror_entity) then return end
local e = surface.create_entity(mirror_entity)
Functions.add_target_entity(e)
local inventory = entity.get_inventory(defines.inventory.turret_ammo)
if inventory.is_empty() then return end
for name, count in pairs(inventory.get_contents()) do e.insert({name = name, count = count}) end
end,
["wall"] = function(surface, entity, mirror_position)
if game.tick > 900 then return end
entity.clone({position = mirror_position, surface = surface, force="south"})
["wall"] = function(surface, entity, target_position, force_name)
local e = entity.clone({position = target_position, surface = surface, force = force_name})
e.active = true
end,
["container"] = function(surface, entity, mirror_position)
if game.tick > 900 then return end
entity.clone({position = mirror_position, surface = surface, force="south"})
["container"] = function(surface, entity, target_position, force_name)
local e = entity.clone({position = target_position, surface = surface, force = force_name})
e.active = true
end,
["fish"] = function(surface, entity, mirror_position)
local mirror_entity = {name = entity.name, position = mirror_position, direction = direction_translation[entity.direction]}
["fish"] = function(surface, entity, target_position, force_name)
local mirror_entity = {name = entity.name, position = target_position}
if not surface.can_place_entity(mirror_entity) then return end
local e = surface.create_entity(mirror_entity)
end,
}
local function process_entity(surface, entity)
local function process_entity(surface, entity, force_name)
if not entity.valid then return end
if not entity_copy_functions[entity.type] then return end
local mirror_position = {x = entity.position.x * -1, y = entity.position.y * -1}
entity_copy_functions[entity.type](surface, entity, mirror_position)
local target_position
if force_name == "north" then
target_position = entity.position
else
target_position = {x = entity.position.x * -1, y = entity.position.y * -1}
end
entity_copy_functions[entity.type](surface, entity, target_position, force_name)
end
local function mirror_tiles(surface, source_area)
mirrored = {}
local i = 0
for x = source_area.left_top.x, source_area.left_top.x+31 do
for y = source_area.left_top.y, source_area.left_top.y+31 do
local tile = surface.get_tile(x, y)
mirrored[i] = {name = tile.name, position = {-x, -y - 1}}
i = i + 1
end
local function copy_chunk(chunk)
local target_surface = game.surfaces.biter_battles
local source_surface = game.surfaces.bb_source
local source_chunk_position = {chunk[1][1], chunk[1][2]}
local source_left_top = {x = source_chunk_position[1] * 32, y = source_chunk_position[2] * 32}
local source_area = {{source_left_top.x, source_left_top.y}, {source_left_top.x + 32, source_left_top.y + 32}}
local target_chunk_position = chunk[1]
local target_left_top = {x = target_chunk_position[1] * 32, y = target_chunk_position[2] * 32}
local target_area = {{target_left_top.x, target_left_top.y}, {target_left_top.x + 32, target_left_top.y + 32}}
if not source_surface.is_chunk_generated(source_chunk_position) then
source_surface.request_to_generate_chunks({x = source_left_top.x + 16, y = source_left_top.y + 16}, 0)
return
end
surface.set_tiles(mirrored, true)
end
local function clear_chunk(surface, area)
surface.destroy_decoratives{area=area}
if area.left_top.y > 32 or area.left_top.x > 32 or area.left_top.x < -32 then
for _, e in pairs(surface.find_entities_filtered({area = area})) do
if e.valid then
e.destroy()
end
end
else
for _, e in pairs(surface.find_entities_filtered({area = area})) do
if e.valid then
if e.name ~= "character" then
e.destroy()
end
end
if chunk[2] == 1 then
source_surface.clone_area({
source_area = source_area,
destination_area = target_area,
destination_surface = target_surface,
--destination_force = …,
clone_tiles = true,
clone_entities = false,
clone_decoratives = false,
clear_destination_entities = false,
clear_destination_decoratives = false,
expand_map = false
})
chunk[2] = chunk[2] + 1
return
end
if chunk[2] == 2 then
for _, entity in pairs(source_surface.find_entities_filtered({area = source_area})) do
process_entity(target_surface, entity, "north")
end
chunk[2] = chunk[2] + 1
return
end
end
local function mirror_chunk(surface, chunk)
--local x = chunk.x * -32 + 32
--local y = chunk.y * -32 + 32
--clear_chunk(surface, {left_top = {x = x, y = y}, right_bottom = {x = x + 32, y = y + 32}})
local chunk_area = {left_top = {x = chunk.x * 32, y = chunk.y * 32}, right_bottom = {x = chunk.x * 32 + 32, y = chunk.y * 32 + 32}}
if not surface.is_chunk_generated(chunk) then
surface.request_to_generate_chunks({x = chunk_area.left_top.x - 16, y = chunk_area.left_top.y - 16}, 1)
surface.force_generate_chunk_requests()
end
for _, tile in pairs(surface.find_tiles_filtered({area = chunk_area})) do
surface.set_tiles({{name = tile.name, position = {x = tile.position.x * -1, y = (tile.position.y * -1) - 1}}}, true)
end
for _, entity in pairs(surface.find_entities_filtered({area = chunk_area})) do
process_entity(surface, entity)
end
for _, decorative in pairs(surface.find_decoratives_filtered{area=chunk_area}) do
surface.create_decoratives{
check_collision=false,
decoratives={{name = decorative.decorative.name, position = {x = decorative.position.x * -1, y = (decorative.position.y * -1) - 1}, amount = decorative.amount}}
for _, decorative in pairs(source_surface.find_decoratives_filtered{area = source_area}) do
target_surface.create_decoratives{
check_collision = false,
decoratives = {{name = decorative.decorative.name, position = decorative.position, amount = decorative.amount}}
}
end
end
local function is_chunk_already_mirrored(chunk)
local index = chunk[1] .. "_" .. chunk[2]
if not global.chunks_mirrored[index] then global.chunks_mirrored[index] = true return false end
return true
end
local function add_work(work)
if not global.ctp then global.ctp = { continue = 1, last = 0 } end
local idx = global.ctp.last + 1
global.ctp[idx] = work
global.ctp.last = idx
end
function Public.add_chunks(event)
local surface = event.surface
if surface.name ~= "biter_battles" then return end
local function mirror_chunk(chunk)
local target_surface = game.surfaces.biter_battles
if event.area.left_top.y < 0 then
if game.tick == 0 then return end
local x = event.area.left_top.x / 32
local y = event.area.left_top.y / 32
if is_chunk_already_mirrored({x, y}) then return end
add_work({x = x, y = y, state = 1})
return
end
local source_surface = game.surfaces.bb_source
local source_chunk_position = {chunk[1][1] * -1 - 1, chunk[1][2] * -1 - 1}
local source_left_top = {x = source_chunk_position[1] * 32, y = source_chunk_position[2] * 32}
local source_area = {{source_left_top.x, source_left_top.y}, {source_left_top.x + 32, source_left_top.y + 32}}
surface.destroy_decoratives{ area = event.area }
-- Destroy biters here before they get active and attack other biters;
-- prevents threat decrease
for _, e in pairs(surface.find_entities_filtered{ area = event.area, force = "enemy" }) do
if e.valid then e.destroy() end
end
local x = (((event.area.left_top.x + 16) * -1) - 16) / 32
local y = (((event.area.left_top.y + 16) * -1) - 16) / 32
if is_chunk_already_mirrored({x, y}) then return end
add_work({x = x, y = y, state = 1})
end
function Public.ticking_work()
if not global.ctp then return end
local work = global.mws or 512 -- define the number of work per tick here (for copies, creations, deletions)
-- 136.5333 is the number of work needed to finish 4*(32*32) operations over 30 ticks (spreading a chunk copy over 30 ticks)
local w = 0
local i = global.ctp.continue
local c = global.ctp[i]
if not c then return end
local state = c.state
local d = c.data
local area = {
left_top = {x = c.x * 32, y = c.y * 32},
right_bottom = {x = c.x * 32 + 32, y = c.y * 32 + 32}
}
local inverted_area = {
left_top = { -area.right_bottom.x, -area.right_bottom.y },
right_bottom = { -area.left_top.x, -area.left_top.y }
}
local surface = game.surfaces["biter_battles"]
if not surface.is_chunk_generated(c) then
--game.print("Chunk not generated yet, requesting..")
surface.request_to_generate_chunks({x = area.left_top.x + 16, y = area.left_top.y + 16}, 0)
-- requeue
add_work(c)
global.ctp.continue = i+1
global.ctp[i] = nil
if not source_surface.is_chunk_generated(source_chunk_position) then
source_surface.request_to_generate_chunks({x = source_left_top.x + 16, y = source_left_top.y + 16}, 0)
return
end
local tasks = {
[1] = {
name = "Clearing entities",
list = function () return surface.find_entities_filtered({area = inverted_area, name = "character", invert = true}) end,
action = function (e) e.destroy() end
},
[2] = {},
[3] = {
name = "Entity copy",
list = function () return surface.find_entities_filtered({area = area}) end,
action = function (entity) process_entity(surface, entity) end
},
[4] = {
name = "Decorative copy",
list = function () return surface.find_decoratives_filtered{area = area} end,
action = function (decorative)
surface.create_decoratives{
check_collision = false,
decoratives = {{
name = decorative.decorative.name,
position = {x = decorative.position.x * -1, y = (decorative.position.y * -1) - 1},
amount = decorative.amount
}}
}
end
}
}
if c.state == 2 then
mirror_tiles(surface, area)
c.state = c.state + 1
c.data = nil
else
local task = tasks[c.state]
-- game.print(task.name)
d = d or task.list()
local last_idx = nil
for k, v in pairs(d) do
task.action(v)
d[k] = nil
last_idx = k
w = w + 1
if w > work then break end
end
local next_idx, _ = next(d, last_idx)
if next_idx == nil then
c.state = c.state + 1
c.data = nil
else
c.data = d
if chunk[2] == 1 then
for _, tile in pairs(source_surface.find_tiles_filtered({area = source_area})) do
target_surface.set_tiles({{name = tile.name, position = {x = tile.position.x * -1 - 1 , y = (tile.position.y * -1) - 1}}}, true)
end
chunk[2] = chunk[2] + 1
return
end
if chunk[2] == 2 then
for _, entity in pairs(source_surface.find_entities_filtered({area = source_area})) do
process_entity(target_surface, entity, "south")
end
chunk[2] = chunk[2] + 1
return
end
for _, decorative in pairs(source_surface.find_decoratives_filtered{area = source_area}) do
target_surface.create_decoratives{
check_collision = false,
decoratives = {{name = decorative.decorative.name, position = {x = (decorative.position.x * -1) - 1, y = (decorative.position.y * -1) - 1}, amount = decorative.amount}}
}
end
return true
end
if c.state == 5 then
-- game.print("Finished processing chunk "..c.x..","..c.y)
global.ctp.continue = i+1
global.ctp[i] = nil
else
global.ctp.continue = i
local function reveal_chunk(chunk)
local surface = game.surfaces.biter_battles
local chunk_position = chunk[1]
for _, force_name in pairs({"north", "south"}) do
local force = game.forces[force_name]
if force.is_chunk_charted(surface, chunk_position) then
force.chart(surface, {{chunk_position[1] * 32, chunk_position[2] * 32}, {chunk_position[1] * 32 + 31, chunk_position[2] * 32 + 31}})
end
end
end
function Public.add_chunk(event)
local surface = event.surface
if surface.name ~= "biter_battles" then return end
local left_top = event.area.left_top
local terrain_gen = global.terrain_gen
if left_top.y < 0 then
terrain_gen.size_of_chunk_copy = terrain_gen.size_of_chunk_copy + 1
terrain_gen.chunk_copy[terrain_gen.size_of_chunk_copy] = {{left_top.x / 32, left_top.y / 32}, 1}
else
terrain_gen.size_of_chunk_mirror = terrain_gen.size_of_chunk_mirror + 1
terrain_gen.chunk_mirror[terrain_gen.size_of_chunk_mirror] = {{left_top.x / 32, left_top.y / 32}, 1}
end
end
local function clear_source_surface(terrain_gen)
if terrain_gen.counter % 1024 == 1023 then
terrain_gen.counter = terrain_gen.counter + 1
local surface = game.surfaces.bb_source
local c = 0
for chunk in surface.get_chunks() do
surface.delete_chunk({chunk.x, chunk.y})
c = c + 1
end
print("Deleted " .. c .. " source surface chunks.")
end
end
local function north_work()
local terrain_gen = global.terrain_gen
for k, chunk in pairs(terrain_gen.chunk_copy) do
if copy_chunk(chunk) then
reveal_chunk(chunk)
table_remove(terrain_gen.chunk_copy, k)
terrain_gen.size_of_chunk_copy = terrain_gen.size_of_chunk_copy - 1
terrain_gen.counter = terrain_gen.counter + 1
end
break
end
clear_source_surface(terrain_gen)
end
local function south_work()
local terrain_gen = global.terrain_gen
for k, chunk in pairs(terrain_gen.chunk_mirror) do
if mirror_chunk(chunk) then
reveal_chunk(chunk)
table_remove(terrain_gen.chunk_mirror, k)
terrain_gen.size_of_chunk_mirror = terrain_gen.size_of_chunk_mirror - 1
terrain_gen.counter = terrain_gen.counter + 1
end
break
end
clear_source_surface(terrain_gen)
end
local works = {
[1] = north_work,
[3] = south_work,
}
function Public.ticking_work()
local work = works[game.tick % 4]
if not work then return end
work()
end
return Public

View File

@ -1,46 +0,0 @@
local Public = {}
local type_blacklist = {
["ammo-turret"] = true,
["artillery-turret"] = true,
["electric-turret"] = true,
["fluid-turret"] = true
}
function Public.deny_building(event)
local entity = event.created_entity
if not entity.valid then return end
if not type_blacklist[event.created_entity.type] then return end
local surface = event.created_entity.surface
local spawners = surface.find_entities_filtered({type = "unit-spawner", area = {{entity.position.x - 70, entity.position.y - 70}, {entity.position.x + 70, entity.position.y + 70}}})
if #spawners == 0 then return end
local allowed_to_build = true
for _, e in pairs(spawners) do
if (e.position.x - entity.position.x)^2 + (e.position.y - entity.position.y)^2 < 4096 then
allowed_to_build = false
break
end
end
if allowed_to_build then return end
if event.player_index then
game.players[event.player_index].insert({name = entity.name, count = 1})
else
local inventory = event.robot.get_inventory(defines.inventory.robot_cargo)
inventory.insert({name = entity.name, count = 1})
end
surface.create_entity({
name = "flying-text",
position = entity.position,
text = "Turret too close to spawner!",
color = {r=0.98, g=0.66, b=0.22}
})
entity.destroy()
end
return Public

View File

@ -1,124 +0,0 @@
local bb_config = require "maps.biter_battles_v2.config"
local event = require 'utils.event'
local function set_chunk_coords_old(radius)
global.chunk_gen_coords = {}
for r = radius, 1, -1 do
for x = r * -1, r - 1, 1 do
local pos = {x = x, y = r * -1}
if math.sqrt(pos.x ^ 2 + pos.y ^ 2) <= radius then table.insert(global.chunk_gen_coords, pos) end
end
for y = r * -1, r - 1, 1 do
local pos = {x = r, y = y}
if math.sqrt(pos.x ^ 2 + pos.y ^ 2) <= radius then table.insert(global.chunk_gen_coords, pos) end
end
for x = r, r * -1 + 1, -1 do
local pos = {x = x, y = r}
if math.sqrt(pos.x ^ 2 + pos.y ^ 2) <= radius then table.insert(global.chunk_gen_coords, pos) end
end
for y = r, r * -1 + 1, -1 do
local pos = {x = r * -1, y = y}
if math.sqrt(pos.x ^ 2 + pos.y ^ 2) <= radius then table.insert(global.chunk_gen_coords, pos) end
end
end
end
local function shrink_table()
local t = {}
for k, chunk in pairs(global.chunk_gen_coords) do
t[chunk.x .. "_" .. chunk.y] = {key = k, chunk = {x = chunk.x, y = chunk.y}}
end
global.chunk_gen_coords = {}
for k, chunk in pairs(t) do
global.chunk_gen_coords[#global.chunk_gen_coords + 1] = {x = chunk.x, y = chunk.y}
end
game.print(global.chunk_gen_coords[#global.chunk_gen_coords])
end
local vectors = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}
function set_chunk_coords(position, radius)
if not global.chunk_gen_coords then global.chunk_gen_coords = {} end
position.x = position.x - radius
position.y = position.y - radius
for r = radius, 1, -1 do
for _, v in pairs(vectors) do
for a = 1, r * 2 - 1, 1 do
position.x = position.x + v[1]
position.y = position.y + v[2]
global.chunk_gen_coords[#global.chunk_gen_coords + 1] = {x = position.x, y = position.y}
end
end
position.x = position.x + 1
position.y = position.y + 1
end
global.chunk_gen_coords[#global.chunk_gen_coords + 1] = {x = position.x, y = position.y}
end
local function draw_gui()
for _, player in pairs(game.connected_players) do
if global.map_generation_complete then
if player.gui.left["map_pregen"] then player.gui.left["map_pregen"].destroy() end
else
local caption = "Map is generating... " .. #global.chunk_gen_coords .. " chunks left. Please get comfy."
if player.gui.left["map_pregen"] then
player.gui.left["map_pregen"].caption = caption
else
local frame = player.gui.left.add({
type = "frame",
caption = caption,
name = "map_pregen"
})
frame.style.font_color = {r = 150, g = 0, b = 255}
frame.style.font = "heading-1"
frame.style.maximal_height = 42
end
end
end
end
local function process_chunk(surface)
if global.map_generation_complete then return end
if game.tick < 300 then return end
if not global.chunk_gen_coords then
set_chunk_coords({x = bb_config.map_pregeneration_radius * 2, y = 0}, bb_config.map_pregeneration_radius)
set_chunk_coords({x = bb_config.map_pregeneration_radius * -2, y = 0}, bb_config.map_pregeneration_radius)
set_chunk_coords({x = 0, y = 0}, bb_config.map_pregeneration_radius)
--shrink_table()
--set_chunk_coords()
--table.shuffle_table(global.chunk_gen_coords)
end
if #global.chunk_gen_coords == 0 then
global.map_generation_complete = true
draw_gui()
for _, player in pairs(game.connected_players) do
player.play_sound{path="utility/new_objective", volume_modifier=0.75}
end
return
end
if not game then return end
local surface = game.surfaces["biter_battles"]
if not surface then return end
local force_chunk_requests = 3
if bb_config.fast_pregen then force_chunk_requests = 16 end
for i = #global.chunk_gen_coords, 1, -1 do
if surface.is_chunk_generated(global.chunk_gen_coords[i]) then
--game.forces.player.chart(surface, {{(global.chunk_gen_coords[i].x * 32), (global.chunk_gen_coords[i].y * 32)}, {(global.chunk_gen_coords[i].x * 32) + 32, (global.chunk_gen_coords[i].y * 32) + 32}})
global.chunk_gen_coords[i] = nil
else
--game.forces.player.chart(surface, {{(global.chunk_gen_coords[i].x * 32), (global.chunk_gen_coords[i].y * 32)}, {(global.chunk_gen_coords[i].x * 32) + 32, (global.chunk_gen_coords[i].y * 32) + 32}})
surface.request_to_generate_chunks({x = (global.chunk_gen_coords[i].x * 32), y = (global.chunk_gen_coords[i].y * 32)}, 1)
surface.force_generate_chunk_requests()
global.chunk_gen_coords[i] = nil
force_chunk_requests = force_chunk_requests - 1
if force_chunk_requests <= 0 then
break
end
end
end
draw_gui()
end
return process_chunk

View File

@ -1,25 +0,0 @@
local function spy_fish(player)
if not player.character then return end
local duration_per_unit = 2700
local i2 = player.get_inventory(defines.inventory.character_main)
if not i2 then return end
local owned_fishes = i2.get_item_count("raw-fish")
owned_fishes = owned_fishes + i2.get_item_count("raw-fish")
if owned_fishes == 0 then
player.print("You have no fish in your inventory.",{ r=0.98, g=0.66, b=0.22})
else
local x = i2.remove({name="raw-fish", count=1})
if x == 0 then i2.remove({name="raw-fish", count=1}) end
local enemy_team = "south"
if player.force.name == "south" then enemy_team = "north" end
if global.spy_fish_timeout[player.force.name] - game.tick > 0 then
global.spy_fish_timeout[player.force.name] = global.spy_fish_timeout[player.force.name] + duration_per_unit
player.print(math.ceil((global.spy_fish_timeout[player.force.name] - game.tick) / 60) .. " seconds of enemy vision left.", { r=0.98, g=0.66, b=0.22})
else
game.print(player.name .. " sent a fish to spy on " .. enemy_team .. " team!", {r=0.98, g=0.66, b=0.22})
global.spy_fish_timeout[player.force.name] = game.tick + duration_per_unit
end
end
end
return spy_fish

View File

@ -1,11 +1,16 @@
local Public = {}
local BiterRaffle = require "functions.biter_raffle"
local bb_config = require "maps.biter_battles_v2.config"
local table_insert = table.insert
local math_floor = math.floor
local math_random = math.random
local math_abs = math.abs
local math_sqrt = math.sqrt
local GetNoise = require "utils.get_noise"
local simplex_noise = require 'utils.simplex_noise'.d2
local spawn_circle_size = 40
local spawn_circle_size = 39
local ores = {"copper-ore", "iron-ore", "stone", "coal"}
local rocks = {"sand-rock-big","sand-rock-big","rock-big","rock-big","rock-big","rock-big", "rock-huge"}
@ -17,6 +22,11 @@ for x = 0, 31, 1 do
end
local size_of_chunk_tile_vectors = #chunk_tile_vectors
local loading_chunk_vectors = {}
for k, v in pairs(chunk_tile_vectors) do
if v[1] == 0 or v[1] == 31 or v[2] == 0 or v[2] == 31 then table_insert(loading_chunk_vectors, v) end
end
local function shuffle(tbl)
local size = #tbl
for i = size, 1, -1 do
@ -69,14 +79,14 @@ local function create_mirrored_tile_chain(surface, tile, count, straightness)
for a = 1, count, 1 do
local tile_placed = false
if math.random(0, 100) > straightness then modifiers = shuffle(modifiers) end
if math_random(0, 100) > straightness then modifiers = shuffle(modifiers) end
for b = 1, 4, 1 do
local pos = {x = position.x + modifiers[b].x, y = position.y + modifiers[b].y}
if surface.get_tile(pos).name ~= tile.name then
surface.set_tiles({{name = "landfill", position = pos}}, true)
surface.set_tiles({{name = tile.name, position = pos}}, true)
surface.set_tiles({{name = "landfill", position = {pos.x * -1, (pos.y * -1) - 1}}}, true)
surface.set_tiles({{name = tile.name, position = {pos.x * -1, (pos.y * -1) - 1}}}, true)
--surface.set_tiles({{name = "landfill", position = {pos.x * -1, (pos.y * -1) - 1}}}, true)
--surface.set_tiles({{name = tile.name, position = {pos.x * -1, (pos.y * -1) - 1}}}, true)
position = {x = pos.x, y = pos.y}
tile_placed = true
break
@ -107,8 +117,8 @@ end
local function get_chunk_position(position)
local chunk_position = {}
position.x = math.floor(position.x, 0)
position.y = math.floor(position.y, 0)
position.x = math_floor(position.x, 0)
position.y = math_floor(position.y, 0)
for x = 0, 31, 1 do
if (position.x - x) % 32 == 0 then chunk_position.x = (position.x - x) / 32 end
end
@ -146,21 +156,14 @@ local function draw_noise_ore_patch(position, name, surface, radius, richness)
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 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
if distance_to_center < radius - math_abs(noise * radius * 0.85) and a > 1 then
if surface.can_place_entity({name = name, position = pos, amount = a}) then
surface.create_entity{name = name, position = pos, amount = a}
local mirror_pos = {x = pos.x * -1, y = pos.y * -1}
surface.create_entity{name = name, position = mirror_pos, amount = a}
for _, e in pairs(surface.find_entities_filtered({position = pos, name = {"wooden-chest", "stone-wall", "gun-turret"}})) do
e.destroy()
end
for _, e in pairs(surface.find_entities_filtered({position = mirror_pos, name = {"wooden-chest", "stone-wall", "gun-turret"}})) do
e.destroy()
end
end
end
end
@ -170,36 +173,20 @@ end
function is_within_spawn_circle(pos)
if math_abs(pos.x) > spawn_circle_size then return false end
if math_abs(pos.y) > spawn_circle_size then return false end
if math.sqrt(pos.x ^ 2 + pos.y ^ 2) > spawn_circle_size then return false end
if math_sqrt(pos.x ^ 2 + pos.y ^ 2) > spawn_circle_size then return false end
return true
end
local river_y_1 = bb_config.border_river_width * -1.5
local river_y_2 = bb_config.border_river_width * 1.5
local river_width_half = math.floor(bb_config.border_river_width * -0.5)
local river_width_half = math_floor(bb_config.border_river_width * -0.5)
function is_horizontal_border_river(pos)
if pos.y < river_y_1 then return false end
if pos.y > river_y_2 then return false end
if pos.y > -5 and pos.x > -5 and pos.x < 5 then return false end
if pos.y >= river_width_half - (math_abs(get_noise(1, pos)) * 4) then return true end
return false
end
local function generate_inner_spawn_circle(pos, distance_to_center, surface)
-- assert(distance_to_center < spawn_circle_size) == true
local tile = false
if distance_to_center < 7 then
tile = "sand-1"
elseif distance_to_center < 9.5 then
tile = "refined-concrete"
else
tile = "deepwater"
if math_random(1, 48) == 1 then surface.create_entity({name = "fish", position = pos}) end
end
surface.set_tiles({{name = tile, position = pos}}, true)
end
local function generate_starting_area(pos, distance_to_center, surface)
-- assert(distance_to_center >= spawn_circle_size) == true
local spawn_wall_radius = 116
@ -245,31 +232,37 @@ local function generate_starting_area(pos, distance_to_center, surface)
if surface.can_place_entity({name = "wooden-chest", position = pos}) and surface.can_place_entity({name = "coal", position = pos}) then
local noise_2 = get_noise(3, pos)
if noise_2 < 0.25 then
if noise_2 > -0.5 then
if noise_2 < 0.35 then
if noise_2 > -0.45 then
if distance_from_spawn_wall > -1.75 and distance_from_spawn_wall < 0 then
surface.create_entity({name = "stone-wall", position = pos, force = "north"})
local e = surface.create_entity({name = "stone-wall", position = pos, force = "neutral"})
e.active = false
end
else
if distance_from_spawn_wall > -1.95 and distance_from_spawn_wall < 0 then
surface.create_entity({name = "stone-wall", position = pos, force = "north"})
local e = surface.create_entity({name = "stone-wall", position = pos, force = "neutral"})
e.active = false
elseif distance_from_spawn_wall > 0 and distance_from_spawn_wall < 4.5 then
local name = "wooden-chest"
local r_max = math.floor(math.abs(distance_from_spawn_wall)) + 2
if math_random(1,3) == 1 then name = name .. "-remnants" end
if math_random(1,r_max) == 1 then surface.create_entity({name = name, position = pos, force = "north"}) end
local r_max = math_floor(math.abs(distance_from_spawn_wall)) + 2
if math_random(1,3) == 1 and not is_horizontal_border_river(pos) then name = name .. "-remnants" end
if math_random(1,r_max) == 1 then
local e = surface.create_entity({name = name, position = pos, force = "neutral"})
e.active = false
end
elseif distance_from_spawn_wall > -6 and distance_from_spawn_wall < -3 then
if math_random(1, 16) == 1 then
if surface.can_place_entity({name = "gun-turret", position = pos}) then
local t = surface.create_entity({name = "gun-turret", position = pos, force = "north"})
t.insert({name = "firearm-magazine", count = math_random(6,12)})
local e = surface.create_entity({name = "gun-turret", position = pos, force = "neutral"})
e.insert({name = "firearm-magazine", count = math_random(6,12)})
e.active = false
end
else
if math_random(1, 16) == 1 then
if math_random(1, 24) == 1 and not is_horizontal_border_river(pos) then
if surface.can_place_entity({name = "gun-turret", position = pos}) then
surface.create_entity({name = "gun-turret-remnants", position = pos, force = "north"})
surface.create_entity({name = "gun-turret-remnants", position = pos, force = "neutral"})
end
end
end
@ -279,75 +272,276 @@ local function generate_starting_area(pos, distance_to_center, surface)
end
end
local function generate_circle_spawn(event)
if global.bb_spawn_generated then return end
local surface = event.surface
local left_top_x = event.area.left_top.x
local left_top_y = event.area.left_top.y
if left_top_x < -160 then return end
if left_top_x > 160 then return end
if left_top_y < -160 then return end
local function generate_river(surface, left_top_x, left_top_y)
if left_top_y < -32 then return end
for x = 0, 31, 1 do
for y = 0, 31, 1 do
local pos = {x = left_top_x + x, y = left_top_y + y}
local distance_to_center = math.sqrt(pos.x ^ 2 + pos.y ^ 2)
if distance_to_center < spawn_circle_size then
generate_inner_spawn_circle(pos, distance_to_center, surface)
else
generate_starting_area(pos, distance_to_center, surface)
end
end
end
regenerate_decoratives(surface, event.area.left_top)
end
function Public.generate_north_silo(surface)
local pos = {x = -32 + math.random(0, 64), y = -72}
local mirror_position = {x = pos.x * -1, y = pos.y * -1}
for _, t in pairs(surface.find_tiles_filtered({area = {{pos.x - 6, pos.y - 6},{pos.x + 6, pos.y + 6}}, name = {"water", "deepwater"}})) do
surface.set_tiles({{name = get_replacement_tile(surface, t.position), position = t.position}})
end
for _, t in pairs(surface.find_tiles_filtered({area = {{mirror_position.x - 6, mirror_position.y - 6},{mirror_position.x + 6, mirror_position.y + 6}}, name = {"water", "deepwater"}})) do
surface.set_tiles({{name = get_replacement_tile(surface, t.position), position = t.position}})
end
global.rocket_silo["north"] = surface.create_entity({
name = "rocket-silo",
position = pos,
force = "north"
})
global.rocket_silo["north"].minable = false
for i = 1, 32, 1 do
create_mirrored_tile_chain(surface, {name = "stone-path", position = global.rocket_silo["north"].position}, 32, 10)
end
end
local function generate_river(event)
if event.area.left_top.y < -32 then return end
local surface = event.surface
local left_top_x = event.area.left_top.x
local left_top_y = event.area.left_top.y
for x = 0, 31, 1 do
for y = 0, 31, 1 do
local pos = {x = left_top_x + x, y = left_top_y + y}
local distance_to_center = math.sqrt(pos.x ^ 2 + pos.y ^ 2)
if is_horizontal_border_river(pos) then
local distance_to_center = math_sqrt(pos.x ^ 2 + pos.y ^ 2)
if is_horizontal_border_river(pos) and distance_to_center > spawn_circle_size - 2 then
surface.set_tiles({{name = "deepwater", position = pos}})
if math_random(1, 64) == 1 then surface.create_entity({name = "fish", position = pos}) end
if math_random(1, 64) == 1 then
local e = surface.create_entity({name = "fish", position = pos})
e.active = false
end
end
end
end
end
local function generate_potential_spawn_ore(surface)
local scrap_vectors = {}
for x = -5, 5, 1 do
for y = -5, 5, 1 do
if math_sqrt(x^2 + y^2) <= 5 then
scrap_vectors[#scrap_vectors + 1] = {x, y}
end
end
end
local size_of_scrap_vectors = #scrap_vectors
local function generate_extra_worm_turrets(surface, left_top)
local chunk_distance_to_center = math_sqrt(left_top.x ^ 2 + left_top.y ^ 2)
if bb_config.bitera_area_distance > chunk_distance_to_center then return end
local amount = (chunk_distance_to_center - bb_config.bitera_area_distance) * 0.0005
if amount < 0 then return end
local floor_amount = math_floor(amount)
local r = math.round(amount - floor_amount, 3) * 1000
if math_random(0, 999) <= r then floor_amount = floor_amount + 1 end
if floor_amount > 64 then floor_amount = 64 end
for _ = 1, floor_amount, 1 do
local worm_turret_name = BiterRaffle.roll("worm", chunk_distance_to_center * 0.00015)
local v = chunk_tile_vectors[math_random(1, size_of_chunk_tile_vectors)]
local position = surface.find_non_colliding_position(worm_turret_name, {left_top.x + v[1], left_top.y + v[2]}, 8, 1)
if position then
local worm = surface.create_entity({name = worm_turret_name, position = position, force = "enemy"})
worm.active = false
-- add some scrap piles
if math_random(1,2) == 1 then
for c = 1, math_random(2,12), 1 do
local vector = scrap_vectors[math_random(1, size_of_scrap_vectors)]
local position = {position.x + vector[1], position.y + vector[2]}
if surface.can_place_entity({name = "mineable-wreckage", position = position, force = "neutral"}) then
local e = surface.create_entity({name = "mineable-wreckage", position = position, force = "neutral"})
e.active = false
end
end
end
end
end
end
local bitera_area_distance = bb_config.bitera_area_distance * -1
local biter_area_angle = 0.45
local function is_biter_area(position)
local a = bitera_area_distance - (math_abs(position.x) * biter_area_angle)
if position.y - 70 > a then return false end
if position.y + 70 < a then return true end
if position.y + (get_noise(3, position) * 64) > a then return false end
return true
end
local function draw_biter_area(surface, left_top_x, left_top_y)
if not is_biter_area({x = left_top_x, y = left_top_y - 96}) then return end
local seed = game.surfaces[1].map_gen_settings.seed
local out_of_map = {}
local tiles = {}
local i = 1
for x = 0, 31, 1 do
for y = 0, 31, 1 do
local position = {x = left_top_x + x, y = left_top_y + y}
if is_biter_area(position) then
local index = math_floor(GetNoise("bb_biterland", position, seed) * 48) % 7 + 1
out_of_map[i] = {name = "out-of-map", position = position}
tiles[i] = {name = "dirt-" .. index, position = position}
i = i + 1
end
end
end
surface.set_tiles(out_of_map, false)
surface.set_tiles(tiles, true)
for _ = 1, 4, 1 do
local v = chunk_tile_vectors[math_random(1, size_of_chunk_tile_vectors)]
local position = {x = left_top_x + v[1], y = left_top_y + v[2]}
if is_biter_area(position) and surface.can_place_entity({name = "spitter-spawner", position = position}) then
if math_random(1, 4) == 1 then
local e = surface.create_entity({name = "spitter-spawner", position = position, force = "enemy"})
e.active = false
else
local e = surface.create_entity({name = "biter-spawner", position = position, force = "enemy"})
e.active = false
end
end
end
local e = (math_abs(left_top_y) - bb_config.bitera_area_distance) * 0.0005
for _ = 1, math_random(3, 6), 1 do
local v = chunk_tile_vectors[math_random(1, size_of_chunk_tile_vectors)]
local position = {x = left_top_x + v[1], y = left_top_y + v[2]}
local worm_turret_name = BiterRaffle.roll("worm", e)
if is_biter_area(position) and surface.can_place_entity({name = worm_turret_name, position = position}) then
surface.create_entity({name = worm_turret_name, position = position, force = "enemy"})
end
end
for _ = 1, math_random(8, 16), 1 do
local v = chunk_tile_vectors[math_random(1, size_of_chunk_tile_vectors)]
local position = {x = left_top_x + v[1], y = left_top_y + v[2]}
if is_biter_area(position) and surface.can_place_entity({name = "mineable-wreckage", position = position}) then
surface.create_entity({name = "mineable-wreckage", position = position, force = "neutral"})
end
end
end
local function mixed_ore(surface, left_top_x, left_top_y)
local seed = game.surfaces[1].map_gen_settings.seed
local noise = GetNoise("bb_ore", {x = left_top_x + 16, y = left_top_y + 16}, seed)
--Draw noise text values to determine which chunks are valid for mixed ore.
--rendering.draw_text{text = noise, surface = game.surfaces.biter_battles, target = {x = left_top_x + 16, y = left_top_y + 16}, color = {255, 255, 255}, scale = 2, font = "default-game"}
--Skip chunks that are too far off the ore noise value.
if noise < 0.45 then return end
--Draw the mixed ore patches.
for x = 0, 31, 1 do
for y = 0, 31, 1 do
local pos = {x = left_top_x + x, y = left_top_y + y}
if surface.can_place_entity({name = "iron-ore", position = pos}) then
local noise = GetNoise("bb_ore", pos, seed)
if noise > 0.75 then
local amount = math_random(1250, 1500) + math_sqrt(pos.x ^ 2 + pos.y ^ 2) * 2
local i = math_floor(noise * 50) % 4 + 1
surface.create_entity({name = ores[i], position = pos, amount = amount})
end
end
end
end
if left_top_y == -32 and math_abs(left_top_x) <= 32 then
for _, e in pairs(surface.find_entities_filtered({area = {{-12, -12},{12, 12}}})) do e.destroy() end
end
end
function Public.generate(event)
local surface = event.surface
local left_top = event.area.left_top
local left_top_x = left_top.x
local left_top_y = left_top.y
if surface.name == "biter_battles" then
local tiles = {}
if math_abs(left_top_x) > 64 or math_abs(left_top_y) > 64 then
for k, v in pairs(loading_chunk_vectors) do tiles[k] = {name = "out-of-map", position = {left_top_x + v[1], left_top_y + v[2]}} end
end
surface.set_tiles(tiles, false)
--[[
if math_abs(left_top.x) > 64 then
if left_top.y == 0 then
local tiles = {}
local i = 1
for x = 0, 31, 1 do
for y = 0, 1, 1 do
tiles[i] = {name = "deepwater", position = {x = left_top.x + x, y = left_top.y + y}}
i = i + 1
end
end
surface.set_tiles(tiles, false)
end
if left_top.y == -32 then
local tiles = {}
local i = 1
for x = 0, 31, 1 do
for y = 30, 31, 1 do
tiles[i] = {name = "deepwater", position = {x = left_top.x + x, y = left_top.y + y}}
i = i + 1
end
end
surface.set_tiles(tiles, false)
end
end
]]
return
end
if surface.name ~= "bb_source" then return end
if left_top_y >= 0 then
surface.destroy_decoratives({area = event.area})
return
end
mixed_ore(surface, left_top_x, left_top_y)
generate_river(surface, left_top_x, left_top_y)
draw_biter_area(surface, left_top_x, left_top_y)
generate_extra_worm_turrets(surface, left_top)
end
function Public.draw_spawn_circle(surface)
local tiles = {}
for x = spawn_circle_size * -1, -1, 1 do
for y = spawn_circle_size * -1, -1, 1 do
local pos = {x = x, y = y}
local distance_to_center = math_sqrt(pos.x ^ 2 + pos.y ^ 2)
if distance_to_center <= spawn_circle_size then
table_insert(tiles, {name = "deepwater", position = pos})
if distance_to_center < 9.5 then
table_insert(tiles, {name = "refined-concrete", position = pos})
if distance_to_center < 7 then
table_insert(tiles, {name = "sand-1", position = pos})
end
-- else
--
end
end
end
end
for i = 1, #tiles, 1 do
table_insert(tiles, {name = tiles[i].name, position = {tiles[i].position.x * -1 - 1, tiles[i].position.y}})
end
surface.set_tiles(tiles, true)
for i = 1, #tiles, 1 do
if tiles[i].name == "deepwater" then
if math_random(1, 48) == 1 then
local e = surface.create_entity({name = "fish", position = tiles[i].position})
e.active = false
end
end
end
end
function Public.draw_spawn_area(surface)
local chunk_r = 4
local r = chunk_r * 32
for x = r * -1, r, 1 do
for y = r * -1, -4, 1 do
local pos = {x = x, y = y}
local distance_to_center = math_sqrt(pos.x ^ 2 + pos.y ^ 2)
generate_starting_area(pos, distance_to_center, surface)
end
end
surface.destroy_decoratives({})
surface.regenerate_decorative()
end
function Public.generate_additional_spawn_ore(surface)
local r = 130
local area = {{r * -1, r * -1}, {r, 0}}
local ores = {}
@ -369,204 +563,41 @@ local function generate_potential_spawn_ore(surface)
end
end
local scrap_vectors = {}
for x = -5, 5, 1 do
for y = -5, 5, 1 do
if math.sqrt(x^2 + y^2) <= 5 then
scrap_vectors[#scrap_vectors + 1] = {x, y}
end
function Public.generate_silo(surface)
local pos = {x = -32 + math_random(0, 64), y = -72}
local mirror_position = {x = pos.x * -1, y = pos.y * -1}
for _, t in pairs(surface.find_tiles_filtered({area = {{pos.x - 6, pos.y - 6},{pos.x + 6, pos.y + 6}}, name = {"water", "deepwater"}})) do
surface.set_tiles({{name = get_replacement_tile(surface, t.position), position = t.position}})
end
end
local size_of_scrap_vectors = #scrap_vectors
local function generate_extra_worm_turrets(surface, left_top)
local chunk_distance_to_center = math.sqrt(left_top.x ^ 2 + left_top.y ^ 2)
if bb_config.bitera_area_distance > chunk_distance_to_center then return end
local amount = (chunk_distance_to_center - bb_config.bitera_area_distance) * 0.0005
if amount < 0 then return end
local floor_amount = math.floor(amount)
local r = math.round(amount - floor_amount, 3) * 1000
if math_random(0, 999) <= r then floor_amount = floor_amount + 1 end
if floor_amount > 64 then floor_amount = 64 end
for _ = 1, floor_amount, 1 do
local worm_turret_name = BiterRaffle.roll("worm", chunk_distance_to_center * 0.0001)
local v = chunk_tile_vectors[math_random(1, size_of_chunk_tile_vectors)]
local position = surface.find_non_colliding_position(worm_turret_name, {left_top.x + v[1], left_top.y + v[2]}, 8, 1)
if position then
local worm = surface.create_entity({name = worm_turret_name, position = position, force = "north_biters"})
-- add some scrap piles
if math_random(1,2) == 1 then
for c = 1, math_random(2,12), 1 do
local vector = scrap_vectors[math_random(1, size_of_scrap_vectors)]
local position = {position.x + vector[1], position.y + vector[2]}
if surface.can_place_entity({name = "mineable-wreckage", position = position, force = "neutral"}) then
surface.create_entity({name = "mineable-wreckage", position = position, force = "neutral"})
end
end
end
end
end
end
local bitera_area_distance = bb_config.bitera_area_distance * -1
local biter_area_angle = 0.45
local function is_biter_area(position)
if position.y - 96 > bitera_area_distance - (math_abs(position.x) * biter_area_angle) then return false end
if position.y + 96 < bitera_area_distance - (math_abs(position.x) * biter_area_angle) then return true end
if position.y + (get_noise(3, position) * 64) > bitera_area_distance - (math_abs(position.x) * biter_area_angle) then return false end
return true
end
local function draw_biter_area(surface, left_top)
local left_top_x = left_top.x
local left_top_y = left_top.y
if left_top_y > bb_config.bitera_area_distance * -1 + 32 then return end
local out_of_map = {}
local tiles = {}
local i = 1
for x = 0, 31, 1 do
for y = 0, 31, 1 do
local position = {x = left_top_x + x, y = left_top_y + y}
if is_biter_area(position) then
local noise_index = math_floor(math_abs(get_noise(3, position)) * 7) + 1
if noise_index > 7 then noise_index = 7 end
out_of_map[i] = {name = "out-of-map", position = position}
tiles[i] = {name = "dirt-" .. noise_index, position = position}
i = i + 1
end
end
for _, t in pairs(surface.find_tiles_filtered({area = {{mirror_position.x - 6, mirror_position.y - 6},{mirror_position.x + 6, mirror_position.y + 6}}, name = {"water", "deepwater"}})) do
surface.set_tiles({{name = get_replacement_tile(surface, t.position), position = t.position}})
end
surface.set_tiles(out_of_map, false)
surface.set_tiles(tiles, true)
for _ = 1, 4, 1 do
local v = chunk_tile_vectors[math_random(1, size_of_chunk_tile_vectors)]
local position = {x = left_top_x + v[1], y = left_top_y + v[2]}
if is_biter_area(position) and surface.can_place_entity({name = "spitter-spawner", position = position}) then
if math_random(1, 4) == 1 then
table.insert(global.unit_spawners.north_biters, surface.create_entity({name = "spitter-spawner", position = position, force = "north_biters"}))
else
table.insert(global.unit_spawners.north_biters, surface.create_entity({name = "biter-spawner", position = position, force = "north_biters"}))
end
end
end
local silo = surface.create_entity({
name = "rocket-silo",
position = pos,
force = "neutral"
})
silo.minable = false
silo.active = false
local e = (math_abs(left_top_y) - bb_config.bitera_area_distance) * 0.0005
for _ = 1, math_random(3, 6), 1 do
local v = chunk_tile_vectors[math_random(1, size_of_chunk_tile_vectors)]
local position = {x = left_top_x + v[1], y = left_top_y + v[2]}
local worm_turret_name = BiterRaffle.roll("worm", e)
if is_biter_area(position) and surface.can_place_entity({name = worm_turret_name, position = position}) then
surface.create_entity({name = worm_turret_name, position = position, force = "north_biters"})
end
for i = 1, 32, 1 do
create_mirrored_tile_chain(surface, {name = "stone-path", position = silo.position}, 32, 10)
end
for _ = 1, math_random(8, 16), 1 do
local v = chunk_tile_vectors[math_random(1, size_of_chunk_tile_vectors)]
local position = {x = left_top_x + v[1], y = left_top_y + v[2]}
if is_biter_area(position) and surface.can_place_entity({name = "mineable-wreckage", position = position}) then
surface.create_entity({name = "mineable-wreckage", position = position, force = "neutral"})
local p = silo.position
for _, entity in pairs(surface.find_entities({{p.x - 4, p.y - 4}, {p.x + 4, p.y + 4}})) do
if entity.type == "simple-entity" or entity.type == "tree" or entity.type == "resource" then
entity.destroy()
end
end
end
local function mixed_ore(event)
local surface = event.surface
local left_top_x = event.area.left_top.x
local left_top_y = event.area.left_top.y
--Draw noise text values to determine which chunks are valid for mixed ore.
--rendering.draw_text{text = get_noise(1, {x = left_top_x + 16, y = left_top_y + 16}), surface = surface, target = {x = left_top_x + 16, y = left_top_y + 16}, color = {255, 255, 255}, time_to_live = 3600, scale = 2, font = "default-game"}
--Skip chunks that are too far off the ore noise value.
if get_noise(1, {x = left_top_x + 16, y = left_top_y + 16}) < 0.52 then return end
--Draw the mixed ore patches.
for x = 0, 31, 1 do
for y = 0, 31, 1 do
local pos = {x = left_top_x + x, y = left_top_y + y}
if surface.can_place_entity({name = "iron-ore", position = pos}) then
local noise = get_noise(1, pos)
if noise > 0.81 then
local amount = math_random(1250, 1500) + math.sqrt(pos.x ^ 2 + pos.y ^ 2) * 1.1
local m = (noise - 0.75) * 16
amount = amount * m
local i = math.ceil(math.abs(noise * 35)) % 4
if i == 0 then i = 4 end
surface.create_entity({name = ores[i], position = pos, amount = amount})
end
end
end
end
end
function Public.generate(event)
if event.area.left_top.y >= 0 then return end
local surface = event.surface
local left_top = event.area.left_top
if surface.name ~= "biter_battles" then return end
for _, e in pairs(surface.find_entities_filtered({area = event.area, force = "enemy"})) do
surface.create_entity({name = e.name, position = e.position, force = "north_biters", direction = e.direction})
e.destroy()
end
mixed_ore(event)
generate_river(event)
generate_circle_spawn(event)
draw_biter_area(surface, left_top)
--[[
if bb_config.builders_area then
for _, t in pairs(surface.find_tiles_filtered({area = event.area, name = {"water", "deepwater"}})) do
builders_area_process_tile(t, surface)
end
for _, e in pairs(surface.find_entities_filtered({area = event.area})) do
builders_area_process_entity(e)
end
end
]]
generate_extra_worm_turrets(surface, left_top)
if global.bb_spawn_generated then return end
if game.tick > 0 then
generate_potential_spawn_ore(surface)
local area = {{-10,-10},{10,10}}
for _, e in pairs(surface.find_entities_filtered({area = area})) do
if e.name ~= "character" then e.destroy() end
end
surface.destroy_decoratives({area = area})
for _, silo in pairs(global.rocket_silo) do
for _, entity in pairs(surface.find_entities({{silo.position.x - 4, silo.position.y - 4}, {silo.position.x + 4, silo.position.y + 4}})) do
if entity.type == "simple-entity" or entity.type == "tree" or entity.type == "resource" then
entity.destroy()
end
end
end
global.bb_spawn_generated = true
end
end
--Landfill Restriction
function Public.restrict_landfill(surface, inventory, tiles)
for _, t in pairs(tiles) do
local distance_to_center = math.sqrt(t.position.x ^ 2 + t.position.y ^ 2)
local distance_to_center = math_sqrt(t.position.x ^ 2 + t.position.y ^ 2)
local check_position = t.position
if check_position.y > 0 then check_position = {x = check_position.x * -1, y = (check_position.y * -1) - 1} end
if is_horizontal_border_river(check_position) or distance_to_center < spawn_circle_size then

View File

@ -3,12 +3,16 @@ local simplex_noise = require 'utils.simplex_noise'.d2
require "modules.satellite_score"
require "modules.biter_noms_you"
require "modules.dangerous_goods"
require "modules.biters_avoid_damage"
require "modules.dynamic_landfill"
require "modules.biters_double_damage"
require "modules.spawners_contain_biters"
require "modules.splice_double"
local math_random = math.random
local math_floor = math.floor
local math_abs = math.abs
local math_sqrt = math.sqrt
local LootRaffle = require "functions.loot_raffle"
local function get_noise(name, pos)
local seed = game.surfaces[1].map_gen_settings.seed
local noise_seed_add = 25000
@ -52,10 +56,14 @@ local function process_tile(surface, pos)
if surface.can_place_entity({name = "wooden-chest", position = pos, force = "neutral"}) then
local e = surface.create_entity({name = "wooden-chest", position = pos, force = "neutral"})
if noise_2 > -0.85 and noise_2 < 0.85 then return end
e.insert({name = global.loot[math.random(1, #global.loot)], count = math.random(1, 8)})
if math_abs(noise_2) > 0.76 or math_random(1, 32) == 1 then
local budget = math_sqrt(pos.x ^ 2 + pos.y ^ 2) + 1
local item_stacks = LootRaffle.roll(budget, 16)
for _, item_stack in pairs(item_stacks) do
e.insert(item_stack)
end
end
end
end
@ -93,75 +101,11 @@ local function on_player_joined_game(event)
end
end
local blacklist = {
["atomic-bomb"] = true,
["battery-mk2-equipment"] = true,
["blueprint"] = true,
["blueprint-book"] = true,
["centrifuge"] = true,
["compilatron-chest"] = true,
["copy-paste-tool"] = true,
["cut-paste-tool"] = true,
["deconstruction-planner"] = true,
["dummy-steel-axe"] = true,
["effectivity-module-2"] = true,
["effectivity-module-3"] = true,
["electric-energy-interface"] = true,
["energy-shield-equipment"] = true,
["energy-shield-mk2-equipment"] = true,
["escape-pod-assembler"] = true,
["escape-pod-lab"] = true,
["escape-pod-power"] = true,
["fusion-reactor-equipment"] = true,
["heat-exchanger"] = true,
["heat-interface"] = true,
["heat-pipe"] = true,
["hidden-electric-energy-interface"] = true,
["infinity-chest"] = true,
["infinity-pipe"] = true,
["laser-turret"] = true,
["nuclear-reactor"] = true,
["oil-refinery"] = true,
["player-port"] = true,
["pollution"] = true,
["power-armor"] = true,
["power-armor-mk2"] = true,
["productivity-module-2"] = true,
["productivity-module-3"] = true,
["rocket-silo"] = true,
["satellite"] = true,
["selection-tool"] = true,
["simple-entity-with-force"] = true,
["simple-entity-with-owner"] = true,
["speed-module-2"] = true,
["speed-module-3"] = true,
["steam-turbine"] = true,
["tank"] = true,
["upgrade-planner"] = true
}
local function on_init()
local surface = game.surfaces[1]
game.forces["player"].set_spawn_position(get_spawn_position(surface), surface)
global.loot = {}
for _, i in pairs(game.item_prototypes) do
if not blacklist[i.name] then
global.loot[#global.loot + 1] = i.name
end
end
end
local function on_entity_died(event)
if not event.entity.valid then return end
if event.entity.type == "tree" then
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
end
end
event.on_init(on_init)
event.add(defines.events.on_chunk_generated, on_chunk_generated)
event.add(defines.events.on_entity_died, on_entity_died)
event.add(defines.events.on_player_joined_game, on_player_joined_game)

View File

@ -10,12 +10,6 @@ local math_sqrt = math.sqrt
local math_floor = math.floor
local function add_enemy_units(surface, room)
for _, tile in pairs(room.room_border_tiles) do
if math_random(1, 2) == 1 then
local name = BiterRaffle.roll("spitter", Functions.get_dungeon_evolution_factor() * 1.5)
local unit = surface.create_entity({name = name, position = tile.position, force = "enemy"})
end
end
for _, tile in pairs(room.room_tiles) do
if math_random(1, 2) == 1 then
local name = BiterRaffle.roll("spitter", Functions.get_dungeon_evolution_factor() * 1.5)

View File

@ -41,6 +41,7 @@ function Public.common_loot_crate(surface, position)
for _, item_stack in pairs(item_stacks) do
container.insert(item_stack)
end
container.minable = false
end
function Public.uncommon_loot_crate(surface, position)
@ -49,6 +50,7 @@ function Public.uncommon_loot_crate(surface, position)
for _, item_stack in pairs(item_stacks) do
container.insert(item_stack)
end
container.minable = false
end
function Public.rare_loot_crate(surface, position)
@ -57,6 +59,7 @@ function Public.rare_loot_crate(surface, position)
for _, item_stack in pairs(item_stacks) do
container.insert(item_stack)
end
container.minable = false
end
function Public.epic_loot_crate(surface, position)
@ -65,6 +68,7 @@ function Public.epic_loot_crate(surface, position)
for _, item_stack in pairs(item_stacks) do
container.insert(item_stack)
end
container.minable = false
end
function Public.crash_site_chest(surface, position)

View File

@ -1,7 +1,7 @@
-- Deep dark dungeons by mewmew --
require "modules.mineable_wreckage_yields_scrap"
require "modules.sticky_landfill"
require "modules.satellite_score"
local MapInfo = require "modules.map_info"
local Room_generator = require "functions.room_generator"
@ -46,9 +46,8 @@ local function get_biome(position)
local seed = game.surfaces[1].map_gen_settings.seed
local seed_addition = 100000
local a = 1
if Get_noise("dungeons", position, seed + seed_addition * a) > 0.65 then return "glitch" end
local a = 1
if Get_noise("dungeons", position, seed + seed_addition * a) > 0.66 then return "glitch" end
a = a + 1
if Get_noise("dungeons", position, seed + seed_addition * a) > 0.60 then return "doom" end
a = a + 1

View File

@ -13,7 +13,6 @@ local RPG = require "modules.rpg"
require "modules.wave_defense.main"
require "modules.biters_yield_coins"
require "modules.no_deconstruction_of_neutral_entities"
require "modules.no_solar"
require "modules.shotgun_buff"
require "modules.explosives"
require "modules.mineable_wreckage_yields_scrap"

View File

@ -1,6 +1,6 @@
-- territorial control by Gerkiz
require "territorial_control_intro"
local Map = require "modules.map_info"
require "on_tick_schedule"
require "modules.fish_respawner"
global.fish_respawner_water_tiles_per_fish = 16
@ -16,13 +16,10 @@ require "modules.biters_yield_coins"
require "modules.mineable_wreckage_yields_scrap"
local shapes = require "tools.shapes"
local event = require 'utils.event'
local map_functions = require "tools.map_functions"
local Event = require 'utils.event'
local unearthing_worm = require "functions.unearthing_worm"
local unearthing_biters = require "functions.unearthing_biters"
local tick_tack_trap = require "functions.tick_tack_trap"
local create_entity_chain = require "functions.create_entity_chain"
local create_tile_chain = require "functions.create_tile_chain"
local map_functions = require "tools.map_functions"
local simplex_noise = require 'utils.simplex_noise'
simplex_noise = simplex_noise.d2
@ -74,9 +71,8 @@ local biters_in_the_void = {
[18] = {"big-biter","behemoth-biter","behemoth-biter","behemoth-biter","behemoth-biter","behemoth-spitter"},
[19] = {"behemoth-biter","behemoth-biter","behemoth-biter","behemoth-biter","behemoth-biter","behemoth-spitter"},
[20] = {"behemoth-biter","behemoth-biter","behemoth-biter","behemoth-biter","behemoth-spitter","behemoth-spitter"}
}
}
local ore_spill_raffle = {"iron-ore","iron-ore","iron-ore","iron-ore","copper-ore","copper-ore","copper-ore","coal","coal"}
local ore_spawn_raffle = {
"iron-ore","iron-ore","iron-ore","iron-ore", "iron-ore","iron-ore","iron-ore","iron-ore", "iron-ore","iron-ore",
"copper-ore","copper-ore","copper-ore", "copper-ore","copper-ore","copper-ore", "copper-ore",
@ -90,18 +86,18 @@ local rock_raffle = {"sand-rock-big","sand-rock-big", "rock-big","rock-big","roc
local tree_raffle = {"tree-02-red","tree-09-red", "tree-02-red","tree-09-red","tree-02-red","tree-09-red","tree-02-red","tree-09-red","tree-02-red","tree-09-red","tree-02-red"}
local function secret_shop(pos, surface)
local secret_market_items = {
local secret_market_items = {
{price = {{"coin", math_random(75,125)}}, offer = {type = 'give-item', item = 'combat-shotgun'}},
{price = {{"coin", math_random(40,60)}}, offer = {type = 'give-item', item = 'rocket-launcher'}},
{price = {{"coin", math_random(40,60)}}, offer = {type = 'give-item', item = 'rocket-launcher'}},
{price = {{"coin", math_random(1,2)}}, offer = {type = 'give-item', item = 'piercing-rounds-magazine'}},
{price = {{"coin", math_random(3,6)}}, offer = {type = 'give-item', item = 'uranium-rounds-magazine'}},
{price = {{"coin", math_random(3,6)}}, offer = {type = 'give-item', item = 'uranium-rounds-magazine'}},
{price = {{"coin", math_random(1,4)}}, offer = {type = 'give-item', item = 'piercing-shotgun-shell'}},
{price = {{"coin", math_random(1,2)}}, offer = {type = 'give-item', item = 'rocket'}},
{price = {{"coin", math_random(2,3)}}, offer = {type = 'give-item', item = 'explosive-rocket'}},
{price = {{"coin", math_random(2,3)}}, offer = {type = 'give-item', item = 'explosive-rocket'}},
{price = {{"coin", math_random(1,2)}}, offer = {type = 'give-item', item = 'explosive-cannon-shell'}},
{price = {{"coin", math_random(3,6)}}, offer = {type = 'give-item', item = 'explosive-uranium-cannon-shell'}},
{price = {{"coin", math_random(4,8)}}, offer = {type = 'give-item', item = 'cluster-grenade'}},
{price = {{"coin", math_random(1,2)}}, offer = {type = 'give-item', item = 'land-mine'}},
{price = {{"coin", math_random(3,6)}}, offer = {type = 'give-item', item = 'explosive-uranium-cannon-shell'}},
{price = {{"coin", math_random(4,8)}}, offer = {type = 'give-item', item = 'cluster-grenade'}},
{price = {{"coin", math_random(1,2)}}, offer = {type = 'give-item', item = 'land-mine'}},
{price = {{"coin", math_random(25,50)}}, offer = {type = 'give-item', item = 'heavy-armor'}},
{price = {{"coin", math_random(125,250)}}, offer = {type = 'give-item', item = 'modular-armor'}},
{price = {{"coin", math_random(300,600)}}, offer = {type = 'give-item', item = 'power-armor'}},
@ -113,7 +109,7 @@ local function secret_shop(pos, surface)
{price = {{"coin", math_random(60,120)}}, offer = {type = 'give-item', item = 'personal-roboport-equipment'}},
{price = {{"coin", math_random(3,9)}}, offer = {type = 'give-item', item = 'construction-robot'}},
{price = {{"coin", math_random(100,200)}}, offer = {type = 'give-item', item = 'energy-shield-equipment'}},
{price = {{"coin", math_random(200,400)}}, offer = {type = 'give-item', item = 'personal-laser-defense-equipment'}},
{price = {{"coin", math_random(200,400)}}, offer = {type = 'give-item', item = 'personal-laser-defense-equipment'}},
{price = {{"coin", math_random(25,50)}}, offer = {type = 'give-item', item = 'railgun'}},
{price = {{"coin", math_random(1,2)}}, offer = {type = 'give-item', item = 'railgun-dart', count = 2}},
{price = {{"coin", math_random(30,60)}}, offer = {type = 'give-item', item = 'loader'}},
@ -123,9 +119,7 @@ local function secret_shop(pos, surface)
{price = {{"coin", math_random(15,35)}}, offer = {type = 'give-item', item = 'cargo-wagon'}},
{price = {{"coin", math_random(1,4)}}, offer = {type = 'give-item', item = 'grenade'}},
{price = {{"coin", 1}}, offer = {type = 'give-item', item = 'rail', count = 4}},
-- {price = {{"coin", 1}}, offer = {type = 'give-item', item = 'rail-signal', count = 2}},
-- {price = {{"coin", 1}}, offer = {type = 'give-item', item = 'rail-chain-signal', count = 2}},
{price = {{"coin", 5}}, offer = {type = 'give-item', item = 'train-stop'}},
{price = {{"coin", 5}}, offer = {type = 'give-item', item = 'train-stop'}},
{price = {{"coin", 1}}, offer = {type = 'give-item', item = 'small-lamp'}},
{price = {{"coin", 2}}, offer = {type = 'give-item', item = 'firearm-magazine'}},
{price = {{"coin", 1}}, offer = {type = 'give-item', item = 'wood', count = math_random(25,75)}},
@ -136,58 +130,52 @@ local function secret_shop(pos, surface)
{price = {{"coin", 1}}, offer = {type = 'give-item', item = 'uranium-ore', count = math_random(25,75)}}
}
secret_market_items = shuffle(secret_market_items)
local market = surface.create_entity {name = "market", position = pos}
market.destructible = false
market.destructible = false
for i = 1, math.random(4, 8), 1 do
market.add_market_item(secret_market_items[i])
end
end
local function spawn_biter(surface, position)
local e = math.ceil(game.forces.enemy.evolution_factor*20)
if e < 1 then e = 1 end
if e > 20 then e = 20 end
if e > 20 then e = 20 end
local biter = biters_in_the_void[e][math_random(1, #biters_in_the_void[e])]
local p = surface.find_non_colliding_position(biter , position, 16, 0.5)
if not p then return end
surface.create_entity{name = biter, position = p}
end
local function get_noise(name, pos)
end
local function get_noise(name, pos)
local seed = game.surfaces[1].map_gen_settings.seed
local noise = {}
local noise_seed_add = 25000
if name == "water" then
if name == "water" then
noise[1] = simplex_noise(pos.x * 0.02, pos.y * 0.02, seed)
seed = seed + noise_seed_add
noise[2] = simplex_noise(pos.x * 0.1, pos.y * 0.1, seed)
seed = seed + noise_seed_add
local noise = noise[1] + noise[2] * 0.2
return noise
local value = noise[1] + noise[2] * 0.2
return value
end
seed = seed + noise_seed_add
if name == "dirt" then
--noise[1] = simplex_noise(pos.x * 0.1, pos.y * 0.1, seed)
if name == "dirt" then
noise[1] = simplex_noise(pos.x * 0.08, pos.y * 0.08, seed)
seed = seed + noise_seed_add
local noise = noise[1]
return noise
local value = noise[1]
return value
end
seed = seed + noise_seed_add
if name == "trees" then
if name == "trees" then
noise[1] = simplex_noise(pos.x * 0.045, pos.y * 0.045, seed)
seed = seed + noise_seed_add
local noise = noise[1]
return noise
local value = noise[1]
return value
end
seed = seed + noise_seed_add
if name == "spawners" then
if name == "spawners" then
noise[1] = simplex_noise(pos.x * 0.02, pos.y * 0.02, seed)
seed = seed + noise_seed_add
local noise = noise[1]
return noise
local value = noise[1]
return value
end
end
@ -202,28 +190,28 @@ local function get_entity(position)
if math_random(1, 128) == 1 then
if position.x > 32 or position.x < -32 or position.y > 32 or position.y < -32 then
local e = math.ceil(game.forces.enemy.evolution_factor*10)
if e < 1 then e = 1 end
if e < 1 then e = 1 end
entity_name = worm_raffle_table[e][math_random(1, #worm_raffle_table[e])]
end
end
end
end
if noise > 0.61 then
entity_name = tree_raffle[math_random(1, #tree_raffle)]
if math_random(1, 128) == 1 then
if position.x > 32 or position.x < -32 or position.y > 32 or position.y < -32 then
local e = math.ceil(game.forces.enemy.evolution_factor*10)
if e < 1 then e = 1 end
if e < 1 then e = 1 end
entity_name = worm_raffle_table[e][math_random(1, #worm_raffle_table[e])]
end
end
end
end
end
end
else
if math_random(1, 2048) == 1 then
entity_name = "market"
entity_name = "market"
end
if math_random(1, 64) == 1 then
local noise_spawners = get_noise("spawners", position)
if noise_spawners > 0.25 and position.x^2 + position.y^2 > 3000 then
@ -240,54 +228,39 @@ end
local function get_noise_tile(position)
local noise = get_noise("dirt", position)
local tile_name
if noise > 0 then
tile_name = "grass-1"
if noise > 0.5 then
tile_name = "dirt-5"
end
else
tile_name = "dirt-7"
tile_name = "dirt-7"
end
local noise = get_noise("water", position)
if noise > 0.71 then
local noise_2 = get_noise("water", position)
if noise_2 > 0.71 then
tile_name = "water"
if noise > 0.78 then
tile_name = "deepwater"
end
if noise_2 > 0.78 then
tile_name = "deepwater"
end
end
if noise < -0.76 then
tile_name = "water"
end
return tile_name
end
local function get_chunk_position(position)
local chunk_position = {}
position.x = math.floor(position.x, 0)
position.y = math.floor(position.y, 0)
for x = 0, 31, 1 do
if (position.x - x) % 32 == 0 then chunk_position.x = (position.x - x) / 32 end
end
for y = 0, 31, 1 do
if (position.y - y) % 32 == 0 then chunk_position.y = (position.y - y) / 32 end
end
return chunk_position
end
local function uncover_map(surface, position, radius_min, radius_max)
local circles = shapes.circles
local circles = shapes.circles
local tiles = {}
local fishes = {}
local regenerate_decoratives = false
for r = radius_min, radius_max, 1 do
for _, position_modifier in pairs(circles[r]) do
for _, position_modifier in pairs(circles[r]) do
local pos = {x = position.x + position_modifier.x, y = position.y + position_modifier.y}
if surface.get_tile(pos).name == "out-of-map" then
regenerate_decoratives = true
local tile_name = get_noise_tile(pos)
insert(tiles, {name = tile_name, position = pos})
if tile_name == "water" or tile_name == "deepwater" then
@ -305,14 +278,14 @@ local function uncover_map(surface, position, radius_min, radius_max)
local area = {{pos.x - 4, pos.y - 4}, {pos.x + 4, pos.y + 4}}
if surface.count_entities_filtered({name = "biter-spawner", area = area}) == 0 then
surface.create_entity({name = entity, position = pos})
end
end
else
surface.create_entity({name = entity, position = pos})
end
end
end
end
end
end
end
end
end
if #tiles > 0 then
@ -326,18 +299,16 @@ end
local function uncover_map_for_player(player)
local position = player.position
local surface = player.surface
local circles = shapes.circles
local circles = shapes.circles
local tiles = {}
local fishes = {}
local uncover_map_schedule = {}
local regenerate_decoratives = false
for r = uncover_radius - 1, uncover_radius, 1 do
for _, position_modifier in pairs(circles[r]) do
local pos = {x = position.x + position_modifier.x, y = position.y + position_modifier.y}
local pos = {x = position.x + position_modifier.x, y = position.y + position_modifier.y}
if surface.get_tile(pos).name == "out-of-map" then
regenerate_decoratives = true
local tile_name = get_noise_tile(pos)
insert(tiles, {name = tile_name, position = pos})
insert(tiles, {name = tile_name, position = pos})
if tile_name == "water" or tile_name == "deepwater" then
if math_random(1, 24) == 1 then insert(fishes, pos) end
else
@ -353,40 +324,40 @@ local function uncover_map_for_player(player)
local area = {{pos.x - 4, pos.y - 4}, {pos.x + 4, pos.y + 4}}
if surface.count_entities_filtered({name = "biter-spawner", area = area}) == 0 then
surface.create_entity({name = entity, position = pos})
end
end
else
surface.create_entity({name = entity, position = pos})
end
end
end
if entity == "biter-spawner" or entity == "spitter-spawner" then
insert(uncover_map_schedule, {x = pos.x, y = pos.y})
end
end
end
end
end
end
end
end
if #tiles > 0 then
surface.set_tiles(tiles, true)
end
end
for _, pos in pairs(uncover_map_schedule) do
uncover_map(surface, pos, 1, 16)
end
uncover_map(surface, pos, 1, 16)
end
for _, fish in pairs(fishes) do
surface.create_entity({name = "fish", position = fish})
end
end
local function on_player_joined_game(event)
local player = game.players[event.player_index]
if not global.territorial_control_init_done then
local map_gen_settings = {}
map_gen_settings.water = "small"
map_gen_settings.cliff_settings = {cliff_elevation_interval = 22, cliff_elevation_0 = 22}
map_gen_settings.cliff_settings = {cliff_elevation_interval = 22, cliff_elevation_0 = 22}
map_gen_settings.autoplace_controls = {
["coal"] = {frequency = "none", size = "none", richness = "none"},
["stone"] = {frequency = "none", size = "none", richness = "none"},
@ -395,34 +366,34 @@ local function on_player_joined_game(event)
["crude-oil"] = {frequency = "none", size = "none", richness = "none"},
["trees"] = {frequency = "none", size = "none", richness = "none"},
["enemy-base"] = {frequency = "none", size = "none", richness = "none"}
}
game.create_surface("territorial_control", map_gen_settings)
}
game.create_surface("territorial_control", map_gen_settings)
local surface = game.surfaces["territorial_control"]
--surface.daytime = 0.5
--surface.freeze_daytime = 1
surface.ticks_per_day = surface.ticks_per_day * 2
surface.min_brightness = 0.08
game.forces["player"].set_spawn_position({0, 0}, surface)
game.map_settings.enemy_expansion.enabled = true
game.map_settings.enemy_evolution.destroy_factor = 0.0016
game.map_settings.enemy_evolution.time_factor = 0
game.map_settings.enemy_evolution.pollution_factor = 0
local turret_positions = {{6, 6}, {-5, -5}, {-5, 6}, {6, -5}}
for _, pos in pairs(turret_positions) do
local turret = surface.create_entity({name = "gun-turret", position = pos, force = "player"})
turret.insert({name = "firearm-magazine", count = 32})
end
local radius = 320
game.forces.player.chart(surface, {{x = -1 * radius, y = -1 * radius}, {x = radius, y = radius}})
global.territorial_control_init_done = true
end
if player.online_time < 1 then
player.insert({name = "submachine-gun", count = 1})
player.insert({name = "submachine-gun", count = 1})
player.insert({name = "iron-plate", count = 64})
player.insert({name = "grenade", count = 3})
player.insert({name = "raw-fish", count = 5})
@ -432,7 +403,7 @@ local function on_player_joined_game(event)
player.insert({name = "firearm-magazine", count = 128})
if global.show_floating_killscore then global.show_floating_killscore[player.name] = false end
end
local surface = game.surfaces["territorial_control"]
if player.online_time < 2 and surface.is_chunk_generated({0,0}) then
player.teleport(surface.find_non_colliding_position("character", {0, 0}, 50, 1), "territorial_control")
@ -450,41 +421,38 @@ local function on_player_changed_position(event)
end
end
local function generate_spawn_area(position_left_top)
local function generate_spawn_area(position_left_top)
if position_left_top.x > 32 then return end
if position_left_top.y > 32 then return end
if position_left_top.x < -32 then return end
if position_left_top.y < -32 then return end
local surface = game.surfaces["territorial_control"]
local entities = {}
local tiles = {}
local tiles = {}
for x = 0, 31, 1 do
for y = 0, 31, 1 do
local tile_to_insert = false
local pos = {x = position_left_top.x + x, y = position_left_top.y + y}
if pos.x > -9 and pos.x < 9 and pos.y > -9 and pos.y < 9 then
tile_to_insert = get_noise_tile(pos)
--if math_random(1, 4) == 1 then
tile_to_insert = "stone-path"
--end
tile_to_insert = get_noise_tile(pos)
tile_to_insert = "stone-path"
if pos.x <= -7 or pos.x >= 7 or pos.y <= -7 or pos.y >= 7 then
if math_random(1, 3) ~= 1 then
table.insert(entities, {name = "stone-wall", position = {x = pos.x, y = pos.y}, force = "player"})
end
end
end
end
if tile_to_insert == "water" or tile_to_insert == "deepwater" then
tile_to_insert = "grass-2"
end
end
if tile_to_insert then
insert(tiles, {name = tile_to_insert, position = pos})
end
end
end
surface.set_tiles(tiles, true)
for _, entity in pairs(entities) do
surface.create_entity(entity)
end
@ -494,11 +462,11 @@ local function on_chunk_generated(event)
if not game.surfaces["territorial_control"] then return end
local surface = game.surfaces["territorial_control"]
if surface.name ~= event.surface.name then return end
local position_left_top = event.area.left_top
generate_spawn_area(position_left_top)
local tiles = {}
local tiles = {}
for x = 0, 31, 1 do
for y = 0, 31, 1 do
local tile_to_insert = "out-of-map"
@ -508,20 +476,20 @@ local function on_chunk_generated(event)
insert(tiles, {name = tile_to_insert, position = pos})
end
end
end
surface.set_tiles(tiles, true)
end
surface.set_tiles(tiles, true)
end
local function on_player_mined_entity(event)
local entity = event.entity
if not entity.valid then return end
if entity.name == "mineable-wreckage" then
if math_random(1,40) == 1 then unearthing_biters(entity.surface, entity.position, math_random(4,12)) end
if math_random(1,80) == 1 then unearthing_worm(entity.surface, entity.position) end
if entity.name == "mineable-wreckage" then
if math_random(1,40) == 1 then unearthing_biters(entity.surface, entity.position, math_random(4,12)) end
if math_random(1,80) == 1 then unearthing_worm(entity.surface, entity.position) end
if math_random(1,160) == 1 then tick_tack_trap(entity.surface, entity.position) end
end
if entity.force.name ~= "scrap" then return end
local positions = {}
local r = math.ceil(entity.prototype.max_health / 32)
@ -537,27 +505,27 @@ local function on_player_mined_entity(event)
unearthing_biters(entity.surface, positions[i], math_random(5,10))
else
unearthing_worm(entity.surface, positions[i])
end
end
end
end
local function on_entity_died(event)
local surface = event.entity.surface
if event.entity.name == "biter-spawner" or event.entity.name == "spitter-spawner" then
if event.entity.name == "biter-spawner" or event.entity.name == "spitter-spawner" then
if math_random(1, 2) ~= 1 then
local name = ore_spawn_raffle[math.random(1,#ore_spawn_raffle)]
local pos = {x = event.entity.position.x, y = event.entity.position.y}
local pos = {x = event.entity.position.x, y = event.entity.position.y}
local amount_modifier = math.ceil(1 + game.forces.enemy.evolution_factor * 10)
local size_modifier = math.floor(game.forces.enemy.evolution_factor * 4)
if name == "crude-oil" then
if name == "crude-oil" then
map_functions.draw_oil_circle(pos, name, surface, 4, math.ceil(100000 * amount_modifier))
else
else
map_functions.draw_smoothed_out_ore_circle(pos, name, surface, 6 + size_modifier, math.ceil(500 * amount_modifier))
end
end
end
if event.entity.type == "tree" or event.entity.name == "mineable-wreckage" or event.entity.type == "rock" then
if math_random(1, 32) == 1 then
spawn_biter(event.entity.surface, event.entity.position)
@ -578,38 +546,49 @@ local disabled_for_deconstruction = {
["tree-02-red"] = true,
["tree-09-red"] = true
}
local function on_marked_for_deconstruction(event)
local function on_marked_for_deconstruction(event)
event.research.force.character_inventory_slots_bonus = game.forces.player.mining_drill_productivity_bonus * 300
if disabled_for_deconstruction[event.entity.name] then
event.entity.cancel_deconstruction(game.players[event.player_index].force.name)
end
end
local function on_research_finished(event)
local function on_research_finished()
game.forces.player.recipes["flamethrower-turret"].enabled = false
end
local function on_tick()
local function on_tick()
if game.tick % 4500 ~= 0 then return end
if math_random(1, 4) ~= 1 then return end
local surface = game.surfaces["territorial_control"]
local biters = surface.find_entities_filtered({type = "unit", force = "enemy", limit = 32})
if biters[1] then
biters = shuffle(biters)
for _, biter in pairs(biters) do
biter.set_command({type = defines.command.attack_area, destination = {x = 0, y = 0}, radius = 64, distraction = defines.distraction.by_anything})
for _, biter in pairs(biters) do
biter.set_command({type = defines.command.attack_area, destination = {x = 0, y = 0}, radius = 64, distraction = defines.distraction.by_anything})
end
end
end
end
event.add(defines.events.on_tick, on_tick)
event.add(defines.events.on_research_finished, on_research_finished)
event.add(defines.events.on_marked_for_deconstruction, on_marked_for_deconstruction)
event.add(defines.events.on_player_mined_entity, on_player_mined_entity)
event.add(defines.events.on_entity_died, on_entity_died)
event.add(defines.events.on_chunk_generated, on_chunk_generated)
event.add(defines.events.on_player_changed_position, on_player_changed_position)
event.add(defines.events.on_player_joined_game, on_player_joined_game)
local function on_init()
local T = Map.Pop_info()
T.localised_category = "territorial_control"
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
end
Event.on_init(on_init)
Event.add(defines.events.on_tick, on_tick)
Event.add(defines.events.on_research_finished, on_research_finished)
Event.add(defines.events.on_marked_for_deconstruction, on_marked_for_deconstruction)
Event.add(defines.events.on_player_mined_entity, on_player_mined_entity)
Event.add(defines.events.on_entity_died, on_entity_died)
Event.add(defines.events.on_chunk_generated, on_chunk_generated)
Event.add(defines.events.on_player_changed_position, on_player_changed_position)
Event.add(defines.events.on_player_joined_game, on_player_joined_game)

View File

@ -1,79 +0,0 @@
local event = require 'utils.event'
local info = [[
Citizen Log #468-2A-3287, Freelancer Trent
To whoever is reading this message,
Any natural resources are rare and the ones worth while are too hard for me to reach.
Luckily, the wrecks yield all kinds of useful scraps, but also various dangers.
Almost lost half a leg some days ago while digging out some scrap.
The wildlife is extremely aggressive, especially at the time of night.
Most of these insect appearing like creatures seem to live underground.
Stay near your light sources, if you want to have a chance of surviving here!
###Log End###
]]
local function create_map_intro_button(player)
if player.gui.top["map_intro_button"] then return end
local b = player.gui.top.add({type = "sprite-button", caption = "?", name = "map_intro_button", tooltip = "Map Info"})
b.style.font_color = {r = 0.8, g = 0.8, b = 0.8}
b.style.font = "heading-1"
b.style.minimal_height = 38
b.style.minimal_width = 38
b.style.top_padding = 2
b.style.left_padding = 4
b.style.right_padding = 4
b.style.bottom_padding = 2
end
local function create_map_intro(player)
if player.gui.left["map_intro_frame"] then player.gui.left["map_intro_frame"].destroy() end
local frame = player.gui.left.add {type = "frame", name = "map_intro_frame", direction = "vertical"}
local t = frame.add {type = "table", column_count = 1}
local b = frame.add {type = "button", caption = "Close", name = "close_map_intro_frame", align = "right"}
b.style.font = "default"
b.style.minimal_height = 30
b.style.minimal_width = 30
b.style.top_padding = 2
b.style.left_padding = 4
b.style.right_padding = 4
b.style.bottom_padding = 2
local frame = t.add {type = "frame"}
local l = frame.add {type = "label", caption = info}
l.style.single_line = false
l.style.font = "heading-3"
l.style.font_color = {r=0.95, g=0.95, b=0.95}
end
local function on_player_joined_game(event)
local player = game.players[event.player_index]
create_map_intro_button(player)
if player.online_time == 0 then
create_map_intro(player)
end
end
local function on_gui_click(event)
if not event then return end
if not event.element then return end
if not event.element.valid then return end
local player = game.players[event.element.player_index]
if event.element.name == "close_map_intro_frame" then player.gui.left["map_intro_frame"].destroy() return end
if event.element.name == "map_intro_button" then
if player.gui.left["map_intro_frame"] then
player.gui.left["map_intro_frame"].destroy()
else
create_map_intro(player)
end
return
end
end
event.add(defines.events.on_player_joined_game, on_player_joined_game)
event.add(defines.events.on_gui_click, on_gui_click)

View File

@ -44,7 +44,7 @@ local function on_player_died(event)
if cause.name == "character" then
if not player.name then return end
if not cause.player.name then return end
if cause.player.tag then
if cause.player.tag ~= "" then
game.print(player.name .. tag .. " was killed by " .. cause.player.name .. " " .. cause.player.tag .. ".", message_color)
else
game.print(player.name .. tag .. " was killed by " .. cause.player.name .. ".", message_color)

View File

@ -2,6 +2,8 @@ local simplex_noise = require "utils.simplex_noise".d2
--add or use noise templates from here
local noises = {
["bb_biterland"] = {{modifier = 0.001, weight = 1}, {modifier = 0.01, weight = 0.35}, {modifier = 0.1, weight = 0.015}},
["bb_ore"] = {{modifier = 0.0042, weight = 1}, {modifier = 0.031, weight = 0.08}, {modifier = 0.1, weight = 0.025}},
["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}},