diff --git a/functions/basic_markets.lua b/functions/basic_markets.lua new file mode 100644 index 00000000..c05cedf3 --- /dev/null +++ b/functions/basic_markets.lua @@ -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 \ No newline at end of file diff --git a/functions/biter_raffle.lua b/functions/biter_raffle.lua index 03f01a32..b767a69f 100644 --- a/functions/biter_raffle.lua +++ b/functions/biter_raffle.lua @@ -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, } diff --git a/functions/loot_raffle.lua b/functions/loot_raffle.lua index ef1bcb58..fab1f810 100644 --- a/functions/loot_raffle.lua +++ b/functions/loot_raffle.lua @@ -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 diff --git a/locale/en/locale.cfg b/locale/en/locale.cfg index 77d3b0cd..ec6080d7 100644 --- a/locale/en/locale.cfg +++ b/locale/en/locale.cfg @@ -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### diff --git a/maps/biter_battles_v2/ai.lua b/maps/biter_battles_v2/ai.lua index d2d10841..431eda75 100644 --- a/maps/biter_battles_v2/ai.lua +++ b/maps/biter_battles_v2/ai.lua @@ -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 diff --git a/maps/biter_battles_v2/biters_landfill.lua b/maps/biter_battles_v2/biters_landfill.lua deleted file mode 100644 index ab4d25bc..00000000 --- a/maps/biter_battles_v2/biters_landfill.lua +++ /dev/null @@ -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 \ No newline at end of file diff --git a/maps/biter_battles_v2/chat.lua b/maps/biter_battles_v2/chat.lua deleted file mode 100644 index b13d5a89..00000000 --- a/maps/biter_battles_v2/chat.lua +++ /dev/null @@ -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 \ No newline at end of file diff --git a/maps/biter_battles_v2/combat_balance.lua b/maps/biter_battles_v2/combat_balance.lua deleted file mode 100644 index a499face..00000000 --- a/maps/biter_battles_v2/combat_balance.lua +++ /dev/null @@ -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 \ No newline at end of file diff --git a/maps/biter_battles_v2/config.lua b/maps/biter_battles_v2/config.lua index 83c25643..0bd5aac0 100644 --- a/maps/biter_battles_v2/config.lua +++ b/maps/biter_battles_v2/config.lua @@ -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. } diff --git a/maps/biter_battles_v2/functions.lua b/maps/biter_battles_v2/functions.lua new file mode 100644 index 00000000..135f5bbe --- /dev/null +++ b/maps/biter_battles_v2/functions.lua @@ -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 \ No newline at end of file diff --git a/maps/biter_battles_v2/game_over.lua b/maps/biter_battles_v2/game_over.lua index b5f32896..58401f52 100644 --- a/maps/biter_battles_v2/game_over.lua +++ b/maps/biter_battles_v2/game_over.lua @@ -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 diff --git a/maps/biter_battles_v2/gui.lua b/maps/biter_battles_v2/gui.lua index 83a5972a..f70437bd 100644 --- a/maps/biter_battles_v2/gui.lua +++ b/maps/biter_battles_v2/gui.lua @@ -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 diff --git a/maps/biter_battles_v2/init.lua b/maps/biter_battles_v2/init.lua index fcecdd6b..dc71c47c 100644 --- a/maps/biter_battles_v2/init.lua +++ b/maps/biter_battles_v2/init.lua @@ -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 diff --git a/maps/biter_battles_v2/main.lua b/maps/biter_battles_v2/main.lua index 8412ba73..3d7d54ac 100644 --- a/maps/biter_battles_v2/main.lua +++ b/maps/biter_battles_v2/main.lua @@ -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' diff --git a/maps/biter_battles_v2/map_info.lua b/maps/biter_battles_v2/map_info.lua deleted file mode 100644 index c7188b5e..00000000 --- a/maps/biter_battles_v2/map_info.lua +++ /dev/null @@ -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 \ No newline at end of file diff --git a/maps/biter_battles_v2/map_settings_tab.lua b/maps/biter_battles_v2/map_settings_tab.lua index a733f55b..ef1c1e6f 100644 --- a/maps/biter_battles_v2/map_settings_tab.lua +++ b/maps/biter_battles_v2/map_settings_tab.lua @@ -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" diff --git a/maps/biter_battles_v2/mirror_terrain.lua b/maps/biter_battles_v2/mirror_terrain.lua index db89bf2c..b74d7c58 100644 --- a/maps/biter_battles_v2/mirror_terrain.lua +++ b/maps/biter_battles_v2/mirror_terrain.lua @@ -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 \ No newline at end of file diff --git a/maps/biter_battles_v2/no_turret_creep.lua b/maps/biter_battles_v2/no_turret_creep.lua deleted file mode 100644 index f904a803..00000000 --- a/maps/biter_battles_v2/no_turret_creep.lua +++ /dev/null @@ -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 \ No newline at end of file diff --git a/maps/biter_battles_v2/pregenerate_chunks.lua b/maps/biter_battles_v2/pregenerate_chunks.lua deleted file mode 100644 index d3fe1e10..00000000 --- a/maps/biter_battles_v2/pregenerate_chunks.lua +++ /dev/null @@ -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 \ No newline at end of file diff --git a/maps/biter_battles_v2/spy_fish.lua b/maps/biter_battles_v2/spy_fish.lua deleted file mode 100644 index efcdceae..00000000 --- a/maps/biter_battles_v2/spy_fish.lua +++ /dev/null @@ -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 \ No newline at end of file diff --git a/maps/biter_battles_v2/terrain.lua b/maps/biter_battles_v2/terrain.lua index 47a2a58f..51e15d94 100644 --- a/maps/biter_battles_v2/terrain.lua +++ b/maps/biter_battles_v2/terrain.lua @@ -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 diff --git a/maps/cratewood_forest.lua b/maps/cratewood_forest.lua index 73142413..05ec9ea7 100644 --- a/maps/cratewood_forest.lua +++ b/maps/cratewood_forest.lua @@ -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) \ No newline at end of file diff --git a/maps/dungeons/biome_acid_zone.lua b/maps/dungeons/biome_acid_zone.lua index 42dd0c00..ca4fab94 100644 --- a/maps/dungeons/biome_acid_zone.lua +++ b/maps/dungeons/biome_acid_zone.lua @@ -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) diff --git a/maps/dungeons/functions.lua b/maps/dungeons/functions.lua index 94e101ae..093fa12d 100644 --- a/maps/dungeons/functions.lua +++ b/maps/dungeons/functions.lua @@ -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) diff --git a/maps/dungeons/main.lua b/maps/dungeons/main.lua index fe94f853..895a0110 100644 --- a/maps/dungeons/main.lua +++ b/maps/dungeons/main.lua @@ -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 diff --git a/maps/mountain_fortress_v2/main.lua b/maps/mountain_fortress_v2/main.lua index 595f6739..cb531fdb 100644 --- a/maps/mountain_fortress_v2/main.lua +++ b/maps/mountain_fortress_v2/main.lua @@ -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" diff --git a/maps/territorial_control.lua b/maps/territorial_control.lua index 1b77765b..b2d079f0 100644 --- a/maps/territorial_control.lua +++ b/maps/territorial_control.lua @@ -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) \ No newline at end of file diff --git a/maps/territorial_control_intro.lua b/maps/territorial_control_intro.lua deleted file mode 100644 index 23494fa1..00000000 --- a/maps/territorial_control_intro.lua +++ /dev/null @@ -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) \ No newline at end of file diff --git a/modules/custom_death_messages.lua b/modules/custom_death_messages.lua index 785c28a9..ad2d7bf9 100644 --- a/modules/custom_death_messages.lua +++ b/modules/custom_death_messages.lua @@ -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) diff --git a/utils/get_noise.lua b/utils/get_noise.lua index 422776b7..fecdcdce 100644 --- a/utils/get_noise.lua +++ b/utils/get_noise.lua @@ -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}},