mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2025-01-04 00:15:45 +02:00
Merge branch 'ComfyFactory:develop' into develop
This commit is contained in:
commit
960b234807
2631
.luacheckrc
2631
.luacheckrc
File diff suppressed because it is too large
Load Diff
@ -121,13 +121,13 @@ local function build_group_gui(data)
|
||||
b.style.minimal_width = actions_width
|
||||
b.style.maximal_width = actions_width
|
||||
else
|
||||
local b = tt.add({type = 'button', caption = 'Leave'})
|
||||
local b = tt.add({type = 'button', caption = {'gui.leave'}})
|
||||
b.style.font = 'default-bold'
|
||||
b.style.minimal_width = actions_width
|
||||
b.style.maximal_width = actions_width
|
||||
end
|
||||
if player.admin == true or group.founder == player.name then
|
||||
local b = tt.add({type = 'button', caption = 'Delete'})
|
||||
local b = tt.add({type = 'button', caption = {'gui.delete'}})
|
||||
b.style.font = 'default-bold'
|
||||
b.style.minimal_width = actions_width
|
||||
b.style.maximal_width = actions_width
|
||||
@ -233,13 +233,9 @@ local function on_gui_click(event)
|
||||
end
|
||||
local player = game.get_player(event.player_index)
|
||||
|
||||
local name = event.element.name
|
||||
local name = element.name
|
||||
|
||||
if not name then
|
||||
return
|
||||
end
|
||||
|
||||
if name == 'tab_' .. module_name then
|
||||
if name and name == 'tab_' .. module_name then
|
||||
local is_spamming = SpamProtection.is_spamming(player, nil, 'Groups tab_Groups')
|
||||
if is_spamming then
|
||||
return
|
||||
@ -320,7 +316,9 @@ local function on_gui_click(event)
|
||||
return
|
||||
end
|
||||
|
||||
if element.type == 'button' and element.caption == 'Join' then
|
||||
local caption = element.caption and element.caption[1]
|
||||
|
||||
if element.type == 'button' and caption == 'gui.join' then
|
||||
this.player_group[player.name] = element.parent.name
|
||||
local str = '[' .. element.parent.name
|
||||
str = str .. ']'
|
||||
@ -339,7 +337,7 @@ local function on_gui_click(event)
|
||||
return
|
||||
end
|
||||
|
||||
if element.type == 'button' and element.caption == 'Delete' then
|
||||
if element.type == 'button' and caption == 'gui.delete' then
|
||||
for _, players in pairs(game.players) do
|
||||
if this.player_group[players.name] then
|
||||
if this.player_group[players.name] == element.parent.name then
|
||||
@ -354,7 +352,7 @@ local function on_gui_click(event)
|
||||
return
|
||||
end
|
||||
|
||||
if element.type == 'button' and element.caption == 'Leave' then
|
||||
if element.type == 'button' and caption == 'gui.leave' then
|
||||
this.player_group[player.name] = '[Group]'
|
||||
player.tag = ''
|
||||
refresh_gui()
|
||||
|
@ -160,6 +160,9 @@ require 'maps.pirates.main'
|
||||
--![[Territorial Control - reveal the map as you walk through the mist]]--
|
||||
--require 'maps.territorial_control'
|
||||
|
||||
--![[Deep Jungle - dangerous map]]--
|
||||
--require 'maps.deep_jungle.main'
|
||||
|
||||
--![[You fell in a dark cave, will you survive?]]--
|
||||
--require 'maps.cave_choppy.main'
|
||||
--require 'maps.cave_miner'
|
||||
@ -215,7 +218,6 @@ require 'maps.pirates.main'
|
||||
|
||||
--![[Misc / WIP]]--
|
||||
--require 'maps.rainbow_road'
|
||||
--require 'maps.deep_jungle'
|
||||
--require 'maps.cratewood_forest'
|
||||
--require 'maps.maze_challenge'
|
||||
--require 'maps.lost_desert'
|
||||
|
@ -5,6 +5,8 @@ description=Description
|
||||
members=Members
|
||||
create=Create
|
||||
join=Join
|
||||
leave=Leave
|
||||
delete=Delete
|
||||
gui_data_cleaning=Gui Data Cleaning
|
||||
spaghett_mode=Spaghett Mode
|
||||
notify_on_polls=Notify on polls
|
||||
|
@ -1,414 +0,0 @@
|
||||
--luacheck: ignore
|
||||
--deep jungle-- mewmew made this --
|
||||
require 'modules.no_deconstruction_of_neutral_entities'
|
||||
require 'modules.spawners_contain_biters'
|
||||
require 'modules.biters_yield_coins'
|
||||
require 'modules.rocks_yield_coins'
|
||||
require 'modules.flashlight_toggle_button'
|
||||
|
||||
local map_functions = require 'tools.map_functions'
|
||||
local simplex_noise = require 'utils.simplex_noise'
|
||||
simplex_noise = simplex_noise.d2
|
||||
local event = require 'utils.event'
|
||||
local math_random = math.random
|
||||
|
||||
local function shuffle(tbl)
|
||||
local size = #tbl
|
||||
for i = size, 1, -1 do
|
||||
local rand = math.random(size)
|
||||
tbl[i], tbl[rand] = tbl[rand], tbl[i]
|
||||
end
|
||||
return tbl
|
||||
end
|
||||
|
||||
local function secret_shop(pos, surface)
|
||||
local secret_market_items = {
|
||||
{price = {{'coin', math_random(300, 600)}}, offer = {type = 'give-item', item = 'combat-shotgun'}},
|
||||
{price = {{'coin', math_random(200, 400)}}, offer = {type = 'give-item', item = 'rocket-launcher'}},
|
||||
{price = {{'coin', math_random(5, 10)}}, offer = {type = 'give-item', item = 'piercing-rounds-magazine'}},
|
||||
--{price = {{"coin", math_random(150,250)}}, offer = {type = 'give-item', item = 'uranium-rounds-magazine'}},
|
||||
{price = {{'coin', math_random(15, 30)}}, offer = {type = 'give-item', item = 'piercing-shotgun-shell'}},
|
||||
{price = {{'coin', math_random(10, 20)}}, offer = {type = 'give-item', item = 'rocket'}},
|
||||
{price = {{'coin', math_random(20, 30)}}, offer = {type = 'give-item', item = 'explosive-rocket'}},
|
||||
{price = {{'coin', math_random(30, 60)}}, offer = {type = 'give-item', item = 'cluster-grenade'}},
|
||||
{price = {{'coin', math_random(8, 16)}}, offer = {type = 'give-item', item = 'land-mine'}},
|
||||
{price = {{'coin', math_random(200, 300)}}, offer = {type = 'give-item', item = 'heavy-armor'}},
|
||||
{price = {{'coin', math_random(400, 800)}}, offer = {type = 'give-item', item = 'modular-armor'}},
|
||||
{price = {{'coin', math_random(1000, 2000)}}, offer = {type = 'give-item', item = 'power-armor'}},
|
||||
{price = {{'coin', math_random(2500, 5000)}}, offer = {type = 'give-item', item = 'fusion-reactor-equipment'}},
|
||||
{price = {{'coin', math_random(200, 400)}}, offer = {type = 'give-item', item = 'battery-equipment'}},
|
||||
{price = {{'coin', math_random(150, 250)}}, offer = {type = 'give-item', item = 'belt-immunity-equipment'}},
|
||||
{price = {{'coin', math_random(100, 200)}}, offer = {type = 'give-item', item = 'night-vision-equipment'}},
|
||||
{price = {{'coin', math_random(400, 800)}}, offer = {type = 'give-item', item = 'exoskeleton-equipment'}},
|
||||
{price = {{'coin', math_random(200, 300)}}, offer = {type = 'give-item', item = 'personal-roboport-equipment'}},
|
||||
{price = {{'coin', math_random(25, 50)}}, offer = {type = 'give-item', item = 'construction-robot'}},
|
||||
-- {price = {{"coin", math_random(10000,20000)}}, offer = {type = 'give-item', item = 'energy-shield-equipment'}},
|
||||
-- {price = {{"coin", math_random(5000,15000)}}, offer = {type = 'give-item', item = 'personal-laser-defense-equipment'}},
|
||||
{price = {{'coin', math_random(100, 300)}}, offer = {type = 'give-item', item = 'loader'}},
|
||||
{price = {{'coin', math_random(200, 400)}}, offer = {type = 'give-item', item = 'fast-loader'}},
|
||||
{price = {{'coin', math_random(300, 500)}}, offer = {type = 'give-item', item = 'express-loader'}},
|
||||
{price = {{'coin', math_random(150, 300)}}, offer = {type = 'give-item', item = 'locomotive'}},
|
||||
{price = {{'coin', math_random(100, 200)}}, offer = {type = 'give-item', item = 'cargo-wagon'}},
|
||||
{price = {{'coin', math_random(5, 15)}}, offer = {type = 'give-item', item = 'grenade'}},
|
||||
{price = {{'coin', math_random(80, 160)}}, offer = {type = 'give-item', item = 'cliff-explosives'}},
|
||||
{price = {{'coin', math_random(10, 20)}}, offer = {type = 'give-item', item = 'explosives', count = 50}},
|
||||
{price = {{'coin', math_random(4, 8)}}, offer = {type = 'give-item', item = 'rail', count = 4}},
|
||||
{price = {{'coin', math_random(20, 30)}}, offer = {type = 'give-item', item = 'train-stop'}},
|
||||
{price = {{'coin', math_random(4, 12)}}, offer = {type = 'give-item', item = 'small-lamp'}},
|
||||
{price = {{'coin', math_random(1, 4)}}, offer = {type = 'give-item', item = 'firearm-magazine'}},
|
||||
{price = {{'coin', math_random(60, 150)}}, offer = {type = 'give-item', item = 'car', count = 1}},
|
||||
{price = {{'coin', math_random(75, 150)}}, offer = {type = 'give-item', item = 'gun-turret', count = 1}},
|
||||
{price = {{'coin', math_random(500, 750)}}, offer = {type = 'give-item', item = 'laser-turret', count = 1}},
|
||||
{price = {{'coin', math_random(1000, 2000)}}, offer = {type = 'give-item', item = 'artillery-turret', count = 1}},
|
||||
{price = {{'coin', math_random(100, 200)}}, offer = {type = 'give-item', item = 'artillery-shell', count = 1}},
|
||||
{price = {{'coin', math_random(50, 150)}}, offer = {type = 'give-item', item = 'artillery-targeting-remote', count = 1}},
|
||||
{price = {{'coin', math_random(5, 15)}}, offer = {type = 'give-item', item = 'shotgun-shell', count = 1}},
|
||||
{price = {{'coin', math_random(8000, 16000)}}, offer = {type = 'give-item', item = 'power-armor-mk2', count = 1}},
|
||||
{price = {{'coin', math_random(80, 160)}}, offer = {type = 'give-item', item = 'solar-panel-equipment', count = 1}},
|
||||
{price = {{'coin', math_random(4, 8)}}, offer = {type = 'give-item', item = 'wood', count = 50}},
|
||||
{price = {{'coin', math_random(4, 8)}}, offer = {type = 'give-item', item = 'iron-ore', count = 50}},
|
||||
{price = {{'coin', math_random(4, 8)}}, offer = {type = 'give-item', item = 'copper-ore', count = 50}},
|
||||
{price = {{'coin', math_random(4, 8)}}, offer = {type = 'give-item', item = 'stone', count = 50}},
|
||||
{price = {{'coin', math_random(4, 8)}}, offer = {type = 'give-item', item = 'coal', count = 50}}
|
||||
--{price = {{"coin", math_random(4,8)}}, offer = {type = 'give-item', item = 'uranium-ore', count = 50}}
|
||||
}
|
||||
secret_market_items = shuffle(secret_market_items)
|
||||
|
||||
local market = surface.create_entity {name = 'market', position = pos}
|
||||
market.destructible = false
|
||||
|
||||
for i = 1, math.random(6, 10), 1 do
|
||||
market.add_market_item(secret_market_items[i])
|
||||
end
|
||||
end
|
||||
|
||||
local function treasure_chest(position)
|
||||
if not game.surfaces['deep_jungle'].can_place_entity({name = 'steel-chest', position = position, force = 'player'}) then
|
||||
return
|
||||
end
|
||||
treasure_chest_raffle_table = {}
|
||||
treasure_chest_loot_weights = {}
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'landfill', count = math_random(8, 16)}, 16})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'iron-gear-wheel', count = math_random(16, 48)}, 8})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'coal', count = math_random(16, 48)}, 2})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'copper-cable', count = math_random(64, 128)}, 8})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'inserter', count = math_random(4, 8)}, 4})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'fast-inserter', count = math_random(4, 8)}, 3})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'burner-inserter', count = math_random(4, 8)}, 6})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'rocket-fuel', count = math_random(1, 5)}, 3})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'small-electric-pole', count = math_random(4, 8)}, 7})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'firearm-magazine', count = math_random(16, 48)}, 8})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'submachine-gun', count = 1}, 4})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'grenade', count = math_random(6, 12)}, 5})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'land-mine', count = math_random(8, 16)}, 5})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'light-armor', count = 1}, 1})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'heavy-armor', count = 1}, 2})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'pipe', count = math_random(10, 100)}, 6})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'explosives', count = math_random(40, 50)}, 6})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'shotgun', count = 1}, 3})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'shotgun-shell', count = math_random(8, 16)}, 3})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'stone-brick', count = math_random(80, 100)}, 4})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'small-lamp', count = math_random(2, 4)}, 2})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'rail', count = math_random(16, 48)}, 3})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'coin', count = math_random(32, 320)}, 1})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'assembling-machine-1', count = math_random(1, 3)}, 3})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'assembling-machine-2', count = math_random(1, 3)}, 2})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'assembling-machine-3', count = math_random(1, 2)}, 1})
|
||||
for _, t in pairs(treasure_chest_loot_weights) do
|
||||
for x = 1, t[2], 1 do
|
||||
table.insert(treasure_chest_raffle_table, t[1])
|
||||
end
|
||||
end
|
||||
|
||||
local e = game.surfaces['deep_jungle'].create_entity {name = 'wooden-chest', position = position, force = 'player'}
|
||||
e.minable = false
|
||||
local i = e.get_inventory(defines.inventory.chest)
|
||||
for x = 1, math_random(3, 7), 1 do
|
||||
local loot = treasure_chest_raffle_table[math_random(1, #treasure_chest_raffle_table)]
|
||||
i.insert(loot)
|
||||
end
|
||||
end
|
||||
|
||||
local function rare_treasure_chest(position)
|
||||
if not game.surfaces['deep_jungle'].can_place_entity({name = 'steel-chest', position = position, force = 'player'}) then
|
||||
return
|
||||
end
|
||||
local rare_treasure_chest_raffle_table = {}
|
||||
local rare_treasure_chest_loot_weights = {}
|
||||
table.insert(rare_treasure_chest_loot_weights, {{name = 'combat-shotgun', count = 1}, 5})
|
||||
table.insert(rare_treasure_chest_loot_weights, {{name = 'piercing-shotgun-shell', count = math_random(8, 16)}, 5})
|
||||
table.insert(rare_treasure_chest_loot_weights, {{name = 'rocket-launcher', count = 1}, 5})
|
||||
table.insert(rare_treasure_chest_loot_weights, {{name = 'rocket', count = math_random(4, 8)}, 5})
|
||||
table.insert(rare_treasure_chest_loot_weights, {{name = 'explosive-rocket', count = math_random(4, 8)}, 5})
|
||||
table.insert(rare_treasure_chest_loot_weights, {{name = 'modular-armor', count = 1}, 3})
|
||||
table.insert(rare_treasure_chest_loot_weights, {{name = 'piercing-rounds-magazine', count = math_random(32, 64)}, 3})
|
||||
table.insert(rare_treasure_chest_loot_weights, {{name = 'defender-capsule', count = math_random(4, 8)}, 5})
|
||||
table.insert(rare_treasure_chest_loot_weights, {{name = 'distractor-capsule', count = math_random(3, 5)}, 4})
|
||||
table.insert(rare_treasure_chest_loot_weights, {{name = 'destroyer-capsule', count = math_random(2, 3)}, 3})
|
||||
for _, t in pairs(rare_treasure_chest_loot_weights) do
|
||||
for x = 1, t[2], 1 do
|
||||
table.insert(rare_treasure_chest_raffle_table, t[1])
|
||||
end
|
||||
end
|
||||
|
||||
local e = game.surfaces['deep_jungle'].create_entity {name = 'steel-chest', position = position, force = 'player'}
|
||||
e.minable = false
|
||||
local i = e.get_inventory(defines.inventory.chest)
|
||||
for x = 1, math_random(2, 3), 1 do
|
||||
local loot = rare_treasure_chest_raffle_table[math_random(1, #rare_treasure_chest_raffle_table)]
|
||||
i.insert(loot)
|
||||
end
|
||||
end
|
||||
|
||||
local function get_noise(name, pos)
|
||||
local seed = game.surfaces[1].map_gen_settings.seed
|
||||
local noise_seed_add = 25000
|
||||
if name == 1 then
|
||||
local noise = {}
|
||||
noise[1] = simplex_noise(pos.x * 0.001, pos.y * 0.001, seed)
|
||||
seed = seed + noise_seed_add
|
||||
noise[2] = simplex_noise(pos.x * 0.01, pos.y * 0.01, seed + noise_seed_add)
|
||||
local noise = noise[1] + noise[2] * 0.1
|
||||
return noise
|
||||
end
|
||||
if name == 2 then
|
||||
local noise = {}
|
||||
noise[1] = simplex_noise(pos.x * 0.015, pos.y * 0.015, seed)
|
||||
seed = seed + noise_seed_add
|
||||
noise[2] = simplex_noise(pos.x * 0.15, pos.y * 0.15, seed + noise_seed_add)
|
||||
local noise = noise[1] + noise[2] * 0.2
|
||||
return noise
|
||||
end
|
||||
if name == 3 then
|
||||
local noise = {}
|
||||
noise[1] = simplex_noise(pos.x * 0.025, pos.y * 0.025, seed)
|
||||
seed = seed + noise_seed_add
|
||||
noise[2] = simplex_noise(pos.x * 0.2, pos.y * 0.2, seed + noise_seed_add)
|
||||
local noise = noise[1] + noise[2] * 0.2
|
||||
return noise
|
||||
end
|
||||
if name == 'greenwater' then
|
||||
local noise = {}
|
||||
noise[1] = simplex_noise(pos.x * 0.003, pos.y * 0.003, seed)
|
||||
seed = seed + noise_seed_add
|
||||
noise[2] = simplex_noise(pos.x * 0.03, pos.y * 0.03, seed + noise_seed_add)
|
||||
local noise = noise[1] + noise[2] * 0.1
|
||||
return noise
|
||||
end
|
||||
end
|
||||
|
||||
local rock_raffle = {'sand-rock-big', 'sand-rock-big', 'rock-big', 'rock-big', 'rock-big', 'rock-big', 'rock-huge'}
|
||||
local tree_raffle = {'tree-04', 'tree-07', 'tree-09', 'tree-06', 'tree-04', 'tree-07', 'tree-09', 'tree-04'}
|
||||
|
||||
local function process_tile(pos)
|
||||
local noise_1 = get_noise(1, pos)
|
||||
if noise_1 > -0.03 and noise_1 < 0.03 then
|
||||
return 'deepwater'
|
||||
end
|
||||
if noise_1 > -0.05 and noise_1 < 0.05 then
|
||||
return 'water'
|
||||
end
|
||||
local noise_greenwater = get_noise('greenwater', pos)
|
||||
if noise_greenwater > -0.035 and noise_greenwater < 0.035 then
|
||||
return 'water-green'
|
||||
end
|
||||
if noise_1 > -0.08 and noise_1 < 0.08 then
|
||||
return false
|
||||
end
|
||||
|
||||
local noise_2 = get_noise(2, pos)
|
||||
if noise_2 > 0.37 or noise_2 < -0.37 then
|
||||
if math_random(1, 4) == 1 then
|
||||
return false, tree_raffle[math.ceil(math.abs(noise_1 * 8))]
|
||||
end
|
||||
end
|
||||
local noise_3 = get_noise(3, pos)
|
||||
if noise_3 > 0.5 then
|
||||
if math_random(1, 3) == 1 then
|
||||
return false, rock_raffle[math_random(1, #rock_raffle)]
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
local function on_chunk_generated(event)
|
||||
local surface = game.surfaces['deep_jungle']
|
||||
if event.surface.name ~= surface.name then
|
||||
return
|
||||
end
|
||||
|
||||
local chunk_pos_x = event.area.left_top.x
|
||||
local chunk_pos_y = event.area.left_top.y
|
||||
|
||||
local tiles = {}
|
||||
local entities_to_place = {}
|
||||
local treasure_chests = {}
|
||||
local rare_treasure_chests = {}
|
||||
local secret_shops = {}
|
||||
|
||||
local tile_to_insert = false
|
||||
for x = 0, 31, 1 do
|
||||
for y = 0, 31, 1 do
|
||||
local pos = {x = chunk_pos_x + x, y = chunk_pos_y + y}
|
||||
|
||||
tile_to_insert, entity_to_place = process_tile(pos)
|
||||
if entity_to_place then
|
||||
table.insert(entities_to_place, {name = entity_to_place, position = pos, force = 'player'})
|
||||
end
|
||||
|
||||
if tile_to_insert then
|
||||
table.insert(tiles, {name = tile_to_insert, position = pos})
|
||||
if math_random(1, 40) == 1 and tile_to_insert == 'deepwater' then
|
||||
surface.create_entity({name = 'fish', position = pos})
|
||||
end
|
||||
end
|
||||
|
||||
if math_random(1, 1500) == 1 then
|
||||
table.insert(treasure_chests, pos)
|
||||
end
|
||||
if math_random(1, 16000) == 1 then
|
||||
table.insert(rare_treasure_chests, pos)
|
||||
end
|
||||
if math_random(1, 8000) == 1 then
|
||||
table.insert(secret_shops, pos)
|
||||
end
|
||||
end
|
||||
end
|
||||
surface.set_tiles(tiles, true)
|
||||
|
||||
for _, e in pairs(entities_to_place) do
|
||||
if not surface.get_tile(e.position).collides_with('player-layer') then
|
||||
surface.create_entity(e)
|
||||
end
|
||||
end
|
||||
for _, p in pairs(treasure_chests) do
|
||||
treasure_chest(p)
|
||||
end
|
||||
for _, p in pairs(rare_treasure_chests) do
|
||||
rare_treasure_chest(p)
|
||||
end
|
||||
for _, p in pairs(secret_shops) do
|
||||
if not surface.get_tile(p).collides_with('player-layer') then
|
||||
local area = {{p.x - 128, p.y - 128}, {p.x + 128, p.y + 128}}
|
||||
if surface.count_entities_filtered({name = 'market', area = area}) == 0 then
|
||||
secret_shop(p, surface)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function on_chunk_charted(event)
|
||||
if not global.chunks_charted then
|
||||
global.chunks_charted = {}
|
||||
end
|
||||
local surface = game.surfaces[event.surface_index]
|
||||
local position = event.position
|
||||
if global.chunks_charted[tostring(position.x) .. tostring(position.y)] then
|
||||
return
|
||||
end
|
||||
global.chunks_charted[tostring(position.x) .. tostring(position.y)] = true
|
||||
|
||||
local decorative_names = {}
|
||||
for k, v in pairs(game.decorative_prototypes) do
|
||||
if v.autoplace_specification then
|
||||
decorative_names[#decorative_names + 1] = k
|
||||
end
|
||||
end
|
||||
surface.regenerate_decorative(decorative_names, {position})
|
||||
|
||||
if math_random(1, 14) ~= 1 then
|
||||
return
|
||||
end
|
||||
map_functions.draw_rainbow_patch({x = position.x * 32 + math_random(1, 32), y = position.y * 32 + math_random(1, 32)}, surface, math_random(14, 26), 2000)
|
||||
end
|
||||
|
||||
local function on_player_joined_game(event)
|
||||
local player = game.players[event.player_index]
|
||||
local surface = game.surfaces['deep_jungle']
|
||||
if player.online_time < 5 and surface.is_chunk_generated({0, 0}) then
|
||||
player.teleport(surface.find_non_colliding_position('character', {0, 0}, 2, 1), 'deep_jungle')
|
||||
else
|
||||
if player.online_time < 5 then
|
||||
player.teleport({0, 0}, 'deep_jungle')
|
||||
end
|
||||
end
|
||||
if player.online_time < 2 then
|
||||
player.insert {name = 'iron-plate', count = 32}
|
||||
end
|
||||
end
|
||||
|
||||
local function on_entity_died(event)
|
||||
local surface = event.entity.surface
|
||||
if event.entity.type == 'tree' then
|
||||
if math_random(1, 8) == 1 then
|
||||
local p = surface.find_non_colliding_position('small-biter', event.entity.position, 2, 0.5)
|
||||
if p then
|
||||
surface.create_entity {name = 'small-biter', position = event.entity.position}
|
||||
end
|
||||
return
|
||||
end
|
||||
if math_random(1, 16) == 1 then
|
||||
local p = surface.find_non_colliding_position('medium-biter', event.entity.position, 2, 0.5)
|
||||
if p then
|
||||
surface.create_entity {name = 'medium-biter', position = event.entity.position}
|
||||
end
|
||||
return
|
||||
end
|
||||
if math_random(1, 32) == 1 then
|
||||
local p = surface.find_non_colliding_position('big-biter', event.entity.position, 2, 0.5)
|
||||
if p then
|
||||
surface.create_entity {name = 'big-biter', position = event.entity.position}
|
||||
end
|
||||
return
|
||||
end
|
||||
if math_random(1, 512) == 1 then
|
||||
local p = surface.find_non_colliding_position('behemoth-biter', event.entity.position, 2, 0.5)
|
||||
if p then
|
||||
surface.create_entity {name = 'behemoth-biter', position = event.entity.position}
|
||||
end
|
||||
return
|
||||
end
|
||||
end
|
||||
if event.entity.type == 'simple-entity' then
|
||||
if math_random(1, 8) == 1 then
|
||||
surface.create_entity {name = 'small-worm-turret', position = event.entity.position}
|
||||
return
|
||||
end
|
||||
if math_random(1, 16) == 1 then
|
||||
surface.create_entity {name = 'medium-worm-turret', position = event.entity.position}
|
||||
return
|
||||
end
|
||||
if math_random(1, 32) == 1 then
|
||||
surface.create_entity {name = 'big-worm-turret', position = event.entity.position}
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function on_init()
|
||||
local map_gen_settings = {}
|
||||
map_gen_settings.moisture = 0.99
|
||||
map_gen_settings.water = 'none'
|
||||
map_gen_settings.starting_area = 'normal'
|
||||
map_gen_settings.cliff_settings = {cliff_elevation_interval = 4, cliff_elevation_0 = 0.1}
|
||||
map_gen_settings.autoplace_controls = {
|
||||
['coal'] = {frequency = 'none', size = 'none', richness = 'none'},
|
||||
['stone'] = {frequency = 'none', size = 'none', richness = 'none'},
|
||||
['copper-ore'] = {frequency = 'none', size = 'none', richness = 'none'},
|
||||
['iron-ore'] = {frequency = 'none', size = 'none', richness = 'none'},
|
||||
['crude-oil'] = {frequency = 'very-high', size = 'big', richness = 'normal'},
|
||||
['trees'] = {frequency = 'none', size = 'none', richness = 'none'},
|
||||
['enemy-base'] = {frequency = 'high', size = 'big', richness = 'good'}
|
||||
}
|
||||
game.create_surface('deep_jungle', map_gen_settings)
|
||||
game.forces['player'].set_spawn_position({0, 0}, game.surfaces['deep_jungle'])
|
||||
end
|
||||
|
||||
event.on_init(on_init)
|
||||
event.add(defines.events.on_chunk_generated, on_chunk_generated)
|
||||
event.add(defines.events.on_chunk_charted, on_chunk_charted)
|
||||
event.add(defines.events.on_entity_died, on_entity_died)
|
||||
event.add(defines.events.on_player_joined_game, on_player_joined_game)
|
||||
|
||||
require 'modules.rocks_yield_ore'
|
508
maps/deep_jungle/generate.lua
Normal file
508
maps/deep_jungle/generate.lua
Normal file
@ -0,0 +1,508 @@
|
||||
local Task = require 'utils.task'
|
||||
local Token = require 'utils.token'
|
||||
local Event = require 'utils.event'
|
||||
local Terrain = require 'maps.deep_jungle.terrain'
|
||||
|
||||
local Public = {}
|
||||
|
||||
local force_chunk = false
|
||||
local ceil = math.ceil
|
||||
local queue_task = Task.queue_task
|
||||
local tiles_per_call = 12
|
||||
local total_calls = ceil(1024 / tiles_per_call)
|
||||
local regen_decoratives = false
|
||||
local generate_map = Terrain.heavy_functions
|
||||
|
||||
-- Set to false by modules that want to control the on_chunk_generated event themselves.
|
||||
Public.enable_register_events = true
|
||||
|
||||
-- Simple "loop" that is UPS friendly.
|
||||
local function get_position(data)
|
||||
data.yv = data.yv + 1
|
||||
|
||||
if data.yv == 32 then
|
||||
if data.xv == 32 then
|
||||
data.xv = 0
|
||||
end
|
||||
if data.yv == 32 then
|
||||
data.yv = 0
|
||||
end
|
||||
data.xv = data.xv + 1
|
||||
end
|
||||
|
||||
data.position = {x = data.top_x + data.xv, y = data.top_y + data.yv}
|
||||
end
|
||||
|
||||
local function do_tile_inner(tiles, tile, pos)
|
||||
if type(tile) == 'string' then
|
||||
tiles[#tiles + 1] = {name = tile, position = pos}
|
||||
end
|
||||
end
|
||||
|
||||
local function do_tile(x, y, data, shape)
|
||||
local pos = {x, y}
|
||||
|
||||
-- local coords need to be 'centered' to allow for correct rotation and scaling.
|
||||
local tile = shape(data)
|
||||
|
||||
if type(tile) == 'table' then
|
||||
do_tile_inner(data.tiles, tile.tile, pos)
|
||||
|
||||
local hidden_tile = tile.hidden_tile
|
||||
if hidden_tile then
|
||||
data.hidden_tiles[#data.hidden_tiles + 1] = {tile = hidden_tile, position = pos}
|
||||
end
|
||||
|
||||
local entities = tile.entities
|
||||
if entities then
|
||||
for _, entity in ipairs(entities) do
|
||||
if not entity.position then
|
||||
entity.position = pos
|
||||
end
|
||||
data.entities[#data.entities + 1] = entity
|
||||
end
|
||||
end
|
||||
|
||||
local buildings = tile.buildings
|
||||
if buildings then
|
||||
for _, entity in ipairs(buildings) do
|
||||
if not entity.position then
|
||||
entity.position = pos
|
||||
end
|
||||
data.buildings[#data.buildings + 1] = entity
|
||||
end
|
||||
end
|
||||
|
||||
local decoratives = tile.decoratives
|
||||
if decoratives then
|
||||
for _, decorative in ipairs(decoratives) do
|
||||
data.decoratives[#data.decoratives + 1] = decorative
|
||||
end
|
||||
end
|
||||
|
||||
local markets = tile.markets
|
||||
if markets then
|
||||
for _, t in ipairs(markets) do
|
||||
if not t.position then
|
||||
t.position = pos
|
||||
end
|
||||
data.markets[#data.markets + 1] = t
|
||||
end
|
||||
end
|
||||
|
||||
local treasure = tile.treasure
|
||||
if treasure then
|
||||
for _, t in ipairs(treasure) do
|
||||
if not t.position then
|
||||
t.position = pos
|
||||
end
|
||||
data.treasure[#data.treasure + 1] = t
|
||||
end
|
||||
end
|
||||
else
|
||||
do_tile_inner(data.tiles, tile, pos)
|
||||
end
|
||||
end
|
||||
|
||||
local function do_row(row, data, shape)
|
||||
local y = data.top_y + row
|
||||
local top_x = data.top_x
|
||||
local tiles = data.tiles
|
||||
|
||||
data.y = y
|
||||
|
||||
for x = top_x, top_x + 31 do
|
||||
data.x = x
|
||||
local pos = {data.x, data.y}
|
||||
|
||||
get_position(data)
|
||||
|
||||
-- local coords need to be 'centered' to allow for correct rotation and scaling.
|
||||
local tile = shape(data)
|
||||
|
||||
if type(tile) == 'table' then
|
||||
do_tile_inner(tiles, tile.tile, pos)
|
||||
|
||||
local hidden_tile = tile.hidden_tile
|
||||
if hidden_tile then
|
||||
data.hidden_tiles[#data.hidden_tiles + 1] = {tile = hidden_tile, position = pos}
|
||||
end
|
||||
|
||||
local entities = tile.entities
|
||||
if entities then
|
||||
for _, entity in ipairs(entities) do
|
||||
if not entity.position then
|
||||
entity.position = pos
|
||||
end
|
||||
data.entities[#data.entities + 1] = entity
|
||||
end
|
||||
end
|
||||
|
||||
local buildings = tile.buildings
|
||||
if buildings then
|
||||
for _, entity in ipairs(buildings) do
|
||||
if not entity.position then
|
||||
entity.position = pos
|
||||
end
|
||||
data.buildings[#data.buildings + 1] = entity
|
||||
end
|
||||
end
|
||||
|
||||
local decoratives = tile.decoratives
|
||||
if decoratives then
|
||||
for _, decorative in ipairs(decoratives) do
|
||||
if not decorative.position then
|
||||
decorative.position = pos
|
||||
end
|
||||
data.decoratives[#data.decoratives + 1] = decorative
|
||||
end
|
||||
end
|
||||
|
||||
local markets = tile.markets
|
||||
if markets then
|
||||
for _, t in ipairs(markets) do
|
||||
if not t.position then
|
||||
t.position = pos
|
||||
end
|
||||
data.markets[#data.markets + 1] = t
|
||||
end
|
||||
end
|
||||
|
||||
local treasure = tile.treasure
|
||||
if treasure then
|
||||
for _, t in ipairs(treasure) do
|
||||
if not t.position then
|
||||
t.position = pos
|
||||
end
|
||||
data.treasure[#data.treasure + 1] = t
|
||||
end
|
||||
end
|
||||
else
|
||||
do_tile_inner(tiles, tile, pos)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function do_place_tiles(data)
|
||||
local surface = data.surface
|
||||
surface.set_tiles(data.tiles, true)
|
||||
end
|
||||
|
||||
local function do_place_hidden_tiles(data)
|
||||
local surface = data.surface
|
||||
surface.set_tiles(data.hidden_tiles, true)
|
||||
end
|
||||
|
||||
local function do_place_decoratives(data)
|
||||
local surface = data.surface
|
||||
if regen_decoratives then
|
||||
surface.regenerate_decorative(nil, {{data.top_x / 32, data.top_y / 32}})
|
||||
end
|
||||
|
||||
local dec = data.decoratives
|
||||
if #dec > 0 then
|
||||
surface.create_decoratives({check_collision = true, decoratives = dec})
|
||||
end
|
||||
end
|
||||
|
||||
local function do_place_buildings(data)
|
||||
local surface = data.surface
|
||||
local entity
|
||||
local callback
|
||||
for _, e in ipairs(data.buildings) do
|
||||
if e.e_type then
|
||||
local p = e.position
|
||||
if
|
||||
surface.count_entities_filtered {
|
||||
area = {{p.x - 32, p.y - 32}, {p.x + 32, p.y + 32}},
|
||||
type = e.e_type,
|
||||
limit = 1
|
||||
} == 0
|
||||
then
|
||||
entity = surface.create_entity(e)
|
||||
if entity and entity.valid then
|
||||
if e.direction then
|
||||
entity.direction = e.direction
|
||||
end
|
||||
if e.force then
|
||||
entity.force = e.force
|
||||
end
|
||||
if e.callback then
|
||||
local c = e.callback.callback
|
||||
if c then
|
||||
local d = {callback_data = e.callback.data}
|
||||
if not d then
|
||||
callback = Token.get(c)
|
||||
callback(entity)
|
||||
else
|
||||
callback = Token.get(c)
|
||||
callback(entity, d)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function do_place_entities(data)
|
||||
local surface = data.surface
|
||||
local entity
|
||||
local callback
|
||||
for _, e in ipairs(data.entities) do
|
||||
if e.collision then
|
||||
if surface.can_place_entity(e) then
|
||||
entity = surface.create_entity(e)
|
||||
if entity then
|
||||
if e.direction then
|
||||
entity.direction = e.direction
|
||||
end
|
||||
if e.force then
|
||||
entity.force = e.force
|
||||
end
|
||||
if e.amount then
|
||||
entity.amount = e.amount
|
||||
end
|
||||
if e.callback then
|
||||
local c = e.callback.callback
|
||||
if not c then
|
||||
return
|
||||
end
|
||||
local d = {callback_data = e.callback.data}
|
||||
if not d then
|
||||
callback = Token.get(c)
|
||||
callback(entity)
|
||||
else
|
||||
callback = Token.get(c)
|
||||
callback(entity, d)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
entity = surface.create_entity(e)
|
||||
if entity then
|
||||
if e.direction then
|
||||
entity.direction = e.direction
|
||||
end
|
||||
if e.force then
|
||||
entity.force = e.force
|
||||
end
|
||||
if e.amount then
|
||||
entity.amount = e.amount
|
||||
end
|
||||
if e.callback then
|
||||
local c = e.callback.callback
|
||||
if c then
|
||||
local d = {callback_data = e.callback.data}
|
||||
if not d then
|
||||
callback = Token.get(c)
|
||||
callback(entity)
|
||||
else
|
||||
callback = Token.get(c)
|
||||
callback(entity, d)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function run_chart_update(data)
|
||||
local x = data.top_x / 32
|
||||
local y = data.top_y / 32
|
||||
local surface = data.surface
|
||||
if not surface or not surface.valid then
|
||||
return
|
||||
end
|
||||
if game.forces.player.is_chunk_charted(surface, {x, y}) then
|
||||
-- Don't use full area, otherwise adjacent chunks get charted
|
||||
game.forces.player.chart(
|
||||
surface,
|
||||
{
|
||||
{data.top_x, data.top_y},
|
||||
{data.top_x + 1, data.top_y + 1}
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
local function map_gen_action(data)
|
||||
local state = data.y
|
||||
|
||||
if state < 32 then
|
||||
local shape = generate_map
|
||||
if shape == nil then
|
||||
return false
|
||||
end
|
||||
|
||||
if not data.surface.valid then
|
||||
return
|
||||
end
|
||||
|
||||
local count = tiles_per_call
|
||||
|
||||
local y = state + data.top_y
|
||||
local x = data.x
|
||||
|
||||
local max_x = data.top_x + 32
|
||||
|
||||
data.y = y
|
||||
|
||||
repeat
|
||||
count = count - 1
|
||||
get_position(data)
|
||||
do_tile(x, y, data, shape)
|
||||
|
||||
x = x + 1
|
||||
|
||||
if x == max_x then
|
||||
y = y + 1
|
||||
if y == data.top_y + 32 then
|
||||
break
|
||||
end
|
||||
x = data.top_x
|
||||
data.y = y
|
||||
end
|
||||
|
||||
data.x = x
|
||||
until count == 0
|
||||
|
||||
data.y = y - data.top_y
|
||||
return true
|
||||
elseif state == 32 then
|
||||
do_place_tiles(data)
|
||||
data.y = 33
|
||||
return true
|
||||
elseif state == 33 then
|
||||
do_place_hidden_tiles(data)
|
||||
data.y = 34
|
||||
return true
|
||||
elseif state == 34 then
|
||||
do_place_entities(data)
|
||||
data.y = 35
|
||||
return true
|
||||
elseif state == 35 then
|
||||
do_place_buildings(data)
|
||||
data.y = 36
|
||||
return true
|
||||
elseif state == 36 then
|
||||
do_place_decoratives(data)
|
||||
data.y = 37
|
||||
return true
|
||||
elseif state == 37 then
|
||||
run_chart_update(data)
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
local map_gen_action_token = Token.register(map_gen_action)
|
||||
|
||||
--- Adds generation of a Chunk of the map to the queue
|
||||
-- @param event <table> the event table from on_chunk_generated
|
||||
function Public.schedule_chunk(event)
|
||||
local surface = event.surface
|
||||
local shape = generate_map
|
||||
|
||||
if event.tick < 1 then
|
||||
return
|
||||
end
|
||||
|
||||
if not surface.valid then
|
||||
return
|
||||
end
|
||||
|
||||
if not shape then
|
||||
return
|
||||
end
|
||||
|
||||
local area = event.area
|
||||
|
||||
local data = {
|
||||
yv = -0,
|
||||
xv = 0,
|
||||
y = 0,
|
||||
x = area.left_top.x,
|
||||
area = area,
|
||||
top_x = area.left_top.x,
|
||||
top_y = area.left_top.y,
|
||||
surface = surface,
|
||||
tiles = {},
|
||||
hidden_tiles = {},
|
||||
entities = {},
|
||||
buildings = {},
|
||||
decoratives = {},
|
||||
markets = {},
|
||||
treasure = {}
|
||||
}
|
||||
|
||||
if not data.surface or not data.surface.valid then
|
||||
return
|
||||
end
|
||||
|
||||
queue_task(map_gen_action_token, data, total_calls)
|
||||
end
|
||||
|
||||
--- Generates a Chunk of map when called
|
||||
-- @param event <table> the event table from on_chunk_generated
|
||||
function Public.do_chunk(event)
|
||||
local surface = event.surface
|
||||
local shape = generate_map
|
||||
|
||||
if not surface.valid then
|
||||
return
|
||||
end
|
||||
|
||||
if not shape then
|
||||
return
|
||||
end
|
||||
|
||||
local area = event.area
|
||||
|
||||
local data = {
|
||||
yv = -0,
|
||||
xv = 0,
|
||||
area = area,
|
||||
top_x = area.left_top.x,
|
||||
top_y = area.left_top.y,
|
||||
surface = surface,
|
||||
tiles = {},
|
||||
hidden_tiles = {},
|
||||
entities = {},
|
||||
buildings = {},
|
||||
decoratives = {},
|
||||
markets = {},
|
||||
treasure = {}
|
||||
}
|
||||
|
||||
if not data.surface.valid then
|
||||
return
|
||||
end
|
||||
|
||||
for row = 0, 31 do
|
||||
do_row(row, data, shape)
|
||||
end
|
||||
|
||||
do_place_tiles(data)
|
||||
do_place_hidden_tiles(data)
|
||||
do_place_entities(data)
|
||||
do_place_buildings(data)
|
||||
do_place_decoratives(data)
|
||||
end
|
||||
|
||||
local do_chunk = Public.do_chunk
|
||||
local schedule_chunk = Public.schedule_chunk
|
||||
|
||||
local function on_chunk(event)
|
||||
if force_chunk then
|
||||
do_chunk(event)
|
||||
else
|
||||
schedule_chunk(event)
|
||||
end
|
||||
end
|
||||
|
||||
Event.add(defines.events.on_chunk_generated, on_chunk)
|
||||
|
||||
return Public
|
142
maps/deep_jungle/main.lua
Normal file
142
maps/deep_jungle/main.lua
Normal file
@ -0,0 +1,142 @@
|
||||
require 'modules.no_deconstruction_of_neutral_entities'
|
||||
require 'modules.spawners_contain_biters'
|
||||
require 'modules.biters_yield_coins'
|
||||
require 'modules.rocks_yield_coins'
|
||||
require 'modules.flashlight_toggle_button'
|
||||
require 'maps.deep_jungle.generate'
|
||||
local Global = require 'utils.global'
|
||||
local Event = require 'utils.event'
|
||||
local map_functions = require 'tools.map_functions'
|
||||
local random = math.random
|
||||
|
||||
local this = {
|
||||
chunks_charted = {}
|
||||
}
|
||||
|
||||
Global.register(
|
||||
this,
|
||||
function(tbl)
|
||||
this = tbl
|
||||
end
|
||||
)
|
||||
|
||||
local Public = {}
|
||||
|
||||
local function on_chunk_charted(event)
|
||||
local surface = game.get_surface(event.surface_index)
|
||||
local deco = game.decorative_prototypes
|
||||
local position = event.position
|
||||
if this.chunks_charted[tostring(position.x) .. tostring(position.y)] then
|
||||
return
|
||||
end
|
||||
this.chunks_charted[tostring(position.x) .. tostring(position.y)] = true
|
||||
|
||||
local decorative_names = {}
|
||||
for k, v in pairs(deco) do
|
||||
if v.autoplace_specification then
|
||||
decorative_names[#decorative_names + 1] = k
|
||||
end
|
||||
end
|
||||
surface.regenerate_decorative(decorative_names, {position})
|
||||
|
||||
if random(1, 14) ~= 1 then
|
||||
return
|
||||
end
|
||||
|
||||
map_functions.draw_rainbow_patch({x = position.x * 32 + random(1, 32), y = position.y * 32 + random(1, 32)}, surface, random(14, 26), 2000)
|
||||
end
|
||||
|
||||
local function on_player_joined_game(event)
|
||||
local player = game.get_player(event.player_index)
|
||||
local surface = game.get_surface('deep_jungle')
|
||||
if player.online_time < 5 and surface.is_chunk_generated({0, 0}) then
|
||||
player.teleport(surface.find_non_colliding_position('character', {0, 0}, 2, 1), 'deep_jungle')
|
||||
else
|
||||
if player.online_time < 5 then
|
||||
player.teleport({0, 0}, 'deep_jungle')
|
||||
end
|
||||
end
|
||||
if player.online_time < 2 then
|
||||
player.insert {name = 'iron-plate', count = 32}
|
||||
end
|
||||
end
|
||||
|
||||
local function on_entity_died(event)
|
||||
local entity = event.entity
|
||||
if not entity or not entity.valid then
|
||||
return
|
||||
end
|
||||
local surface = entity.surface
|
||||
if entity.type == 'tree' then
|
||||
if random(1, 8) == 1 then
|
||||
local p = surface.find_non_colliding_position('small-biter', entity.position, 2, 0.5)
|
||||
if p then
|
||||
surface.create_entity {name = 'small-biter', position = entity.position}
|
||||
end
|
||||
return
|
||||
end
|
||||
if random(1, 16) == 1 then
|
||||
local p = surface.find_non_colliding_position('medium-biter', entity.position, 2, 0.5)
|
||||
if p then
|
||||
surface.create_entity {name = 'medium-biter', position = entity.position}
|
||||
end
|
||||
return
|
||||
end
|
||||
if random(1, 32) == 1 then
|
||||
local p = surface.find_non_colliding_position('big-biter', entity.position, 2, 0.5)
|
||||
if p then
|
||||
surface.create_entity {name = 'big-biter', position = entity.position}
|
||||
end
|
||||
return
|
||||
end
|
||||
if random(1, 512) == 1 then
|
||||
local p = surface.find_non_colliding_position('behemoth-biter', entity.position, 2, 0.5)
|
||||
if p then
|
||||
surface.create_entity {name = 'behemoth-biter', position = entity.position}
|
||||
end
|
||||
return
|
||||
end
|
||||
end
|
||||
if entity.type == 'simple-entity' then
|
||||
if random(1, 8) == 1 then
|
||||
surface.create_entity {name = 'small-worm-turret', position = entity.position}
|
||||
return
|
||||
end
|
||||
if random(1, 16) == 1 then
|
||||
surface.create_entity {name = 'medium-worm-turret', position = entity.position}
|
||||
return
|
||||
end
|
||||
if random(1, 32) == 1 then
|
||||
surface.create_entity {name = 'big-worm-turret', position = entity.position}
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function on_init()
|
||||
local map_gen_settings = {}
|
||||
map_gen_settings.moisture = 0.99
|
||||
map_gen_settings.water = 'none'
|
||||
map_gen_settings.starting_area = 'normal'
|
||||
map_gen_settings.cliff_settings = {cliff_elevation_interval = 4, cliff_elevation_0 = 0.1}
|
||||
map_gen_settings.autoplace_controls = {
|
||||
['coal'] = {frequency = 'none', size = 'none', richness = 'none'},
|
||||
['stone'] = {frequency = 'none', size = 'none', richness = 'none'},
|
||||
['copper-ore'] = {frequency = 'none', size = 'none', richness = 'none'},
|
||||
['iron-ore'] = {frequency = 'none', size = 'none', richness = 'none'},
|
||||
['crude-oil'] = {frequency = 'very-high', size = 'big', richness = 'normal'},
|
||||
['trees'] = {frequency = 'none', size = 'none', richness = 'none'},
|
||||
['enemy-base'] = {frequency = 'high', size = 'big', richness = 'good'}
|
||||
}
|
||||
game.create_surface('deep_jungle', map_gen_settings)
|
||||
game.forces.player.set_spawn_position({0, 0}, game.surfaces['deep_jungle'])
|
||||
end
|
||||
|
||||
Event.on_init(on_init)
|
||||
Event.add(defines.events.on_chunk_charted, on_chunk_charted)
|
||||
Event.add(defines.events.on_entity_died, on_entity_died)
|
||||
Event.add(defines.events.on_player_joined_game, on_player_joined_game)
|
||||
|
||||
require 'modules.rocks_yield_ore'
|
||||
|
||||
return Public
|
291
maps/deep_jungle/terrain.lua
Normal file
291
maps/deep_jungle/terrain.lua
Normal file
@ -0,0 +1,291 @@
|
||||
local simplex_noise = require 'utils.simplex_noise'
|
||||
local random = math.random
|
||||
|
||||
local Public = {}
|
||||
|
||||
local function shuffle(tbl)
|
||||
local size = #tbl
|
||||
for i = size, 1, -1 do
|
||||
local rand = math.random(size)
|
||||
tbl[i], tbl[rand] = tbl[rand], tbl[i]
|
||||
end
|
||||
return tbl
|
||||
end
|
||||
|
||||
local function secret_shop(pos, surface)
|
||||
local secret_market_items = {
|
||||
{price = {{'coin', random(300, 600)}}, offer = {type = 'give-item', item = 'combat-shotgun'}},
|
||||
{price = {{'coin', random(200, 400)}}, offer = {type = 'give-item', item = 'rocket-launcher'}},
|
||||
{price = {{'coin', random(5, 10)}}, offer = {type = 'give-item', item = 'piercing-rounds-magazine'}},
|
||||
--{price = {{"coin", random(150,250)}}, offer = {type = 'give-item', item = 'uranium-rounds-magazine'}},
|
||||
{price = {{'coin', random(15, 30)}}, offer = {type = 'give-item', item = 'piercing-shotgun-shell'}},
|
||||
{price = {{'coin', random(10, 20)}}, offer = {type = 'give-item', item = 'rocket'}},
|
||||
{price = {{'coin', random(20, 30)}}, offer = {type = 'give-item', item = 'explosive-rocket'}},
|
||||
{price = {{'coin', random(30, 60)}}, offer = {type = 'give-item', item = 'cluster-grenade'}},
|
||||
{price = {{'coin', random(8, 16)}}, offer = {type = 'give-item', item = 'land-mine'}},
|
||||
{price = {{'coin', random(200, 300)}}, offer = {type = 'give-item', item = 'heavy-armor'}},
|
||||
{price = {{'coin', random(400, 800)}}, offer = {type = 'give-item', item = 'modular-armor'}},
|
||||
{price = {{'coin', random(1000, 2000)}}, offer = {type = 'give-item', item = 'power-armor'}},
|
||||
{price = {{'coin', random(2500, 5000)}}, offer = {type = 'give-item', item = 'fusion-reactor-equipment'}},
|
||||
{price = {{'coin', random(200, 400)}}, offer = {type = 'give-item', item = 'battery-equipment'}},
|
||||
{price = {{'coin', random(150, 250)}}, offer = {type = 'give-item', item = 'belt-immunity-equipment'}},
|
||||
{price = {{'coin', random(100, 200)}}, offer = {type = 'give-item', item = 'night-vision-equipment'}},
|
||||
{price = {{'coin', random(400, 800)}}, offer = {type = 'give-item', item = 'exoskeleton-equipment'}},
|
||||
{price = {{'coin', random(200, 300)}}, offer = {type = 'give-item', item = 'personal-roboport-equipment'}},
|
||||
{price = {{'coin', random(25, 50)}}, offer = {type = 'give-item', item = 'construction-robot'}},
|
||||
-- {price = {{"coin", random(10000,20000)}}, offer = {type = 'give-item', item = 'energy-shield-equipment'}},
|
||||
-- {price = {{"coin", random(5000,15000)}}, offer = {type = 'give-item', item = 'personal-laser-defense-equipment'}},
|
||||
{price = {{'coin', random(100, 300)}}, offer = {type = 'give-item', item = 'loader'}},
|
||||
{price = {{'coin', random(200, 400)}}, offer = {type = 'give-item', item = 'fast-loader'}},
|
||||
{price = {{'coin', random(300, 500)}}, offer = {type = 'give-item', item = 'express-loader'}},
|
||||
{price = {{'coin', random(150, 300)}}, offer = {type = 'give-item', item = 'locomotive'}},
|
||||
{price = {{'coin', random(100, 200)}}, offer = {type = 'give-item', item = 'cargo-wagon'}},
|
||||
{price = {{'coin', random(5, 15)}}, offer = {type = 'give-item', item = 'grenade'}},
|
||||
{price = {{'coin', random(80, 160)}}, offer = {type = 'give-item', item = 'cliff-explosives'}},
|
||||
{price = {{'coin', random(10, 20)}}, offer = {type = 'give-item', item = 'explosives', count = 50}},
|
||||
{price = {{'coin', random(4, 8)}}, offer = {type = 'give-item', item = 'rail', count = 4}},
|
||||
{price = {{'coin', random(20, 30)}}, offer = {type = 'give-item', item = 'train-stop'}},
|
||||
{price = {{'coin', random(4, 12)}}, offer = {type = 'give-item', item = 'small-lamp'}},
|
||||
{price = {{'coin', random(1, 4)}}, offer = {type = 'give-item', item = 'firearm-magazine'}},
|
||||
{price = {{'coin', random(60, 150)}}, offer = {type = 'give-item', item = 'car', count = 1}},
|
||||
{price = {{'coin', random(75, 150)}}, offer = {type = 'give-item', item = 'gun-turret', count = 1}},
|
||||
{price = {{'coin', random(500, 750)}}, offer = {type = 'give-item', item = 'laser-turret', count = 1}},
|
||||
{price = {{'coin', random(1000, 2000)}}, offer = {type = 'give-item', item = 'artillery-turret', count = 1}},
|
||||
{price = {{'coin', random(100, 200)}}, offer = {type = 'give-item', item = 'artillery-shell', count = 1}},
|
||||
{price = {{'coin', random(50, 150)}}, offer = {type = 'give-item', item = 'artillery-targeting-remote', count = 1}},
|
||||
{price = {{'coin', random(5, 15)}}, offer = {type = 'give-item', item = 'shotgun-shell', count = 1}},
|
||||
{price = {{'coin', random(8000, 16000)}}, offer = {type = 'give-item', item = 'power-armor-mk2', count = 1}},
|
||||
{price = {{'coin', random(80, 160)}}, offer = {type = 'give-item', item = 'solar-panel-equipment', count = 1}},
|
||||
{price = {{'coin', random(4, 8)}}, offer = {type = 'give-item', item = 'wood', count = 50}},
|
||||
{price = {{'coin', random(4, 8)}}, offer = {type = 'give-item', item = 'iron-ore', count = 50}},
|
||||
{price = {{'coin', random(4, 8)}}, offer = {type = 'give-item', item = 'copper-ore', count = 50}},
|
||||
{price = {{'coin', random(4, 8)}}, offer = {type = 'give-item', item = 'stone', count = 50}},
|
||||
{price = {{'coin', random(4, 8)}}, offer = {type = 'give-item', item = 'coal', count = 50}}
|
||||
--{price = {{"coin", random(4,8)}}, offer = {type = 'give-item', item = 'uranium-ore', count = 50}}
|
||||
}
|
||||
secret_market_items = shuffle(secret_market_items)
|
||||
|
||||
local market = surface.create_entity {name = 'market', position = pos}
|
||||
market.destructible = false
|
||||
|
||||
for i = 1, math.random(6, 10), 1 do
|
||||
market.add_market_item(secret_market_items[i])
|
||||
end
|
||||
end
|
||||
|
||||
local function treasure_chest(position)
|
||||
if not game.surfaces['deep_jungle'].can_place_entity({name = 'steel-chest', position = position, force = 'player'}) then
|
||||
return
|
||||
end
|
||||
local treasure_chest_raffle_table = {}
|
||||
local treasure_chest_loot_weights = {}
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'landfill', count = random(8, 16)}, 16})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'iron-gear-wheel', count = random(16, 48)}, 8})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'coal', count = random(16, 48)}, 2})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'copper-cable', count = random(64, 128)}, 8})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'inserter', count = random(4, 8)}, 4})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'fast-inserter', count = random(4, 8)}, 3})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'burner-inserter', count = random(4, 8)}, 6})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'rocket-fuel', count = random(1, 5)}, 3})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'small-electric-pole', count = random(4, 8)}, 7})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'firearm-magazine', count = random(16, 48)}, 8})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'submachine-gun', count = 1}, 4})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'grenade', count = random(6, 12)}, 5})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'land-mine', count = random(8, 16)}, 5})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'light-armor', count = 1}, 1})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'heavy-armor', count = 1}, 2})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'pipe', count = random(10, 100)}, 6})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'explosives', count = random(40, 50)}, 6})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'shotgun', count = 1}, 3})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'shotgun-shell', count = random(8, 16)}, 3})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'stone-brick', count = random(80, 100)}, 4})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'small-lamp', count = random(2, 4)}, 2})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'rail', count = random(16, 48)}, 3})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'coin', count = random(32, 320)}, 1})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'assembling-machine-1', count = random(1, 3)}, 3})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'assembling-machine-2', count = random(1, 3)}, 2})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'assembling-machine-3', count = random(1, 2)}, 1})
|
||||
for _, t in pairs(treasure_chest_loot_weights) do
|
||||
for _ = 1, t[2], 1 do
|
||||
table.insert(treasure_chest_raffle_table, t[1])
|
||||
end
|
||||
end
|
||||
|
||||
local e = game.surfaces['deep_jungle'].create_entity {name = 'wooden-chest', position = position, force = 'player'}
|
||||
e.minable = false
|
||||
local i = e.get_inventory(defines.inventory.chest)
|
||||
for _ = 1, random(3, 7), 1 do
|
||||
local loot = treasure_chest_raffle_table[random(1, #treasure_chest_raffle_table)]
|
||||
i.insert(loot)
|
||||
end
|
||||
end
|
||||
|
||||
local function rare_treasure_chest(position)
|
||||
if not game.surfaces['deep_jungle'].can_place_entity({name = 'steel-chest', position = position, force = 'player'}) then
|
||||
return
|
||||
end
|
||||
local rare_treasure_chest_raffle_table = {}
|
||||
local rare_treasure_chest_loot_weights = {}
|
||||
table.insert(rare_treasure_chest_loot_weights, {{name = 'combat-shotgun', count = 1}, 5})
|
||||
table.insert(rare_treasure_chest_loot_weights, {{name = 'piercing-shotgun-shell', count = random(8, 16)}, 5})
|
||||
table.insert(rare_treasure_chest_loot_weights, {{name = 'rocket-launcher', count = 1}, 5})
|
||||
table.insert(rare_treasure_chest_loot_weights, {{name = 'rocket', count = random(4, 8)}, 5})
|
||||
table.insert(rare_treasure_chest_loot_weights, {{name = 'explosive-rocket', count = random(4, 8)}, 5})
|
||||
table.insert(rare_treasure_chest_loot_weights, {{name = 'modular-armor', count = 1}, 3})
|
||||
table.insert(rare_treasure_chest_loot_weights, {{name = 'piercing-rounds-magazine', count = random(32, 64)}, 3})
|
||||
table.insert(rare_treasure_chest_loot_weights, {{name = 'defender-capsule', count = random(4, 8)}, 5})
|
||||
table.insert(rare_treasure_chest_loot_weights, {{name = 'distractor-capsule', count = random(3, 5)}, 4})
|
||||
table.insert(rare_treasure_chest_loot_weights, {{name = 'destroyer-capsule', count = random(2, 3)}, 3})
|
||||
for _, t in pairs(rare_treasure_chest_loot_weights) do
|
||||
for _ = 1, t[2], 1 do
|
||||
table.insert(rare_treasure_chest_raffle_table, t[1])
|
||||
end
|
||||
end
|
||||
|
||||
local e = game.surfaces['deep_jungle'].create_entity {name = 'steel-chest', position = position, force = 'player'}
|
||||
e.minable = false
|
||||
local i = e.get_inventory(defines.inventory.chest)
|
||||
for _ = 1, random(2, 3), 1 do
|
||||
local loot = rare_treasure_chest_raffle_table[random(1, #rare_treasure_chest_raffle_table)]
|
||||
i.insert(loot)
|
||||
end
|
||||
end
|
||||
|
||||
local function get_noise(name, pos)
|
||||
local seed = game.surfaces[1].map_gen_settings.seed
|
||||
local d2 = simplex_noise.d2
|
||||
local noise_seed_add = 25000
|
||||
if name == 1 then
|
||||
local noise = {}
|
||||
noise[1] = d2(pos.x * 0.001, pos.y * 0.001, seed)
|
||||
seed = seed + noise_seed_add
|
||||
noise[2] = d2(pos.x * 0.01, pos.y * 0.01, seed + noise_seed_add)
|
||||
noise = noise[1] + noise[2] * 0.1
|
||||
return noise
|
||||
end
|
||||
if name == 2 then
|
||||
local noise = {}
|
||||
noise[1] = d2(pos.x * 0.015, pos.y * 0.015, seed)
|
||||
seed = seed + noise_seed_add
|
||||
noise[2] = d2(pos.x * 0.15, pos.y * 0.15, seed + noise_seed_add)
|
||||
noise = noise[1] + noise[2] * 0.2
|
||||
return noise
|
||||
end
|
||||
if name == 3 then
|
||||
local noise = {}
|
||||
noise[1] = d2(pos.x * 0.025, pos.y * 0.025, seed)
|
||||
seed = seed + noise_seed_add
|
||||
noise[2] = d2(pos.x * 0.2, pos.y * 0.2, seed + noise_seed_add)
|
||||
noise = noise[1] + noise[2] * 0.2
|
||||
return noise
|
||||
end
|
||||
if name == 'greenwater' then
|
||||
local noise = {}
|
||||
noise[1] = d2(pos.x * 0.003, pos.y * 0.003, seed)
|
||||
seed = seed + noise_seed_add
|
||||
noise[2] = d2(pos.x * 0.03, pos.y * 0.03, seed + noise_seed_add)
|
||||
noise = noise[1] + noise[2] * 0.1
|
||||
return noise
|
||||
end
|
||||
end
|
||||
|
||||
local rock_raffle = {'sand-rock-big', 'sand-rock-big', 'rock-big', 'rock-big', 'rock-big', 'rock-big', 'rock-huge'}
|
||||
local tree_raffle = {'tree-04', 'tree-07', 'tree-09', 'tree-06', 'tree-04', 'tree-07', 'tree-09', 'tree-04'}
|
||||
|
||||
local function process_tile(pos)
|
||||
local noise_1 = get_noise(1, pos)
|
||||
if noise_1 > -0.03 and noise_1 < 0.03 then
|
||||
return 'deepwater'
|
||||
end
|
||||
if noise_1 > -0.05 and noise_1 < 0.05 then
|
||||
return 'water'
|
||||
end
|
||||
local noise_greenwater = get_noise('greenwater', pos)
|
||||
if noise_greenwater > -0.035 and noise_greenwater < 0.035 then
|
||||
return 'water-green'
|
||||
end
|
||||
if noise_1 > -0.08 and noise_1 < 0.08 then
|
||||
return false
|
||||
end
|
||||
|
||||
local noise_2 = get_noise(2, pos)
|
||||
if noise_2 > 0.37 or noise_2 < -0.37 then
|
||||
if random(1, 4) == 1 then
|
||||
return false, tree_raffle[math.ceil(math.abs(noise_1 * 8))]
|
||||
end
|
||||
end
|
||||
local noise_3 = get_noise(3, pos)
|
||||
if noise_3 > 0.5 then
|
||||
if random(1, 3) == 1 then
|
||||
return false, rock_raffle[random(1, #rock_raffle)]
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
local function process_bits(data)
|
||||
local pos = data.position
|
||||
local tiles = data.tiles
|
||||
local entities = data.entities
|
||||
|
||||
local surface = game.surfaces['deep_jungle']
|
||||
|
||||
local treasure_chests = {}
|
||||
local rare_treasure_chests = {}
|
||||
local secret_shops = {}
|
||||
|
||||
local tile_to_insert, entity_to_place = process_tile(pos)
|
||||
if entity_to_place then
|
||||
entities[#entities + 1] = {name = entity_to_place, position = pos, force = 'player'}
|
||||
end
|
||||
|
||||
if tile_to_insert then
|
||||
tiles[#tiles + 1] = {name = tile_to_insert, position = pos}
|
||||
if random(1, 40) == 1 and tile_to_insert == 'deepwater' then
|
||||
entities[#entities + 1] = {name = 'fish', position = pos}
|
||||
end
|
||||
end
|
||||
|
||||
if random(1, 1500) == 1 then
|
||||
table.insert(treasure_chests, pos)
|
||||
end
|
||||
if random(1, 16000) == 1 then
|
||||
table.insert(rare_treasure_chests, pos)
|
||||
end
|
||||
if random(1, 8000) == 1 then
|
||||
table.insert(secret_shops, pos)
|
||||
end
|
||||
|
||||
for _, v in pairs(treasure_chests) do
|
||||
treasure_chest(v)
|
||||
end
|
||||
for _, v in pairs(rare_treasure_chests) do
|
||||
rare_treasure_chest(v)
|
||||
end
|
||||
for _, v in pairs(secret_shops) do
|
||||
if not surface.get_tile(v).collides_with('player-layer') then
|
||||
local area = {{v.x - 128, v.y - 128}, {v.x + 128, v.y + 128}}
|
||||
if surface.count_entities_filtered({name = 'market', area = area}) == 0 then
|
||||
secret_shop(v, surface)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Public.heavy_functions(data)
|
||||
local surface = data.surface
|
||||
local map_name = 'deep_jungle'
|
||||
|
||||
if string.sub(surface.name, 0, #map_name) ~= map_name then
|
||||
return
|
||||
end
|
||||
|
||||
if not data.seed then
|
||||
data.seed = surface.map_gen_settings.seed
|
||||
end
|
||||
|
||||
process_bits(data)
|
||||
end
|
||||
|
||||
return Public
|
@ -1,477 +0,0 @@
|
||||
--luacheck: ignore
|
||||
--deep jungle-- mewmew made this --
|
||||
local map_functions = require 'tools.map_functions'
|
||||
local simplex_noise = require 'utils.simplex_noise'
|
||||
simplex_noise = simplex_noise.d2
|
||||
local event = require 'utils.event'
|
||||
local math_random = math.random
|
||||
|
||||
local function treasure_chest(position)
|
||||
local p = game.surfaces['deep_jungle'].find_non_colliding_position('wooden-chest', position, 2, 0.5)
|
||||
if not p then
|
||||
return
|
||||
end
|
||||
|
||||
treasure_chest_raffle_table = {}
|
||||
treasure_chest_loot_weights = {}
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'iron-gear-wheel', count = math_random(16, 48)}, 10})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'coal', count = math_random(16, 48)}, 2})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'copper-cable', count = math_random(64, 128)}, 10})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'inserter', count = math_random(8, 16)}, 4})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'fast-inserter', count = math_random(4, 8)}, 3})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'stack-filter-inserter', count = math_random(2, 4)}, 1})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'stack-inserter', count = math_random(2, 4)}, 1})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'burner-inserter', count = math_random(16, 32)}, 6})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'electric-engine-unit', count = math_random(1, 16)}, 3})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'engine-unit', count = math_random(1, 16)}, 3})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'rocket-fuel', count = math_random(1, 5)}, 3})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'empty-barrel', count = math_random(1, 10)}, 7})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'lubricant-barrel', count = math_random(1, 10)}, 3})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'crude-oil-barrel', count = math_random(1, 10)}, 3})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'iron-stick', count = math_random(1, 100)}, 8})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'small-electric-pole', count = math_random(8, 32)}, 9})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'firearm-magazine', count = math_random(16, 48)}, 8})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'grenade', count = math_random(16, 32)}, 5})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'land-mine', count = math_random(24, 48)}, 5})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'light-armor', count = 1}, 1})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'heavy-armor', count = 1}, 2})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'pipe', count = math_random(10, 100)}, 6})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'wooden-chest', count = 1}, 1})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'burner-mining-drill', count = 1}, 1})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'iron-axe', count = 1}, 1})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'steel-axe', count = 1}, 3})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'raw-wood', count = math_random(5, 50)}, 2})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'sulfur', count = math_random(20, 50)}, 7})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'explosives', count = math_random(20, 50)}, 6})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'shotgun', count = 1}, 2})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'stone-brick', count = math_random(80, 100)}, 4})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'small-lamp', count = math_random(3, 10)}, 4})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'rail', count = math_random(32, 100)}, 4})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'coin', count = math_random(32, 100)}, 1})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'assembling-machine-1', count = math_random(1, 4)}, 2})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'assembling-machine-2', count = math_random(1, 3)}, 2})
|
||||
table.insert(treasure_chest_loot_weights, {{name = 'assembling-machine-3', count = math_random(1, 2)}, 1})
|
||||
for _, t in pairs(treasure_chest_loot_weights) do
|
||||
for x = 1, t[2], 1 do
|
||||
table.insert(treasure_chest_raffle_table, t[1])
|
||||
end
|
||||
end
|
||||
|
||||
local e = game.surfaces['deep_jungle'].create_entity {name = 'wooden-chest', position = p, force = 'player'}
|
||||
e.minable = false
|
||||
local i = e.get_inventory(defines.inventory.chest)
|
||||
for x = 1, math_random(3, 7), 1 do
|
||||
local loot = treasure_chest_raffle_table[math_random(1, #treasure_chest_raffle_table)]
|
||||
i.insert(loot)
|
||||
end
|
||||
end
|
||||
|
||||
local function rare_treasure_chest(position)
|
||||
local p = game.surfaces['deep_jungle'].find_non_colliding_position('steel-chest', position, 2, 0.5)
|
||||
if not p then
|
||||
return
|
||||
end
|
||||
|
||||
local rare_treasure_chest_raffle_table = {}
|
||||
local rare_treasure_chest_loot_weights = {}
|
||||
table.insert(rare_treasure_chest_loot_weights, {{name = 'combat-shotgun', count = 1}, 5})
|
||||
table.insert(rare_treasure_chest_loot_weights, {{name = 'piercing-shotgun-shell', count = math_random(16, 48)}, 5})
|
||||
table.insert(rare_treasure_chest_loot_weights, {{name = 'rocket-launcher', count = 1}, 5})
|
||||
table.insert(rare_treasure_chest_loot_weights, {{name = 'rocket', count = math_random(16, 48)}, 5})
|
||||
table.insert(rare_treasure_chest_loot_weights, {{name = 'explosive-rocket', count = math_random(16, 48)}, 5})
|
||||
table.insert(rare_treasure_chest_loot_weights, {{name = 'modular-armor', count = 1}, 3})
|
||||
table.insert(rare_treasure_chest_loot_weights, {{name = 'power-armor', count = 1}, 1})
|
||||
table.insert(rare_treasure_chest_loot_weights, {{name = 'uranium-rounds-magazine', count = math_random(16, 48)}, 3})
|
||||
table.insert(rare_treasure_chest_loot_weights, {{name = 'piercing-rounds-magazine', count = math_random(64, 128)}, 3})
|
||||
table.insert(rare_treasure_chest_loot_weights, {{name = 'exoskeleton-equipment', count = 1}, 2})
|
||||
table.insert(rare_treasure_chest_loot_weights, {{name = 'defender-capsule', count = math_random(8, 16)}, 5})
|
||||
table.insert(rare_treasure_chest_loot_weights, {{name = 'distractor-capsule', count = math_random(4, 8)}, 4})
|
||||
table.insert(rare_treasure_chest_loot_weights, {{name = 'destroyer-capsule', count = math_random(4, 8)}, 3})
|
||||
table.insert(rare_treasure_chest_loot_weights, {{name = 'atomic-bomb', count = 1}, 1})
|
||||
for _, t in pairs(rare_treasure_chest_loot_weights) do
|
||||
for x = 1, t[2], 1 do
|
||||
table.insert(rare_treasure_chest_raffle_table, t[1])
|
||||
end
|
||||
end
|
||||
|
||||
local e = game.surfaces['deep_jungle'].create_entity {name = 'steel-chest', position = p, force = 'player'}
|
||||
e.minable = false
|
||||
local i = e.get_inventory(defines.inventory.chest)
|
||||
for x = 1, math_random(2, 3), 1 do
|
||||
local loot = rare_treasure_chest_raffle_table[math_random(1, #rare_treasure_chest_raffle_table)]
|
||||
i.insert(loot)
|
||||
end
|
||||
end
|
||||
|
||||
local function get_noise(name, pos)
|
||||
local seed = game.surfaces[1].map_gen_settings.seed
|
||||
local noise_seed_add = 25000
|
||||
seed = seed + noise_seed_add
|
||||
if name == 1 then
|
||||
local noise = {}
|
||||
noise[1] = simplex_noise(pos.x * 0.01, pos.y * 0.01, seed)
|
||||
seed = seed + noise_seed_add
|
||||
noise[2] = simplex_noise(pos.x * 0.1, pos.y * 0.1, seed)
|
||||
local noise = noise[1] + noise[2] * 0.1
|
||||
return noise
|
||||
end
|
||||
seed = seed + noise_seed_add
|
||||
seed = seed + noise_seed_add
|
||||
if name == 2 then
|
||||
local noise = {}
|
||||
noise[1] = simplex_noise(pos.x * 0.01, pos.y * 0.01, seed)
|
||||
seed = seed + noise_seed_add
|
||||
noise[2] = simplex_noise(pos.x * 0.1, pos.y * 0.1, seed)
|
||||
local noise = noise[1] + noise[2] * 0.1
|
||||
return noise
|
||||
end
|
||||
seed = seed + noise_seed_add
|
||||
seed = seed + noise_seed_add
|
||||
if name == 3 then
|
||||
local noise = {}
|
||||
noise[1] = simplex_noise(pos.x * 0.001, pos.y * 0.001, seed)
|
||||
seed = seed + noise_seed_add
|
||||
noise[2] = simplex_noise(pos.x * 0.01, pos.y * 0.01, seed)
|
||||
local noise = noise[1] + noise[2] * 0.1
|
||||
return noise
|
||||
end
|
||||
seed = seed + noise_seed_add
|
||||
seed = seed + noise_seed_add
|
||||
if name == 4 then
|
||||
local noise = {}
|
||||
noise[1] = simplex_noise(pos.x * 0.01, pos.y * 0.01, seed)
|
||||
seed = seed + noise_seed_add
|
||||
noise[2] = simplex_noise(pos.x * 0.1, pos.y * 0.1, seed)
|
||||
local noise = noise[1] + noise[2] * 0.2
|
||||
return noise
|
||||
end
|
||||
seed = seed + noise_seed_add
|
||||
seed = seed + noise_seed_add
|
||||
if name == 5 then
|
||||
local noise = {}
|
||||
noise[1] = simplex_noise(pos.x * 0.05, pos.y * 0.05, seed)
|
||||
local noise = noise[1]
|
||||
return noise
|
||||
end
|
||||
seed = seed + noise_seed_add
|
||||
seed = seed + noise_seed_add
|
||||
if name == 6 then
|
||||
local noise = {}
|
||||
noise[1] = simplex_noise(pos.x * 0.05, pos.y * 0.05, seed)
|
||||
local noise = noise[1]
|
||||
return noise
|
||||
end
|
||||
end
|
||||
|
||||
local worm_raffle = {'small-worm-turret', 'small-worm-turret', 'small-worm-turret', 'medium-worm-turret', 'medium-worm-turret', 'big-worm-turret'}
|
||||
local rock_raffle = {'sand-rock-big', 'sand-rock-big', 'rock-big', 'rock-big', 'rock-big', 'rock-big', 'rock-huge'}
|
||||
|
||||
local function on_chunk_generated(event)
|
||||
local surface = game.surfaces['deep_jungle']
|
||||
if event.surface.name ~= surface.name then
|
||||
return
|
||||
end
|
||||
|
||||
local chunk_pos_x = event.area.left_top.x
|
||||
local chunk_pos_y = event.area.left_top.y
|
||||
|
||||
local tiles = {}
|
||||
local entities_to_place = {
|
||||
rocks = {},
|
||||
worms = {},
|
||||
enemy_buildings = {},
|
||||
trees = {},
|
||||
fish = {},
|
||||
treasure_chests = {},
|
||||
rare_treasure_chests = {}
|
||||
}
|
||||
local decoratives = {}
|
||||
|
||||
local entities = surface.find_entities(event.area)
|
||||
for _, e in pairs(entities) do
|
||||
if e.type == 'tree' or e.force.name == 'enemy' then
|
||||
e.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
local tile_to_insert = false
|
||||
for x = 0, 31, 1 do
|
||||
for y = 0, 31, 1 do
|
||||
local pos_x = chunk_pos_x + x
|
||||
local pos_y = chunk_pos_y + y
|
||||
local pos = {x = pos_x, y = pos_y}
|
||||
tile_to_insert = false
|
||||
|
||||
local noise_3 = get_noise(3, pos)
|
||||
if noise_3 > -0.1 and noise_3 < 0.1 then
|
||||
if noise_3 > -0.05 and noise_3 < 0.05 then
|
||||
tile_to_insert = 'water'
|
||||
if math_random(1, 40) == 1 then
|
||||
table.insert(entities_to_place.fish, pos)
|
||||
end
|
||||
end
|
||||
if noise_3 > -0.03 and noise_3 < 0.03 then
|
||||
tile_to_insert = 'deepwater'
|
||||
if math_random(1, 40) == 1 then
|
||||
table.insert(entities_to_place.fish, pos)
|
||||
end
|
||||
end
|
||||
else
|
||||
local tile_distance_to_center = pos_x ^ 2 + pos_y ^ 2
|
||||
local noise_1 = get_noise(1, pos)
|
||||
local noise_2 = get_noise(2, pos)
|
||||
local noise_4 = get_noise(4, pos)
|
||||
if tile_distance_to_center > 10000 then
|
||||
if math_random(1, 500) == 1 then
|
||||
table.insert(entities_to_place.worms, pos)
|
||||
end
|
||||
if noise_4 > -0.1 and noise_4 < 0.1 and noise_1 > 0.3 and noise_2 > 0.3 then
|
||||
if math_random(1, 8) == 1 then
|
||||
table.insert(entities_to_place.rocks, pos)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if noise_4 < -0.8 or noise_4 > 0.8 then
|
||||
tile_to_insert = 'dirt-6'
|
||||
end
|
||||
if noise_3 < -0.1 then
|
||||
if noise_1 > 0.2 then
|
||||
if math_random(1, 4) == 1 then
|
||||
table.insert(entities_to_place.trees, {'tree-02', pos})
|
||||
end
|
||||
if math_random(1, 7500) == 1 then
|
||||
table.insert(entities_to_place.rare_treasure_chests, pos)
|
||||
end
|
||||
if math_random(1, 1250) == 1 then
|
||||
table.insert(entities_to_place.treasure_chests, pos)
|
||||
end
|
||||
if noise_1 > 0.8 and tile_distance_to_center > 8000 then
|
||||
tile_to_insert = 'water-green'
|
||||
if math_random(1, 24) == 1 then
|
||||
table.insert(entities_to_place.fish, pos)
|
||||
end
|
||||
end
|
||||
end
|
||||
if noise_1 < -0.2 then
|
||||
if math_random(1, 4) == 1 then
|
||||
table.insert(entities_to_place.trees, {'tree-04', pos})
|
||||
end
|
||||
if math_random(1, 7500) == 1 then
|
||||
table.insert(entities_to_place.rare_treasure_chests, pos)
|
||||
end
|
||||
if math_random(1, 1250) == 1 then
|
||||
table.insert(entities_to_place.treasure_chests, pos)
|
||||
end
|
||||
if noise_1 < -0.75 and tile_distance_to_center > 8000 then
|
||||
if math_random(1, 36) == 1 then
|
||||
table.insert(entities_to_place.enemy_buildings, pos)
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
if noise_2 > 0.2 then
|
||||
if math_random(1, 4) == 1 then
|
||||
table.insert(entities_to_place.trees, {'tree-07', pos})
|
||||
end
|
||||
if math_random(1, 7500) == 1 then
|
||||
table.insert(entities_to_place.rare_treasure_chests, pos)
|
||||
end
|
||||
if math_random(1, 1250) == 1 then
|
||||
table.insert(entities_to_place.treasure_chests, pos)
|
||||
end
|
||||
if noise_2 > 0.75 and tile_distance_to_center > 8000 then
|
||||
if math_random(1, 36) == 1 then
|
||||
table.insert(entities_to_place.enemy_buildings, pos)
|
||||
end
|
||||
end
|
||||
end
|
||||
if noise_2 < -0.2 then
|
||||
if math_random(1, 4) == 1 then
|
||||
table.insert(entities_to_place.trees, {'tree-09', pos})
|
||||
end
|
||||
if math_random(1, 7500) == 1 then
|
||||
table.insert(entities_to_place.rare_treasure_chests, pos)
|
||||
end
|
||||
if math_random(1, 1250) == 1 then
|
||||
table.insert(entities_to_place.treasure_chests, pos)
|
||||
end
|
||||
if noise_2 < -0.8 and tile_distance_to_center > 8000 then
|
||||
tile_to_insert = 'water-green'
|
||||
if math_random(1, 24) == 1 then
|
||||
table.insert(entities_to_place.fish, pos)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if tile_to_insert ~= 'deepwater' and tile_to_insert ~= 'water' and tile_to_insert ~= 'water-green' then
|
||||
if math_random(1, 3) == 1 then
|
||||
local noise = get_noise(5, pos)
|
||||
if noise > 0.2 then
|
||||
table.insert(decoratives, {name = 'green-hairy-grass', position = pos, amount = 2})
|
||||
end
|
||||
if noise < -0.7 then
|
||||
table.insert(decoratives, {name = 'green-pita', position = pos, amount = 2})
|
||||
end
|
||||
local noise = get_noise(6, pos)
|
||||
if noise > 0.7 then
|
||||
table.insert(decoratives, {name = 'green-croton', position = pos, amount = 3})
|
||||
end
|
||||
if noise < -0.2 then
|
||||
table.insert(decoratives, {name = 'green-asterisk', position = pos, amount = 2})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if tile_to_insert == false then
|
||||
table.insert(tiles, {name = 'grass-1', position = {pos_x, pos_y}})
|
||||
else
|
||||
table.insert(tiles, {name = tile_to_insert, position = {pos_x, pos_y}})
|
||||
end
|
||||
end
|
||||
end
|
||||
surface.set_tiles(tiles, true)
|
||||
surface.create_decoratives {check_collision = false, decoratives = decoratives}
|
||||
|
||||
for _, p in pairs(entities_to_place.enemy_buildings) do
|
||||
if math_random(1, 3) == 1 then
|
||||
if surface.can_place_entity({name = 'spitter-spawner', position = p}) then
|
||||
surface.create_entity {name = 'spitter-spawner', position = p}
|
||||
end
|
||||
else
|
||||
if surface.can_place_entity({name = 'biter-spawner', position = p}) then
|
||||
surface.create_entity {name = 'biter-spawner', position = p}
|
||||
end
|
||||
end
|
||||
end
|
||||
for _, p in pairs(entities_to_place.worms) do
|
||||
local e = worm_raffle[math_random(1, #worm_raffle)]
|
||||
if surface.can_place_entity({name = e, position = p}) then
|
||||
surface.create_entity {name = e, position = p}
|
||||
end
|
||||
end
|
||||
for _, p in pairs(entities_to_place.rocks) do
|
||||
local e = rock_raffle[math_random(1, #rock_raffle)]
|
||||
surface.create_entity {name = e, position = p}
|
||||
end
|
||||
for _, p in pairs(entities_to_place.trees) do
|
||||
if surface.can_place_entity({name = p[1], position = p[2]}) then
|
||||
surface.create_entity {name = p[1], position = p[2]}
|
||||
end
|
||||
end
|
||||
for _, p in pairs(entities_to_place.treasure_chests) do
|
||||
treasure_chest(p)
|
||||
end
|
||||
for _, p in pairs(entities_to_place.rare_treasure_chests) do
|
||||
rare_treasure_chest(p)
|
||||
end
|
||||
for _, p in pairs(entities_to_place.fish) do
|
||||
surface.create_entity {name = 'fish', position = p}
|
||||
end
|
||||
end
|
||||
|
||||
local function on_chunk_charted(event)
|
||||
if not global.chunks_charted then
|
||||
global.chunks_charted = {}
|
||||
end
|
||||
local surface = game.surfaces[event.surface_index]
|
||||
local position = event.position
|
||||
if global.chunks_charted[tostring(position.x) .. tostring(position.y)] then
|
||||
return
|
||||
end
|
||||
global.chunks_charted[tostring(position.x) .. tostring(position.y)] = true
|
||||
local force = event.force
|
||||
|
||||
if math_random(1, 12) ~= 1 then
|
||||
return
|
||||
end
|
||||
map_functions.draw_rainbow_patch({x = position.x * 32 + math_random(1, 32), y = position.y * 32 + math_random(1, 32)}, surface, math_random(14, 26), 2000)
|
||||
end
|
||||
|
||||
local function on_player_joined_game(event)
|
||||
local player = game.players[event.player_index]
|
||||
if not global.map_init_done then
|
||||
game.forces['player'].technologies['flamethrower'].enabled = false
|
||||
local map_gen_settings = {}
|
||||
map_gen_settings.water = 'none'
|
||||
map_gen_settings.cliff_settings = {cliff_elevation_interval = 4, cliff_elevation_0 = 0.1}
|
||||
map_gen_settings.autoplace_controls = {
|
||||
['coal'] = {frequency = 'high', size = 'big', richness = 'normal'},
|
||||
['stone'] = {frequency = 'high', size = 'big', richness = 'normal'},
|
||||
['copper-ore'] = {frequency = 'high', size = 'big', richness = 'normal'},
|
||||
['iron-ore'] = {frequency = 'high', size = 'big', richness = 'normal'},
|
||||
['crude-oil'] = {frequency = 'high', size = 'big', richness = 'normal'},
|
||||
['trees'] = {frequency = 'none', size = 'none', richness = 'none'},
|
||||
['enemy-base'] = {frequency = 'none', size = 'none', richness = 'none'},
|
||||
--["grass"] = {frequency = "none", size = "none", richness = "none"},
|
||||
['sand'] = {frequency = 'none', size = 'none', richness = 'none'},
|
||||
['desert'] = {frequency = 'none', size = 'none', richness = 'none'},
|
||||
['dirt'] = {frequency = 'none', size = 'none', richness = 'none'}
|
||||
}
|
||||
game.map_settings.pollution.pollution_restored_per_tree_damage = 0
|
||||
game.create_surface('deep_jungle', map_gen_settings)
|
||||
game.forces['player'].set_spawn_position({0, 0}, game.surfaces['deep_jungle'])
|
||||
global.map_init_done = true
|
||||
end
|
||||
local surface = game.surfaces['deep_jungle']
|
||||
if player.online_time < 5 and surface.is_chunk_generated({0, 0}) then
|
||||
player.teleport(surface.find_non_colliding_position('character', {0, 0}, 2, 1), 'deep_jungle')
|
||||
else
|
||||
if player.online_time < 5 then
|
||||
player.teleport({0, 0}, 'deep_jungle')
|
||||
end
|
||||
end
|
||||
if player.online_time < 10 then
|
||||
player.insert {name = 'submachine-gun', count = 1}
|
||||
player.insert {name = 'raw-fish', count = 12}
|
||||
player.insert {name = 'firearm-magazine', count = 32}
|
||||
player.insert {name = 'steel-axe', count = 1}
|
||||
player.insert {name = 'light-armor', count = 1}
|
||||
end
|
||||
end
|
||||
|
||||
local function on_marked_for_deconstruction(event)
|
||||
if event.entity.name == 'rock-huge' or event.entity.name == 'rock-big' or event.entity.name == 'sand-rock-big' or event.entity.name == 'fish' or event.entity.type == 'tree' then
|
||||
event.entity.cancel_deconstruction(game.players[event.player_index].force.name)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_entity_died(event)
|
||||
if event.entity.type == 'tree' then
|
||||
if math_random(1, 6) == 1 then
|
||||
local surface = game.surfaces['deep_jungle']
|
||||
local p = surface.find_non_colliding_position('small-biter', event.entity.position, 2, 0.5)
|
||||
if p then
|
||||
surface.create_entity {name = 'small-biter', position = event.entity.position}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function cheat_mode()
|
||||
local cheat_mode_enabed = true
|
||||
if cheat_mode_enabed == true then
|
||||
local surface = game.surfaces['deep_jungle']
|
||||
game.player.cheat_mode = true
|
||||
game.players[1].insert({name = 'power-armor-mk2'})
|
||||
game.players[1].insert({name = 'fusion-reactor-equipment', count = 4})
|
||||
game.players[1].insert({name = 'personal-laser-defense-equipment', count = 8})
|
||||
game.players[1].insert({name = 'rocket-launcher'})
|
||||
game.players[1].insert({name = 'explosive-rocket', count = 200})
|
||||
game.speed = 2
|
||||
surface.daytime = 1
|
||||
game.player.force.research_all_technologies()
|
||||
game.forces['enemy'].evolution_factor = 0.2
|
||||
local chart = 300
|
||||
local surface = game.surfaces['deep_jungle']
|
||||
game.forces['player'].chart(surface, {lefttop = {x = chart * -1, y = chart * -1}, rightbottom = {x = chart, y = chart}})
|
||||
end
|
||||
end
|
||||
|
||||
event.add(defines.events.on_chunk_generated, on_chunk_generated)
|
||||
event.add(defines.events.on_chunk_charted, on_chunk_charted)
|
||||
event.add(defines.events.on_entity_died, on_entity_died)
|
||||
event.add(defines.events.on_marked_for_deconstruction, on_marked_for_deconstruction)
|
||||
event.add(defines.events.on_player_joined_game, on_player_joined_game)
|
@ -53,6 +53,9 @@ function Public.bouncy_shells(event)
|
||||
return false
|
||||
end
|
||||
local cause = event.cause
|
||||
if not cause and not cause.valid then
|
||||
return
|
||||
end
|
||||
if cause.shooting_state.state == defines.shooting.not_shooting then
|
||||
return false
|
||||
end
|
||||
|
@ -101,7 +101,7 @@ function Public.get_replacement_tile(surface, position)
|
||||
shuffle(vectors)
|
||||
for k, v in pairs(vectors) do
|
||||
local tile = surface.get_tile(position.x + v[1], position.y + v[2])
|
||||
if tile and not tile.collides_with('resource-layer') then
|
||||
if tile and tile.valid and not tile.collides_with('resource-layer') then
|
||||
return tile.name
|
||||
end
|
||||
end
|
||||
|
@ -711,6 +711,7 @@ function Public.remove_offline_players()
|
||||
return
|
||||
end
|
||||
local offline_players = WPT.get('offline_players')
|
||||
local offline_players_surface_removal = WPT.get('offline_players_surface_removal')
|
||||
local active_surface_index = WPT.get('active_surface_index')
|
||||
local surface = game.surfaces[active_surface_index]
|
||||
local player_inv = {}
|
||||
@ -729,7 +730,9 @@ function Public.remove_offline_players()
|
||||
player_inv[3] = target.get_inventory(defines.inventory.character_guns)
|
||||
player_inv[4] = target.get_inventory(defines.inventory.character_ammo)
|
||||
player_inv[5] = target.get_inventory(defines.inventory.character_trash)
|
||||
ICT_Functions.remove_surface(target) -- remove empty surface
|
||||
if offline_players_surface_removal then
|
||||
ICT_Functions.remove_surface(target) -- remove empty surface
|
||||
end
|
||||
|
||||
if target.get_item_count() == 0 then -- if the player has zero items, don't do anything
|
||||
offline_players[i] = nil
|
||||
|
@ -742,42 +742,43 @@ function Public.remove_surface(player)
|
||||
kick_players_from_surface(car)
|
||||
|
||||
local trust_system = IC.get('trust_system')
|
||||
local owner = car.owner
|
||||
|
||||
if owner then
|
||||
owner = game.get_player(owner)
|
||||
if owner and owner.valid then
|
||||
if trust_system[owner.index] then
|
||||
trust_system[owner.index] = nil
|
||||
end
|
||||
end
|
||||
if trust_system[player.index] then
|
||||
trust_system[player.index] = nil
|
||||
end
|
||||
|
||||
local renders = IC.get('renders')
|
||||
|
||||
if renders[owner.index] then
|
||||
rendering.destroy(renders[owner.index])
|
||||
renders[owner.index] = nil
|
||||
if renders[player.index] then
|
||||
rendering.destroy(renders[player.index])
|
||||
renders[player.index] = nil
|
||||
end
|
||||
|
||||
local player_gui_data = IC.get('player_gui_data')
|
||||
if player_gui_data[owner.name] then
|
||||
player_gui_data[owner.name] = nil
|
||||
if player_gui_data[player.name] then
|
||||
player_gui_data[player.name] = nil
|
||||
end
|
||||
|
||||
local players = IC.get('players')
|
||||
if players[owner.index] then
|
||||
players[owner.index] = nil
|
||||
if players[player.index] then
|
||||
players[player.index] = nil
|
||||
end
|
||||
|
||||
local misc_settings = IC.get('misc_settings')
|
||||
if misc_settings[owner.index] then
|
||||
misc_settings[owner.index] = nil
|
||||
if misc_settings[player.index] then
|
||||
misc_settings[player.index] = nil
|
||||
end
|
||||
|
||||
kill_doors(car)
|
||||
|
||||
surfaces[car.saved_entity] = nil
|
||||
cars[car.saved_entity] = nil
|
||||
|
||||
local surface_index = car.surface
|
||||
local surface = game.surfaces[surface_index]
|
||||
kill_doors(car)
|
||||
if not surface or not surface.valid then
|
||||
return
|
||||
end
|
||||
|
||||
for _, tile in pairs(surface.find_tiles_filtered({area = car.area})) do
|
||||
surface.set_tiles({{name = 'out-of-map', position = tile.position}}, true)
|
||||
end
|
||||
@ -787,8 +788,6 @@ function Public.remove_surface(player)
|
||||
surface.set_tiles({{name = 'out-of-map', position = {x = p.x - 1, y = p.y}}}, true)
|
||||
end
|
||||
game.delete_surface(surface)
|
||||
surfaces[car.saved_entity] = nil
|
||||
cars[car.saved_entity] = nil
|
||||
end
|
||||
|
||||
function Public.kill_car(entity)
|
||||
@ -1195,6 +1194,9 @@ function Public.remove_invalid_cars()
|
||||
end
|
||||
for k, index in pairs(surfaces) do
|
||||
local surface = game.surfaces[index]
|
||||
if not validate_entity(surface) then
|
||||
return
|
||||
end
|
||||
if not cars[tonumber(surface.name)] then
|
||||
game.delete_surface(surface)
|
||||
surfaces[k] = nil
|
||||
|
@ -190,6 +190,7 @@ function Public.reset_table()
|
||||
this.disconnect_wagon = false
|
||||
this.offline_players_enabled = true
|
||||
this.offline_players = {}
|
||||
this.offline_players_surface_removal = false
|
||||
this.collapse_amount = false
|
||||
this.collapse_speed = false
|
||||
this.y_value_position = 20
|
||||
|
@ -4,6 +4,7 @@
|
||||
local Global = require 'utils.global'
|
||||
local Session = require 'utils.datastore.session_data'
|
||||
local Event = require 'utils.event'
|
||||
local Freeplay = require 'utils.freeplay'
|
||||
local Server = require 'utils.server'
|
||||
local MapFuntions = require 'tools.map_functions'
|
||||
local CommonFunctions = require 'utils.common'
|
||||
@ -19,6 +20,9 @@ local Color = require 'utils.color_presets'
|
||||
-- require 'modules.thirst'
|
||||
|
||||
local this = {
|
||||
entities_cache = nil,
|
||||
active_surface = nil,
|
||||
last_friend = nil,
|
||||
remove_offline_players = {
|
||||
players = {},
|
||||
time = 216000, -- 1h
|
||||
@ -270,6 +274,88 @@ local industrial_zone_layers = {
|
||||
}
|
||||
}
|
||||
|
||||
local industrial_zone_layers_modded = {
|
||||
{
|
||||
type = 'LuaTile',
|
||||
name = 'concrete',
|
||||
objects = {
|
||||
'concrete'
|
||||
},
|
||||
elevation = 0.3,
|
||||
resolution = 0.2,
|
||||
hook = nil,
|
||||
deps = nil
|
||||
},
|
||||
{
|
||||
type = 'LuaTile',
|
||||
name = 'stones',
|
||||
objects = {
|
||||
'stone-path'
|
||||
},
|
||||
elevation = 0.2,
|
||||
resolution = 0.4,
|
||||
hook = nil,
|
||||
deps = nil
|
||||
},
|
||||
{
|
||||
type = 'LuaTile',
|
||||
name = 'shallows',
|
||||
objects = {
|
||||
'water-shallow'
|
||||
},
|
||||
elevation = 0.7,
|
||||
resolution = 0.01,
|
||||
hook = nil,
|
||||
deps = nil
|
||||
},
|
||||
{
|
||||
type = 'LuaEntity',
|
||||
name = 'scrap',
|
||||
objects = {
|
||||
'mineable-wreckage'
|
||||
},
|
||||
elevation = 0.5,
|
||||
resolution = 0.1,
|
||||
hook = set_neutral_to_entity,
|
||||
deps = nil
|
||||
},
|
||||
{
|
||||
type = 'LuaEntity',
|
||||
name = 'walls',
|
||||
objects = {
|
||||
'stone-wall'
|
||||
},
|
||||
elevation = 0.5,
|
||||
resolution = 0.09,
|
||||
hook = set_neutral_to_entity,
|
||||
deps = nil
|
||||
},
|
||||
{
|
||||
type = 'LuaEntity',
|
||||
name = 'hostile',
|
||||
objects = {
|
||||
'character',
|
||||
'gun-turret'
|
||||
},
|
||||
elevation = 0.92,
|
||||
resolution = 0.99,
|
||||
hook = set_noise_hostile_hook,
|
||||
deps = fetch_common
|
||||
},
|
||||
{
|
||||
type = 'LuaEntity',
|
||||
name = 'structures',
|
||||
objects = {
|
||||
'big-electric-pole',
|
||||
'medium-electric-pole'
|
||||
},
|
||||
elevation = 0.9,
|
||||
resolution = 0.9,
|
||||
hook = set_neutral_to_entity,
|
||||
deps = nil
|
||||
}
|
||||
}
|
||||
|
||||
local swampy_rivers_layers = {
|
||||
{
|
||||
type = 'LuaTile',
|
||||
@ -359,9 +445,11 @@ this.presets = {
|
||||
['swampy-rivers'] = swampy_rivers_layers
|
||||
}
|
||||
|
||||
this.entities_cache = nil
|
||||
this.surface = nil
|
||||
this.last_friend = nil
|
||||
this.presets_modded = {
|
||||
['flooded-metropolia'] = industrial_zone_layers_modded,
|
||||
['swampy-rivers'] = swampy_rivers_layers
|
||||
}
|
||||
|
||||
local function pick_map()
|
||||
return this.maps[CommonFunctions.rand_range(1, #this.maps)]
|
||||
end
|
||||
@ -430,18 +518,25 @@ this.bp = {
|
||||
merchant = require('planet_prison.bp.merchant')
|
||||
}
|
||||
local function init_game()
|
||||
Freeplay.set('disabled', true)
|
||||
LayersFunctions.init()
|
||||
ClaimsFunctions.init(MapConfig.claim_markers, MapConfig.claim_max_distance)
|
||||
|
||||
local map = pick_map()
|
||||
local preset = this.presets[map.name]
|
||||
this.surface = game.create_surface('arena', map)
|
||||
this.surface.brightness_visual_weights = {
|
||||
local preset
|
||||
if is_game_modded() then
|
||||
preset = this.presets_modded[map.name]
|
||||
else
|
||||
preset = this.presets[map.name]
|
||||
end
|
||||
local surface = game.create_surface('arena', map)
|
||||
surface.brightness_visual_weights = {
|
||||
1 / 0.85,
|
||||
1 / 0.85,
|
||||
1 / 0.85
|
||||
}
|
||||
this.surface.ticks_per_day = 25000 * 4
|
||||
surface.ticks_per_day = 25000 * 4
|
||||
this.active_surface = surface.index
|
||||
this.perks = {}
|
||||
this.events.merchant.spawn_tick = game.tick + 5000
|
||||
this.events.raid_groups = {}
|
||||
@ -507,7 +602,12 @@ local explode_ship =
|
||||
function(data)
|
||||
local ship = data.ship
|
||||
local id = data.id
|
||||
local surface = data.surface
|
||||
local active_surface = data.active_surface
|
||||
local surface = game.get_surface(active_surface)
|
||||
if not surface or not surface.valid then
|
||||
return
|
||||
end
|
||||
|
||||
for _, ent in pairs(Blueprints.reference_get_entities(ship)) do
|
||||
if not ent.valid then
|
||||
goto continue
|
||||
@ -554,7 +654,7 @@ local function do_spawn_point(player)
|
||||
}
|
||||
|
||||
local id = rendering.draw_text(object)
|
||||
local data = {id = id, time_left = time_left, ship = instance, surface = player.surface}
|
||||
local data = {id = id, time_left = time_left, ship = instance, active_surface = player.surface.index}
|
||||
|
||||
local timer = Timers.set_timer(time_left, explode_ship)
|
||||
Timers.set_timer_on_update(timer, explode_ship_update)
|
||||
@ -824,7 +924,8 @@ local function init_player(p)
|
||||
this.perks[p.name] = {
|
||||
flashlight_enable = true,
|
||||
minimap = false,
|
||||
chat_global = true
|
||||
chat_global = true,
|
||||
init = true
|
||||
}
|
||||
|
||||
for i = 1, 7 do
|
||||
@ -881,8 +982,9 @@ end
|
||||
local function on_player_joined_game(e)
|
||||
local p = game.players[e.player_index]
|
||||
player_reconnected(p)
|
||||
redraw_gui(p)
|
||||
|
||||
if this.perks and this.perks[p.name] then
|
||||
if this.perks and this.perks[p.name] and this.perks[p.name].init then
|
||||
return
|
||||
end
|
||||
init_player(p)
|
||||
@ -986,7 +1088,6 @@ local function _calculate_attack_costs(surf, bb)
|
||||
}
|
||||
local objects = surf.find_entities_filtered(query)
|
||||
if next(objects) == nil then
|
||||
log('B')
|
||||
return 0
|
||||
end
|
||||
|
||||
@ -1230,7 +1331,7 @@ local function cause_event(s)
|
||||
end
|
||||
|
||||
local function on_tick()
|
||||
local s = this.surface
|
||||
local s = this.active_surface
|
||||
if not s then
|
||||
log('on_tick: surface empty!')
|
||||
return
|
||||
@ -1238,7 +1339,7 @@ local function on_tick()
|
||||
|
||||
local tick = game.tick
|
||||
|
||||
local surf = this.surface
|
||||
local surf = game.get_surface(this.active_surface)
|
||||
if not surf or not surf.valid then
|
||||
return
|
||||
end
|
||||
@ -1248,7 +1349,7 @@ local function on_tick()
|
||||
end
|
||||
|
||||
LayersFunctions.do_job(surf)
|
||||
cause_event(s)
|
||||
cause_event(surf)
|
||||
|
||||
if (tick + 1) % 60 == 0 then
|
||||
Timers.do_job()
|
||||
@ -1291,6 +1392,7 @@ local valid_ents = {
|
||||
['crash-site-spaceship-wreck-small-4'] = true,
|
||||
['crash-site-spaceship-wreck-small-5'] = true,
|
||||
['crash-site-spaceship-wreck-small-6'] = true,
|
||||
['mineable-wreckage'] = true,
|
||||
['sand-rock-big'] = true,
|
||||
['rock-big'] = true,
|
||||
['rock-huge'] = true
|
||||
@ -1753,8 +1855,20 @@ local function move_to_orbit(player)
|
||||
orbit_perms.add_player(player)
|
||||
end
|
||||
|
||||
local function on_marked_for_deconstruction(event)
|
||||
local entity = event.entity
|
||||
local player = game.get_player(event.player_index)
|
||||
if entity and entity.valid and player and player.valid then
|
||||
entity.cancel_deconstruction(player.force.name)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_rocket_launched(e)
|
||||
local surf = this.surface
|
||||
local surf = game.get_surface(this.active_surface)
|
||||
if not surf or not surf.valid then
|
||||
return
|
||||
end
|
||||
|
||||
local pid = e.player_index
|
||||
surf.print('>> The rocket was launched')
|
||||
if pid == nil then
|
||||
@ -1781,6 +1895,7 @@ Event.add(defines.events.on_player_banned, on_player_died)
|
||||
Event.add(defines.events.on_pre_player_left_game, on_pre_player_left_game)
|
||||
Event.add(defines.events.on_player_respawned, on_player_respawned)
|
||||
Event.add(defines.events.on_player_dropped_item, on_player_dropped_item)
|
||||
Event.add(defines.events.on_marked_for_deconstruction, on_marked_for_deconstruction)
|
||||
Event.add(defines.events.on_entity_damaged, on_entity_damaged)
|
||||
Event.add(defines.events.on_entity_died, on_entity_died)
|
||||
Event.add(defines.events.on_market_item_purchased, on_market_item_purchased)
|
||||
|
@ -1,4 +1,4 @@
|
||||
local CommonFunctions = require 'maps.planet_prison.mod.common'
|
||||
local CommonFunctions = require 'utils.common'
|
||||
local Global = require 'utils.global'
|
||||
local Token = require 'utils.token'
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
local CommonFunctions = require 'maps.planet_prison.mod.common'
|
||||
local CommonFunctions = require 'utils.common'
|
||||
local Global = require 'utils.global'
|
||||
|
||||
local Public = {}
|
||||
|
@ -1,4 +1,4 @@
|
||||
local CommonFunctions = require 'maps.planet_prison.mod.common'
|
||||
local CommonFunctions = require 'utils.common'
|
||||
local SimplexFunctions = require 'maps.planet_prison.mod.simplex_noise'
|
||||
local Token = require 'utils.token'
|
||||
local Global = require 'utils.global'
|
||||
|
@ -1,7 +1,7 @@
|
||||
-- Original implementation taken from here https://github.com/thenumbernine/lua-simplexnoise/blob/master/2d.lua
|
||||
|
||||
local Global = require 'utils.global'
|
||||
local CommonFunctions = require 'maps.planet_prison.mod.common'
|
||||
local CommonFunctions = require 'utils.common'
|
||||
|
||||
local Public = {}
|
||||
local this = {}
|
||||
|
@ -6,6 +6,7 @@ require 'modules.biters_yield_coins'
|
||||
require 'modules.scrap_towny_ffa.mining'
|
||||
require 'modules.scrap_towny_ffa.on_tick_schedule'
|
||||
require 'modules.scrap_towny_ffa.building'
|
||||
require 'modules.scrap_towny_ffa.spaceship'
|
||||
require 'modules.scrap_towny_ffa.town_center'
|
||||
require 'modules.scrap_towny_ffa.market'
|
||||
require 'modules.scrap_towny_ffa.slots'
|
||||
@ -18,6 +19,8 @@ require 'modules.scrap_towny_ffa.trap'
|
||||
require 'modules.scrap_towny_ffa.turrets_drop_ammo'
|
||||
require 'modules.scrap_towny_ffa.combat_balance'
|
||||
|
||||
local Autostash = require 'modules.autostash'
|
||||
local BottomFrame = require 'comfy_panel.bottom_frame'
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
local Nauvis = require 'modules.scrap_towny_ffa.nauvis'
|
||||
local Biters = require 'modules.scrap_towny_ffa.biters'
|
||||
@ -28,43 +31,91 @@ local Team = require 'modules.scrap_towny_ffa.team'
|
||||
local Spawn = require 'modules.scrap_towny_ffa.spawn'
|
||||
local Radar = require 'modules.scrap_towny_ffa.limited_radar'
|
||||
|
||||
local default_surface = 'nauvis'
|
||||
-- for testing purposes only!!!
|
||||
local testing_mode = false
|
||||
|
||||
-- how long in ticks between spawn and death will be considered spawn kill (10 seconds)
|
||||
local max_ticks_between_spawns = 60 * 10
|
||||
-- how many players must login before teams are teams_enabled
|
||||
local min_players_for_enabling_towns = 0
|
||||
|
||||
local function load_buffs(player)
|
||||
if player.force.name ~= 'player' and player.force.name ~= 'rogue' then return end
|
||||
local ffatable = Table.get_table()
|
||||
local player_index = player.index
|
||||
if player.character == nil then return end
|
||||
if ffatable.buffs[player_index] == nil then ffatable.buffs[player_index] = {} end
|
||||
if ffatable.buffs[player_index].character_inventory_slots_bonus ~= nil then
|
||||
player.character.character_inventory_slots_bonus = ffatable.buffs[player_index].character_inventory_slots_bonus
|
||||
end
|
||||
if ffatable.buffs[player_index].character_mining_speed_modifier ~= nil then
|
||||
player.character.character_mining_speed_modifier = ffatable.buffs[player_index].character_mining_speed_modifier
|
||||
end
|
||||
if ffatable.buffs[player_index].character_crafting_speed_modifier ~= nil then
|
||||
player.character.character_crafting_speed_modifier = ffatable.buffs[player_index].character_crafting_speed_modifier
|
||||
end
|
||||
end
|
||||
|
||||
local function on_player_joined_game(event)
|
||||
local ffatable = Table.get_table()
|
||||
local player = game.players[event.player_index]
|
||||
local surface = game.surfaces[default_surface]
|
||||
local surface = game.surfaces['nauvis']
|
||||
|
||||
player.game_view_settings.show_minimap = false
|
||||
player.game_view_settings.show_map_view_options = false
|
||||
player.game_view_settings.show_entity_info = true
|
||||
player.map_view_settings = {
|
||||
["show-logistic-network"] = false,
|
||||
["show-electric-network"] = false,
|
||||
["show-turret-range"] = false,
|
||||
["show-pollution"] = false,
|
||||
["show-train-station-names"] = false,
|
||||
["show-player-names"] = false,
|
||||
["show-networkless-logistic-members"] = false,
|
||||
["show-non-standard-map-info"] = false
|
||||
}
|
||||
player.show_on_map = false
|
||||
--player.game_view_settings.show_side_menu = false
|
||||
|
||||
Info.toggle_button(player)
|
||||
Info.show(player)
|
||||
Team.set_player_color(player)
|
||||
if player.force ~= game.forces.player then
|
||||
return
|
||||
end
|
||||
|
||||
-- setup outlanders
|
||||
Team.set_player_to_outlander(player)
|
||||
|
||||
if player.online_time == 0 then
|
||||
Info.show(player)
|
||||
if testing_mode then
|
||||
ffatable.towns_enabled = true
|
||||
else
|
||||
ffatable.players = ffatable.players + 1
|
||||
if ffatable.players >= min_players_for_enabling_towns then ffatable.towns_enabled = true end
|
||||
end
|
||||
|
||||
player.teleport({0, 0}, game.surfaces['limbo'])
|
||||
Team.give_outlander_items(player)
|
||||
Team.give_key(player)
|
||||
Team.set_player_to_outlander(player)
|
||||
Team.give_player_items(player)
|
||||
player.insert{name="coin", count="100"}
|
||||
player.insert{name="stone-furnace", count="1"}
|
||||
Team.give_key(player.index)
|
||||
if (testing_mode == true) then
|
||||
player.cheat_mode = true
|
||||
player.force.research_all_technologies()
|
||||
player.insert{name="coin", count="9900"}
|
||||
end
|
||||
-- first time spawn point
|
||||
local spawn_point = Spawn.get_spawn_point(player, surface)
|
||||
local spawn_point = Spawn.get_new_spawn_point(player, surface)
|
||||
ffatable.strikes[player.name] = 0
|
||||
Spawn.clear_spawn_point(spawn_point, surface)
|
||||
-- reset cooldown
|
||||
ffatable.cooldowns_town_placement[player.index] = 0
|
||||
ffatable.last_respawn[player.name] = 0
|
||||
player.teleport(spawn_point, surface)
|
||||
return
|
||||
end
|
||||
load_buffs(player)
|
||||
|
||||
if not ffatable.requests[player.index] then
|
||||
return
|
||||
end
|
||||
if ffatable.requests[player.index] ~= 'kill-character' then
|
||||
if not ffatable.requests[player.index] or ffatable.requests[player.index] ~= 'kill-character' then
|
||||
return
|
||||
end
|
||||
if player.character then
|
||||
@ -79,39 +130,57 @@ local function on_player_respawned(event)
|
||||
local ffatable = Table.get_table()
|
||||
local player = game.players[event.player_index]
|
||||
local surface = player.surface
|
||||
Team.give_player_items(player)
|
||||
if player.force == game.forces['rogue'] then
|
||||
Team.set_player_to_outlander(player)
|
||||
end
|
||||
if player.force == game.forces['player'] then
|
||||
Team.give_key(player)
|
||||
Team.give_key(player.index)
|
||||
end
|
||||
|
||||
-- TODO: this needs fixing!
|
||||
-- 5 second cooldown
|
||||
--local last_respawn = ffatable.cooldowns_last_respawn[player.name]
|
||||
--if last_respawn == nil then last_respawn = 0 end
|
||||
-- get_spawn_point will always return a valid spawn
|
||||
local spawn_point = Spawn.get_spawn_point(player, surface)
|
||||
-- reset cooldown
|
||||
ffatable.cooldowns_last_respawn[player.name] = game.tick
|
||||
|
||||
player.teleport(surface.find_non_colliding_position('character', spawn_point, 0, 0.5, false), surface)
|
||||
-- reset cooldown
|
||||
ffatable.last_respawn[player.name] = game.tick
|
||||
player.teleport(spawn_point, surface)
|
||||
load_buffs(player)
|
||||
end
|
||||
|
||||
local function on_player_died(event)
|
||||
local ffatable = Table.get_table()
|
||||
local player = game.players[event.player_index]
|
||||
ffatable.cooldowns_last_death[player.name] = game.tick
|
||||
if ffatable.strikes[player.name] == nil then ffatable.strikes[player.name] = 0 end
|
||||
|
||||
local ticks_elapsed = game.tick - ffatable.last_respawn[player.name]
|
||||
if ticks_elapsed < max_ticks_between_spawns then
|
||||
ffatable.strikes[player.name] = ffatable.strikes[player.name] + 1
|
||||
else
|
||||
ffatable.strikes[player.name] = 0
|
||||
end
|
||||
end
|
||||
|
||||
local function on_init()
|
||||
local ffatable = Table.get_table()
|
||||
Autostash.insert_into_furnace(true)
|
||||
Autostash.insert_into_wagon(true)
|
||||
Autostash.bottom_button(true)
|
||||
BottomFrame.reset()
|
||||
BottomFrame.activate_custom_buttons(true)
|
||||
|
||||
--log("on_init")
|
||||
game.enemy_has_vision_on_land_mines = false
|
||||
game.draw_resource_selection = true
|
||||
game.disable_tutorial_triggers()
|
||||
|
||||
ffatable.cooldowns_last_respawn = {}
|
||||
ffatable.cooldowns_last_death = {}
|
||||
local ffatable = Table.get_table()
|
||||
ffatable.last_respawn = {}
|
||||
ffatable.last_death = {}
|
||||
ffatable.strikes = {}
|
||||
ffatable.testing_mode = testing_mode
|
||||
ffatable.spawn_point = {}
|
||||
ffatable.buffs = {}
|
||||
ffatable.players = 0
|
||||
ffatable.towns_enabled = true
|
||||
|
||||
Nauvis.initialize()
|
||||
Team.initialize()
|
||||
@ -136,6 +205,8 @@ local function on_nth_tick(event)
|
||||
if not tick_actions[seconds] then
|
||||
return
|
||||
end
|
||||
--game.surfaces['nauvis'].play_sound({path = 'utility/alert_destroyed', volume_modifier = 1})
|
||||
--log('seconds = ' .. seconds)
|
||||
tick_actions[seconds]()
|
||||
end
|
||||
|
||||
|
@ -41,7 +41,12 @@ local function anarchy_gui(player)
|
||||
frame.style.minimal_height = total_height
|
||||
|
||||
local t = frame.add({type = 'table', column_count = 5})
|
||||
local headings = {{'Title', group_name_width}, {'Description', description_width}, {'Members', members_width * member_columns}, {'', actions_width * 2 - 30}}
|
||||
local headings = {
|
||||
{'Title', group_name_width},
|
||||
{'Description', description_width},
|
||||
{'Members', members_width * member_columns},
|
||||
{'', actions_width * 2 - 30}
|
||||
}
|
||||
for _, h in pairs(headings) do
|
||||
local l = t.add({type = 'label', caption = h[1]})
|
||||
l.style.font_color = {r = 0.98, g = 0.66, b = 0.22}
|
||||
@ -60,7 +65,8 @@ local function anarchy_gui(player)
|
||||
b.style.right_padding = 4
|
||||
b.style.bottom_padding = 2
|
||||
|
||||
local scroll_pane = frame.add({type = 'scroll-pane', name = 'scroll_pane', direction = 'vertical', horizontal_scroll_policy = 'never', vertical_scroll_policy = 'auto'})
|
||||
local scroll_pane =
|
||||
frame.add({type = 'scroll-pane', name = 'scroll_pane', direction = 'vertical', horizontal_scroll_policy = 'never', vertical_scroll_policy = 'auto'})
|
||||
scroll_pane.style.maximal_height = total_height - 50
|
||||
scroll_pane.style.minimal_height = total_height - 50
|
||||
|
||||
@ -268,7 +274,12 @@ local function new_group(frame, player)
|
||||
local color = player.color
|
||||
color = {r = color.r * 0.6 + 0.4, g = color.g * 0.6 + 0.4, b = color.b * 0.6 + 0.4, a = 1}
|
||||
|
||||
global.alliance_groups[new_group_name] = {name = new_group_name, color = color, description = new_group_description, members = {[tostring(player.name)] = player.index}}
|
||||
global.alliance_groups[new_group_name] = {
|
||||
name = new_group_name,
|
||||
color = color,
|
||||
description = new_group_description,
|
||||
members = {[tostring(player.name)] = player.index}
|
||||
}
|
||||
color = {r = player.color.r * 0.7 + 0.3, g = player.color.g * 0.7 + 0.3, b = player.color.b * 0.7 + 0.3, a = 1}
|
||||
game.print(tostring(player.name) .. ' has founded a new group!', color)
|
||||
game.print('>> ' .. new_group_name, {r = 0.98, g = 0.66, b = 0.22})
|
||||
@ -368,7 +379,8 @@ local function on_gui_click(event)
|
||||
if event.element.type == 'button' and event.element.caption == 'Join' then
|
||||
if global.spam_protection[tostring(player.name)] > game.tick then
|
||||
player.print(
|
||||
'Please wait ' .. math.ceil((global.spam_protection[tostring(player.name)] - game.tick) / 60) .. ' seconds before sending another request.',
|
||||
'Please wait ' ..
|
||||
math.ceil((global.spam_protection[tostring(player.name)] - game.tick) / 60) .. ' seconds before sending another request.',
|
||||
message_color
|
||||
)
|
||||
return
|
||||
@ -429,7 +441,6 @@ local function on_player_joined_game(event)
|
||||
permission_group.set_allows_action(defines.input_action.gui_value_changed, true)
|
||||
permission_group.set_allows_action(defines.input_action.gui_click, true)
|
||||
permission_group.set_allows_action(defines.input_action.gui_selection_state_changed, true)
|
||||
permission_group.set_allows_action(defines.input_action.open_kills_gui, true)
|
||||
permission_group.set_allows_action(defines.input_action.open_character_gui, true)
|
||||
permission_group.set_allows_action(defines.input_action.edit_permission_group, true)
|
||||
permission_group.set_allows_action(defines.input_action.toggle_show_entity_info, true)
|
||||
|
@ -1,4 +1,3 @@
|
||||
--luacheck: ignore
|
||||
local Public = {}
|
||||
local math_random = math.random
|
||||
local math_floor = math.floor
|
||||
@ -10,6 +9,7 @@ local table_remove = table.remove
|
||||
local table_shuffle = table.shuffle_table
|
||||
|
||||
local Global = require 'utils.global'
|
||||
local BiterHealthBooster = require 'modules.biter_health_booster_v2'
|
||||
|
||||
local tick_schedule = {}
|
||||
Global.register(
|
||||
@ -29,7 +29,7 @@ local function get_commmands(target, group)
|
||||
|
||||
local target_position = target.position
|
||||
local distance_to_target = math_floor(math_sqrt((target_position.x - group_position.x) ^ 2 + (target_position.y - group_position.y) ^ 2))
|
||||
local steps = math_floor(distance_to_target / step_length) + 1
|
||||
local steps = math_floor((distance_to_target - 27) / step_length) + 1
|
||||
local vector = {math_round((target_position.x - group_position.x) / steps, 3), math_round((target_position.y - group_position.y) / steps, 3)}
|
||||
|
||||
for _ = 1, steps, 1 do
|
||||
@ -38,7 +38,7 @@ local function get_commmands(target, group)
|
||||
local position = group.surface.find_non_colliding_position('small-biter', group_position, step_length, 2)
|
||||
if position then
|
||||
commands[#commands + 1] = {
|
||||
type = defines.command.attack_area,
|
||||
type = defines.command.go_to_location,
|
||||
destination = {x = position.x, y = position.y},
|
||||
radius = 16,
|
||||
distraction = defines.distraction.by_damage
|
||||
@ -46,17 +46,22 @@ local function get_commmands(target, group)
|
||||
end
|
||||
end
|
||||
|
||||
commands[#commands + 1] = {
|
||||
type = defines.command.attack_area,
|
||||
destination = target.position,
|
||||
radius = 12,
|
||||
distraction = defines.distraction.by_enemy
|
||||
}
|
||||
commands[#commands + 1] = {
|
||||
type = defines.command.attack,
|
||||
target = target,
|
||||
distraction = defines.distraction.by_damage
|
||||
}
|
||||
commands[#commands + 1] = {
|
||||
type = defines.command.attack_area,
|
||||
destination = target.position,
|
||||
radius = 27,
|
||||
distraction = defines.distraction.by_anything
|
||||
}
|
||||
commands[#commands + 1] = {
|
||||
type = defines.command.build_base,
|
||||
destination = target.position,
|
||||
distraction = defines.distraction.by_damage
|
||||
}
|
||||
|
||||
return commands
|
||||
end
|
||||
@ -68,8 +73,13 @@ local function roll_market()
|
||||
return
|
||||
end
|
||||
local keyset = {}
|
||||
for town_name, _ in pairs(town_centers) do
|
||||
table_insert(keyset, town_name)
|
||||
for town_name, town_center in pairs(town_centers) do
|
||||
local evolution = Evolution.get_biter_evolution(town_center.market.position)
|
||||
local tries = math_floor(evolution * 20)
|
||||
-- 1 try for each 5% of evolution
|
||||
for _ = 1, tries, 1 do
|
||||
table_insert(keyset, town_name)
|
||||
end
|
||||
end
|
||||
local tc = math_random(1, #keyset)
|
||||
return town_centers[keyset[tc]]
|
||||
@ -107,6 +117,9 @@ end
|
||||
|
||||
function Public.validate_swarms()
|
||||
local ffatable = Table.get_table()
|
||||
if ffatable.testing_mode then
|
||||
return
|
||||
end
|
||||
for k, swarm in pairs(ffatable.swarms) do
|
||||
if not is_swarm_valid(swarm) then
|
||||
table_remove(ffatable.swarms, k)
|
||||
@ -116,6 +129,9 @@ end
|
||||
|
||||
function Public.unit_groups_start_moving()
|
||||
local ffatable = Table.get_table()
|
||||
if ffatable.testing_mode then
|
||||
return
|
||||
end
|
||||
for _, swarm in pairs(ffatable.swarms) do
|
||||
if swarm.group then
|
||||
if swarm.group.valid then
|
||||
@ -125,22 +141,34 @@ function Public.unit_groups_start_moving()
|
||||
end
|
||||
end
|
||||
|
||||
local function new_town(town_center)
|
||||
-- cooldown for swarms on new towns is 15 minutes
|
||||
local cooldown_ticks = 15 * 3600
|
||||
local elapsed_ticks = game.tick - town_center.creation_tick
|
||||
-- skip if within first 30 minutes and town evolution < 0.25
|
||||
if elapsed_ticks < cooldown_ticks and town_center.evolution.biters < 0.15 then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function Public.swarm(town_center, radius)
|
||||
if town_center == nil then
|
||||
return
|
||||
end
|
||||
local ffatable = Table.get_table()
|
||||
if ffatable.testing_mode then
|
||||
return
|
||||
end
|
||||
local r = radius or 32
|
||||
local tc = town_center or roll_market()
|
||||
if not tc or r > 512 then
|
||||
return
|
||||
end
|
||||
|
||||
-- skip if town evolution < 0.25
|
||||
if town_center.get_biter_evolution < 0.25 then
|
||||
-- cancel if relatively new town
|
||||
if new_town(tc) then
|
||||
return
|
||||
end
|
||||
|
||||
-- skip if we have to many swarms already
|
||||
local count = table_size(ffatable.swarms)
|
||||
local towns = table_size(ffatable.town_centers)
|
||||
@ -167,15 +195,18 @@ function Public.swarm(town_center, radius)
|
||||
return
|
||||
end
|
||||
|
||||
-- get our evolution
|
||||
local evolution = 0
|
||||
-- get our evolution at the spawner location
|
||||
local evolution
|
||||
if spawner.name == 'spitter-spawner' then
|
||||
evolution = Evolution.get_biter_evolution(spawner)
|
||||
else
|
||||
evolution = Evolution.get_spitter_evolution(spawner)
|
||||
end
|
||||
|
||||
-- get our target amount of enemies
|
||||
-- get the evolution at the market location
|
||||
local market_evolution = Evolution.get_evolution(market.position)
|
||||
|
||||
-- get our target amount of enemies based on relative evolution
|
||||
local count2 = (evolution * 124) + 4
|
||||
|
||||
local units = spawner.surface.find_enemy_units(spawner.position, 16, market.force)
|
||||
@ -192,6 +223,18 @@ function Public.swarm(town_center, radius)
|
||||
return
|
||||
end
|
||||
|
||||
-- try up to 10 times to throw in a boss based on market evolution
|
||||
-- evolution = 0%, chances 0 in 10
|
||||
-- evoution = 10%, chances 1 in 10
|
||||
-- evolution = 20%, chances 2 in 10
|
||||
-- evolution = 100%, chances 10 in 10
|
||||
local health_multiplier = 40 * market_evolution + 10
|
||||
for _ = 1, math_floor(market_evolution * 10), 1 do
|
||||
if math_random(1, 2) == 1 then
|
||||
BiterHealthBooster.add_boss_unit(units[1], health_multiplier)
|
||||
end
|
||||
end
|
||||
|
||||
local unit_group_position = surface.find_non_colliding_position('biter-spawner', units[1].position, 256, 1)
|
||||
if not unit_group_position then
|
||||
return
|
||||
@ -215,6 +258,30 @@ function Public.swarm(town_center, radius)
|
||||
table_insert(ffatable.swarms, {group = unit_group, timeout = game.tick + 36000})
|
||||
end
|
||||
|
||||
local function on_unit_group_finished_gathering(event)
|
||||
local unit_group = event.group
|
||||
local position = unit_group.position
|
||||
local entities = unit_group.surface.find_entities_filtered({position = position, radius = 256, name = 'market'})
|
||||
local target = entities[1]
|
||||
if target ~= nil then
|
||||
local force = target.force
|
||||
local ffatable = Table.get_table()
|
||||
local town_centers = ffatable.town_centers
|
||||
local town_center = town_centers[force.name]
|
||||
-- cancel if relatively new town
|
||||
if new_town(town_center) then
|
||||
return
|
||||
end
|
||||
unit_group.set_command(
|
||||
{
|
||||
type = defines.command.compound,
|
||||
structure_type = defines.compound_command.return_last,
|
||||
commands = get_commmands(target, unit_group)
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_tick()
|
||||
if not tick_schedule[game.tick] then
|
||||
return
|
||||
@ -232,10 +299,13 @@ end
|
||||
local on_init = function()
|
||||
local ffatable = Table.get_table()
|
||||
ffatable.swarms = {}
|
||||
BiterHealthBooster.acid_nova(true)
|
||||
BiterHealthBooster.check_on_entity_died(true)
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.on_init(on_init)
|
||||
Event.add(defines.events.on_tick, on_tick)
|
||||
Event.add(defines.events.on_unit_group_finished_gathering, on_unit_group_finished_gathering)
|
||||
|
||||
return Public
|
||||
|
@ -1,29 +1,89 @@
|
||||
--luacheck: ignore
|
||||
local Public = {}
|
||||
|
||||
local math_floor = math.floor
|
||||
local table_insert = table.insert
|
||||
local table_size = table.size
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
|
||||
local town_radius = 27
|
||||
local connection_radius = 7
|
||||
|
||||
local blacklist_entity_types = {
|
||||
['car'] = true,
|
||||
['character'] = true,
|
||||
['combat-robot'] = true,
|
||||
['construction-robot'] = true,
|
||||
['logistic-robot'] = true,
|
||||
['entity-ghost'] = true,
|
||||
['character-corpse'] = true,
|
||||
['corpse'] = true
|
||||
}
|
||||
-- these should be allowed to place inside any base by outlanders as neutral
|
||||
local neutral_whitelist = {
|
||||
['wooden-chest'] = true,
|
||||
['burner-inserter'] = true,
|
||||
['car'] = true,
|
||||
['coin'] = true,
|
||||
['express-loader'] = true,
|
||||
['fast-inserter'] = true,
|
||||
['fast-loader'] = true,
|
||||
['filter-inserter'] = true,
|
||||
['inserter'] = true,
|
||||
['iron-chest'] = true,
|
||||
['loader'] = true,
|
||||
['long-handed-inserter'] = true,
|
||||
['raw-fish'] = true,
|
||||
['stack-filter-inserter'] = true,
|
||||
['stack-inserter'] = true,
|
||||
['steel-chest'] = true,
|
||||
['raw-fish'] = true
|
||||
['tank'] = true,
|
||||
['wooden-chest'] = true
|
||||
}
|
||||
|
||||
local entity_type_whitelist = {
|
||||
-- these should be allowed to place outside any base by town players
|
||||
local team_whitelist = {
|
||||
['burner-inserter'] = true,
|
||||
['car'] = true,
|
||||
['cargo-wagon'] = true,
|
||||
['coin'] = true,
|
||||
['curved-rail'] = true,
|
||||
['electric-pole'] = true,
|
||||
['express-loader'] = true,
|
||||
['fast-inserter'] = true,
|
||||
['fast-loader'] = true,
|
||||
['filter-inserter'] = true,
|
||||
['inserter'] = true,
|
||||
['fluid-wagon'] = true,
|
||||
['iron-chest'] = true,
|
||||
['loader'] = true,
|
||||
['long-handed-inserter'] = true,
|
||||
['locomotive'] = true,
|
||||
['rail'] = true,
|
||||
['rail-chain-signal'] = true,
|
||||
['rail-signal'] = true,
|
||||
['raw-fish'] = true,
|
||||
['stack-filter-inserter'] = true,
|
||||
['stack-inserter'] = true,
|
||||
['steel-chest'] = true,
|
||||
['straight-rail'] = true,
|
||||
['tank'] = true,
|
||||
['train-stop'] = true,
|
||||
['wooden-chest'] = true
|
||||
}
|
||||
|
||||
-- these need to be prototypes
|
||||
local team_entities = {
|
||||
['accumulator'] = true,
|
||||
['ammo-turret'] = true,
|
||||
['arithmetic-combinator'] = true,
|
||||
['artillery-turret'] = true,
|
||||
['assembling-machine'] = true,
|
||||
['beacon'] = true,
|
||||
['boiler'] = true,
|
||||
['burner-generator'] = true,
|
||||
['constant-combinator'] = true,
|
||||
['container'] = true,
|
||||
['curved-rail'] = true,
|
||||
['decider-combinator'] = true,
|
||||
['electric-energy-interface'] = true,
|
||||
['electric-pole'] = true,
|
||||
['electric-turret'] = true,
|
||||
['fluid-turret'] = true,
|
||||
@ -38,26 +98,27 @@ local entity_type_whitelist = {
|
||||
['lab'] = true,
|
||||
['lamp'] = true,
|
||||
['land-mine'] = true,
|
||||
['linked-belt'] = true,
|
||||
['linked-container'] = true,
|
||||
['loader'] = true,
|
||||
['loader-1x1'] = true,
|
||||
['logistic-container'] = true,
|
||||
['market'] = true,
|
||||
['mining-drill'] = true,
|
||||
['offshore-pump'] = true,
|
||||
['pipe'] = true,
|
||||
['pipe-to-ground'] = true,
|
||||
['player-port'] = true,
|
||||
['power-switch'] = true,
|
||||
['programmable-speaker'] = true,
|
||||
['pump'] = true,
|
||||
['radar'] = true,
|
||||
['rail-chain-signal'] = true,
|
||||
['rail-signal'] = true,
|
||||
['reactor'] = true,
|
||||
['roboport'] = true,
|
||||
['rocket-silo'] = true,
|
||||
['solar-panel'] = true,
|
||||
['splitter'] = true,
|
||||
['storage-tank'] = true,
|
||||
['straight-rail'] = true,
|
||||
['train-stop'] = true,
|
||||
['transport-belt'] = true,
|
||||
['underground-belt'] = true,
|
||||
['wall'] = true
|
||||
@ -70,7 +131,7 @@ local function isolated(surface, force, position)
|
||||
local count = 0
|
||||
|
||||
for _, e in pairs(surface.find_entities_filtered({area = area, force = force.name})) do
|
||||
if entity_type_whitelist[e.type] then
|
||||
if team_entities[e.type] then
|
||||
count = count + 1
|
||||
if count > 1 then
|
||||
return false
|
||||
@ -85,12 +146,13 @@ local function refund_item(event, item_name)
|
||||
if item_name == 'blueprint' then
|
||||
return
|
||||
end
|
||||
if event.player_index then
|
||||
if event.player_index ~= nil then
|
||||
game.players[event.player_index].insert({name = item_name, count = 1})
|
||||
return
|
||||
end
|
||||
|
||||
if event.robot then
|
||||
-- return item to robot, but don't replace ghost (otherwise might loop)
|
||||
if event.robot ~= nil then
|
||||
local inventory = event.robot.get_inventory(defines.inventory.robot_cargo)
|
||||
inventory.insert({name = item_name, count = 1})
|
||||
return
|
||||
@ -108,7 +170,7 @@ local function error_floaty(surface, position, msg)
|
||||
)
|
||||
end
|
||||
|
||||
local function in_range(pos1, pos2, radius)
|
||||
function Public.in_range(pos1, pos2, radius)
|
||||
if pos1 == nil then
|
||||
return false
|
||||
end
|
||||
@ -126,170 +188,399 @@ local function in_range(pos1, pos2, radius)
|
||||
return false
|
||||
end
|
||||
|
||||
-- is the position near a town?
|
||||
function Public.near_town(position, surface, radius)
|
||||
local ffatable = Table.get_table()
|
||||
for _, town_center in pairs(ffatable.town_centers) do
|
||||
if town_center ~= nil then
|
||||
local market = town_center.market
|
||||
if in_range(position, market.position, radius) and market.surface == surface then
|
||||
return true
|
||||
end
|
||||
function Public.in_area(position, area_center, area_radius)
|
||||
if position == nil then
|
||||
return false
|
||||
end
|
||||
if area_center == nil then
|
||||
return false
|
||||
end
|
||||
if area_radius < 1 then
|
||||
return true
|
||||
end
|
||||
if position.x >= area_center.x - area_radius and position.x <= area_center.x + area_radius then
|
||||
if position.y >= area_center.y - area_radius and position.y <= area_center.y + area_radius then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function in_town(force, position)
|
||||
-- is the position near another town?
|
||||
function Public.near_another_town(force_name, position, surface, radius)
|
||||
-- check for nearby town centers
|
||||
if force_name == nil then
|
||||
return false
|
||||
end
|
||||
local ffatable = Table.get_table()
|
||||
local forces = {}
|
||||
-- check for nearby town centers
|
||||
local fail = false
|
||||
if table_size(ffatable.town_centers) > 0 then
|
||||
for _, town_center in pairs(ffatable.town_centers) do
|
||||
if town_center ~= nil then
|
||||
local market = town_center.market
|
||||
if market ~= nil and market.valid then
|
||||
local market_force = market.force
|
||||
if market_force ~= nil then
|
||||
if market_force.name ~= nil then
|
||||
table_insert(forces, market_force.name)
|
||||
if force_name ~= market_force.name then
|
||||
if Public.in_range(position, market.position, radius) == true then
|
||||
fail = true
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if fail == true then
|
||||
return true
|
||||
end
|
||||
end
|
||||
-- check for nearby town entities
|
||||
if table.size(forces) > 0 then
|
||||
local entities = surface.find_entities_filtered({position = position, radius = radius, force = forces})
|
||||
for _, e in pairs(entities) do
|
||||
if e.valid and e.force ~= nil then
|
||||
local entity_force_name = e.force.name
|
||||
--if force_name ~= force.name and force_name ~= 'enemy' and force_name ~= 'neutral' and force_name ~= 'player' and force_name ~= 'rogue' then
|
||||
if entity_force_name ~= nil then
|
||||
if entity_force_name ~= force_name then
|
||||
if blacklist_entity_types[e.type] ~= true then
|
||||
fail = true
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if fail == true then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function in_own_town(force, position)
|
||||
local ffatable = Table.get_table()
|
||||
local town_center = ffatable.town_centers[force.name]
|
||||
if town_center ~= nil then
|
||||
local center = town_center.market.position
|
||||
if position.x >= center.x - town_radius and position.x <= center.x + town_radius then
|
||||
if position.y >= center.y - town_radius and position.y <= center.y + town_radius then
|
||||
return true
|
||||
local market = town_center.market
|
||||
if market ~= nil then
|
||||
local center = market.position
|
||||
if position.x >= center.x - town_radius and position.x <= center.x + town_radius then
|
||||
if position.y >= center.y - town_radius and position.y <= center.y + town_radius then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function prevent_isolation_entity(event, player)
|
||||
local p = player or nil
|
||||
function Public.in_restricted_zone(surface, position)
|
||||
if surface.name ~= 'nauvis' then
|
||||
return false
|
||||
end
|
||||
local chunk_position = {}
|
||||
chunk_position.x = math_floor(position.x / 32)
|
||||
chunk_position.y = math_floor(position.y / 32)
|
||||
if chunk_position.x <= -33 or chunk_position.x >= 32 or chunk_position.y <= -33 or chunk_position.y >= 32 then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function prevent_entity_in_restricted_zone(event)
|
||||
local player_index = event.player_index or nil
|
||||
local entity = event.created_entity
|
||||
local position = entity.position
|
||||
if not entity.valid then
|
||||
return
|
||||
end
|
||||
local entity_name = entity.name
|
||||
local item = event.item
|
||||
if item == nil then
|
||||
return
|
||||
end
|
||||
local item_name = item.name
|
||||
local force = entity.force
|
||||
if force == game.forces.player then
|
||||
return
|
||||
end
|
||||
if force == game.forces['rogue'] then
|
||||
if entity == nil or not entity.valid then
|
||||
return
|
||||
end
|
||||
local name = entity.name
|
||||
local surface = entity.surface
|
||||
local position = entity.position
|
||||
local error = false
|
||||
if not in_town(force, position) and isolated(surface, force, position) then
|
||||
if Public.in_restricted_zone(surface, position) then
|
||||
error = true
|
||||
entity.destroy()
|
||||
if entity_name ~= 'entity-ghost' and entity_name ~= 'tile-ghost' then
|
||||
refund_item(event, item_name)
|
||||
local item = event.item
|
||||
if name ~= 'entity-ghost' and name ~= 'tile-ghost' and item ~= nil then
|
||||
refund_item(event, item.name)
|
||||
end
|
||||
--return true
|
||||
end
|
||||
if error == true then
|
||||
if p ~= nil then
|
||||
p.play_sound({path = 'utility/cannot_build', position = p.position, volume_modifier = 0.75})
|
||||
if player_index ~= nil then
|
||||
local player = game.players[player_index]
|
||||
player.play_sound({path = 'utility/cannot_build', position = player.position, volume_modifier = 0.75})
|
||||
end
|
||||
error_floaty(surface, position, 'Building is not connected to town!')
|
||||
error_floaty(surface, position, 'Can not build in restricted zone!')
|
||||
end
|
||||
end
|
||||
|
||||
local function prevent_isolation_tile(event, player)
|
||||
local p = player or nil
|
||||
local tile = event.tile
|
||||
if not tile.valid then
|
||||
local function prevent_unconnected_town_entities(event)
|
||||
local player_index = event.player_index or nil
|
||||
local entity = event.created_entity
|
||||
if entity == nil or not entity.valid then
|
||||
return
|
||||
end
|
||||
local name = entity.name
|
||||
local surface = entity.surface
|
||||
local position = entity.position
|
||||
local force = entity.force
|
||||
if force.index == game.forces.player.index or force.index == game.forces['rogue'].index then
|
||||
-- no town restrictions if outlander or rogue
|
||||
return
|
||||
end
|
||||
local error = false
|
||||
if name ~= 'entity-ghost' then
|
||||
if not in_own_town(force, position) and isolated(surface, force, position) and not team_whitelist[name] then
|
||||
error = true
|
||||
entity.destroy()
|
||||
local item = event.item
|
||||
if item ~= nil then
|
||||
refund_item(event, item.name)
|
||||
end
|
||||
end
|
||||
end
|
||||
if error == true then
|
||||
if player_index ~= nil then
|
||||
local player = game.players[player_index]
|
||||
player.play_sound({path = 'utility/cannot_build', position = player.position, volume_modifier = 0.75})
|
||||
end
|
||||
error_floaty(surface, position, 'Building is not connected to your town!')
|
||||
end
|
||||
end
|
||||
|
||||
local function prevent_landfill_in_restricted_zone(event)
|
||||
local player_index = event.player_index or nil
|
||||
local tile = event.tile
|
||||
if tile == nil or not tile.valid then
|
||||
return
|
||||
end
|
||||
local surface = game.surfaces[event.surface_index]
|
||||
local fail = false
|
||||
local position
|
||||
for _, t in pairs(event.tiles) do
|
||||
local old_tile = t.old_tile
|
||||
position = t.position
|
||||
if Public.in_restricted_zone(surface, position) then
|
||||
fail = true
|
||||
surface.set_tiles({{name = old_tile.name, position = position}}, true)
|
||||
refund_item(event, tile.name)
|
||||
end
|
||||
end
|
||||
if fail == true then
|
||||
if player_index ~= nil then
|
||||
local player = game.players[player_index]
|
||||
player.play_sound({path = 'utility/cannot_build', position = player.position, volume_modifier = 0.75})
|
||||
end
|
||||
error_floaty(surface, position, 'Can not build in restricted zone!')
|
||||
end
|
||||
return fail
|
||||
end
|
||||
|
||||
local function prevent_unconnected_town_tiles(event)
|
||||
local player_index = event.player_index or nil
|
||||
local tile = event.tile
|
||||
if tile == nil or not tile.valid then
|
||||
return
|
||||
end
|
||||
local tile_name = tile.name
|
||||
local surface = game.surfaces[event.surface_index]
|
||||
local tiles = event.tiles
|
||||
local force
|
||||
if event.player_index then
|
||||
force = game.players[event.player_index].force
|
||||
if player_index ~= nil then
|
||||
force = game.players[player_index].force
|
||||
else
|
||||
force = event.robot.force
|
||||
end
|
||||
local error = false
|
||||
local fail = false
|
||||
local position
|
||||
for _, t in pairs(tiles) do
|
||||
local old_tile = t.old_tile
|
||||
position = t.position
|
||||
if not in_town(force, position) and isolated(surface, force, position) then
|
||||
error = true
|
||||
surface.set_tiles({{name = old_tile.name, position = position}}, true)
|
||||
if tile_name ~= 'tile-ghost' then
|
||||
if tile_name == 'stone-path' then
|
||||
tile_name = 'stone-brick'
|
||||
if tile.name ~= 'tile-ghost' then
|
||||
if not in_own_town(force, position) and isolated(surface, force, position) then
|
||||
fail = true
|
||||
surface.set_tiles({{name = old_tile.name, position = position}}, true)
|
||||
if tile.name == 'stone-path' then
|
||||
tile.name = 'stone-brick'
|
||||
end
|
||||
refund_item(event, tile_name)
|
||||
refund_item(event, tile.name)
|
||||
end
|
||||
end
|
||||
end
|
||||
if error == true then
|
||||
if p ~= nil then
|
||||
p.play_sound({path = 'utility/cannot_build', position = p.position, volume_modifier = 0.75})
|
||||
if fail == true then
|
||||
if player_index ~= nil then
|
||||
local player = game.players[player_index]
|
||||
player.play_sound({path = 'utility/cannot_build', position = player.position, volume_modifier = 0.75})
|
||||
end
|
||||
error_floaty(surface, position, 'Tile is not connected to town!')
|
||||
end
|
||||
end
|
||||
|
||||
local function restrictions(event, player)
|
||||
local p = player or nil
|
||||
local function prevent_entities_near_towns(event)
|
||||
local player_index = event.player_index or nil
|
||||
local entity = event.created_entity
|
||||
if not entity.valid then
|
||||
if entity == nil or not entity.valid then
|
||||
return
|
||||
end
|
||||
local entity_name = entity.name
|
||||
local name = entity.name
|
||||
local surface = entity.surface
|
||||
local position = entity.position
|
||||
local error = false
|
||||
if entity.force == game.forces['player'] or entity.force == game.forces['rogue'] then
|
||||
if Public.near_town(position, surface, 32) then
|
||||
error = true
|
||||
local force_name
|
||||
if player_index ~= nil then
|
||||
local player = game.players[player_index]
|
||||
if player ~= nil then
|
||||
local force = player.force
|
||||
if force ~= nil then
|
||||
force_name = force.name
|
||||
end
|
||||
end
|
||||
else
|
||||
local robot = event.robot
|
||||
if robot ~= nil then
|
||||
local force = robot.force
|
||||
if force ~= nil then
|
||||
force_name = force.name
|
||||
end
|
||||
end
|
||||
end
|
||||
if Public.near_another_town(force_name, position, surface, 32) == true then
|
||||
if neutral_whitelist[name] then
|
||||
entity.force = game.forces['neutral']
|
||||
else
|
||||
entity.destroy()
|
||||
if entity_name ~= 'entity-ghost' then
|
||||
if player_index ~= nil then
|
||||
local player = game.players[player_index]
|
||||
player.play_sound({path = 'utility/cannot_build', position = player.position, volume_modifier = 0.75})
|
||||
end
|
||||
error_floaty(surface, position, "Can't build near town!")
|
||||
if name ~= 'entity-ghost' then
|
||||
refund_item(event, event.stack.name)
|
||||
end
|
||||
else
|
||||
entity.force = game.forces['neutral']
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function prevent_tiles_near_towns(event)
|
||||
local player_index = event.player_index or nil
|
||||
local tile = event.tile
|
||||
if tile == nil or not tile.valid then
|
||||
return
|
||||
end
|
||||
if error == true then
|
||||
if p ~= nil then
|
||||
p.play_sound({path = 'utility/cannot_build', position = p.position, volume_modifier = 0.75})
|
||||
local surface = game.surfaces[event.surface_index]
|
||||
local force_name
|
||||
if player_index ~= nil then
|
||||
local player = game.players[player_index]
|
||||
if player ~= nil then
|
||||
local force = player.force
|
||||
if force ~= nil then
|
||||
force_name = force.name
|
||||
end
|
||||
end
|
||||
else
|
||||
local robot = event.robot
|
||||
if robot ~= nil then
|
||||
local force = robot.force
|
||||
if force ~= nil then
|
||||
force_name = force.name
|
||||
end
|
||||
end
|
||||
end
|
||||
local fail = false
|
||||
local position
|
||||
for _, t in pairs(event.tiles) do
|
||||
local old_tile = t.old_tile
|
||||
position = t.position
|
||||
if Public.near_another_town(force_name, position, surface, 32) == true then
|
||||
fail = true
|
||||
surface.set_tiles({{name = old_tile.name, position = position}}, true)
|
||||
refund_item(event, tile.name)
|
||||
end
|
||||
end
|
||||
if fail == true then
|
||||
if player_index ~= nil then
|
||||
local player = game.players[player_index]
|
||||
player.play_sound({path = 'utility/cannot_build', position = player.position, volume_modifier = 0.75})
|
||||
end
|
||||
error_floaty(surface, position, "Can't build near town!")
|
||||
end
|
||||
return fail
|
||||
end
|
||||
|
||||
if not neutral_whitelist[entity.type] then
|
||||
return
|
||||
local function prevent_neutral_deconstruct(event)
|
||||
local player = game.players[event.player_index] or nil
|
||||
local entity = event.entity
|
||||
if entity.to_be_deconstructed() and entity.force.name == 'neutral' then
|
||||
for _, f in pairs(game.forces) do
|
||||
if entity.is_registered_for_deconstruction(f) then
|
||||
entity.cancel_deconstruction(f, player)
|
||||
end
|
||||
end
|
||||
end
|
||||
entity.force = game.forces['neutral']
|
||||
end
|
||||
|
||||
-- called when a player places an item, or a ghost
|
||||
local function on_built_entity(event)
|
||||
local player = game.players[event.player_index]
|
||||
if prevent_isolation_entity(event, player) then
|
||||
if prevent_entity_in_restricted_zone(event) then
|
||||
return
|
||||
end
|
||||
restrictions(event, player)
|
||||
if prevent_entities_near_towns(event) then
|
||||
return
|
||||
end
|
||||
if player.force.index ~= game.forces['player'].index and player.force.index ~= game.forces['rogue'].index then
|
||||
prevent_unconnected_town_entities(event)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_robot_built_entity(event)
|
||||
if prevent_isolation_entity(event) then
|
||||
local robot = event.robot
|
||||
if prevent_entity_in_restricted_zone(event) then
|
||||
return
|
||||
end
|
||||
restrictions(event)
|
||||
if prevent_entities_near_towns(event) then
|
||||
return
|
||||
end
|
||||
if robot.force.index ~= game.forces['player'].index and robot.force.index ~= game.forces['rogue'].index then
|
||||
prevent_unconnected_town_entities(event)
|
||||
end
|
||||
end
|
||||
|
||||
-- called when a player places landfill
|
||||
local function on_player_built_tile(event)
|
||||
local player = game.players[event.player_index]
|
||||
prevent_isolation_tile(event, player)
|
||||
if prevent_landfill_in_restricted_zone(event) then
|
||||
return
|
||||
end
|
||||
if prevent_tiles_near_towns(event) then
|
||||
return
|
||||
end
|
||||
if player.force.index ~= game.forces['player'].index and player.force.index ~= game.forces['rogue'].index then
|
||||
prevent_unconnected_town_tiles(event)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_robot_built_tile(event)
|
||||
prevent_isolation_tile(event)
|
||||
local robot = event.robot
|
||||
if prevent_landfill_in_restricted_zone(event) then
|
||||
return
|
||||
end
|
||||
if prevent_tiles_near_towns(event) then
|
||||
return
|
||||
end
|
||||
if robot.force.index ~= game.forces['player'].index and robot.force.index ~= game.forces['rogue'].index then
|
||||
prevent_unconnected_town_tiles(event)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_marked_for_deconstruction(event)
|
||||
prevent_neutral_deconstruct(event)
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
@ -297,5 +588,6 @@ Event.add(defines.events.on_built_entity, on_built_entity)
|
||||
Event.add(defines.events.on_player_built_tile, on_player_built_tile)
|
||||
Event.add(defines.events.on_robot_built_entity, on_robot_built_entity)
|
||||
Event.add(defines.events.on_robot_built_tile, on_robot_built_tile)
|
||||
Event.add(defines.events.on_marked_for_deconstruction, on_marked_for_deconstruction)
|
||||
|
||||
return Public
|
||||
|
216
modules/scrap_towny_ffa/colors.lua
Normal file
216
modules/scrap_towny_ffa/colors.lua
Normal file
@ -0,0 +1,216 @@
|
||||
local Public = {}
|
||||
|
||||
local table_shuffle = table.shuffle_table
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
local Color = require 'utils.color_presets'
|
||||
|
||||
local colors = {}
|
||||
colors[1] = {name = 'Almond', rgb = {239, 222, 205}}
|
||||
colors[2] = {name = 'Antique Brass', rgb = {205, 149, 117}}
|
||||
colors[3] = {name = 'Apricot', rgb = {253, 217, 181}}
|
||||
colors[4] = {name = 'Aquamarine', rgb = {120, 219, 226}}
|
||||
colors[5] = {name = 'Asparagus', rgb = {135, 169, 107}}
|
||||
colors[6] = {name = 'Atomic Tangerine', rgb = {255, 164, 116}}
|
||||
colors[7] = {name = 'Banana Mania', rgb = {250, 231, 181}}
|
||||
colors[8] = {name = 'Beaver', rgb = {159, 129, 112}}
|
||||
colors[9] = {name = 'Bittersweet', rgb = {253, 124, 110}}
|
||||
colors[10] = {name = 'Black', rgb = {0, 0, 0}}
|
||||
colors[11] = {name = 'Blizzard Blue', rgb = {172, 229, 238}}
|
||||
colors[12] = {name = 'Blue', rgb = {31, 117, 254}}
|
||||
colors[13] = {name = 'Blue Bell', rgb = {162, 162, 208}}
|
||||
colors[14] = {name = 'Blue Gray', rgb = {102, 153, 204}}
|
||||
colors[15] = {name = 'Blue Green', rgb = {13, 152, 186}}
|
||||
colors[16] = {name = 'Blue Violet', rgb = {115, 102, 189}}
|
||||
colors[17] = {name = 'Blush', rgb = {222, 93, 131}}
|
||||
colors[18] = {name = 'Brick Red', rgb = {203, 65, 84}}
|
||||
colors[19] = {name = 'Brown', rgb = {180, 103, 77}}
|
||||
colors[20] = {name = 'Burnt Orange', rgb = {255, 127, 73}}
|
||||
colors[21] = {name = 'Burnt Sienna', rgb = {234, 126, 93}}
|
||||
colors[22] = {name = 'Cadet Blue', rgb = {176, 183, 198}}
|
||||
colors[23] = {name = 'Canary', rgb = {255, 255, 153}}
|
||||
colors[24] = {name = 'Caribbean Green', rgb = {28, 211, 162}}
|
||||
colors[25] = {name = 'Carnation Pink', rgb = {255, 170, 204}}
|
||||
colors[26] = {name = 'Cerise', rgb = {221, 68, 146}}
|
||||
colors[27] = {name = 'Cerulean', rgb = {29, 172, 214}}
|
||||
colors[28] = {name = 'Chestnut', rgb = {188, 93, 88}}
|
||||
colors[29] = {name = 'Copper', rgb = {221, 148, 117}}
|
||||
colors[30] = {name = 'Cornflower', rgb = {154, 206, 235}}
|
||||
colors[31] = {name = 'Cotton Candy', rgb = {255, 188, 217}}
|
||||
colors[32] = {name = 'Dandelion', rgb = {253, 219, 109}}
|
||||
colors[33] = {name = 'Denim', rgb = {43, 108, 196}}
|
||||
colors[34] = {name = 'Desert Sand', rgb = {239, 205, 184}}
|
||||
colors[35] = {name = 'Eggplant', rgb = {110, 81, 96}}
|
||||
colors[36] = {name = 'Electric Lime', rgb = {206, 255, 29}}
|
||||
colors[37] = {name = 'Fern', rgb = {113, 188, 120}}
|
||||
colors[38] = {name = 'Forest Green', rgb = {109, 174, 129}}
|
||||
colors[39] = {name = 'Fuchsia', rgb = {195, 100, 197}}
|
||||
colors[40] = {name = 'Fuzzy Wuzzy', rgb = {204, 102, 102}}
|
||||
colors[41] = {name = 'Gold', rgb = {231, 198, 151}}
|
||||
colors[42] = {name = 'Goldenrod', rgb = {252, 217, 117}}
|
||||
colors[43] = {name = 'Granny Smith Apple', rgb = {168, 228, 160}}
|
||||
colors[44] = {name = 'Gray', rgb = {149, 145, 140}}
|
||||
colors[45] = {name = 'Green', rgb = {28, 172, 120}}
|
||||
colors[46] = {name = 'Green Blue', rgb = {17, 100, 180}}
|
||||
colors[47] = {name = 'Green Yellow', rgb = {240, 232, 145}}
|
||||
colors[48] = {name = 'Hot Magenta', rgb = {255, 29, 206}}
|
||||
colors[49] = {name = 'Inchworm', rgb = {178, 236, 93}}
|
||||
colors[50] = {name = 'Indigo', rgb = {93, 118, 203}}
|
||||
colors[51] = {name = 'Jazzberry Jam', rgb = {202, 55, 103}}
|
||||
colors[52] = {name = 'Jungle Green', rgb = {59, 176, 143}}
|
||||
colors[53] = {name = 'Laser Lemon', rgb = {254, 254, 34}}
|
||||
colors[54] = {name = 'Lavender', rgb = {252, 180, 213}}
|
||||
colors[55] = {name = 'Lemon Yellow', rgb = {255, 244, 79}}
|
||||
colors[56] = {name = 'Macaroni and Cheese', rgb = {255, 189, 136}}
|
||||
colors[57] = {name = 'Magenta', rgb = {246, 100, 175}}
|
||||
colors[58] = {name = 'Magic Mint', rgb = {170, 240, 209}}
|
||||
colors[59] = {name = 'Mahogany', rgb = {205, 74, 76}}
|
||||
colors[60] = {name = 'Maize', rgb = {237, 209, 156}}
|
||||
colors[61] = {name = 'Manatee', rgb = {151, 154, 170}}
|
||||
colors[62] = {name = 'Mango Tango', rgb = {255, 130, 67}}
|
||||
colors[63] = {name = 'Maroon', rgb = {200, 56, 90}}
|
||||
colors[64] = {name = 'Mauvelous', rgb = {239, 152, 170}}
|
||||
colors[65] = {name = 'Melon', rgb = {253, 188, 180}}
|
||||
colors[66] = {name = 'Midnight Blue', rgb = {26, 72, 118}}
|
||||
colors[67] = {name = 'Mountain Meadow', rgb = {48, 186, 143}}
|
||||
colors[68] = {name = 'Mulberry', rgb = {197, 75, 140}}
|
||||
colors[69] = {name = 'Navy Blue', rgb = {25, 116, 210}}
|
||||
colors[70] = {name = 'Neon Carrot', rgb = {255, 163, 67}}
|
||||
colors[71] = {name = 'Olive Green', rgb = {186, 184, 108}}
|
||||
colors[72] = {name = 'Orange', rgb = {255, 117, 56}}
|
||||
colors[73] = {name = 'Orange Red', rgb = {255, 43, 43}}
|
||||
colors[74] = {name = 'Orange Yellow', rgb = {248, 213, 104}}
|
||||
colors[75] = {name = 'Orchid', rgb = {230, 168, 215}}
|
||||
colors[76] = {name = 'Outer Space', rgb = {65, 74, 76}}
|
||||
colors[77] = {name = 'Outrageous Orange', rgb = {255, 110, 74}}
|
||||
colors[78] = {name = 'Pacific Blue', rgb = {28, 169, 201}}
|
||||
colors[79] = {name = 'Peach', rgb = {255, 207, 171}}
|
||||
colors[80] = {name = 'Periwinkle', rgb = {197, 208, 230}}
|
||||
colors[81] = {name = 'Piggy Pink', rgb = {253, 221, 230}}
|
||||
colors[82] = {name = 'Pine Green', rgb = {21, 128, 120}}
|
||||
colors[83] = {name = 'Pink Flamingo', rgb = {252, 116, 253}}
|
||||
colors[84] = {name = 'Pink Sherbert', rgb = {247, 143, 167}}
|
||||
colors[85] = {name = 'Plum', rgb = {142, 69, 133}}
|
||||
colors[86] = {name = 'Purple Heart', rgb = {116, 66, 200}}
|
||||
colors[87] = {name = "Purple Mountain's Majesty", rgb = {157, 129, 186}}
|
||||
colors[88] = {name = 'Purple Pizzazz', rgb = {254, 78, 218}}
|
||||
colors[89] = {name = 'Radical Red', rgb = {255, 73, 108}}
|
||||
colors[90] = {name = 'Raw Sienna', rgb = {214, 138, 89}}
|
||||
colors[91] = {name = 'Raw Umber', rgb = {113, 75, 35}}
|
||||
colors[92] = {name = 'Razzle Dazzle Rose', rgb = {255, 72, 208}}
|
||||
colors[93] = {name = 'Razzmatazz', rgb = {227, 37, 107}}
|
||||
colors[94] = {name = 'Red', rgb = {238, 32, 77}}
|
||||
colors[95] = {name = 'Red Orange', rgb = {255, 83, 73}}
|
||||
colors[96] = {name = 'Red Violet', rgb = {192, 68, 143}}
|
||||
colors[97] = {name = "Robin's Egg Blue", rgb = {31, 206, 203}}
|
||||
colors[98] = {name = 'Royal Purple', rgb = {120, 81, 169}}
|
||||
colors[99] = {name = 'Salmon', rgb = {255, 155, 170}}
|
||||
colors[100] = {name = 'Scarlet', rgb = {252, 40, 71}}
|
||||
colors[101] = {name = "Screamin' Green", rgb = {118, 255, 122}}
|
||||
colors[102] = {name = 'Sea Green', rgb = {159, 226, 191}}
|
||||
colors[103] = {name = 'Sepia', rgb = {165, 105, 79}}
|
||||
colors[104] = {name = 'Shadow', rgb = {138, 121, 93}}
|
||||
colors[105] = {name = 'Shamrock', rgb = {69, 206, 162}}
|
||||
colors[106] = {name = 'Shocking Pink', rgb = {251, 126, 253}}
|
||||
colors[107] = {name = 'Silver', rgb = {205, 197, 194}}
|
||||
colors[108] = {name = 'Sky Blue', rgb = {128, 218, 235}}
|
||||
colors[109] = {name = 'Spring Green', rgb = {236, 234, 190}}
|
||||
colors[110] = {name = 'Sunglow', rgb = {255, 207, 72}}
|
||||
colors[111] = {name = 'Sunset Orange', rgb = {253, 94, 83}}
|
||||
colors[112] = {name = 'Tan', rgb = {250, 167, 108}}
|
||||
colors[113] = {name = 'Teal Blue', rgb = {24, 167, 181}}
|
||||
colors[114] = {name = 'Thistle', rgb = {235, 199, 223}}
|
||||
colors[115] = {name = 'Tickle Me Pink', rgb = {252, 137, 172}}
|
||||
colors[116] = {name = 'Timberwolf', rgb = {219, 215, 210}}
|
||||
colors[117] = {name = 'Tropical Rain Forest', rgb = {23, 128, 109}}
|
||||
colors[118] = {name = 'Tumbleweed', rgb = {222, 170, 136}}
|
||||
colors[119] = {name = 'Turquoise Blue', rgb = {119, 221, 231}}
|
||||
colors[120] = {name = 'Unmellow Yellow', rgb = {255, 255, 102}}
|
||||
colors[121] = {name = 'Violet (Purple)', rgb = {146, 110, 174}}
|
||||
colors[122] = {name = 'Violet Blue', rgb = {50, 74, 178}}
|
||||
colors[123] = {name = 'Violet Red', rgb = {247, 83, 148}}
|
||||
colors[124] = {name = 'Vivid Tangerine', rgb = {255, 160, 137}}
|
||||
colors[125] = {name = 'Vivid Violet', rgb = {143, 80, 157}}
|
||||
colors[126] = {name = 'White', rgb = {255, 255, 255}}
|
||||
colors[127] = {name = 'Wild Blue Yonder', rgb = {162, 173, 208}}
|
||||
colors[128] = {name = 'Wild Strawberry', rgb = {255, 67, 164}}
|
||||
colors[129] = {name = 'Wild Watermelon', rgb = {252, 108, 133}}
|
||||
colors[130] = {name = 'Wisteria', rgb = {205, 164, 222}}
|
||||
colors[131] = {name = 'Yellow', rgb = {252, 232, 131}}
|
||||
colors[132] = {name = 'Yellow Green', rgb = {197, 227, 132}}
|
||||
colors[133] = {name = 'Yellow Orange', rgb = {255, 174, 66}}
|
||||
|
||||
local function is_color_used(color, town_centers)
|
||||
for _, center in pairs(town_centers) do
|
||||
if center.color then
|
||||
if center.color.r == color.r and center.color.g == color.g and center.color.b == color.b then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Public.get_random_color()
|
||||
local ffatable = Table.get_table()
|
||||
local town_centers = ffatable.town_centers
|
||||
local rgb
|
||||
local color = {}
|
||||
local name
|
||||
local shuffle_index = {}
|
||||
for i = 1, #colors, 1 do
|
||||
shuffle_index[i] = i
|
||||
end
|
||||
table_shuffle(shuffle_index)
|
||||
for i = 1, #colors, 1 do
|
||||
rgb = colors[shuffle_index[i]].rgb
|
||||
name = colors[shuffle_index[i]].name
|
||||
local red = rgb[1] / 255
|
||||
local green = rgb[2] / 255
|
||||
local blue = rgb[3] / 255
|
||||
color.r = red
|
||||
color.g = green
|
||||
color.b = blue
|
||||
if not is_color_used(color, town_centers) then
|
||||
--log("color = " .. name)
|
||||
return {name = name, color = color}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function random_color(cmd)
|
||||
local player = game.players[cmd.player_index]
|
||||
if not player or not player.valid then
|
||||
return
|
||||
end
|
||||
local force = player.force
|
||||
if force.name == 'player' or force.name == 'rogue' then
|
||||
player.print('You are not member of a town!', Color.fail)
|
||||
return
|
||||
end
|
||||
local ffatable = Table.get_table()
|
||||
local town_center = ffatable.town_centers[force.name]
|
||||
|
||||
local crayon = Public.get_random_color()
|
||||
|
||||
town_center.color = crayon.color
|
||||
rendering.set_color(town_center.town_caption, town_center.color)
|
||||
for _, p in pairs(force.players) do
|
||||
if p.index == player.index then
|
||||
player.print('Your town color is now ' .. crayon.name, crayon.color)
|
||||
else
|
||||
player.print(player.name .. ' has set the town color to ' .. crayon.name, crayon.color)
|
||||
end
|
||||
p.color = crayon.color
|
||||
p.chat_color = crayon.color
|
||||
end
|
||||
end
|
||||
|
||||
commands.add_command(
|
||||
'random-color',
|
||||
'Randomly color your town..',
|
||||
function(cmd)
|
||||
random_color(cmd)
|
||||
end
|
||||
)
|
||||
|
||||
return Public
|
@ -35,9 +35,8 @@ local balance_functions = {
|
||||
local function on_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)
|
||||
local key = string_sub(research_name, 0, b)
|
||||
if balance_functions[key] then
|
||||
balance_functions[key](force_name)
|
||||
return
|
||||
|
@ -1,5 +1,6 @@
|
||||
local Public = {}
|
||||
local math_floor = math.floor
|
||||
local math_log10 = math.log10
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
|
||||
@ -29,6 +30,7 @@ local max_evolution_distance = 1024
|
||||
local max_pollution_behemoth = 256
|
||||
local max_pollution_big = 64
|
||||
local max_pollution_medium = 16
|
||||
-- max_factor < 1.0 means technology sum of weights will be greater than 1.0
|
||||
local max_factor = 0.8
|
||||
|
||||
-- technology weights (biter, spitter, worm)
|
||||
@ -106,7 +108,6 @@ local technology_weights = {
|
||||
['gate'] = {biter = 1, spitter = 1, worm = 1},
|
||||
['gun-turret'] = {biter = 1, spitter = 1, worm = 1},
|
||||
['heavy-armor'] = {biter = 5, spitter = 5, worm = 5},
|
||||
['improved-equipment'] = {biter = 1, spitter = 1, worm = 1},
|
||||
['inserter-capacity-bonus-1'] = {biter = 1, spitter = 1, worm = 1},
|
||||
['inserter-capacity-bonus-3'] = {biter = 1, spitter = 1, worm = 1},
|
||||
['inserter-capacity-bonus-4'] = {biter = 1, spitter = 1, worm = 1},
|
||||
@ -117,13 +118,13 @@ local technology_weights = {
|
||||
['land-mine'] = {biter = 5, spitter = 5, worm = 5},
|
||||
['landfill'] = {biter = 1, spitter = 1, worm = 1},
|
||||
['laser'] = {biter = 5, spitter = 5, worm = 5},
|
||||
['laser-turret-speed-1'] = {biter = 5, spitter = 5, worm = 5},
|
||||
['laser-turret-speed-2'] = {biter = 5, spitter = 5, worm = 5},
|
||||
['laser-turret-speed-3'] = {biter = 5, spitter = 5, worm = 5},
|
||||
['laser-turret-speed-4'] = {biter = 5, spitter = 5, worm = 5},
|
||||
['laser-turret-speed-5'] = {biter = 5, spitter = 5, worm = 5},
|
||||
['laser-turret-speed-6'] = {biter = 5, spitter = 5, worm = 5},
|
||||
['laser-turret-speed-7'] = {biter = 5, spitter = 5, worm = 5},
|
||||
['laser-shooting-speed-1'] = {biter = 5, spitter = 5, worm = 5},
|
||||
['laser-shooting-speed-2'] = {biter = 5, spitter = 5, worm = 5},
|
||||
['laser-shooting-speed-3'] = {biter = 5, spitter = 5, worm = 5},
|
||||
['laser-shooting-speed-4'] = {biter = 5, spitter = 5, worm = 5},
|
||||
['laser-shooting-speed-5'] = {biter = 5, spitter = 5, worm = 5},
|
||||
['laser-shooting-speed-6'] = {biter = 5, spitter = 5, worm = 5},
|
||||
['laser-shooting-speed-7'] = {biter = 5, spitter = 5, worm = 5},
|
||||
['laser-turret'] = {biter = 5, spitter = 5, worm = 5},
|
||||
['logistic-robotics'] = {biter = 1, spitter = 1, worm = 1},
|
||||
['logistic-science-pack'] = {biter = 25, spitter = 25, worm = 25},
|
||||
@ -240,89 +241,128 @@ max_spitter_weight = max_spitter_weight * max_factor
|
||||
max_worm_weight = max_worm_weight * max_factor
|
||||
|
||||
local function get_unit_size(evolution)
|
||||
-- returns a value 0-3 that represents the unit size
|
||||
-- returns a value 1-4 that represents the unit size
|
||||
|
||||
-- basically evo values of: 0%, 10%, 30%, 60%, 80%, 100%
|
||||
-- small unit chances are 100%, 100%, 50%, 25%, 12.5%, 0%
|
||||
-- medium unit chances are 0%, 0%, 50%, 25%, 12.5%, 0%
|
||||
-- big unit chances are 0%, 0%, 0%, 50%, 25%, 0%
|
||||
-- behemoth unit chances are 0%, 0%, 0%, 0%, 50%, 100%
|
||||
-- basically evo values of: 0% 10% 20% 30% 40% 50% 60% 70% 80% 90% 100%
|
||||
-- -----------------------------------------------------------------------------------
|
||||
-- small unit chances are 100% 60% 40% 30% 20% 15% 7.5% 0% 0% 0% 0%
|
||||
-- medium unit chances are 0% 40% 40% 30% 20% 15% 7.5% 12.5% 25% 0% 0%
|
||||
-- big unit chances are 0% 0% 20% 40% 60% 60% 75% 75% 50% 50% 0%
|
||||
-- behemoth unit chances are 0% 0% 0% 0% 0% 10% 10% 12.5% 25% 50% 100%
|
||||
-- and curve accordingly in between evo values
|
||||
|
||||
-- magic stuff happens here
|
||||
if (evolution < 0.10) then
|
||||
-- 0%
|
||||
if (evolution < 0.1) then
|
||||
return 1
|
||||
end
|
||||
if (evolution >= 0.10 and evolution < 0.40) then
|
||||
local r = (evolution - 0.10) * 5
|
||||
if math.random() < 0.5 then
|
||||
return 1
|
||||
end
|
||||
if math.random() < r then
|
||||
-- 10%
|
||||
if (evolution >= 0.1 and evolution < 0.2) then
|
||||
local r = math.random()
|
||||
if r < 0.6 then
|
||||
return 1
|
||||
end
|
||||
return 2
|
||||
end
|
||||
if (evolution >= 0.30 and evolution < 0.60) then
|
||||
local r = (evolution - 0.30) * 3.3333
|
||||
if math.random() < 0.5 then
|
||||
if math.random() < 0.5 then
|
||||
-- 20%
|
||||
if (evolution >= 0.2 and evolution < 0.3) then
|
||||
local r = math.random()
|
||||
if r < 0.8 then
|
||||
if r < 0.4 then
|
||||
return 1
|
||||
else
|
||||
if math.random() < r then
|
||||
return 2
|
||||
end
|
||||
end
|
||||
return 3
|
||||
end
|
||||
-- 30%
|
||||
if (evolution >= 0.3 and evolution < 0.4) then
|
||||
local r = math.random()
|
||||
if r < 0.6 then
|
||||
if r < 0.3 then
|
||||
return 1
|
||||
else
|
||||
return 2
|
||||
end
|
||||
end
|
||||
return 3
|
||||
end
|
||||
-- 40%
|
||||
if (evolution >= 0.4 and evolution < 0.5) then
|
||||
local r = math.random()
|
||||
if r < 0.4 then
|
||||
if r < 0.2 then
|
||||
return 1
|
||||
else
|
||||
return 2
|
||||
end
|
||||
end
|
||||
return 3
|
||||
end
|
||||
-- 50%
|
||||
if (evolution >= 0.5 and evolution < 0.6) then
|
||||
local r = math.random()
|
||||
if r < 0.9 then
|
||||
if r < 0.3 then
|
||||
if r < 0.15 then
|
||||
return 1
|
||||
else
|
||||
return 2
|
||||
end
|
||||
end
|
||||
else
|
||||
if math.random() < r then
|
||||
return 3
|
||||
end
|
||||
return 4
|
||||
end
|
||||
-- 60%
|
||||
if (evolution >= 0.60 and evolution < 0.70) then
|
||||
local r = math.random()
|
||||
if r < 0.9 then
|
||||
if r < 0.15 then
|
||||
if r < 0.075 then
|
||||
return 1
|
||||
else
|
||||
return 2
|
||||
end
|
||||
end
|
||||
return 3
|
||||
end
|
||||
return 4
|
||||
end
|
||||
-- 70%
|
||||
if (evolution >= 0.70 and evolution < 0.80) then
|
||||
local r = math.random()
|
||||
if r < 0.985 then
|
||||
if r < 0.125 then
|
||||
return 2
|
||||
else
|
||||
return 3
|
||||
end
|
||||
end
|
||||
return 4
|
||||
end
|
||||
if (evolution >= 0.60 and evolution < 0.80) then
|
||||
local r = (evolution - 0.60) * 5
|
||||
if math.random() < 0.5 then
|
||||
if math.random() < 0.5 then
|
||||
if math.random() < r then
|
||||
return 1
|
||||
else
|
||||
return 2
|
||||
end
|
||||
else
|
||||
if math.random() < r then
|
||||
return 2
|
||||
else
|
||||
return 3
|
||||
end
|
||||
end
|
||||
else
|
||||
if math.random() < r then
|
||||
return 3
|
||||
else
|
||||
return 4
|
||||
end
|
||||
end
|
||||
end
|
||||
if (evolution >= 0.80 and evolution < 1.0) then
|
||||
local r = (evolution - 0.80) * 5
|
||||
if math.random() < 0.5 then
|
||||
if math.random() < r then
|
||||
if math.random() < r then
|
||||
return 1
|
||||
else
|
||||
return 2
|
||||
end
|
||||
-- 80%
|
||||
if (evolution >= 0.80 and evolution < 0.90) then
|
||||
local r = math.random()
|
||||
if r < 0.75 then
|
||||
if r < 0.25 then
|
||||
return 2
|
||||
else
|
||||
return 3
|
||||
end
|
||||
else
|
||||
return 4
|
||||
end
|
||||
return 4
|
||||
end
|
||||
-- 90%
|
||||
if (evolution >= 0.90 and evolution < 1) then
|
||||
local r = math.random()
|
||||
if r < 0.5 then
|
||||
return 3
|
||||
end
|
||||
return 4
|
||||
end
|
||||
-- 100%
|
||||
if (evolution >= 1.0) then
|
||||
return 4
|
||||
end
|
||||
@ -336,6 +376,16 @@ local function distance_squared(pos1, pos2)
|
||||
return d2
|
||||
end
|
||||
|
||||
-- calculate the relative evolution based on evolution factor (0.0-1.0) and distance factor (0.0-1.0)
|
||||
local function calculate_relative_evolution(evolution_factor, distance_factor)
|
||||
-- distance factor will be from 0.0 to 1.0 but drop off dramatically towards zero
|
||||
local log_distance_factor = math_log10(distance_factor * 10 + 1)
|
||||
local evo = log_distance_factor * evolution_factor
|
||||
if evo < 0.0 then evo = 0.0 end
|
||||
if evo > 1.0 then evo = 1.0 end
|
||||
return evo
|
||||
end
|
||||
|
||||
local function get_relative_biter_evolution(position)
|
||||
local ffatable = Table.get_table()
|
||||
local relative_evolution = 0.0
|
||||
@ -343,9 +393,10 @@ local function get_relative_biter_evolution(position)
|
||||
-- for all of the teams
|
||||
local teams = ffatable.town_centers
|
||||
for _, town_center in pairs(teams) do
|
||||
local market_position = town_center.market.position
|
||||
local market = town_center.market
|
||||
if market == nil or not market.valid then return relative_evolution end
|
||||
-- calculate the distance squared
|
||||
local d2 = distance_squared(position, market_position)
|
||||
local d2 = distance_squared(position, market.position)
|
||||
if d2 < max_d2 then
|
||||
-- get the distance factor (0.0-1.0)
|
||||
local distance_factor = 1.0 - d2 / max_d2
|
||||
@ -356,8 +407,8 @@ local function get_relative_biter_evolution(position)
|
||||
if town_center.evolution.biters == nil then
|
||||
town_center.evolution.biters = 0.0
|
||||
end
|
||||
local evolution_factor = town_center.evolution.biters
|
||||
local evo = distance_factor * evolution_factor
|
||||
local evo = calculate_relative_evolution(town_center.evolution.biters, distance_factor)
|
||||
-- get the highest of the relative evolutions of each town
|
||||
relative_evolution = math.max(relative_evolution, evo)
|
||||
end
|
||||
end
|
||||
@ -371,9 +422,10 @@ local function get_relative_spitter_evolution(position)
|
||||
-- for all of the teams
|
||||
local teams = ffatable.town_centers
|
||||
for _, town_center in pairs(teams) do
|
||||
local market_position = town_center.market.position
|
||||
local market = town_center.market
|
||||
if market == nil or not market.valid then return relative_evolution end
|
||||
-- calculate the distance squared
|
||||
local d2 = distance_squared(position, market_position)
|
||||
local d2 = distance_squared(position, market.position)
|
||||
if d2 < max_d2 then
|
||||
-- get the distance factor (0.0-1.0)
|
||||
local distance_factor = 1.0 - d2 / max_d2
|
||||
@ -384,8 +436,8 @@ local function get_relative_spitter_evolution(position)
|
||||
if town_center.evolution.spitters == nil then
|
||||
town_center.evolution.spitters = 0.0
|
||||
end
|
||||
local evolution_factor = town_center.evolution.spitters
|
||||
local evo = distance_factor * evolution_factor
|
||||
local evo = calculate_relative_evolution(town_center.evolution.spitters, distance_factor)
|
||||
-- get the highest of the relative evolutions of each town
|
||||
relative_evolution = math.max(relative_evolution, evo)
|
||||
end
|
||||
end
|
||||
@ -399,9 +451,10 @@ local function get_relative_worm_evolution(position)
|
||||
-- for all of the teams
|
||||
local teams = ffatable.town_centers
|
||||
for _, town_center in pairs(teams) do
|
||||
local market_position = town_center.market.position
|
||||
local market = town_center.market
|
||||
if market == nil or not market.valid then return relative_evolution end
|
||||
-- calculate the distance squared
|
||||
local d2 = distance_squared(position, market_position)
|
||||
local d2 = distance_squared(position, market.position)
|
||||
if d2 < max_d2 then
|
||||
-- get the distance factor (0.0-1.0)
|
||||
local distance_factor = 1.0 - d2 / max_d2
|
||||
@ -412,8 +465,8 @@ local function get_relative_worm_evolution(position)
|
||||
if town_center.evolution.worms == nil then
|
||||
town_center.evolution.worms = 0.0
|
||||
end
|
||||
local evolution_factor = town_center.evolution.worms
|
||||
local evo = distance_factor * evolution_factor
|
||||
local evo = calculate_relative_evolution(town_center.evolution.worms, distance_factor)
|
||||
-- get the highest of the relative evolutions of each town
|
||||
relative_evolution = math.max(relative_evolution, evo)
|
||||
end
|
||||
end
|
||||
@ -577,12 +630,13 @@ local function is_worm(entity)
|
||||
return false
|
||||
end
|
||||
|
||||
-- update evolution based on research completed (weighted)
|
||||
-- sets the evolution to a value from 0.0 to 1.0 based on research progress
|
||||
local function update_evolution(force_name, technology)
|
||||
if technology == nil then
|
||||
return
|
||||
end
|
||||
local ffatable = Table.get_table()
|
||||
-- update evolution based on research completed (weighted)
|
||||
local town_center = ffatable.town_centers[force_name]
|
||||
-- town_center is a reference to a global table
|
||||
if not town_center then
|
||||
@ -600,6 +654,7 @@ local function update_evolution(force_name, technology)
|
||||
local spitter_weight = weight.spitter
|
||||
local worm_weight = weight.worm
|
||||
-- update the evolution values (0.0 to 1.0)
|
||||
-- max weights might be less than 1.0, to allow for evo > 1.0
|
||||
local b = (biter_weight / max_biter_weight)
|
||||
local s = (spitter_weight / max_spitter_weight)
|
||||
local w = (worm_weight / max_worm_weight)
|
||||
@ -613,9 +668,9 @@ end
|
||||
|
||||
local function on_research_finished(event)
|
||||
local research = event.research
|
||||
local force_name = research.force.name
|
||||
local force = research.force
|
||||
local technology = research.name
|
||||
update_evolution(force_name, technology)
|
||||
update_evolution(force.name, technology)
|
||||
end
|
||||
|
||||
local function on_entity_spawned(event)
|
||||
|
@ -13,7 +13,7 @@ function Public.reproduce()
|
||||
if #fishes == 0 then
|
||||
return
|
||||
end
|
||||
if #fishes >= 100 then
|
||||
if #fishes >= 128 then
|
||||
return
|
||||
end
|
||||
-- pick a random fish
|
||||
@ -52,15 +52,18 @@ local function on_player_used_capsule(event)
|
||||
end
|
||||
|
||||
-- if using fish on water
|
||||
if tile.name == 'water' and tile.name == 'water-green' and tile.name == 'deepwater' and tile.name == 'deepwater-green' then
|
||||
if tile.name == 'water'
|
||||
or tile.name == 'water-green'
|
||||
or tile.name == 'water-mud'
|
||||
or tile.name == 'water-shallow'
|
||||
or tile.name == 'deepwater'
|
||||
or tile.name == 'deepwater-green'
|
||||
then
|
||||
-- get the count of fish in the water nearby and test if can be repopulated
|
||||
local fishes = surface.find_entities_filtered({name = 'fish', position = position, radius = 27})
|
||||
if #fishes < 12 then
|
||||
surface.create_entity({name = 'water-splash', position = position})
|
||||
surface.create_entity({name = 'fish', position = position})
|
||||
surface.play_sound({path = 'utility/achievement_unlocked', position = player.position, volume_modifier = 1})
|
||||
return
|
||||
end
|
||||
surface.create_entity({name = 'water-splash', position = position})
|
||||
surface.create_entity({name = 'fish', position = position})
|
||||
surface.play_sound({path = 'utility/achievement_unlocked', position = player.position, volume_modifier = 1})
|
||||
return
|
||||
end
|
||||
-- otherwise return the fish and make no sound
|
||||
player.insert({name = 'raw-fish', count = 1})
|
||||
|
@ -10,17 +10,17 @@ The local inhabitants are indifferent to you at first, so long as you don't buil
|
||||
by foreign technology. In fact, they get quite aggressive at the scent of it. If you were to hurt any of the natives you will be
|
||||
brandished a rogue until your untimely death or until you find better digs.
|
||||
|
||||
To create a new town or outpost simply place a furnace down in a suitable spot that is not near any other towns or obstructed.
|
||||
To create a new town simply place a furnace down in a suitable spot that is not near any other towns or obstructed.
|
||||
The world seems to be limited in size with uninhabitable zones on four sides. News towns can only be built within these
|
||||
borders and you must leave room for the town's size (radius of 27) when placing a new town.
|
||||
borders and you must leave room for the town's size (radius of 27) when placing a new town. Each town costs 100 coins.
|
||||
TIP: It's best to find a spot far from existing towns and pollution, as enemies will become aggressive once you form a town.
|
||||
|
||||
Once a town is formed, members may invite other players and teams using a raw fish. To invite another player, drop a fish
|
||||
on that player (with the Z key). To accept an invite, offer a fish in return to the member. To leave a town, simply drop coal
|
||||
Once a town is formed, members may invite other players and teams using a coin. To invite another player, drop a coin
|
||||
on that player (with the Z key). To accept an invite, offer a coin in return to the member. To leave a town, simply drop coal
|
||||
on the market. As a member of a town, your respawn point will change to that of the town.
|
||||
|
||||
To form any alliance with another town, drop a fish on a member or their market. If they agree they can reciprocate with a
|
||||
fish offering.
|
||||
To form any alliance with another town, drop a coin on a member or their market. If they agree they can reciprocate with a
|
||||
coin offering.
|
||||
|
||||
The town market is the heart of your town. If it is destroyed, your town is destroyed and you will lose all research. So
|
||||
protect it well, repair it whenever possible, and if you can afford, increase its health by purchasing upgrades. If your
|
||||
@ -67,14 +67,14 @@ function Public.show(player)
|
||||
|
||||
t = t.add {type = 'table', column_count = 4}
|
||||
|
||||
local label2 = t.add {type = 'label', caption = 'Outlander' .. '(' .. #game.forces.player.connected_players .. ')'}
|
||||
local label2 = t.add {type = 'label', caption = 'Outlander' .. ':' .. #game.forces.player.connected_players .. ' '}
|
||||
label2.style.font_color = {170, 170, 170}
|
||||
label2.style.font = 'heading-3'
|
||||
label2.style.minimal_width = 80
|
||||
|
||||
for _, town_center in pairs(ffatable.town_centers) do
|
||||
local force = town_center.market.force
|
||||
local label3 = t.add {type = 'label', caption = force.name .. '(' .. #force.connected_players .. ')'}
|
||||
local label3 = t.add {type = 'label', caption = force.name .. ':' .. #force.connected_players .. ' '}
|
||||
label3.style.font = 'heading-3'
|
||||
label3.style.minimal_width = 80
|
||||
label3.style.font_color = town_center.color
|
||||
|
@ -1,6 +1,10 @@
|
||||
local Public = {}
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
|
||||
function Public.reset()
|
||||
local ffatable = Table.get_table()
|
||||
if ffatable.testing_mode then return end
|
||||
for index = 1, table.size(game.forces), 1 do
|
||||
local force = game.forces[index]
|
||||
if force ~= nil then
|
||||
@ -9,7 +13,47 @@ function Public.reset()
|
||||
end
|
||||
end
|
||||
|
||||
--local Event = require 'utils.event'
|
||||
--Event.add(defines.events.on_chunk_charted, on_chunk_charted)
|
||||
local function add_force(id, force_name)
|
||||
local forces = rendering.get_forces(id)
|
||||
for _, force in ipairs(forces) do
|
||||
if force.name == force_name or force == force_name then return end
|
||||
end
|
||||
forces[#forces + 1] = force_name
|
||||
rendering.set_forces(id, forces)
|
||||
end
|
||||
|
||||
local function update_forces(id)
|
||||
local forces = rendering.get_forces(id)
|
||||
local new_forces = {}
|
||||
for _, force in ipairs(forces) do
|
||||
if force ~= nil and force.valid then
|
||||
new_forces[#new_forces + 1] = force.name
|
||||
end
|
||||
end
|
||||
rendering.set_forces(id, new_forces)
|
||||
end
|
||||
|
||||
local function on_chunk_charted(event)
|
||||
local surface = game.surfaces[event.surface_index]
|
||||
local force = event.force
|
||||
local area = event.area
|
||||
local markets = surface.find_entities_filtered({area = area, name = 'market'})
|
||||
for _, market in pairs(markets) do
|
||||
local force_name = market.force.name
|
||||
local ffatable = Table.get_table()
|
||||
local town_center = ffatable.town_centers[force_name]
|
||||
-- town caption
|
||||
local town_caption = town_center.town_caption
|
||||
update_forces(town_caption)
|
||||
add_force(town_caption, force.name)
|
||||
-- health text
|
||||
local health_text = town_center.health_text
|
||||
update_forces(health_text)
|
||||
add_force(health_text, force.name)
|
||||
end
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.add(defines.events.on_chunk_charted, on_chunk_charted)
|
||||
|
||||
return Public
|
||||
|
19
modules/scrap_towny_ffa/map.lua
Normal file
19
modules/scrap_towny_ffa/map.lua
Normal file
@ -0,0 +1,19 @@
|
||||
local Public = {}
|
||||
|
||||
function Public.disable_world_map(player)
|
||||
player.map_view_settings = {
|
||||
["show-player-names"] = false,
|
||||
}
|
||||
player.show_on_map = false
|
||||
player.game_view_settings.show_minimap = false
|
||||
end
|
||||
|
||||
function Public.enable_world_map(player)
|
||||
player.map_view_settings = {
|
||||
["show-player-names"] = true,
|
||||
}
|
||||
player.show_on_map = true
|
||||
player.game_view_settings.show_minimap = true
|
||||
end
|
||||
|
||||
return Public
|
@ -9,45 +9,75 @@ local upgrade_functions = {
|
||||
local market = town_center.market
|
||||
local surface = market.surface
|
||||
if town_center.max_health > 500000 then
|
||||
return
|
||||
return false
|
||||
end
|
||||
town_center.health = town_center.health + town_center.max_health
|
||||
town_center.max_health = town_center.max_health * 2
|
||||
Town_center.set_market_health(market, 0)
|
||||
surface.play_sound({path = 'utility/achievement_unlocked', position = player.position, volume_modifier = 1})
|
||||
return true
|
||||
end,
|
||||
-- Upgrade Backpack
|
||||
[2] = function(town_center, player)
|
||||
local market = town_center.market
|
||||
local force = market.force
|
||||
local surface = market.surface
|
||||
if force.character_inventory_slots_bonus > 100 then
|
||||
return
|
||||
if force.character_inventory_slots_bonus + 5 > 100 then
|
||||
return false
|
||||
end
|
||||
force.character_inventory_slots_bonus = force.character_inventory_slots_bonus + 5
|
||||
surface.play_sound({path = 'utility/achievement_unlocked', position = player.position, volume_modifier = 1})
|
||||
return true
|
||||
end,
|
||||
-- Upgrade Mining Productivity
|
||||
[3] = function(town_center, player)
|
||||
local market = town_center.market
|
||||
local force = market.force
|
||||
local surface = market.surface
|
||||
if town_center.upgrades.mining_prod >= 10 then
|
||||
return
|
||||
if town_center.upgrades.mining_prod + 1 > 10 then
|
||||
return false
|
||||
end
|
||||
town_center.upgrades.mining_prod = town_center.upgrades.mining_prod + 1
|
||||
force.mining_drill_productivity_bonus = force.mining_drill_productivity_bonus + 0.1
|
||||
surface.play_sound({path = 'utility/achievement_unlocked', position = player.position, volume_modifier = 1})
|
||||
return true
|
||||
end,
|
||||
-- Upgrade Pickaxe Speed
|
||||
[4] = function(town_center, player)
|
||||
local market = town_center.market
|
||||
local force = market.force
|
||||
local surface = market.surface
|
||||
if town_center.upgrades.mining_speed + 1 > 10 then
|
||||
return false
|
||||
end
|
||||
town_center.upgrades.mining_speed = town_center.upgrades.mining_speed + 1
|
||||
force.manual_mining_speed_modifier = force.manual_mining_speed_modifier + 0.1
|
||||
surface.play_sound({path = 'utility/achievement_unlocked', position = player.position, volume_modifier = 1})
|
||||
return true
|
||||
end,
|
||||
-- Upgrade Crafting Speed
|
||||
[5] = function(town_center, player)
|
||||
local market = town_center.market
|
||||
local force = market.force
|
||||
local surface = market.surface
|
||||
if town_center.upgrades.crafting_speed + 1 > 10 then
|
||||
return false
|
||||
end
|
||||
town_center.upgrades.crafting_speed = town_center.upgrades.crafting_speed + 1
|
||||
force.manual_crafting_speed_modifier = force.manual_crafting_speed_modifier + 0.1
|
||||
surface.play_sound({path = 'utility/achievement_unlocked', position = player.position, volume_modifier = 1})
|
||||
return true
|
||||
end,
|
||||
-- Laser Turret Slot
|
||||
[4] = function(town_center, player)
|
||||
[6] = function(town_center, player)
|
||||
local market = town_center.market
|
||||
local surface = market.surface
|
||||
town_center.upgrades.laser_turret.slots = town_center.upgrades.laser_turret.slots + 1
|
||||
surface.play_sound({path = 'utility/new_objective', position = player.position, volume_modifier = 1})
|
||||
return true
|
||||
end,
|
||||
-- Set Spawn Point
|
||||
[5] = function(town_center, player)
|
||||
[7] = function(town_center, player)
|
||||
local ffatable = Table.get_table()
|
||||
local market = town_center.market
|
||||
local force = market.force
|
||||
@ -55,6 +85,7 @@ local upgrade_functions = {
|
||||
local spawn_point = force.get_spawn_position(surface)
|
||||
ffatable.spawn_point[player.name] = spawn_point
|
||||
surface.play_sound({path = 'utility/scenario_message', position = player.position, volume_modifier = 1})
|
||||
return false
|
||||
end
|
||||
}
|
||||
|
||||
@ -70,31 +101,39 @@ end
|
||||
local function set_offers(town_center)
|
||||
local market = town_center.market
|
||||
local force = market.force
|
||||
local market_items = {}
|
||||
|
||||
-- special offers
|
||||
local special_offers = {}
|
||||
|
||||
if town_center.max_health < 500000 then
|
||||
special_offers[1] = {{{'coin', town_center.max_health * 0.1}}, 'Upgrade Town Center Health'}
|
||||
else
|
||||
special_offers[1] = {{{'coin', 1}}, 'Maximum Health upgrades reached!'}
|
||||
special_offers[1] = {{}, 'Maximum Health upgrades reached!'}
|
||||
end
|
||||
if force.character_inventory_slots_bonus <= 100 then
|
||||
if force.character_inventory_slots_bonus + 5 <= 100 then
|
||||
special_offers[2] = {{{'coin', (force.character_inventory_slots_bonus / 5 + 1) * 50}}, 'Upgrade Backpack +5 Slot'}
|
||||
else
|
||||
special_offers[2] = {{{'coin', 1}}, 'Maximum Backpack upgrades reached!'}
|
||||
special_offers[2] = {{}, 'Maximum Backpack upgrades reached!'}
|
||||
end
|
||||
if town_center.upgrades.mining_prod < 10 then
|
||||
if town_center.upgrades.mining_prod + 1 <= 10 then
|
||||
special_offers[3] = {{{'coin', (town_center.upgrades.mining_prod + 1) * 400}}, 'Upgrade Mining Productivity +10%'}
|
||||
else
|
||||
special_offers[3] = {{{'coin', 1}}, 'Maximum Mining upgrades reached!'}
|
||||
special_offers[3] = {{}, 'Maximum Productivity upgrades reached!'}
|
||||
end
|
||||
if town_center.upgrades.mining_speed + 1 <= 10 then
|
||||
special_offers[4] = {{{'coin', (town_center.upgrades.mining_speed + 1) * 400}}, 'Upgrade Mining Speed +10%'}
|
||||
else
|
||||
special_offers[4] = {{}, 'Maximum Mining Speed upgrades reached!'}
|
||||
end
|
||||
if town_center.upgrades.crafting_speed + 1 <= 10 then
|
||||
special_offers[5] = {{{'coin', (town_center.upgrades.crafting_speed + 1) * 400}}, 'Upgrade Crafting Speed +10%'}
|
||||
else
|
||||
special_offers[5] = {{}, 'Maximum Crafting Speed upgrades reached!'}
|
||||
end
|
||||
local laser_turret = 'Laser Turret Slot [#' .. tostring(town_center.upgrades.laser_turret.slots + 1) .. ']'
|
||||
special_offers[4] = {{{'coin', 1000 + (town_center.upgrades.laser_turret.slots * 50)}}, laser_turret}
|
||||
special_offers[6] = {{{'coin', 1000 + (town_center.upgrades.laser_turret.slots * 50)}}, laser_turret}
|
||||
local spawn_point = 'Set Spawn Point'
|
||||
special_offers[5] = {{{'coin', 1}}, spawn_point}
|
||||
|
||||
local market_items = {}
|
||||
|
||||
special_offers[7] = {{}, spawn_point}
|
||||
for _, v in pairs(special_offers) do
|
||||
table_insert(market_items, {price = v[1], offer = {type = 'nothing', effect_description = v[2]}})
|
||||
end
|
||||
@ -111,6 +150,7 @@ local function set_offers(town_center)
|
||||
table_insert(market_items, {price = {{'coin', 600}}, offer = {type = 'give-item', item = 'fast-loader', count = 1}})
|
||||
table_insert(market_items, {price = {{'coin', 900}}, offer = {type = 'give-item', item = 'express-loader', count = 1}})
|
||||
-- scrap selling
|
||||
table_insert(market_items, {price = {{'raw-fish', 1}}, offer = {type = 'give-item', item = 'coin', count = 1}})
|
||||
table_insert(market_items, {price = {{'wood', 7}}, offer = {type = 'give-item', item = 'coin', count = 1}})
|
||||
table_insert(market_items, {price = {{'iron-ore', 7}}, offer = {type = 'give-item', item = 'coin', count = 1}})
|
||||
table_insert(market_items, {price = {{'copper-ore', 7}}, offer = {type = 'give-item', item = 'coin', count = 1}})
|
||||
@ -129,6 +169,7 @@ end
|
||||
|
||||
local function refresh_offers(event)
|
||||
local ffatable = Table.get_table()
|
||||
local player = game.players[event.player_index]
|
||||
local market = event.entity or event.market
|
||||
if not market then
|
||||
return
|
||||
@ -143,8 +184,22 @@ local function refresh_offers(event)
|
||||
if not town_center then
|
||||
return
|
||||
end
|
||||
clear_offers(market)
|
||||
set_offers(town_center)
|
||||
if player.force == market.force then
|
||||
clear_offers(market)
|
||||
set_offers(town_center)
|
||||
else
|
||||
if player.opened ~= nil then
|
||||
player.opened = nil
|
||||
player.surface.create_entity(
|
||||
{
|
||||
name = 'flying-text',
|
||||
position = {market.position.x - 1.75, market.position.y},
|
||||
text = 'Sorry, we are closed.',
|
||||
color = {r = 1, g = 0.68, b = 0.26}
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function offer_purchased(event)
|
||||
@ -156,21 +211,30 @@ local function offer_purchased(event)
|
||||
if not upgrade_functions[offer_index] then
|
||||
return
|
||||
end
|
||||
|
||||
local town_center = ffatable.town_centers[market.force.name]
|
||||
if not town_center then
|
||||
return
|
||||
end
|
||||
|
||||
upgrade_functions[offer_index](town_center, player)
|
||||
|
||||
if count > 1 then
|
||||
if upgrade_functions[offer_index](town_center, player) then
|
||||
-- reimburse extra purchased
|
||||
if count > 1 then
|
||||
local offers = market.get_market_items()
|
||||
if offers[offer_index].price ~= nil then
|
||||
local price = offers[offer_index].price[1].amount
|
||||
player.insert({name = 'coin', count = price * (count - 1)})
|
||||
end
|
||||
end
|
||||
else
|
||||
-- reimburse purchase
|
||||
local offers = market.get_market_items()
|
||||
local price = offers[offer_index].price[1].amount
|
||||
player.insert({name = 'coin', count = price * (count - 1)})
|
||||
if offers[offer_index].price ~= nil then
|
||||
local price = offers[offer_index].price[1].amount
|
||||
player.insert({name = 'coin', count = price * (count)})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- called for all gui events
|
||||
local function on_gui_opened(event)
|
||||
local gui_type = event.gui_type
|
||||
if gui_type ~= defines.gui_type.entity then
|
||||
@ -180,25 +244,53 @@ local function on_gui_opened(event)
|
||||
if entity == nil or not entity.valid then
|
||||
return
|
||||
end
|
||||
if entity.type == 'market' then
|
||||
if entity.name == 'market' then
|
||||
refresh_offers(event)
|
||||
end
|
||||
end
|
||||
|
||||
-- called for all market events
|
||||
local function on_market_item_purchased(event)
|
||||
offer_purchased(event)
|
||||
refresh_offers(event)
|
||||
local market = event.market
|
||||
if market.name == 'market' then
|
||||
offer_purchased(event)
|
||||
refresh_offers(event)
|
||||
end
|
||||
end
|
||||
|
||||
local function inside(pos, area)
|
||||
return pos.x >= area.left_top.x and pos.x <= area.right_bottom.x and pos.y >= area.left_top.y and pos.y <= area.right_bottom.y
|
||||
end
|
||||
|
||||
local function on_tick(_)
|
||||
local ffatable = Table.get_table()
|
||||
if not ffatable.town_centers then
|
||||
return
|
||||
local function equal(pos1, pos2)
|
||||
return pos1.x == pos2.x and pos1.y == pos2.y
|
||||
end
|
||||
|
||||
local function is_loader(entity)
|
||||
return entity.name == 'loader' or entity.name == 'fast-loader' or entity.name == 'express-loader'
|
||||
end
|
||||
|
||||
local function is_filtered_inserter(entity)
|
||||
return entity.name == 'filter-inserter' or entity.name == "stack-filter-inserter"
|
||||
end
|
||||
|
||||
local function max_stack_size(entity)
|
||||
if is_loader(entity) then return 1 end
|
||||
if (entity.name == "stack-inserter" or entity.name == "stack-filter-inserter") then
|
||||
local override = entity.inserter_stack_size_override
|
||||
if override > 0 then return override end
|
||||
local capacity = entity.force.stack_inserter_capacity_bonus
|
||||
return 1 + capacity
|
||||
else
|
||||
local override = entity.inserter_stack_size_override
|
||||
if override > 0 then return override end
|
||||
local bonus = entity.force.inserter_stack_size_bonus
|
||||
return 1 + bonus
|
||||
end
|
||||
end
|
||||
|
||||
local function get_connected_entities(market)
|
||||
if not market.valid then return {} end
|
||||
local items = {
|
||||
'burner-inserter',
|
||||
'inserter',
|
||||
@ -211,117 +303,211 @@ local function on_tick(_)
|
||||
'fast-loader',
|
||||
'express-loader'
|
||||
}
|
||||
for _, town_center in pairs(ffatable.town_centers) do
|
||||
local market = town_center.market
|
||||
local items2 = {
|
||||
'long-handed-inserter',
|
||||
}
|
||||
local bb = market.bounding_box
|
||||
local s = market.surface
|
||||
local area = {left_top = {bb.left_top.x - 1, bb.left_top.y - 1}, right_bottom = {bb.right_bottom.x + 1, bb.right_bottom.y + 1}}
|
||||
local entities = s.find_entities_filtered({area = area, name = items})
|
||||
local area2 = {left_top = {bb.left_top.x - 2, bb.left_top.y - 2}, right_bottom = {bb.right_bottom.x + 2, bb.right_bottom.y + 2}}
|
||||
local entities2 = s.find_entities_filtered({area = area2, name = items2})
|
||||
for k,v in pairs(entities2) do
|
||||
entities[k] = v
|
||||
end
|
||||
return entities
|
||||
end
|
||||
|
||||
local function get_inserter_filter(entity)
|
||||
-- return the first filter
|
||||
local filter_mode = entity.inserter_filter_mode
|
||||
if filter_mode == 'whitelist' then
|
||||
return entity.get_filter(1)
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function get_loader_filter(entity, index)
|
||||
-- return first two filter types
|
||||
return entity.get_filter(index)
|
||||
end
|
||||
|
||||
local function get_loader_market_position(entity)
|
||||
-- gets the position of the market relative to the loader
|
||||
local position = {x=entity.position.x, y=entity.position.y}
|
||||
local orientation = entity.orientation
|
||||
local type = entity.loader_type
|
||||
if (orientation == 0.0 and type == "input") or (orientation == 0.5 and type == "output") then
|
||||
position.y = position.y - 1.5
|
||||
end
|
||||
if (orientation == 0.25 and type == "input") or (orientation == 0.75 and type == "output") then
|
||||
position.x = position.x + 1.5
|
||||
end
|
||||
if (orientation == 0.5 and type == "input") or (orientation == 0.0 and type == "output") then
|
||||
position.y = position.y + 1.5
|
||||
end
|
||||
if (orientation == 0.75 and type == "input") or (orientation == 0.25 and type == "output") then
|
||||
position.x = position.x - 1.5
|
||||
end
|
||||
return position
|
||||
end
|
||||
|
||||
local function output_loader_items(town_center, trade, entity, index)
|
||||
local item = trade.offer.item
|
||||
local line = entity.get_transport_line(index)
|
||||
if line.can_insert_at_back() and town_center.output_buffer[item] > 0 then
|
||||
local stack = {name = item, count = 1}
|
||||
town_center.output_buffer[item] = town_center.output_buffer[item] - 1
|
||||
line.insert_at_back(stack)
|
||||
end
|
||||
end
|
||||
|
||||
local function output_inserter_items(town_center, trade, entity)
|
||||
local item = trade.offer.item
|
||||
local stack_size = max_stack_size(entity)
|
||||
local count = 0
|
||||
while town_center.output_buffer[item] > 0 and count < stack_size do
|
||||
town_center.output_buffer[item] = town_center.output_buffer[item] - 1
|
||||
count = count + 1
|
||||
end
|
||||
if count > 0 then
|
||||
local stack = {name = item, count = count}
|
||||
entity.held_stack.set_stack(stack)
|
||||
end
|
||||
end
|
||||
|
||||
local function trade_scrap_for_coin(town_center, market, trade, stack)
|
||||
local item = stack.name
|
||||
local amount = stack.count
|
||||
-- buffer the input in an item buffer that can be sold for coin
|
||||
if town_center.input_buffer[item] == nil then
|
||||
town_center.input_buffer[item] = 0
|
||||
end
|
||||
town_center.input_buffer[item] = town_center.input_buffer[item] + amount
|
||||
--log("input_buffer[" .. item .. "] = " .. town_center.input_buffer[item])
|
||||
|
||||
local price = trade.price[1].amount
|
||||
local count = trade.offer.count
|
||||
while town_center.input_buffer[item] >= price do
|
||||
town_center.input_buffer[item] = town_center.input_buffer[item] - price
|
||||
town_center.coin_balance = town_center.coin_balance + count
|
||||
end
|
||||
Town_center.update_coin_balance(market.force)
|
||||
--log("input_buffer[" .. item .. "] = " .. town_center.input_buffer[item])
|
||||
end
|
||||
|
||||
local function trade_coin_for_items(town_center, market, trade)
|
||||
local item = trade.offer.item
|
||||
local count = trade.offer.count
|
||||
local price = trade.price[1].amount
|
||||
if town_center.output_buffer[item] == nil then
|
||||
town_center.output_buffer[item] = 0
|
||||
end
|
||||
while town_center.coin_balance - price >= 0 do
|
||||
if town_center.output_buffer[item] == 0 then
|
||||
town_center.coin_balance = town_center.coin_balance - price
|
||||
town_center.output_buffer[item] = town_center.output_buffer[item] + count
|
||||
else
|
||||
break
|
||||
end
|
||||
end
|
||||
Town_center.update_coin_balance(market.force)
|
||||
end
|
||||
|
||||
local function handle_loader_output(town_center, market, entity, index)
|
||||
local line = entity.get_transport_line(index)
|
||||
-- get loader filters
|
||||
local filter = get_loader_filter(entity, index)
|
||||
if filter == nil then return end
|
||||
if filter == 'coin' then
|
||||
-- output for coins
|
||||
while town_center.coin_balance > 0 and line.can_insert_at_back() do
|
||||
town_center.coin_balance = town_center.coin_balance - 1
|
||||
local stack = {name = 'coin', count = 1}
|
||||
line.insert_at_back(stack)
|
||||
end
|
||||
Town_center.update_coin_balance(market.force)
|
||||
else
|
||||
-- output for matching purchases
|
||||
local offers = market.get_market_items()
|
||||
if offers == nil then
|
||||
set_offers(town_center)
|
||||
end
|
||||
local s = market.surface
|
||||
local force = market.force
|
||||
-- get the bounding box for the market
|
||||
local bb = market.bounding_box
|
||||
local area = {left_top = {bb.left_top.x - 2, bb.left_top.y - 2}, right_bottom = {bb.right_bottom.x + 2, bb.right_bottom.y + 2}}
|
||||
local entities = s.find_entities_filtered({area = area, name = items})
|
||||
for _, e in pairs(entities) do
|
||||
if e.name ~= 'loader' and e.name ~= 'fast-loader' and e.name ~= 'express-loader' then
|
||||
local ppos = e.pickup_position
|
||||
local dpos = e.drop_position
|
||||
-- pulling an item from the market
|
||||
if inside(ppos, bb) and e.drop_target then
|
||||
local stack = e.held_stack
|
||||
local spos = e.held_stack_position
|
||||
if inside(spos, bb) then
|
||||
local filter
|
||||
local filter_mode = e.inserter_filter_mode
|
||||
if filter_mode ~= nil then
|
||||
for i = 1, e.filter_slot_count do
|
||||
if e.get_filter(i) ~= nil then
|
||||
filter = e.get_filter(i)
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
if (filter_mode == 'whitelist' and filter == 'coin') or (filter_mode == 'blacklist' and filter == nil) or (filter_mode == nil) then
|
||||
if stack.valid and town_center.coin_balance > 0 then
|
||||
-- pull coins
|
||||
stack.set_stack({name = 'coin', count = 1})
|
||||
town_center.coin_balance = town_center.coin_balance - 1
|
||||
Town_center.update_coin_balance(force)
|
||||
end
|
||||
else
|
||||
if filter_mode == 'whitelist' and filter ~= nil and stack.valid then
|
||||
-- purchased and pull items if output buffer is empty
|
||||
-- buffer the output in a item buffer since the stack might be too small
|
||||
-- output items are shared among the output
|
||||
for _, trade in ipairs(offers) do
|
||||
local type = trade.offer.type
|
||||
local item = trade.offer.item
|
||||
local count = trade.offer.count or 1
|
||||
local cost = trade.price[1].amount
|
||||
if type == 'give-item' and item == filter then
|
||||
if town_center.output_buffer[item] == nil then
|
||||
town_center.output_buffer[item] = 0
|
||||
end
|
||||
if town_center.output_buffer[item] == 0 then
|
||||
-- fill buffer
|
||||
if town_center.coin_balance >= cost then
|
||||
town_center.coin_balance = town_center.coin_balance - cost
|
||||
Town_center.update_coin_balance(force)
|
||||
town_center.output_buffer[item] = town_center.output_buffer[item] + count
|
||||
--log("output_buffer[" .. item .. "] = " .. town_center.output_buffer[item])
|
||||
end
|
||||
end
|
||||
if town_center.output_buffer[item] > 0 and not stack.valid_for_read then
|
||||
-- output the item
|
||||
local amount = 1
|
||||
if stack.can_set_stack({name = item, count = amount}) then
|
||||
town_center.output_buffer[item] = town_center.output_buffer[item] - amount
|
||||
stack.set_stack({name = item, count = amount})
|
||||
--log("output_buffer[" .. item .. "] = " .. town_center.output_buffer[item])
|
||||
end
|
||||
end
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if offers ~= nil then
|
||||
for _, trade in ipairs(offers) do
|
||||
if trade.offer.type == 'give-item' then
|
||||
local item = trade.price[1].name
|
||||
if item == 'coin' and trade.offer.item == filter then
|
||||
trade_coin_for_items(town_center, market, trade)
|
||||
output_loader_items(town_center, trade, entity, index)
|
||||
end
|
||||
end
|
||||
-- pushing an item to the market (coins or scrap)
|
||||
if e.pickup_target and inside(dpos, bb) then
|
||||
local stack = e.held_stack
|
||||
local spos = e.held_stack_position
|
||||
if stack.valid_for_read and inside(spos, bb) then
|
||||
local name = stack.name
|
||||
local amount = stack.count
|
||||
if name == 'coin' then
|
||||
-- push coins
|
||||
e.remove_item(stack)
|
||||
town_center.coin_balance = town_center.coin_balance + amount
|
||||
Town_center.update_coin_balance(force)
|
||||
else
|
||||
-- push items to turn into coin
|
||||
for _, trade in ipairs(offers) do
|
||||
local type = trade.offer.type
|
||||
local item = trade.price[1].name
|
||||
local count = trade.price[1].amount
|
||||
local cost = trade.offer.count
|
||||
if type == 'give-item' and name == item and item ~= 'coin' then
|
||||
e.remove_item(stack)
|
||||
-- buffer the input in an item buffer that can be sold
|
||||
if town_center.input_buffer[item] == nil then
|
||||
town_center.input_buffer[item] = 0
|
||||
end
|
||||
town_center.input_buffer[item] = town_center.input_buffer[item] + amount
|
||||
--log("input_buffer[" .. item .. "] = " .. town_center.input_buffer[item])
|
||||
if town_center.input_buffer[item] >= count then
|
||||
town_center.input_buffer[item] = town_center.input_buffer[item] - count
|
||||
town_center.coin_balance = town_center.coin_balance + cost
|
||||
Town_center.update_coin_balance(force)
|
||||
--log("input_buffer[" .. item .. "] = " .. town_center.input_buffer[item])
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function handle_inserter_output(town_center, market, entity)
|
||||
-- get inserter filter
|
||||
local filter = get_inserter_filter(entity)
|
||||
if filter == nil then return end
|
||||
local amount = max_stack_size(entity)
|
||||
local stack = {name = 'coin', count = amount}
|
||||
if filter == 'coin' then
|
||||
-- output coins
|
||||
if amount > town_center.coin_balance then amount = town_center.coin_balance end
|
||||
stack.count = amount
|
||||
if town_center.coin_balance > 0 then
|
||||
town_center.coin_balance = town_center.coin_balance - amount
|
||||
entity.held_stack.set_stack(stack)
|
||||
end
|
||||
Town_center.update_coin_balance(market.force)
|
||||
else
|
||||
-- for matching coin purchases
|
||||
local offers = market.get_market_items()
|
||||
if offers == nil then
|
||||
set_offers(town_center)
|
||||
end
|
||||
if offers ~= nil then
|
||||
for _, trade in ipairs(offers) do
|
||||
if trade.offer.type == 'give-item' and trade.offer.item == filter then
|
||||
local item = trade.price[1].name
|
||||
if item == 'coin' then
|
||||
trade_coin_for_items(town_center, market, trade)
|
||||
output_inserter_items(town_center, trade, entity)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function handle_loader_input(town_center, market, entity, index)
|
||||
local line = entity.get_transport_line(index)
|
||||
-- check for a line item at the back where we can pull
|
||||
if line.valid then
|
||||
local length = #line
|
||||
if length > 1 or (length == 1 and line.can_insert_at_back()) then
|
||||
local line_item = line[length].name
|
||||
local stack = {name = line_item, count = 1}
|
||||
if line_item == 'coin' then
|
||||
-- insert coins
|
||||
line.remove_item(stack)
|
||||
town_center.coin_balance = town_center.coin_balance + stack.count
|
||||
Town_center.update_coin_balance(market.force)
|
||||
else
|
||||
local offers = market.get_market_items()
|
||||
if offers == nil then
|
||||
set_offers(town_center)
|
||||
end
|
||||
if offers ~= nil then
|
||||
for _, trade in ipairs(offers) do
|
||||
if trade.offer.type == 'give-item' then
|
||||
local item = trade.price[1].name
|
||||
if item == stack.name and trade.offer.item == 'coin' then
|
||||
-- trade scrap for coin
|
||||
line.remove_item(stack)
|
||||
trade_scrap_for_coin(town_center, market, trade, stack)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -331,6 +517,142 @@ local function on_tick(_)
|
||||
end
|
||||
end
|
||||
|
||||
local function handle_inserter_input(town_center, market, entity)
|
||||
-- check if stack is coin or resource
|
||||
local stack = {name = entity.held_stack.name, count = entity.held_stack.count}
|
||||
if stack.name == 'coin' and stack.count > 0 then
|
||||
-- insert coins
|
||||
entity.remove_item(stack)
|
||||
town_center.coin_balance = town_center.coin_balance + stack.count
|
||||
Town_center.update_coin_balance(market.force)
|
||||
else
|
||||
local offers = market.get_market_items()
|
||||
if offers == nil then
|
||||
set_offers(town_center)
|
||||
end
|
||||
if offers ~= nil then
|
||||
for _, trade in ipairs(offers) do
|
||||
if trade.offer.type == 'give-item' and trade.offer.item == 'coin' then
|
||||
local item = trade.price[1].name
|
||||
if item == stack.name and trade.offer.item == 'coin' then
|
||||
-- trade scrap for coin
|
||||
entity.remove_item(stack)
|
||||
trade_scrap_for_coin(town_center, market, trade, stack)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function handle_market_input(town_center, market, entity)
|
||||
if is_loader(entity) then
|
||||
-- handle loader input
|
||||
-- we don't care about filters
|
||||
local max_index = entity.get_max_transport_line_index()
|
||||
for index = 1, max_index, 1 do
|
||||
handle_loader_input(town_center, market, entity, index)
|
||||
end
|
||||
else
|
||||
-- handle inserter input
|
||||
-- we don't care about filters
|
||||
local stack = entity.held_stack
|
||||
if stack ~= nil then
|
||||
-- if there is a pickup target
|
||||
local spos = entity.held_stack_position
|
||||
local dpos = entity.drop_position
|
||||
if equal(spos, dpos) then
|
||||
if stack.valid_for_read and stack.count > 0 then
|
||||
-- if there is a stack
|
||||
-- insert an item into the market
|
||||
handle_inserter_input(town_center, market, entity)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function handle_market_output(town_center, market, entity)
|
||||
if is_loader(entity) then
|
||||
-- handle loader output
|
||||
local max_index = entity.get_max_transport_line_index()
|
||||
for index = 1, max_index, 1 do
|
||||
if get_loader_filter(entity, index) ~= nil then
|
||||
handle_loader_output(town_center, market, entity, index)
|
||||
end
|
||||
end
|
||||
else
|
||||
if is_filtered_inserter(entity) then
|
||||
-- handle inserter output
|
||||
if entity.drop_target ~= nil then
|
||||
-- if the pickup position is inside the market
|
||||
--log("inside pickup position and there is a drop target")
|
||||
local stack = entity.held_stack
|
||||
local spos = entity.held_stack_position
|
||||
local ppos = entity.pickup_position
|
||||
if equal(spos, ppos) then
|
||||
-- if the stack position is inside the market
|
||||
if stack == nil or stack.count == 0 then
|
||||
-- if there is space on the stack
|
||||
-- pull an item from the market
|
||||
handle_inserter_output(town_center, market, entity, stack)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function get_entity_mode(market, entity)
|
||||
local bb = market.bounding_box
|
||||
if is_loader(entity) then
|
||||
local mpos = get_loader_market_position(entity)
|
||||
if inside(mpos, bb) then
|
||||
return entity.loader_type
|
||||
else
|
||||
return 'none'
|
||||
end
|
||||
else
|
||||
local dpos = entity.drop_position
|
||||
local ppos = entity.pickup_position
|
||||
if inside(dpos, bb) then
|
||||
return 'input'
|
||||
end
|
||||
if inside(ppos, bb) then
|
||||
return 'output'
|
||||
end
|
||||
return "none"
|
||||
end
|
||||
end
|
||||
|
||||
local function handle_connected_entity(town_center, market, entity)
|
||||
local mode = get_entity_mode(market, entity)
|
||||
if mode == "input" then
|
||||
handle_market_input(town_center, market, entity)
|
||||
end
|
||||
if mode == "output" then
|
||||
handle_market_output(town_center, market, entity)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_tick(_)
|
||||
local ffatable = Table.get_table()
|
||||
if not ffatable.town_centers then
|
||||
return
|
||||
end
|
||||
for _, town_center in pairs(ffatable.town_centers) do
|
||||
-- get connected entities on markets
|
||||
local market = town_center.market
|
||||
local entities = get_connected_entities(market)
|
||||
-- handle connected entity
|
||||
for _, entity in pairs(entities) do
|
||||
if entity.force == market.force then
|
||||
handle_connected_entity(town_center, market, entity)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.add(defines.events.on_tick, on_tick)
|
||||
Event.add(defines.events.on_gui_opened, on_gui_opened)
|
||||
|
@ -1,5 +1,6 @@
|
||||
local Public = {}
|
||||
local math_random = math.random
|
||||
|
||||
--local Server = require 'utils.server'
|
||||
|
||||
local function create_limbo()
|
||||
game.create_surface('limbo')
|
||||
@ -17,14 +18,14 @@ local function initialize_nauvis()
|
||||
['copper-ore'] = {frequency = 'none', size = 1, richness = 'normal'},
|
||||
['iron-ore'] = {frequency = 'none', size = 1, richness = 'normal'},
|
||||
['uranium-ore'] = {frequency = 'none', size = 1, richness = 'normal'},
|
||||
['crude-oil'] = {frequency = 'none', size = 1, richness = 'normal'},
|
||||
['crude-oil'] = {frequency = 'very-low', size = 'very-small', richness = 'normal'},
|
||||
trees = {frequency = 2, size = 'normal', richness = 'normal'},
|
||||
['enemy-base'] = {frequency = 8, size = 1, richness = 'normal'}
|
||||
['enemy-base'] = {frequency = 'very-high', size = 2, richness = 'normal'}
|
||||
}
|
||||
mgs.autoplace_settings = {
|
||||
entity = {
|
||||
settings = {
|
||||
['rock-huge'] = {frequency = 3, size = 12, richness = 'very-high'},
|
||||
['rock-huge'] = {frequency = 2, size = 12, richness = 'very-high'},
|
||||
['rock-big'] = {frequency = 3, size = 12, richness = 'very-high'},
|
||||
['sand-rock-big'] = {frequency = 3, size = 12, richness = 1, 'very-high'}
|
||||
}
|
||||
@ -53,8 +54,9 @@ local function initialize_nauvis()
|
||||
mgs.peaceful_mode = false
|
||||
mgs.starting_area = 'none'
|
||||
mgs.terrain_segmentation = 8
|
||||
mgs.width = 2048
|
||||
mgs.height = 2048
|
||||
-- terrain size is 64 x 64 chunks, water size is 80 x 80
|
||||
mgs.width = 2560
|
||||
mgs.height = 2560
|
||||
--mgs.starting_points = {
|
||||
-- {x = 0, y = 0}
|
||||
--}
|
||||
@ -67,7 +69,7 @@ local function initialize_nauvis()
|
||||
--moisture = 0,
|
||||
|
||||
-- here we are overriding the aux noise-layer with a fixed value to keep aux consistent across the map
|
||||
-- it allows to free up the aux noise expression
|
||||
-- it allows to free up the aux noise expression
|
||||
-- aux should be not sand, nor red sand
|
||||
--aux = 0.5,
|
||||
|
||||
@ -111,11 +113,11 @@ local function initialize_nauvis()
|
||||
-- a constant intensity means base distribution will be consistent with regard to distance
|
||||
['enemy-base-intensity'] = 1,
|
||||
-- adjust this value to set how many nests spawn per tile
|
||||
['enemy-base-frequency'] = 0.2,
|
||||
['enemy-base-frequency'] = 0.4,
|
||||
-- this will make and average base radius around 12 tiles
|
||||
['enemy-base-radius'] = 12
|
||||
}
|
||||
mgs.seed = math_random(10000, 99999)
|
||||
mgs.seed = game.surfaces[1].map_gen_settings.seed
|
||||
surface.map_gen_settings = mgs
|
||||
surface.peaceful_mode = false
|
||||
surface.always_day = false
|
||||
@ -123,6 +125,20 @@ local function initialize_nauvis()
|
||||
surface.clear(true)
|
||||
surface.regenerate_entity({'rock-huge', 'rock-big', 'sand-rock-big'})
|
||||
surface.regenerate_decorative()
|
||||
-- this will force generate the entire map
|
||||
--Server.to_discord_embed('ScrapTownyFFA Map Regeneration in Progress')
|
||||
--surface.request_to_generate_chunks({x=0,y=0},64)
|
||||
--surface.force_generate_chunk_requests()
|
||||
--Server.to_discord_embed('Regeneration Complete')
|
||||
end
|
||||
|
||||
local function initialize_limbo()
|
||||
local surface = game.surfaces['limbo']
|
||||
surface.generate_with_lab_tiles = true
|
||||
surface.peaceful_mode = true
|
||||
surface.always_day = true
|
||||
surface.freeze_daytime = true
|
||||
surface.clear(true)
|
||||
end
|
||||
|
||||
function Public.initialize()
|
||||
@ -167,8 +183,8 @@ function Public.initialize()
|
||||
game.map_settings.enemy_expansion.max_expansion_cooldown = 3600 -- maximum time before next expansion
|
||||
|
||||
-- unit group settings
|
||||
game.map_settings.unit_group.min_group_gathering_time = 600
|
||||
game.map_settings.unit_group.max_group_gathering_time = 3600
|
||||
game.map_settings.unit_group.min_group_gathering_time = 400
|
||||
game.map_settings.unit_group.max_group_gathering_time = 2400
|
||||
game.map_settings.unit_group.max_wait_time_for_late_members = 3600
|
||||
game.map_settings.unit_group.max_group_radius = 30.0
|
||||
game.map_settings.unit_group.min_group_radius = 5.0
|
||||
@ -192,6 +208,7 @@ function Public.initialize()
|
||||
--game.map_settings.steering.moving.force_unit_fuzzy_goto_behavior = false
|
||||
|
||||
create_limbo()
|
||||
initialize_limbo()
|
||||
initialize_nauvis()
|
||||
end
|
||||
|
||||
|
@ -47,15 +47,21 @@ local pollution_index = {
|
||||
|
||||
function Public.market_scent()
|
||||
local ffatable = Table.get_table()
|
||||
if ffatable.testing_mode then
|
||||
return
|
||||
end
|
||||
local town_centers = ffatable.town_centers
|
||||
if town_centers == nil then
|
||||
return
|
||||
end
|
||||
for _, town_center in pairs(town_centers) do
|
||||
local market = town_center.market
|
||||
local pollution = pollution_index['market']
|
||||
local amount = math_random(pollution.min, pollution.max)
|
||||
market.surface.pollute(market.position, amount)
|
||||
if market ~= nil and market.valid then
|
||||
local pollution = pollution_index['market']
|
||||
local amount = math_random(pollution.min, pollution.max)
|
||||
local evolution = town_center.evolution.biters
|
||||
market.surface.pollute(market.position, amount + evolution * 500)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -4,7 +4,6 @@ local table_insert = table.insert
|
||||
local table_shuffle = table.shuffle_table
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
local Evolution = require 'modules.scrap_towny_ffa.evolution'
|
||||
|
||||
local valid_entities = {
|
||||
['rock-big'] = true,
|
||||
@ -13,21 +12,21 @@ local valid_entities = {
|
||||
}
|
||||
|
||||
local size_raffle = {
|
||||
{'giant', 128, 256},
|
||||
{'huge', 64, 128},
|
||||
{'big', 32, 64},
|
||||
{'small', 16, 32},
|
||||
{'tiny', 8, 16}
|
||||
{'giant', 1024, 2048},
|
||||
{'huge', 512, 1024},
|
||||
{'big', 256, 510},
|
||||
{'small', 126, 256},
|
||||
{'tiny', 64, 128}
|
||||
}
|
||||
|
||||
local function get_chances()
|
||||
local chances = {}
|
||||
table_insert(chances, {'iron-ore', 25})
|
||||
table_insert(chances, {'iron-ore', 24})
|
||||
table_insert(chances, {'copper-ore', 18})
|
||||
table_insert(chances, {'mixed', 15})
|
||||
table_insert(chances, {'mixed', 12})
|
||||
table_insert(chances, {'coal', 14})
|
||||
table_insert(chances, {'stone', 8})
|
||||
table_insert(chances, {'uranium-ore', 3})
|
||||
table_insert(chances, {'stone', 12})
|
||||
table_insert(chances, {'uranium-ore', 8})
|
||||
return chances
|
||||
end
|
||||
|
||||
@ -42,42 +41,52 @@ local function set_raffle()
|
||||
ffatable.rocks_yield_ore_veins.mixed_ores = {'iron-ore', 'copper-ore', 'stone', 'coal'}
|
||||
end
|
||||
|
||||
local function get_amount(position)
|
||||
local base = 256
|
||||
local relative_evolution = Evolution.get_evolution(position)
|
||||
local tier = 4 + math_floor(relative_evolution * 16)
|
||||
return (math_random(1, base) + math_random(1, 2 ^ tier))
|
||||
local function get_amount()
|
||||
local base = 256 + 2 ^ 8
|
||||
local max = 2 ^ 12
|
||||
return math_random(math_random(256, base), math_random(base, max))
|
||||
end
|
||||
|
||||
local function draw_chain(surface, count, ore, ore_entities, ore_positions)
|
||||
local ffatable = Table.get_table()
|
||||
local vectors = {{0, -1}, {-1, 0}, {1, 0}, {0, 1}}
|
||||
local vectors = {{0, -0.75}, {-0.75, 0}, {0.75, 0}, {0, 0.75}}
|
||||
local r = math_random(1, #ore_entities)
|
||||
local position = {x = ore_entities[r].position.x, y = ore_entities[r].position.y}
|
||||
local position = {x = ore_entities[r].ore.position.x, y = ore_entities[r].ore.position.y}
|
||||
for _ = 1, count, 1 do
|
||||
table_shuffle(vectors)
|
||||
for i = 1, 4, 1 do
|
||||
local p = {x = position.x + vectors[i][1], y = position.y + vectors[i][2]}
|
||||
-- dispersion will make patches more round
|
||||
local dx = (math_random(0, 100) - 50) / 100
|
||||
local dy = (math_random(0, 100) - 50) / 100
|
||||
local dp = {x = p.x + dx, y = p.y + dy}
|
||||
|
||||
local name = ore
|
||||
if ore == 'mixed' then
|
||||
name = ffatable.rocks_yield_ore_veins.mixed_ores[math_random(1, #ffatable.rocks_yield_ore_veins.mixed_ores)]
|
||||
end
|
||||
if surface.can_place_entity({name = name, position = p, amount = 1}) then
|
||||
if not ore_positions[p.x .. '_' .. p.y] then
|
||||
position.x = p.x
|
||||
position.y = p.y
|
||||
ore_positions[p.x .. '_' .. p.y] = true
|
||||
ore_entities[#ore_entities + 1] = {name = name, position = p, amount = get_amount(p)}
|
||||
break
|
||||
if surface.can_place_entity({name = name, position = p, force = 'neutral'}) then
|
||||
if math_random(1, 2) == 1 then
|
||||
if not ore_positions[p.x .. '_' .. p.y] then
|
||||
position.x = p.x
|
||||
position.y = p.y
|
||||
ore_positions[p.x .. '_' .. p.y] = true
|
||||
ore_entities[#ore_entities + 1] = {ore = {name = name, position = dp}, amount = get_amount()}
|
||||
break
|
||||
end
|
||||
end
|
||||
else
|
||||
if surface.can_fast_replace({name = name, position = p}) then
|
||||
if math_random(1, 2) == 1 then
|
||||
-- existing ore of same name
|
||||
if surface.can_fast_replace({name = name, position = p, force = 'neutral'}) then
|
||||
local amount = get_amount()
|
||||
local deposit = surface.find_entity(name, p)
|
||||
if deposit ~= nil then
|
||||
amount = amount + deposit
|
||||
if not ore_positions[p.x .. '_' .. p.y] then
|
||||
position.x = p.x
|
||||
position.y = p.y
|
||||
ore_positions[p.x .. '_' .. p.y] = true
|
||||
ore_entities[#ore_entities + 1] = {name = name, position = p, amount = get_amount(p), fast_replace = true}
|
||||
ore_entities[#ore_entities + 1] = {ore = {name = name, position = dp}, amount = amount, fast_replace = true}
|
||||
break
|
||||
end
|
||||
end
|
||||
@ -129,13 +138,15 @@ local function ore_vein(event)
|
||||
end
|
||||
|
||||
local position = event.entity.position
|
||||
local ore_entities = {{name = ore, position = {x = position.x, y = position.y}, amount = get_amount(position)}}
|
||||
local ore_entities = {{ore = {name = ore, position = {x = position.x, y = position.y}}, amount = get_amount()}}
|
||||
if ore == 'mixed' then
|
||||
ore_entities = {
|
||||
{
|
||||
name = ffatable.rocks_yield_ore_veins.mixed_ores[math_random(1, #ffatable.rocks_yield_ore_veins.mixed_ores)],
|
||||
position = {x = position.x, y = position.y},
|
||||
amount = get_amount(position)
|
||||
ore = {
|
||||
name = ffatable.rocks_yield_ore_veins.mixed_ores[math_random(1, #ffatable.rocks_yield_ore_veins.mixed_ores)],
|
||||
position = {x = position.x, y = position.y}
|
||||
},
|
||||
amount = get_amount()
|
||||
}
|
||||
}
|
||||
end
|
||||
@ -148,32 +159,43 @@ local function ore_vein(event)
|
||||
if count < c then
|
||||
c = count
|
||||
end
|
||||
|
||||
local placed_ore_count = #ore_entities
|
||||
|
||||
draw_chain(surface, c, ore, ore_entities, ore_positions)
|
||||
|
||||
count = count - (#ore_entities - placed_ore_count)
|
||||
|
||||
if count <= 0 then
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
for _, e in pairs(ore_entities) do
|
||||
surface.create_entity(e)
|
||||
-- place the ore
|
||||
for _, ore_entity in pairs(ore_entities) do
|
||||
if ore_entity.fast_replace then
|
||||
local e = surface.find_entity(ore_entity.ore.name, ore_entity.ore.position)
|
||||
e.amount = ore_entity.amount
|
||||
else
|
||||
local e = surface.create_entity(ore_entity.ore)
|
||||
e.amount = ore_entity.amount
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function on_player_mined_entity(event)
|
||||
local ffatable = Table.get_table()
|
||||
local rocks_yield_ore_veins = Table.get('rocks_yield_ore_veins')
|
||||
if not rocks_yield_ore_veins then
|
||||
return
|
||||
end
|
||||
|
||||
local player = game.players[event.player_index]
|
||||
if player.force.technologies['steel-processing'].researched == false then
|
||||
return
|
||||
end
|
||||
if not event.entity.valid then
|
||||
return
|
||||
end
|
||||
if not valid_entities[event.entity.name] then
|
||||
return
|
||||
end
|
||||
if math_random(1, ffatable.rocks_yield_ore_veins.chance) ~= 1 then
|
||||
if math_random(1, rocks_yield_ore_veins.chance) ~= 1 then
|
||||
return
|
||||
end
|
||||
ore_vein(event)
|
||||
@ -184,7 +206,7 @@ local function on_init()
|
||||
ffatable.rocks_yield_ore_veins = {}
|
||||
ffatable.rocks_yield_ore_veins.raffle = {}
|
||||
ffatable.rocks_yield_ore_veins.mixed_ores = {}
|
||||
ffatable.rocks_yield_ore_veins.chance = 4
|
||||
ffatable.rocks_yield_ore_veins.chance = 10
|
||||
set_raffle()
|
||||
end
|
||||
|
||||
|
@ -1,5 +1,3 @@
|
||||
local table_size = table.size
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
|
||||
-- called whenever a player places an item
|
||||
@ -16,7 +14,7 @@ local function on_built_entity(event)
|
||||
local force = player.force
|
||||
local town_center = ffatable.town_centers[force.name]
|
||||
local surface = entity.surface
|
||||
if force == game.forces['player'] or force == game.forces['rogue'] or town_center == nil then
|
||||
if force.index == game.forces['player'].index or force.index == game.forces['rogue'].index or town_center == nil then
|
||||
surface.create_entity(
|
||||
{
|
||||
name = 'flying-text',
|
||||
@ -31,7 +29,8 @@ local function on_built_entity(event)
|
||||
end
|
||||
local slots = town_center.upgrades.laser_turret.slots
|
||||
local locations = town_center.upgrades.laser_turret.locations
|
||||
if table_size(locations) >= slots then
|
||||
|
||||
if locations >= slots then
|
||||
surface.create_entity(
|
||||
{
|
||||
name = 'flying-text',
|
||||
@ -44,12 +43,24 @@ local function on_built_entity(event)
|
||||
entity.destroy()
|
||||
return
|
||||
end
|
||||
local position = entity.position
|
||||
local key = tostring('{' .. position.x .. ',' .. position.y .. '}')
|
||||
locations[key] = true
|
||||
local key = script.register_on_entity_destroyed(entity)
|
||||
if (ffatable.laser_turrets == nil) then
|
||||
ffatable.laser_turrets = {}
|
||||
end
|
||||
ffatable.laser_turrets[key] = force.index
|
||||
locations = locations + 1
|
||||
town_center.upgrades.laser_turret.locations = locations
|
||||
surface.create_entity(
|
||||
{
|
||||
name = 'flying-text',
|
||||
position = entity.position,
|
||||
text = 'Using ' .. locations .. '/' .. slots .. ' slots',
|
||||
color = {r = 1.0, g = 1.0, b = 1.0}
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
-- called whenever a player places an item
|
||||
-- called whenever a robot places an item
|
||||
local function on_robot_built_entity(event)
|
||||
local ffatable = Table.get_table()
|
||||
local entity = event.created_entity
|
||||
@ -63,7 +74,7 @@ local function on_robot_built_entity(event)
|
||||
local force = robot.force
|
||||
local town_center = ffatable.town_centers[force.name]
|
||||
local surface = entity.surface
|
||||
if force == game.forces['player'] or force == game.forces['rogue'] or town_center == nil then
|
||||
if force.index == game.forces['player'].index or force.index == game.forces['rogue'].index or town_center == nil then
|
||||
surface.create_entity(
|
||||
{
|
||||
name = 'flying-text',
|
||||
@ -78,7 +89,7 @@ local function on_robot_built_entity(event)
|
||||
end
|
||||
local slots = town_center.upgrades.laser_turret.slots
|
||||
local locations = town_center.upgrades.laser_turret.locations
|
||||
if table_size(locations) >= slots then
|
||||
if locations >= slots then
|
||||
surface.create_entity(
|
||||
{
|
||||
name = 'flying-text',
|
||||
@ -91,31 +102,51 @@ local function on_robot_built_entity(event)
|
||||
entity.destroy()
|
||||
return
|
||||
end
|
||||
local position = entity.position
|
||||
local key = tostring('{' .. position.x .. ',' .. position.y .. '}')
|
||||
locations[key] = true
|
||||
local key = script.register_on_entity_destroyed(entity)
|
||||
if (ffatable.laser_turrets == nil) then
|
||||
ffatable.laser_turrets = {}
|
||||
end
|
||||
ffatable.laser_turrets[key] = force.index
|
||||
locations = locations + 1
|
||||
town_center.upgrades.laser_turret.locations = locations
|
||||
surface.create_entity(
|
||||
{
|
||||
name = 'flying-text',
|
||||
position = entity.position,
|
||||
text = 'Using ' .. locations .. '/' .. slots .. ' slots',
|
||||
color = {r = 1.0, g = 1.0, b = 1.0}
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
-- called whenever a player mines an entity but before it is removed from the map
|
||||
-- will have the contents of the drops
|
||||
local function on_player_mined_entity(event)
|
||||
-- called whenever a laser-turret is removed from the map
|
||||
local function on_entity_destroyed(event)
|
||||
local key = event.registration_number
|
||||
local ffatable = Table.get_table()
|
||||
local player = game.players[event.player_index]
|
||||
local force = player.force
|
||||
local entity = event.entity
|
||||
if entity.name == 'laser-turret' then
|
||||
local town_center = ffatable.town_centers[force.name]
|
||||
if force == game.forces['player'] or force == game.forces['rogue'] or town_center == nil then
|
||||
return
|
||||
if (ffatable.laser_turrets == nil) then
|
||||
return
|
||||
end
|
||||
if (ffatable.laser_turrets[key] ~= nil) then
|
||||
local index = ffatable.laser_turrets[key]
|
||||
local force = game.forces[index]
|
||||
if force ~= nil then
|
||||
local town_center = ffatable.town_centers[force.name]
|
||||
if town_center ~= nil then
|
||||
if force.index == game.forces['player'].index or force.index == game.forces['rogue'].index or town_center == nil then
|
||||
return
|
||||
end
|
||||
local locations = town_center.upgrades.laser_turret.locations
|
||||
locations = locations - 1
|
||||
if (locations < 0) then
|
||||
locations = 0
|
||||
end
|
||||
town_center.upgrades.laser_turret.locations = locations
|
||||
end
|
||||
end
|
||||
local locations = town_center.upgrades.laser_turret.locations
|
||||
local position = entity.position
|
||||
local key = tostring('{' .. position.x .. ',' .. position.y .. '}')
|
||||
locations[key] = nil
|
||||
end
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.add(defines.events.on_built_entity, on_built_entity)
|
||||
Event.add(defines.events.on_robot_built_entity, on_robot_built_entity)
|
||||
Event.add(defines.events.on_player_mined_entity, on_player_mined_entity)
|
||||
Event.add(defines.events.on_entity_destroyed, on_entity_destroyed)
|
||||
|
268
modules/scrap_towny_ffa/spaceship.lua
Normal file
268
modules/scrap_towny_ffa/spaceship.lua
Normal file
@ -0,0 +1,268 @@
|
||||
local table_insert = table.insert
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
|
||||
local upgrade_functions = {
|
||||
-- Upgrade Backpack
|
||||
[1] = function(player)
|
||||
local ffatable = Table.get_table()
|
||||
local surface = player.surface
|
||||
if player.character.character_inventory_slots_bonus + 5 > 100 then
|
||||
return false
|
||||
end
|
||||
player.character.character_inventory_slots_bonus = player.character.character_inventory_slots_bonus + 5
|
||||
if not ffatable.buffs[player.index] then
|
||||
ffatable.buffs[player.index] = {}
|
||||
end
|
||||
if not ffatable.buffs[player.index].character_inventory_slots_bonus then
|
||||
ffatable.buffs[player.index].character_inventory_slots_bonus = 0
|
||||
end
|
||||
ffatable.buffs[player.index].character_inventory_slots_bonus = player.character.character_inventory_slots_bonus
|
||||
surface.play_sound({path = 'utility/achievement_unlocked', position = player.position, volume_modifier = 1})
|
||||
return true
|
||||
end,
|
||||
-- Upgrade Pickaxe Speed
|
||||
[2] = function(player)
|
||||
local ffatable = Table.get_table()
|
||||
local surface = player.surface
|
||||
if player.character.character_mining_speed_modifier + 0.1 > 1 then
|
||||
return false
|
||||
end
|
||||
player.character.character_mining_speed_modifier = player.character.character_mining_speed_modifier + 0.1
|
||||
if not ffatable.buffs[player.index] then
|
||||
ffatable.buffs[player.index] = {}
|
||||
end
|
||||
if not ffatable.buffs[player.index].character_mining_speed_modifier then
|
||||
ffatable.buffs[player.index].character_mining_speed_modifier = 0
|
||||
end
|
||||
ffatable.buffs[player.index].character_mining_speed_modifier = player.character.character_mining_speed_modifier
|
||||
surface.play_sound({path = 'utility/achievement_unlocked', position = player.position, volume_modifier = 1})
|
||||
return true
|
||||
end,
|
||||
-- Upgrade Crafting Speed
|
||||
[3] = function(player)
|
||||
local ffatable = Table.get_table()
|
||||
local surface = player.surface
|
||||
if player.character.character_crafting_speed_modifier + 0.1 > 1 then
|
||||
return false
|
||||
end
|
||||
player.character.character_crafting_speed_modifier = player.character.character_crafting_speed_modifier + 0.1
|
||||
if not ffatable.buffs[player.index] then
|
||||
ffatable.buffs[player.index] = {}
|
||||
end
|
||||
if not ffatable.buffs[player.index].character_crafting_speed_modifier then
|
||||
ffatable.buffs[player.index].character_crafting_speed_modifier = 0
|
||||
end
|
||||
ffatable.buffs[player.index].character_crafting_speed_modifier = player.character.character_crafting_speed_modifier
|
||||
surface.play_sound({path = 'utility/achievement_unlocked', position = player.position, volume_modifier = 1})
|
||||
return true
|
||||
end,
|
||||
-- Set Spawn Point
|
||||
[4] = function(player)
|
||||
local ffatable = Table.get_table()
|
||||
local surface = player.surface
|
||||
local position = player.position
|
||||
position = surface.find_non_colliding_position('character', position, 0, 0.25)
|
||||
if position ~= nil and player ~= nil then
|
||||
ffatable.spawn_point[player.name] = {x = position.x, y = position.y}
|
||||
surface.play_sound({path = 'utility/scenario_message', position = player.position, volume_modifier = 1})
|
||||
else
|
||||
surface.create_entity(
|
||||
{
|
||||
name = 'flying-text',
|
||||
position = position,
|
||||
text = 'Could not find open space for spawnpoint!',
|
||||
color = {r = 0.77, g = 0.0, b = 0.0}
|
||||
}
|
||||
)
|
||||
end
|
||||
return false
|
||||
end
|
||||
}
|
||||
|
||||
local function clear_offers(market)
|
||||
for _ = 1, 256, 1 do
|
||||
local a = market.remove_market_item(1)
|
||||
if a == false then
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function set_offers(market, player)
|
||||
local market_items = {}
|
||||
|
||||
-- special offers are only for outlanders and rogues
|
||||
local special_offers = {}
|
||||
local force = player.force
|
||||
if force.index == game.forces['player'].index or force.index == game.forces['rogue'].index then
|
||||
if player.character.character_inventory_slots_bonus + 5 <= 100 then
|
||||
special_offers[1] = {{{'coin', (player.character.character_inventory_slots_bonus / 5 + 1) * 50}}, 'Upgrade Backpack +5 Slot'}
|
||||
else
|
||||
special_offers[1] = {{}, 'Maximum Backpack upgrades reached!'}
|
||||
end
|
||||
if player.character.character_mining_speed_modifier + 0.1 <= 1 then
|
||||
special_offers[2] = {{{'coin', (player.character.character_mining_speed_modifier * 10 + 1) * 400}}, 'Upgrade Mining Speed +10%'}
|
||||
else
|
||||
special_offers[2] = {{}, 'Maximum Mining Speed upgrades reached!'}
|
||||
end
|
||||
|
||||
if player.character.character_crafting_speed_modifier + 0.1 <= 1 then
|
||||
special_offers[3] = {{{'coin', (player.character.character_crafting_speed_modifier * 10 + 1) * 400}}, 'Upgrade Crafting Speed +10%'}
|
||||
else
|
||||
special_offers[3] = {{}, 'Maximum Crafting Speed upgrades reached!'}
|
||||
end
|
||||
local spawn_point = 'Set Spawn Point'
|
||||
special_offers[4] = {{}, spawn_point}
|
||||
else
|
||||
local spawn_point = 'Set Spawn Point'
|
||||
special_offers[1] = {{}, spawn_point}
|
||||
end
|
||||
for _, v in pairs(special_offers) do
|
||||
table_insert(market_items, {price = v[1], offer = {type = 'nothing', effect_description = v[2]}})
|
||||
end
|
||||
|
||||
-- coin purchases
|
||||
table_insert(market_items, {price = {{'coin', 1}}, offer = {type = 'give-item', item = 'raw-fish', count = 1}})
|
||||
table_insert(market_items, {price = {{'coin', 4}}, offer = {type = 'give-item', item = 'firearm-magazine', count = 5}})
|
||||
table_insert(market_items, {price = {{'coin', 10}}, offer = {type = 'give-item', item = 'grenade', count = 6}})
|
||||
table_insert(market_items, {price = {{'coin', 40}}, offer = {type = 'give-item', item = 'piercing-rounds-magazine', count = 10}})
|
||||
table_insert(market_items, {price = {{'coin', 75}}, offer = {type = 'give-item', item = 'heavy-armor', count = 1}})
|
||||
table_insert(market_items, {price = {{'coin', 150}}, offer = {type = 'give-item', item = 'modular-armor', count = 1}})
|
||||
-- scrap selling
|
||||
table_insert(market_items, {price = {{'raw-fish', 1}}, offer = {type = 'give-item', item = 'coin', count = 1}})
|
||||
table_insert(market_items, {price = {{'wood', 7}}, offer = {type = 'give-item', item = 'coin', count = 1}})
|
||||
table_insert(market_items, {price = {{'copper-cable', 12}}, offer = {type = 'give-item', item = 'coin', count = 1}})
|
||||
table_insert(market_items, {price = {{'copper-plate', 5}}, offer = {type = 'give-item', item = 'coin', count = 1}})
|
||||
table_insert(market_items, {price = {{'iron-stick', 12}}, offer = {type = 'give-item', item = 'coin', count = 1}})
|
||||
table_insert(market_items, {price = {{'iron-gear-wheel', 3}}, offer = {type = 'give-item', item = 'coin', count = 1}})
|
||||
table_insert(market_items, {price = {{'iron-plate', 5}}, offer = {type = 'give-item', item = 'coin', count = 1}})
|
||||
table_insert(market_items, {price = {{'steel-plate', 1}}, offer = {type = 'give-item', item = 'coin', count = 1}})
|
||||
table_insert(market_items, {price = {{'empty-barrel', 1}}, offer = {type = 'give-item', item = 'coin', count = 1}})
|
||||
table_insert(market_items, {price = {{'crude-oil-barrel', 1}}, offer = {type = 'give-item', item = 'coin', count = 1}})
|
||||
table_insert(market_items, {price = {{'heavy-oil-barrel', 1}}, offer = {type = 'give-item', item = 'coin', count = 1}})
|
||||
table_insert(market_items, {price = {{'light-oil-barrel', 1}}, offer = {type = 'give-item', item = 'coin', count = 1}})
|
||||
table_insert(market_items, {price = {{'lubricant-barrel', 1}}, offer = {type = 'give-item', item = 'coin', count = 1}})
|
||||
table_insert(market_items, {price = {{'petroleum-gas-barrel', 1}}, offer = {type = 'give-item', item = 'coin', count = 1}})
|
||||
table_insert(market_items, {price = {{'sulfuric-acid-barrel', 1}}, offer = {type = 'give-item', item = 'coin', count = 1}})
|
||||
table_insert(market_items, {price = {{'water-barrel', 1}}, offer = {type = 'give-item', item = 'coin', count = 1}})
|
||||
table_insert(market_items, {price = {{'electronic-circuit', 5}}, offer = {type = 'give-item', item = 'coin', count = 1}})
|
||||
table_insert(market_items, {price = {{'advanced-circuit', 1}}, offer = {type = 'give-item', item = 'coin', count = 5}})
|
||||
table_insert(market_items, {price = {{'processing-unit', 1}}, offer = {type = 'give-item', item = 'coin', count = 10}})
|
||||
table_insert(market_items, {price = {{'plastic-bar', 1}}, offer = {type = 'give-item', item = 'coin', count = 1}})
|
||||
table_insert(market_items, {price = {{'green-wire', 5}}, offer = {type = 'give-item', item = 'coin', count = 1}})
|
||||
table_insert(market_items, {price = {{'red-wire', 5}}, offer = {type = 'give-item', item = 'coin', count = 1}})
|
||||
table_insert(market_items, {price = {{'battery', 1}}, offer = {type = 'give-item', item = 'coin', count = 1}})
|
||||
table_insert(market_items, {price = {{'heat-pipe', 1}}, offer = {type = 'give-item', item = 'coin', count = 1}})
|
||||
table_insert(market_items, {price = {{'pipe', 8}}, offer = {type = 'give-item', item = 'coin', count = 1}})
|
||||
table_insert(market_items, {price = {{'pipe-to-ground', 1}}, offer = {type = 'give-item', item = 'coin', count = 1}})
|
||||
|
||||
for _, item in pairs(market_items) do
|
||||
market.add_market_item(item)
|
||||
end
|
||||
end
|
||||
|
||||
local function refresh_offers(event)
|
||||
local player_index = event.player_index
|
||||
if player_index == nil then
|
||||
return
|
||||
end
|
||||
local player = game.players[event.player_index]
|
||||
local ffatable = Table.get_table()
|
||||
local market = event.entity or event.market
|
||||
if not market then
|
||||
return
|
||||
end
|
||||
if not market.valid then
|
||||
return
|
||||
end
|
||||
if market.name ~= 'crash-site-spaceship-market' then
|
||||
return
|
||||
end
|
||||
local position = market.position
|
||||
local spaceship = ffatable.spaceships[position.x][position.y]
|
||||
if not spaceship then
|
||||
return
|
||||
end
|
||||
clear_offers(market)
|
||||
set_offers(market, player)
|
||||
end
|
||||
|
||||
local function offer_purchased(event)
|
||||
local ffatable = Table.get_table()
|
||||
local player = game.players[event.player_index]
|
||||
local market = event.market
|
||||
local offer_index = event.offer_index
|
||||
local count = event.count
|
||||
if not upgrade_functions[offer_index] then
|
||||
return
|
||||
end
|
||||
local spaceship = ffatable.spaceships[market.position.x][market.position.y]
|
||||
if not spaceship then
|
||||
return
|
||||
end
|
||||
if upgrade_functions[offer_index](player) then
|
||||
-- reimburse extra purchased
|
||||
if count > 1 then
|
||||
local offers = market.get_market_items()
|
||||
if offers[offer_index].price ~= nil then
|
||||
local price = offers[offer_index].price[1].amount
|
||||
player.insert({name = 'coin', count = price * (count - 1)})
|
||||
end
|
||||
end
|
||||
else
|
||||
-- reimburse purchase
|
||||
local offers = market.get_market_items()
|
||||
if offers[offer_index].price ~= nil then
|
||||
local price = offers[offer_index].price[1].amount
|
||||
player.insert({name = 'coin', count = price * (count)})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function on_gui_opened(event)
|
||||
local gui_type = event.gui_type
|
||||
if gui_type == defines.gui_type.entity then
|
||||
local entity = event.entity
|
||||
if entity ~= nil or entity.valid then
|
||||
-- crash-site-spaceship
|
||||
if entity.name == 'crash-site-spaceship-market' then
|
||||
refresh_offers(event)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function on_market_item_purchased(event)
|
||||
local market = event.market
|
||||
if market.name == 'crash-site-spaceship-market' then
|
||||
offer_purchased(event)
|
||||
refresh_offers(event)
|
||||
end
|
||||
end
|
||||
|
||||
local function kill_spaceship(entity)
|
||||
local ffatable = Table.get_table()
|
||||
local spaceship = ffatable.spaceships[entity.position.x][entity.position.y]
|
||||
if spaceship ~= nil then
|
||||
ffatable.spaceships[entity.position.x][entity.position.y] = nil
|
||||
end
|
||||
end
|
||||
|
||||
local function on_entity_died(event)
|
||||
local entity = event.entity
|
||||
if entity.name == 'crash-site-spaceship-market' then
|
||||
kill_spaceship(entity)
|
||||
end
|
||||
end
|
||||
|
||||
local on_init = function()
|
||||
local ffatable = Table.get_table()
|
||||
ffatable.spaceships = {}
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.on_init(on_init)
|
||||
Event.add(defines.events.on_gui_opened, on_gui_opened)
|
||||
Event.add(defines.events.on_market_item_purchased, on_market_item_purchased)
|
||||
Event.add(defines.events.on_entity_died, on_entity_died)
|
@ -1,4 +1,3 @@
|
||||
--luacheck: ignore
|
||||
local Public = {}
|
||||
|
||||
local table_size = table.size
|
||||
@ -69,11 +68,19 @@ end
|
||||
|
||||
-- is the position empty
|
||||
local function is_empty(position, surface)
|
||||
local entity_radius = 1
|
||||
local tile_radius = 1
|
||||
local entities = surface.count_entities_filtered({position = position, radius = entity_radius, collision_mask = {'object-layer', 'player-layer'}})
|
||||
--log("entities = " .. entities)
|
||||
if entities > 0 then
|
||||
local chunk_position = {}
|
||||
chunk_position.x = math_floor(position.x / 32)
|
||||
chunk_position.y = math_floor(position.y / 32)
|
||||
if not surface.is_chunk_generated(chunk_position) then
|
||||
-- force load the chunk
|
||||
surface.request_to_generate_chunks(position, 0)
|
||||
surface.force_generate_chunk_requests()
|
||||
end
|
||||
local entity_radius = 3
|
||||
local tile_radius = 2
|
||||
local entities = surface.find_entities_filtered({position = position, radius = entity_radius})
|
||||
--log("entities = " .. #entities)
|
||||
if #entities > 0 then
|
||||
return false
|
||||
end
|
||||
local tiles = surface.count_tiles_filtered({position = position, radius = tile_radius, collision_mask = 'water-tile'})
|
||||
@ -87,14 +94,17 @@ local function is_empty(position, surface)
|
||||
end
|
||||
|
||||
-- finds a valid spawn point that is not near a town and not in a polluted area
|
||||
local function find_valid_spawn_point(surface)
|
||||
local function find_valid_spawn_point(force_name, surface)
|
||||
local ffatable = Table.get_table()
|
||||
|
||||
-- check center of map first if valid
|
||||
local position = {x = 0, y = 0}
|
||||
--log("testing {" .. position.x .. "," .. position.y .. "}")
|
||||
force_load(position, surface, 1)
|
||||
|
||||
-- is the point near any buildings
|
||||
if in_use(position) == false then
|
||||
if Building.near_town(position, surface, spawn_point_town_buffer) == false then
|
||||
if Building.near_another_town(force_name, position, surface, spawn_point_town_buffer) == false then
|
||||
-- force load the position
|
||||
if is_empty(position, surface) == true then
|
||||
--log("found valid spawn point at {" .. position.x .. "," .. position.y .. "}")
|
||||
@ -133,7 +143,7 @@ local function find_valid_spawn_point(surface)
|
||||
force_load(position, surface, 1)
|
||||
if in_use(target) == false then
|
||||
if has_pollution(target, surface) == false then
|
||||
if Building.near_town(target, surface, spawn_point_town_buffer) == false then
|
||||
if Building.near_another_town(force_name, target, surface, spawn_point_town_buffer) == false then
|
||||
if is_empty(target, surface) == true then
|
||||
--log("found valid spawn point at {" .. target.x .. "," .. target.y .. "}")
|
||||
position = target
|
||||
@ -145,7 +155,6 @@ local function find_valid_spawn_point(surface)
|
||||
end
|
||||
-- near a town, increment the radius and select another angle
|
||||
radius = radius + math_random(1, spawn_point_incremental_distance)
|
||||
angle = math_random(0, 360)
|
||||
tries = tries + 1
|
||||
end
|
||||
return {x = 0, y = 0}
|
||||
@ -154,7 +163,14 @@ end
|
||||
function Public.get_new_spawn_point(player, surface)
|
||||
local ffatable = Table.get_table()
|
||||
-- get a new spawn point
|
||||
local position = find_valid_spawn_point(surface)
|
||||
local position = {0, 0}
|
||||
if player ~= nil then
|
||||
local force = player.force
|
||||
if force ~= nil then
|
||||
local force_name = force.name
|
||||
position = find_valid_spawn_point(force_name, surface)
|
||||
end
|
||||
end
|
||||
-- should never be invalid or blocked
|
||||
ffatable.spawn_point[player.name] = position
|
||||
--log("player " .. player.name .. " assigned new spawn point at {" .. position.x .. "," .. position.y .. "}")
|
||||
@ -164,21 +180,16 @@ end
|
||||
-- gets a new or existing spawn point for the player
|
||||
function Public.get_spawn_point(player, surface)
|
||||
local ffatable = Table.get_table()
|
||||
if ffatable.spawn_point == nil then
|
||||
ffatable.spawn_point = {}
|
||||
end
|
||||
-- test the existing spawn point
|
||||
local position = ffatable.spawn_point[player.name]
|
||||
if position ~= nil then
|
||||
-- if there is a spawn point and less than three strikes
|
||||
if position ~= nil and ffatable.strikes[player.name] < 3 then
|
||||
-- check that the spawn point is not blocked
|
||||
if surface.can_place_entity({name = 'character', position = position}) then
|
||||
--log("player " .. player.name .. "using existing spawn point at {" .. position.x .. "," .. position.y .. "}")
|
||||
return position
|
||||
else
|
||||
position = surface.find_non_colliding_position('character', position, 16, 0.25)
|
||||
if (position ~= nil) then
|
||||
return position
|
||||
end
|
||||
position = surface.find_non_colliding_position('character', position, 0, 0.25)
|
||||
return position
|
||||
end
|
||||
end
|
||||
-- otherwise get a new spawn point
|
||||
|
@ -20,6 +20,25 @@ function Public.get_table()
|
||||
return ffatable
|
||||
end
|
||||
|
||||
function Public.get(key)
|
||||
if key then
|
||||
return ffatable[key]
|
||||
else
|
||||
return ffatable
|
||||
end
|
||||
end
|
||||
|
||||
function Public.set(key, value)
|
||||
if key and (value or value == false) then
|
||||
ffatable[key] = value
|
||||
return ffatable[key]
|
||||
elseif key then
|
||||
return ffatable[key]
|
||||
else
|
||||
return ffatable
|
||||
end
|
||||
end
|
||||
|
||||
local on_init = function()
|
||||
Public.reset_table()
|
||||
end
|
||||
|
@ -1,10 +1,12 @@
|
||||
--luacheck: ignore
|
||||
local Public = {}
|
||||
|
||||
local math_random = math.random
|
||||
local table_size = table.size
|
||||
local string_match = string.match
|
||||
local string_lower = string.lower
|
||||
|
||||
local Server = require 'utils.server'
|
||||
local Map = require 'modules.scrap_towny_ffa.map'
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
|
||||
local outlander_color = {150, 150, 150}
|
||||
@ -13,70 +15,118 @@ local rogue_color = {150, 150, 150}
|
||||
local rogue_chat_color = {170, 170, 170}
|
||||
local item_drop_radius = 1.65
|
||||
|
||||
local destroy_wall_types = {
|
||||
['gate'] = true,
|
||||
['wall'] = true
|
||||
}
|
||||
|
||||
local destroy_military_types = {
|
||||
['ammo-turret'] = true,
|
||||
['artillery-turret'] = true,
|
||||
['artillery-wagon'] = true,
|
||||
['electric-turret'] = true,
|
||||
['fluid-turret'] = true,
|
||||
['lab'] = true,
|
||||
['land-mine'] = true,
|
||||
['logistic-robot'] = true,
|
||||
['radar'] = true,
|
||||
['reactor'] = true,
|
||||
['roboport'] = true,
|
||||
['rocket-silo'] = true
|
||||
}
|
||||
|
||||
local destroy_robot_types = {
|
||||
['combat-robot'] = true,
|
||||
['construction-robot'] = true,
|
||||
['logistic-robot'] = true
|
||||
}
|
||||
|
||||
local function min_slots(slots)
|
||||
local min = 0
|
||||
for i = 1, 3, 1 do
|
||||
if slots[i] > min then
|
||||
min = slots[i]
|
||||
end
|
||||
end
|
||||
return min
|
||||
end
|
||||
|
||||
local function can_force_accept_member(force)
|
||||
local ffatable = Table.get_table()
|
||||
local town_centers = ffatable.town_centers
|
||||
local size_of_town_centers = ffatable.size_of_town_centers
|
||||
local member_limit = 0
|
||||
|
||||
if size_of_town_centers <= 1 then
|
||||
return true
|
||||
if ffatable.member_limit == nil then
|
||||
ffatable.member_limit = 1
|
||||
end
|
||||
|
||||
for _, town in pairs(town_centers) do
|
||||
member_limit = member_limit + table_size(town.market.force.connected_players)
|
||||
-- get the members of each force name into a table
|
||||
local slots = {0, 0, 0}
|
||||
for _, town_center in pairs(town_centers) do
|
||||
local players = table_size(town_center.market.force.players)
|
||||
-- get min value for all slots
|
||||
local min = min_slots(slots)
|
||||
-- if our value greater than min of all three replace that slot
|
||||
if players > min then
|
||||
for i = 1, 3, 1 do
|
||||
if slots[i] == min then
|
||||
slots[i] = players
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
member_limit = math.floor(member_limit / size_of_town_centers) + 4
|
||||
-- get the min of all slots
|
||||
local member_limit = min_slots(slots) + 1
|
||||
ffatable.member_limit = member_limit
|
||||
|
||||
if #force.connected_players >= member_limit then
|
||||
game.print('>> Town ' .. force.name .. ' has too many settlers! Current limit (' .. member_limit .. ')', {255, 255, 0})
|
||||
return
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
local function is_towny(force)
|
||||
if force == game.forces['player'] or force == game.forces['rogue'] then
|
||||
return false
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function Public.has_key(player)
|
||||
if not (player and player.valid) then
|
||||
return
|
||||
local function is_towny(force)
|
||||
if force.index == game.forces['player'].index or force.index == game.forces['rogue'].index then
|
||||
return false
|
||||
end
|
||||
local ffatable = Table.get_table()
|
||||
|
||||
return ffatable.key[player.index]
|
||||
return true
|
||||
end
|
||||
|
||||
function Public.give_key(player)
|
||||
if not (player and player.valid) then
|
||||
return
|
||||
end
|
||||
function Public.has_key(index)
|
||||
local ffatable = Table.get_table()
|
||||
|
||||
ffatable.key[player.index] = true
|
||||
if ffatable.key == nil then
|
||||
ffatable.key = {}
|
||||
end
|
||||
if ffatable.key[index] ~= nil then
|
||||
return ffatable.key[index]
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function Public.remove_key(player)
|
||||
if not (player and player.valid) then
|
||||
return
|
||||
end
|
||||
function Public.give_key(index)
|
||||
local ffatable = Table.get_table()
|
||||
if ffatable.key == nil then
|
||||
ffatable.key = {}
|
||||
end
|
||||
ffatable.key[index] = true
|
||||
end
|
||||
|
||||
ffatable.key[player.index] = false
|
||||
function Public.remove_key(index)
|
||||
local ffatable = Table.get_table()
|
||||
if ffatable.key == nil then
|
||||
ffatable.key = {}
|
||||
end
|
||||
ffatable.key[index] = false
|
||||
end
|
||||
|
||||
function Public.set_player_color(player)
|
||||
local ffatable = Table.get_table()
|
||||
if player.force == game.forces['player'] then
|
||||
if player.force.index == game.forces['player'].index then
|
||||
player.color = outlander_color
|
||||
player.chat_color = outlander_chat_color
|
||||
return
|
||||
end
|
||||
if player.force == game.forces['rogue'] then
|
||||
if player.force.index == game.forces['rogue'].index then
|
||||
player.color = rogue_color
|
||||
player.chat_color = rogue_chat_color
|
||||
return
|
||||
@ -114,51 +164,62 @@ function Public.set_all_player_colors()
|
||||
end
|
||||
end
|
||||
|
||||
local function reset_player(player)
|
||||
if player.character ~= nil then
|
||||
local character = player.character
|
||||
character.character_crafting_speed_modifier = 0.0
|
||||
character.character_mining_speed_modifier = 0.0
|
||||
character.character_inventory_slots_bonus = 0
|
||||
end
|
||||
end
|
||||
|
||||
function Public.add_player_to_town(player, town_center)
|
||||
local ffatable = Table.get_table()
|
||||
local market = town_center.market
|
||||
local force = market.force
|
||||
local surface = market.surface
|
||||
reset_player(player)
|
||||
player.force = market.force
|
||||
Public.remove_key(player)
|
||||
Public.remove_key(player.index)
|
||||
ffatable.spawn_point[player.name] = force.get_spawn_position(surface)
|
||||
game.permissions.get_group(force.name).add_player(player)
|
||||
player.tag = ''
|
||||
Map.enable_world_map(player)
|
||||
Public.set_player_color(player)
|
||||
end
|
||||
|
||||
function Public.give_outlander_items(player)
|
||||
player.insert({name = 'stone-furnace', count = 1})
|
||||
-- given to player upon respawn
|
||||
function Public.give_player_items(player)
|
||||
player.clear_items_inside()
|
||||
player.insert({name = 'raw-fish', count = 3})
|
||||
player.insert({name = 'coal', count = 3})
|
||||
end
|
||||
|
||||
function Public.set_player_to_outlander(player)
|
||||
local ffatable = Table.get_table()
|
||||
player.force = game.forces.player
|
||||
if ffatable.spawn_point[player.name] then
|
||||
ffatable.spawn_point[player.name] = nil
|
||||
if player == nil then
|
||||
return
|
||||
end
|
||||
player.force = game.forces.player
|
||||
if game.permissions.get_group('outlander') == nil then
|
||||
game.permissions.create_group('outlander')
|
||||
end
|
||||
game.permissions.get_group('outlander').add_player(player)
|
||||
player.tag = '[Outlander]'
|
||||
Map.disable_world_map(player)
|
||||
Public.set_player_color(player)
|
||||
Public.give_key(player)
|
||||
Public.give_key(player.index)
|
||||
end
|
||||
|
||||
local function set_player_to_rogue(player)
|
||||
local ffatable = Table.get_table()
|
||||
player.force = game.forces['rogue']
|
||||
if ffatable.spawn_point[player.name] then
|
||||
ffatable.spawn_point[player.name] = nil
|
||||
if player == nil then
|
||||
return
|
||||
end
|
||||
player.force = 'rogue'
|
||||
if game.permissions.get_group('rogue') == nil then
|
||||
game.permissions.create_group('rogue')
|
||||
end
|
||||
game.permissions.get_group('rogue').add_player(player)
|
||||
player.tag = '[Rogue]'
|
||||
Map.disable_world_map(player)
|
||||
Public.set_player_color(player)
|
||||
end
|
||||
|
||||
@ -167,6 +228,11 @@ local function ally_outlander(player, target)
|
||||
local requesting_force = player.force
|
||||
local target_force = target.force
|
||||
|
||||
-- don't handle if towns not yet enabled
|
||||
if not ffatable.towns_enabled then
|
||||
player.print('You must wait for more players to join!', {255, 255, 0})
|
||||
return false
|
||||
end
|
||||
-- don't handle request if target is not a town
|
||||
if not is_towny(requesting_force) and not is_towny(target_force) then
|
||||
return false
|
||||
@ -181,7 +247,7 @@ local function ally_outlander(player, target)
|
||||
if not is_towny(requesting_force) and is_towny(target_force) then
|
||||
ffatable.requests[player.index] = target_force.name
|
||||
|
||||
local target_player = false
|
||||
local target_player
|
||||
if target.type == 'character' then
|
||||
target_player = target.player
|
||||
else
|
||||
@ -333,7 +399,10 @@ local function declare_war(player, item)
|
||||
requesting_force.set_friend(target_force, false)
|
||||
target_force.set_friend(requesting_force, false)
|
||||
|
||||
game.print('>> ' .. player.name .. ' has dropped the coal! Town ' .. target_force.name .. ' and ' .. requesting_force.name .. ' are now at war!', {255, 255, 0})
|
||||
game.print(
|
||||
'>> ' .. player.name .. ' has dropped the coal! Town ' .. target_force.name .. ' and ' .. requesting_force.name .. ' are now at war!',
|
||||
{255, 255, 0}
|
||||
)
|
||||
end
|
||||
|
||||
local function delete_chart_tag_for_all_forces(market)
|
||||
@ -351,13 +420,15 @@ local function delete_chart_tag_for_all_forces(market)
|
||||
end
|
||||
end
|
||||
|
||||
function Public.add_chart_tag(force, market)
|
||||
function Public.add_chart_tag(town_center)
|
||||
local market = town_center.market
|
||||
local force = market.force
|
||||
local position = market.position
|
||||
local tags = force.find_chart_tags(market.surface, {{position.x - 0.1, position.y - 0.1}, {position.x + 0.1, position.y + 0.1}})
|
||||
if tags[1] then
|
||||
return
|
||||
end
|
||||
force.add_chart_tag(market.surface, {icon = {type = 'item', name = 'stone-furnace'}, position = position, text = market.force.name .. "'s Town"})
|
||||
force.add_chart_tag(market.surface, {icon = {type = 'item', name = 'stone-furnace'}, position = position, text = town_center.town_name})
|
||||
end
|
||||
|
||||
function Public.update_town_chart_tags()
|
||||
@ -366,9 +437,11 @@ function Public.update_town_chart_tags()
|
||||
local forces = game.forces
|
||||
for _, town_center in pairs(town_centers) do
|
||||
local market = town_center.market
|
||||
for _, force in pairs(forces) do
|
||||
if force.is_chunk_visible(market.surface, town_center.chunk_position) then
|
||||
Public.add_chart_tag(force, market)
|
||||
if market ~= nil and market.valid then
|
||||
for _, force in pairs(forces) do
|
||||
if force.is_chunk_visible(market.surface, town_center.chunk_position) then
|
||||
Public.add_chart_tag(town_center)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -386,6 +459,35 @@ local function reset_permissions(permission_group)
|
||||
end
|
||||
end
|
||||
|
||||
local function enable_blueprints(permission_group)
|
||||
local defs = {
|
||||
defines.input_action.alt_select_blueprint_entities,
|
||||
defines.input_action.cancel_new_blueprint,
|
||||
defines.input_action.change_blueprint_record_label,
|
||||
defines.input_action.clear_selected_blueprint,
|
||||
defines.input_action.create_blueprint_like,
|
||||
defines.input_action.cycle_blueprint_backwards,
|
||||
defines.input_action.cycle_blueprint_forwards,
|
||||
defines.input_action.delete_blueprint_library,
|
||||
defines.input_action.delete_blueprint_record,
|
||||
defines.input_action.drop_blueprint_record,
|
||||
defines.input_action.drop_to_blueprint_book,
|
||||
defines.input_action.export_blueprint,
|
||||
defines.input_action.grab_blueprint_record,
|
||||
defines.input_action.import_blueprint,
|
||||
defines.input_action.import_blueprint_string,
|
||||
defines.input_action.open_blueprint_library_gui,
|
||||
defines.input_action.open_blueprint_record,
|
||||
defines.input_action.select_blueprint_entities,
|
||||
defines.input_action.setup_blueprint,
|
||||
defines.input_action.setup_single_blueprint_record,
|
||||
defines.input_action.upgrade_open_blueprint
|
||||
}
|
||||
for _, d in pairs(defs) do
|
||||
permission_group.set_allows_action(d, true)
|
||||
end
|
||||
end
|
||||
|
||||
local function disable_blueprints(permission_group)
|
||||
local defs = {
|
||||
defines.input_action.alt_select_blueprint_entities,
|
||||
@ -408,7 +510,30 @@ local function disable_blueprints(permission_group)
|
||||
defines.input_action.select_blueprint_entities,
|
||||
defines.input_action.setup_blueprint,
|
||||
defines.input_action.setup_single_blueprint_record,
|
||||
defines.input_action.upgrade_open_blueprint,
|
||||
defines.input_action.upgrade_open_blueprint
|
||||
}
|
||||
for _, d in pairs(defs) do
|
||||
permission_group.set_allows_action(d, false)
|
||||
end
|
||||
end
|
||||
|
||||
local function enable_deconstruct(permission_group)
|
||||
local defs = {
|
||||
defines.input_action.deconstruct,
|
||||
defines.input_action.clear_selected_deconstruction_item,
|
||||
defines.input_action.cancel_deconstruct,
|
||||
defines.input_action.toggle_deconstruction_item_entity_filter_mode,
|
||||
defines.input_action.toggle_deconstruction_item_tile_filter_mode,
|
||||
defines.input_action.set_deconstruction_item_tile_selection_mode,
|
||||
defines.input_action.set_deconstruction_item_trees_and_rocks_only
|
||||
}
|
||||
for _, d in pairs(defs) do
|
||||
permission_group.set_allows_action(d, true)
|
||||
end
|
||||
end
|
||||
|
||||
local function disable_deconstruct(permission_group)
|
||||
local defs = {
|
||||
defines.input_action.deconstruct,
|
||||
defines.input_action.clear_selected_deconstruction_item,
|
||||
defines.input_action.cancel_deconstruct,
|
||||
@ -425,12 +550,12 @@ end
|
||||
local function enable_artillery(force, permission_group)
|
||||
permission_group.set_allows_action(defines.input_action.use_artillery_remote, true)
|
||||
force.technologies['artillery'].enabled = true
|
||||
force.technologies['artillery-shell-range-1'].enabled = false
|
||||
force.technologies['artillery-shell-speed-1'].enabled = false
|
||||
force.recipes['artillery-turret'].enabled = true
|
||||
force.recipes['artillery-wagon'].enabled = true
|
||||
force.recipes['artillery-targeting-remote'].enabled = true
|
||||
force.recipes['artillery-shell'].enabled = true
|
||||
force.technologies['artillery-shell-range-1'].enabled = true
|
||||
force.technologies['artillery-shell-speed-1'].enabled = true
|
||||
force.recipes['artillery-turret'].enabled = false
|
||||
force.recipes['artillery-wagon'].enabled = false
|
||||
force.recipes['artillery-targeting-remote'].enabled = false
|
||||
force.recipes['artillery-shell'].enabled = false
|
||||
end
|
||||
|
||||
local function disable_artillery(force, permission_group)
|
||||
@ -490,11 +615,13 @@ end
|
||||
|
||||
-- setup a team force
|
||||
function Public.add_new_force(force_name)
|
||||
local ffatable = Table.get_table()
|
||||
-- disable permissions
|
||||
local force = game.create_force(force_name)
|
||||
local permission_group = game.permissions.create_group(force_name)
|
||||
reset_permissions(permission_group)
|
||||
disable_blueprints(permission_group)
|
||||
enable_blueprints(permission_group)
|
||||
enable_deconstruct(permission_group)
|
||||
enable_artillery(force, permission_group)
|
||||
disable_spidertron(force, permission_group)
|
||||
disable_rockets(force)
|
||||
@ -510,15 +637,29 @@ function Public.add_new_force(force_name)
|
||||
-- balance initial combat
|
||||
force.set_ammo_damage_modifier('landmine', -0.75)
|
||||
force.set_ammo_damage_modifier('grenade', -0.5)
|
||||
if (ffatable.testing_mode == true) then
|
||||
local e_force = game.forces['enemy']
|
||||
e_force.set_friend(force, true) -- team force should not be attacked by turrets
|
||||
e_force.set_cease_fire(force, true) -- team force should not be attacked by units
|
||||
force.enable_all_prototypes()
|
||||
force.research_all_technologies()
|
||||
end
|
||||
return force
|
||||
end
|
||||
|
||||
local function kill_force(force_name)
|
||||
local function kill_force(force_name, cause)
|
||||
local ffatable = Table.get_table()
|
||||
local force = game.forces[force_name]
|
||||
local market = ffatable.town_centers[force_name].market
|
||||
local town_center = ffatable.town_centers[force_name]
|
||||
local market = town_center.market
|
||||
local position = market.position
|
||||
local surface = market.surface
|
||||
surface.create_entity({name = 'big-artillery-explosion', position = market.position})
|
||||
local balance = town_center.coin_balance
|
||||
local town_name = town_center.town_name
|
||||
surface.create_entity({name = 'big-artillery-explosion', position = position})
|
||||
for _, player in pairs(force.players) do
|
||||
ffatable.spawn_point[player.name] = nil
|
||||
ffatable.cooldowns_town_placement[player.index] = game.tick + 3600 * 15
|
||||
if player.character then
|
||||
player.character.die()
|
||||
else
|
||||
@ -526,22 +667,108 @@ local function kill_force(force_name)
|
||||
end
|
||||
player.force = game.forces.player
|
||||
Public.set_player_color(player)
|
||||
Public.give_key(player.index)
|
||||
end
|
||||
for _, e in pairs(surface.find_entities_filtered({force = force_name})) do
|
||||
if e.valid then
|
||||
if e.type == 'wall' or e.type == 'gate' then
|
||||
if destroy_military_types[e.type] == true then
|
||||
surface.create_entity({name = 'big-artillery-explosion', position = position})
|
||||
e.die()
|
||||
else
|
||||
if destroy_robot_types[e.type] == true then
|
||||
surface.create_entity({name = 'explosion', position = position})
|
||||
e.die()
|
||||
else
|
||||
if destroy_wall_types[e.type] == true then
|
||||
e.die()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
for _, e in pairs(surface.find_entities_filtered({force = force_name})) do
|
||||
if e.valid then
|
||||
e.force = game.forces['neutral']
|
||||
local damage = math_random() * 2.5 - 0.5
|
||||
if damage > 0 then
|
||||
if damage >= 1 or e.health == nil then
|
||||
e.die()
|
||||
else
|
||||
local health = e.health
|
||||
e.health = health * damage
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
local r = 27
|
||||
for _, e in pairs(
|
||||
surface.find_entities_filtered({area = {{position.x - r, position.y - r}, {position.x + r, position.y + r}}, force = 'neutral', type = 'resource'})
|
||||
) do
|
||||
if e.name ~= 'crude-oil' then
|
||||
e.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
game.merge_forces(force_name, 'neutral')
|
||||
ffatable.town_centers[force_name] = nil
|
||||
ffatable.size_of_town_centers = ffatable.size_of_town_centers - 1
|
||||
ffatable.number_of_towns = ffatable.number_of_towns - 1
|
||||
delete_chart_tag_for_all_forces(market)
|
||||
game.print('>> ' .. force_name .. "'s town has fallen! [gps=" .. math.floor(market.position.x) .. ',' .. math.floor(market.position.y) .. ']', {255, 255, 0})
|
||||
-- reward the killer
|
||||
if cause == nil or not cause.valid then
|
||||
Server.to_discord_embed(town_name .. ' has fallen!')
|
||||
game.print('>> ' .. town_name .. ' has fallen!', {255, 255, 0})
|
||||
return
|
||||
end
|
||||
if cause.force == nil then
|
||||
Server.to_discord_embed(town_name .. ' has fallen!')
|
||||
game.print('>> ' .. town_name .. ' has fallen!', {255, 255, 0})
|
||||
return
|
||||
end
|
||||
if cause.force.name == 'player' or cause.force.name == 'rogue' then
|
||||
local items = {name = 'coin', count = balance}
|
||||
town_center.coin_balance = 0
|
||||
if balance > 0 then
|
||||
if cause.can_insert(items) then
|
||||
cause.insert(items)
|
||||
else
|
||||
local chest = surface.create_entity({name = 'steel-chest', position = position, force = 'neutral'})
|
||||
chest.insert(items)
|
||||
end
|
||||
end
|
||||
if cause.force.name == 'player' then
|
||||
Server.to_discord_embed(town_name .. ' has fallen to outlanders!')
|
||||
game.print('>> ' .. town_name .. ' has fallen to outlanders!', {255, 255, 0})
|
||||
else
|
||||
Server.to_discord_embed(town_name .. ' has fallen to rogues!')
|
||||
game.print('>> ' .. town_name .. ' has fallen to rogues!', {255, 255, 0})
|
||||
end
|
||||
else
|
||||
if cause.force.name ~= 'enemy' then
|
||||
if ffatable.town_centers[cause.force.name] ~= nil then
|
||||
local killer_town_center = ffatable.town_centers[cause.force.name]
|
||||
if balance > 0 then
|
||||
killer_town_center.coin_balance = killer_town_center.coin_balance + balance
|
||||
end
|
||||
Server.to_discord_embed(town_name .. ' has fallen to ' .. killer_town_center.town_name .. '!')
|
||||
game.print('>> ' .. town_name .. ' has fallen to ' .. killer_town_center.town_name .. '!', {255, 255, 0})
|
||||
end
|
||||
else
|
||||
Server.to_discord_embed(town_name .. ' has fallen!')
|
||||
game.print('>> ' .. town_name .. ' has fallen!', {255, 255, 0})
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local player_force_disabled_recipes = {'lab', 'automation-science-pack', 'stone-brick', 'radar'}
|
||||
-- hand craftable
|
||||
local player_force_disabled_recipes = {
|
||||
'lab',
|
||||
'automation-science-pack',
|
||||
'steel-furnace',
|
||||
'electric-furnace',
|
||||
'stone-wall',
|
||||
'stone-brick',
|
||||
'radar'
|
||||
}
|
||||
local player_force_enabled_recipes = {
|
||||
'submachine-gun',
|
||||
'assembling-machine-1',
|
||||
@ -552,24 +779,40 @@ local player_force_enabled_recipes = {
|
||||
'splitter',
|
||||
'steel-plate',
|
||||
'car',
|
||||
'cargo-wagon',
|
||||
'constant-combinator',
|
||||
'tank',
|
||||
'engine-unit',
|
||||
'constant-combinator',
|
||||
'green-wire',
|
||||
'locomotive',
|
||||
'rail',
|
||||
'train-stop',
|
||||
'red-wire',
|
||||
'arithmetic-combinator',
|
||||
'decider-combinator'
|
||||
}
|
||||
|
||||
local function setup_neutral_force()
|
||||
local force = game.forces['neutral']
|
||||
force.technologies['military'].researched = true
|
||||
force.technologies['automation'].researched = true
|
||||
force.technologies['logistic-science-pack'].researched = true
|
||||
force.technologies['steel-processing'].researched = true
|
||||
force.technologies['engine'].researched = true
|
||||
force.recipes['submachine-gun'].enabled = true
|
||||
force.recipes['engine-unit'].enabled = true
|
||||
force.recipes['stone-brick'].enabled = false
|
||||
force.recipes['radar'].enabled = false
|
||||
force.recipes['lab'].enabled = false
|
||||
force.recipes['automation-science-pack'].enabled = false
|
||||
force.recipes['logistic-science-pack'].enabled = false
|
||||
end
|
||||
|
||||
-- setup the player force (this is the default for Outlanders)
|
||||
local function setup_player_force()
|
||||
local ffatable = Table.get_table()
|
||||
local force = game.forces.player
|
||||
local permission_group = game.permissions.create_group('outlander')
|
||||
-- disable permissions
|
||||
reset_permissions(permission_group)
|
||||
disable_blueprints(permission_group)
|
||||
disable_deconstruct(permission_group)
|
||||
disable_artillery(force, permission_group)
|
||||
disable_spidertron(force, permission_group)
|
||||
disable_rockets(force)
|
||||
@ -593,15 +836,20 @@ local function setup_player_force()
|
||||
end
|
||||
force.set_ammo_damage_modifier('landmine', -0.75)
|
||||
force.set_ammo_damage_modifier('grenade', -0.5)
|
||||
if (ffatable.testing_mode == true) then
|
||||
force.enable_all_prototypes()
|
||||
end
|
||||
end
|
||||
|
||||
local function setup_rogue_force()
|
||||
local ffatable = Table.get_table()
|
||||
local force_name = 'rogue'
|
||||
local force = game.create_force(force_name)
|
||||
local permission_group = game.permissions.create_group(force_name)
|
||||
-- disable permissions
|
||||
reset_permissions(permission_group)
|
||||
disable_blueprints(permission_group)
|
||||
disable_deconstruct(permission_group)
|
||||
disable_artillery(force, permission_group)
|
||||
disable_spidertron(force, permission_group)
|
||||
disable_rockets(force)
|
||||
@ -625,22 +873,31 @@ local function setup_rogue_force()
|
||||
end
|
||||
force.set_ammo_damage_modifier('landmine', -0.75)
|
||||
force.set_ammo_damage_modifier('grenade', -0.5)
|
||||
if (ffatable.testing_mode == true) then
|
||||
force.enable_all_prototypes()
|
||||
end
|
||||
end
|
||||
|
||||
local function setup_enemy_force()
|
||||
local ffatable = Table.get_table()
|
||||
local e_force = game.forces['enemy']
|
||||
e_force.evolution_factor = 1 -- this should never change since we are changing biter types on spawn
|
||||
e_force.set_friend(game.forces.player, true) -- outlander force (player) should not be attacked by turrets
|
||||
e_force.set_cease_fire(game.forces.player, true) -- outlander force (player) should not be attacked by units
|
||||
e_force.set_friend(game.forces['rogue'], false) -- rogue force (rogue) should be attacked by turrets
|
||||
e_force.set_cease_fire(game.forces['rogue'], false) -- rogue force (rogue) should be attacked by units
|
||||
-- note, these don't prevent an outlander or rogue from attacking a unit or spawner, we need to handle separately
|
||||
if (ffatable.testing_mode == true) then
|
||||
e_force.set_friend(game.forces['rogue'], true) -- rogue force (rogue) should not be attacked by turrets
|
||||
e_force.set_cease_fire(game.forces['rogue'], true) -- rogue force (rogue) should not be attacked by units
|
||||
else
|
||||
-- note, these don't prevent an outlander or rogue from attacking a unit or spawner, we need to handle separately
|
||||
e_force.set_friend(game.forces['rogue'], false) -- rogue force (rogue) should be attacked by turrets
|
||||
e_force.set_cease_fire(game.forces['rogue'], false) -- rogue force (rogue) should be attacked by units
|
||||
end
|
||||
end
|
||||
|
||||
local function on_player_dropped_item(event)
|
||||
local player = game.players[event.player_index]
|
||||
local entity = event.entity
|
||||
if entity.stack.name == 'raw-fish' then
|
||||
if entity.stack.name == 'coin' then
|
||||
ally_town(player, entity)
|
||||
return
|
||||
end
|
||||
@ -669,9 +926,9 @@ local function on_entity_damaged(event)
|
||||
-- special case to handle enemies attacked by outlanders
|
||||
if entity.force == game.forces['enemy'] then
|
||||
if cause ~= nil then
|
||||
if cause.type == 'character' and force == game.forces['player'] then
|
||||
if cause.type == 'character' and force.index == game.forces['player'].index then
|
||||
local player = cause.player
|
||||
if force == game.forces['player'] then
|
||||
if player ~= nil and force.index == game.forces['player'].index then
|
||||
-- set the force of the player to rogue until they die or create a town
|
||||
set_player_to_rogue(player)
|
||||
end
|
||||
@ -679,12 +936,12 @@ local function on_entity_damaged(event)
|
||||
-- cars and tanks
|
||||
if cause.type == 'car' or cause.type == 'tank' then
|
||||
local driver = cause.get_driver()
|
||||
if driver ~= nil and driver.force == game.forces['player'] then
|
||||
if driver ~= nil and driver.force.index == game.forces['player'].index then
|
||||
-- set the force of the player to rogue until they die or create a town
|
||||
set_player_to_rogue(driver)
|
||||
end
|
||||
local passenger = cause.get_passenger()
|
||||
if passenger ~= nil and passenger.force == game.forces['player'] then
|
||||
if passenger ~= nil and passenger.force.index == game.forces['player'].index then
|
||||
-- set the force of the player to rogue until they die or create a town
|
||||
set_player_to_rogue(passenger)
|
||||
end
|
||||
@ -693,16 +950,18 @@ local function on_entity_damaged(event)
|
||||
if cause.type == 'locomotive' or cause.type == 'cargo-wagon' or cause.type == 'fluid-wagon' or cause.type == 'artillery-wagon' then
|
||||
local train = cause.train
|
||||
for _, passenger in pairs(train.passengers) do
|
||||
if passenger ~= nil and passenger.force == game.forces['player'] then
|
||||
if passenger ~= nil and passenger.force.index == game.forces['player'].index then
|
||||
set_player_to_rogue(passenger)
|
||||
end
|
||||
end
|
||||
end
|
||||
-- combat robots
|
||||
if cause.type == 'combat-robot' and force == game.forces['player'] then
|
||||
if cause.type == 'combat-robot' then
|
||||
local owner = cause.last_user
|
||||
-- set the force of the player to rogue until they die or create a town
|
||||
set_player_to_rogue(owner)
|
||||
if owner ~= nil and owner.force == game.forces['player]'] then
|
||||
-- set the force of the player to rogue until they die or create a town
|
||||
set_player_to_rogue(owner)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -710,8 +969,9 @@ end
|
||||
|
||||
local function on_entity_died(event)
|
||||
local entity = event.entity
|
||||
if entity.name == 'market' then
|
||||
kill_force(entity.force.name)
|
||||
local cause = event.cause
|
||||
if entity ~= nil and entity.valid and entity.name == 'market' then
|
||||
kill_force(entity.force.name, cause)
|
||||
end
|
||||
end
|
||||
|
||||
@ -723,7 +983,7 @@ local function on_post_entity_died(event)
|
||||
local entities = game.surfaces[event.surface_index].find_entities_filtered({position = event.position, radius = 1})
|
||||
for _, e in pairs(entities) do
|
||||
if e.type == 'character-corpse' then
|
||||
Public.remove_key(e)
|
||||
Public.remove_key(e.character_corpse_player_index)
|
||||
end
|
||||
end
|
||||
end
|
||||
@ -735,12 +995,16 @@ end
|
||||
local function on_console_chat(event)
|
||||
local player = game.players[event.player_index]
|
||||
if string_match(string_lower(event.message), '%[armor%=') then
|
||||
if string_match(event.message, player.name) then
|
||||
return
|
||||
end
|
||||
player.clear_console()
|
||||
game.print('>> ' .. player.name .. ' is trying to gain an unfair advantage!')
|
||||
end
|
||||
end
|
||||
|
||||
function Public.initialize()
|
||||
setup_neutral_force()
|
||||
setup_player_force()
|
||||
setup_rogue_force()
|
||||
setup_enemy_force()
|
||||
|
@ -5,13 +5,17 @@ local table_insert = table.insert
|
||||
local math_floor = math.floor
|
||||
local table_shuffle = table.shuffle_table
|
||||
|
||||
local Server = require 'utils.server'
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
local Team = require 'modules.scrap_towny_ffa.team'
|
||||
local Building = require 'modules.scrap_towny_ffa.building'
|
||||
local Colors = require 'modules.scrap_towny_ffa.colors'
|
||||
local Enemy = require 'modules.scrap_towny_ffa.enemy'
|
||||
local Color = require 'utils.color_presets'
|
||||
|
||||
local town_radius = 27
|
||||
local radius_between_towns = 160
|
||||
local ore_amount = 250
|
||||
local radius_between_towns = 64
|
||||
local ore_amount = 1000 * (200 / 168.5)
|
||||
|
||||
local colors = {}
|
||||
local c1 = 250
|
||||
@ -63,8 +67,8 @@ end
|
||||
|
||||
local resource_vectors = {}
|
||||
resource_vectors[1] = {}
|
||||
for x = 7, 24, 1 do
|
||||
for y = 7, 24, 1 do
|
||||
for x = 10, 22, 1 do
|
||||
for y = 10, 22, 1 do
|
||||
table_insert(resource_vectors[1], {x, y})
|
||||
end
|
||||
end
|
||||
@ -103,12 +107,17 @@ for _, vector in pairs(additional_resource_vectors[3]) do
|
||||
table_insert(additional_resource_vectors[4], {vector[1], vector[2] * -1})
|
||||
end
|
||||
|
||||
local clear_whitelist_types = {
|
||||
['simple-entity'] = true,
|
||||
['resource'] = true,
|
||||
['cliff'] = true,
|
||||
['tree'] = true
|
||||
}
|
||||
--local clear_whitelist_types = {
|
||||
-- ['character'] = true,
|
||||
-- ['market'] = true,
|
||||
-- ['simple-entity'] = true,
|
||||
-- ['simple-entity-with-owner'] = true,
|
||||
-- ['container'] = true,
|
||||
-- ['car'] = true,
|
||||
-- ['resource'] = true,
|
||||
-- ['cliff'] = true,
|
||||
-- ['tree'] = true
|
||||
--}
|
||||
|
||||
local starter_supplies = {
|
||||
{name = 'raw-fish', count = 3},
|
||||
@ -121,14 +130,15 @@ local starter_supplies = {
|
||||
{name = 'shotgun', count = 1},
|
||||
{name = 'shotgun-shell', count = 8},
|
||||
{name = 'firearm-magazine', count = 16},
|
||||
{name = 'firearm-magazine', count = 16},
|
||||
{name = 'gun-turret', count = 2}
|
||||
}
|
||||
|
||||
local function count_nearby_ore(surface, position, ore_name)
|
||||
local count = 0
|
||||
local r = town_radius + 8
|
||||
for _, e in pairs(surface.find_entities_filtered({area = {{position.x - r, position.y - r}, {position.x + r, position.y + r}}, force = 'neutral', name = ore_name})) do
|
||||
for _, e in pairs(
|
||||
surface.find_entities_filtered({area = {{position.x - r, position.y - r}, {position.x + r, position.y + r}}, force = 'neutral', name = ore_name})
|
||||
) do
|
||||
count = count + e.amount
|
||||
end
|
||||
return count
|
||||
@ -140,14 +150,14 @@ local function draw_town_spawn(player_name)
|
||||
local position = market.position
|
||||
local surface = market.surface
|
||||
|
||||
local area = {{position.x - (town_radius + 1), position.y - (town_radius + 1)}, {position.x + (town_radius + 1), position.y + (town_radius + 1)}}
|
||||
--local area = {{position.x - (town_radius + 1), position.y - (town_radius + 1)}, {position.x + (town_radius + 1), position.y + (town_radius + 1)}}
|
||||
|
||||
-- remove other than cliffs, rocks and ores and trees
|
||||
for _, e in pairs(surface.find_entities_filtered({area = area, force = 'neutral'})) do
|
||||
if not clear_whitelist_types[e.type] then
|
||||
e.destroy()
|
||||
end
|
||||
end
|
||||
--for _, e in pairs(surface.find_entities_filtered({area = area, force = 'neutral'})) do
|
||||
-- if not clear_whitelist_types[e.type] then
|
||||
-- e.destroy()
|
||||
-- end
|
||||
--end
|
||||
|
||||
-- create walls
|
||||
for _, vector in pairs(gate_vectors_horizontal) do
|
||||
@ -196,7 +206,7 @@ local function draw_town_spawn(player_name)
|
||||
local p = {position.x + m1, position.y + m2}
|
||||
p = surface.find_non_colliding_position('wooden-chest', p, 64, 1)
|
||||
if p then
|
||||
local e = surface.create_entity({name = 'wooden-chest', position = p, force = player_name})
|
||||
local e = surface.create_entity({name = 'iron-chest', position = p, force = player_name})
|
||||
local inventory = e.get_inventory(defines.inventory.chest)
|
||||
inventory.insert(item_stack)
|
||||
end
|
||||
@ -225,7 +235,7 @@ local function draw_town_spawn(player_name)
|
||||
local y = position.y + vector[2]
|
||||
local p = {x = x, y = y}
|
||||
if surface.get_tile(p).name ~= 'out-of-map' then
|
||||
surface.set_tiles({{name = 'water-green', position = p}})
|
||||
surface.set_tiles({{name = 'water-shallow', position = p}})
|
||||
end
|
||||
end
|
||||
|
||||
@ -265,9 +275,8 @@ local function draw_town_spawn(player_name)
|
||||
--end
|
||||
end
|
||||
|
||||
local function is_valid_location(surface, position)
|
||||
local function is_valid_location(force_name, surface, position)
|
||||
local ffatable = Table.get_table()
|
||||
|
||||
if not surface.can_place_entity({name = 'market', position = position}) then
|
||||
surface.create_entity(
|
||||
{
|
||||
@ -282,13 +291,12 @@ local function is_valid_location(surface, position)
|
||||
|
||||
for _, vector in pairs(town_wall_vectors) do
|
||||
local p = {x = math_floor(position.x + vector[1]), y = math_floor(position.y + vector[2])}
|
||||
local tile = surface.get_tile(p.x, p.y)
|
||||
if tile.name == 'out-of-map' then
|
||||
if Building.in_restricted_zone(surface, p) then
|
||||
surface.create_entity(
|
||||
{
|
||||
name = 'flying-text',
|
||||
position = position,
|
||||
text = 'Town would be off-map!',
|
||||
text = 'Can not build in restricted zone!',
|
||||
color = {r = 0.77, g = 0.0, b = 0.0}
|
||||
}
|
||||
)
|
||||
@ -296,52 +304,53 @@ local function is_valid_location(surface, position)
|
||||
end
|
||||
end
|
||||
|
||||
if ffatable.size_of_town_centers > 48 then
|
||||
if ffatable.number_of_towns > 48 then
|
||||
surface.create_entity(
|
||||
{
|
||||
name = 'flying-text',
|
||||
position = position,
|
||||
text = 'Too many town centers on the map!',
|
||||
text = 'Too many towns on the map!',
|
||||
color = {r = 0.77, g = 0.0, b = 0.0}
|
||||
}
|
||||
)
|
||||
return false
|
||||
end
|
||||
|
||||
if Building.near_town(position, surface, radius_between_towns) then
|
||||
if Building.near_another_town(force_name, position, surface, radius_between_towns) == true then
|
||||
surface.create_entity(
|
||||
{
|
||||
name = 'flying-text',
|
||||
position = position,
|
||||
text = 'Town location is too close to another town center!',
|
||||
text = 'Town location is too close to others!',
|
||||
color = {r = 0.77, g = 0.0, b = 0.0}
|
||||
}
|
||||
)
|
||||
return false
|
||||
end
|
||||
|
||||
local area = {{position.x - town_radius, position.y - town_radius}, {position.x + town_radius, position.y + town_radius}}
|
||||
local count = 0
|
||||
for _, e in pairs(surface.find_entities_filtered({area = area})) do
|
||||
if e.force.name == 'enemy' then
|
||||
count = count + 1
|
||||
end
|
||||
end
|
||||
|
||||
if count > 1 then
|
||||
surface.create_entity(
|
||||
{
|
||||
name = 'flying-text',
|
||||
position = position,
|
||||
text = 'I got a bad feeling about this! There are enemies nearby.',
|
||||
color = {r = 0.77, g = 0.0, b = 0.0}
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
function Public.in_any_town(position)
|
||||
local ffatable = Table.get_table()
|
||||
local town_centers = ffatable.town_centers
|
||||
for _, town_center in pairs(town_centers) do
|
||||
local market = town_center.market
|
||||
if market ~= nil then
|
||||
if Building.in_area(position, market.position, town_radius) == true then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function Public.update_town_name(force)
|
||||
local ffatable = Table.get_table()
|
||||
local town_center = ffatable.town_centers[force.name]
|
||||
rendering.set_text(town_center.town_caption, town_center.town_name)
|
||||
end
|
||||
|
||||
function Public.set_market_health(entity, final_damage_amount)
|
||||
local ffatable = Table.get_table()
|
||||
local town_center = ffatable.town_centers[entity.force.name]
|
||||
@ -360,137 +369,125 @@ function Public.update_coin_balance(force)
|
||||
rendering.set_text(town_center.coins_text, 'Coins: ' .. town_center.coin_balance)
|
||||
end
|
||||
|
||||
local function is_color_used(color, town_centers)
|
||||
for _, center in pairs(town_centers) do
|
||||
if center.color then
|
||||
if center.color.r == color.r and center.color.g == color.g and center.color.b == color.b then
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function get_color()
|
||||
local ffatable = Table.get_table()
|
||||
local town_centers = ffatable.town_centers
|
||||
local c
|
||||
|
||||
local shuffle_index = {}
|
||||
for i = 1, #colors, 1 do
|
||||
shuffle_index[i] = i
|
||||
end
|
||||
table_shuffle(shuffle_index)
|
||||
|
||||
for i = 1, #colors, 1 do
|
||||
c = {r = colors[shuffle_index[i]][1], g = colors[shuffle_index[i]][2], b = colors[shuffle_index[i]][3]}
|
||||
if not is_color_used(c, town_centers) then
|
||||
return c
|
||||
end
|
||||
end
|
||||
|
||||
return c
|
||||
end
|
||||
|
||||
local function found_town(event)
|
||||
local entity = event.created_entity
|
||||
-- is a valid entity placed?
|
||||
if entity == nil or not entity.valid then
|
||||
return true
|
||||
end -- cancel, not a valid entity placed
|
||||
if entity.name ~= 'stone-furnace' then
|
||||
return false
|
||||
end -- cancel, player did not place a stone-furnace
|
||||
local player = game.players[event.player_index]
|
||||
if player.force ~= game.forces.player and player.force ~= game.forces['rogue'] then
|
||||
return false
|
||||
end -- cancel, player is in a team already
|
||||
local force_name = tostring(player.name)
|
||||
if game.forces[force_name] then
|
||||
return
|
||||
end -- cancel, player is mayor of town
|
||||
if Team.has_key(player) == false then
|
||||
return false
|
||||
end -- cancel, player has already placed a town
|
||||
end
|
||||
|
||||
local player = game.players[event.player_index]
|
||||
|
||||
-- is player not a character?
|
||||
local character = player.character
|
||||
if character == nil then
|
||||
return
|
||||
end
|
||||
|
||||
-- is it a stone-furnace?
|
||||
if entity.name ~= 'stone-furnace' then
|
||||
return
|
||||
end
|
||||
|
||||
-- is player in a town already?
|
||||
if player.force.index ~= game.forces.player.index and player.force.index ~= game.forces['rogue'].index then
|
||||
return
|
||||
end
|
||||
|
||||
-- try to place the town
|
||||
|
||||
local force_name = tostring(player.name)
|
||||
local surface = entity.surface
|
||||
local ffatable = Table.get_table()
|
||||
local position = entity.position
|
||||
|
||||
entity.destroy()
|
||||
|
||||
-- are towns enabled?
|
||||
local ffatable = Table.get_table()
|
||||
if not ffatable.towns_enabled then
|
||||
player.print('You must wait for more players to join!', {255, 255, 0})
|
||||
player.insert({name = 'stone-furnace', count = 1})
|
||||
return
|
||||
end
|
||||
|
||||
-- is player mayor of town that still exists?
|
||||
|
||||
if game.forces[force_name] then
|
||||
player.insert({name = 'stone-furnace', count = 1})
|
||||
return
|
||||
end
|
||||
|
||||
-- has player placed a town already?
|
||||
if Team.has_key(player.index) == false then
|
||||
player.insert({name = 'stone-furnace', count = 1})
|
||||
return
|
||||
end
|
||||
|
||||
-- is town placement on cooldown?
|
||||
if ffatable.cooldowns_town_placement[player.index] then
|
||||
if game.tick < ffatable.cooldowns_town_placement[player.index] then
|
||||
surface.create_entity(
|
||||
{
|
||||
name = 'flying-text',
|
||||
position = entity.position,
|
||||
position = position,
|
||||
text = 'Town founding is on cooldown for ' .. math.ceil((ffatable.cooldowns_town_placement[player.index] - game.tick) / 3600) .. ' minutes.',
|
||||
color = {r = 0.77, g = 0.0, b = 0.0}
|
||||
}
|
||||
)
|
||||
player.insert({name = 'stone-furnace', count = 1})
|
||||
entity.destroy()
|
||||
return true
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local position = entity.position
|
||||
entity.destroy()
|
||||
|
||||
if not is_valid_location(surface, position) then
|
||||
-- is it a valid location to place a town?
|
||||
if not is_valid_location(force_name, surface, position) then
|
||||
player.insert({name = 'stone-furnace', count = 1})
|
||||
return true
|
||||
return
|
||||
end
|
||||
|
||||
Team.add_new_force(force_name)
|
||||
-- does player have 100 coins?
|
||||
local inventory = character.get_main_inventory()
|
||||
if inventory == nil or inventory.get_item_count('coin') < 100 then
|
||||
player.print('Towns cost 100 coins!', {255, 255, 0})
|
||||
player.insert({name = 'stone-furnace', count = 1})
|
||||
return
|
||||
else
|
||||
inventory.remove({name = 'coin', count = 100})
|
||||
end
|
||||
|
||||
local force = Team.add_new_force(force_name)
|
||||
|
||||
ffatable.town_centers[force_name] = {}
|
||||
local town_center = ffatable.town_centers[force_name]
|
||||
town_center.town_name = player.name .. "'s Town"
|
||||
town_center.market = surface.create_entity({name = 'market', position = position, force = force_name})
|
||||
town_center.chunk_position = {math.floor(town_center.market.position.x / 32), math.floor(town_center.market.position.y / 32)}
|
||||
town_center.max_health = 1000
|
||||
town_center.max_health = 100
|
||||
town_center.coin_balance = 0
|
||||
town_center.input_buffer = {}
|
||||
town_center.output_buffer = {}
|
||||
town_center.health = town_center.max_health
|
||||
town_center.color = get_color()
|
||||
local crayola = Colors.get_random_color()
|
||||
town_center.color = crayola.color
|
||||
town_center.research_counter = 1
|
||||
town_center.upgrades = {}
|
||||
town_center.upgrades.mining_prod = 0
|
||||
town_center.upgrades.mining_speed = 0
|
||||
town_center.upgrades.crafting_speed = 0
|
||||
town_center.upgrades.laser_turret = {}
|
||||
town_center.upgrades.laser_turret.slots = 0
|
||||
town_center.upgrades.laser_turret.locations = {}
|
||||
town_center.upgrades.laser_turret.locations = 0
|
||||
town_center.evolution = {}
|
||||
town_center.evolution.biters = 0
|
||||
town_center.evolution.spitters = 0
|
||||
town_center.evolution.worms = 0
|
||||
|
||||
town_center.coins_text =
|
||||
rendering.draw_text {
|
||||
text = 'Coins: ' .. town_center.coin_balance,
|
||||
surface = surface,
|
||||
target = town_center.market,
|
||||
target_offset = {0, -2.75},
|
||||
color = {200, 200, 200},
|
||||
scale = 1.00,
|
||||
font = 'default-game',
|
||||
alignment = 'center',
|
||||
scale_with_zoom = false
|
||||
}
|
||||
|
||||
town_center.health_text =
|
||||
rendering.draw_text {
|
||||
text = 'HP: ' .. town_center.health .. ' / ' .. town_center.max_health,
|
||||
surface = surface,
|
||||
target = town_center.market,
|
||||
target_offset = {0, -3.25},
|
||||
color = {200, 200, 200},
|
||||
scale = 1.00,
|
||||
font = 'default-game',
|
||||
alignment = 'center',
|
||||
scale_with_zoom = false
|
||||
}
|
||||
town_center.creation_tick = game.tick
|
||||
|
||||
town_center.town_caption =
|
||||
rendering.draw_text {
|
||||
text = player.name .. "'s Town",
|
||||
text = town_center.town_name,
|
||||
surface = surface,
|
||||
forces = {force_name},
|
||||
target = town_center.market,
|
||||
target_offset = {0, -4.25},
|
||||
color = town_center.color,
|
||||
@ -500,27 +497,51 @@ local function found_town(event)
|
||||
scale_with_zoom = false
|
||||
}
|
||||
|
||||
ffatable.size_of_town_centers = ffatable.size_of_town_centers + 1
|
||||
town_center.health_text =
|
||||
rendering.draw_text {
|
||||
text = 'HP: ' .. town_center.health .. ' / ' .. town_center.max_health,
|
||||
surface = surface,
|
||||
forces = {force_name},
|
||||
target = town_center.market,
|
||||
target_offset = {0, -3.25},
|
||||
color = {200, 200, 200},
|
||||
scale = 1.00,
|
||||
font = 'default-game',
|
||||
alignment = 'center',
|
||||
scale_with_zoom = false
|
||||
}
|
||||
|
||||
town_center.coins_text =
|
||||
rendering.draw_text {
|
||||
text = 'Coins: ' .. town_center.coin_balance,
|
||||
surface = surface,
|
||||
forces = {force_name},
|
||||
target = town_center.market,
|
||||
target_offset = {0, -2.75},
|
||||
color = {200, 200, 200},
|
||||
scale = 1.00,
|
||||
font = 'default-game',
|
||||
alignment = 'center',
|
||||
scale_with_zoom = false
|
||||
}
|
||||
|
||||
ffatable.number_of_towns = ffatable.number_of_towns + 1
|
||||
|
||||
Enemy.clear_enemies(position, surface, town_radius * 2)
|
||||
draw_town_spawn(force_name)
|
||||
|
||||
Team.add_player_to_town(player, town_center)
|
||||
Team.add_chart_tag(game.forces.player, town_center.market)
|
||||
|
||||
local force = player.force
|
||||
|
||||
-- set the spawn point
|
||||
local pos = {x = town_center.market.position.x, y = town_center.market.position.y + 4}
|
||||
--log("setting spawn point = {" .. spawn_point.x .. "," .. spawn_point.y .. "}")
|
||||
force.set_spawn_position(pos, surface)
|
||||
ffatable.spawn_point[player.name] = pos
|
||||
|
||||
ffatable.cooldowns_town_placement[player.index] = game.tick + 3600 * 15
|
||||
|
||||
Team.remove_key(player)
|
||||
Team.add_player_to_town(player, town_center)
|
||||
Team.remove_key(player.index)
|
||||
Team.add_chart_tag(town_center)
|
||||
|
||||
game.print('>> ' .. player.name .. ' has founded a new town!', {255, 255, 0})
|
||||
return true
|
||||
Server.to_discord_embed(player.name .. ' has founded a new town!')
|
||||
player.print('Your town color is ' .. crayola.name, crayola.color)
|
||||
end
|
||||
|
||||
local function on_built_entity(event)
|
||||
@ -554,10 +575,52 @@ end
|
||||
local on_init = function()
|
||||
local ffatable = Table.get_table()
|
||||
ffatable.town_centers = {}
|
||||
ffatable.size_of_town_centers = 0
|
||||
ffatable.number_of_towns = 0
|
||||
ffatable.cooldowns_town_placement = {}
|
||||
end
|
||||
|
||||
local function rename_town(cmd)
|
||||
local player = game.players[cmd.player_index]
|
||||
if not player or not player.valid then
|
||||
return
|
||||
end
|
||||
local force = player.force
|
||||
if force.name == 'player' or force.name == 'rogue' then
|
||||
player.print('You are not member of a town!', Color.fail)
|
||||
return
|
||||
end
|
||||
local name = cmd.parameter
|
||||
if name == nil then
|
||||
player.print('Must specify new town name!', Color.fail)
|
||||
return
|
||||
end
|
||||
local ffatable = Table.get_table()
|
||||
local town_center = ffatable.town_centers[force.name]
|
||||
local old_name = town_center.town_name
|
||||
town_center.town_name = name
|
||||
Public.update_town_name(force)
|
||||
|
||||
for _, p in pairs(force.players) do
|
||||
if p == player then
|
||||
player.print('Your town name is now ' .. name, town_center.color)
|
||||
else
|
||||
player.print(player.name .. ' has renamed the town to ' .. name, town_center.color)
|
||||
end
|
||||
Team.set_player_color(p)
|
||||
end
|
||||
|
||||
game.print('>> ' .. old_name .. ' is now known as ' .. '"' .. name .. '"', {255, 255, 0})
|
||||
Server.to_discord_embed(old_name .. ' is now known as ' .. '"' .. name .. '"')
|
||||
end
|
||||
|
||||
commands.add_command(
|
||||
'rename-town',
|
||||
'Renames your town..',
|
||||
function(cmd)
|
||||
rename_town(cmd)
|
||||
end
|
||||
)
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.on_init(on_init)
|
||||
Event.add(defines.events.on_built_entity, on_built_entity)
|
||||
|
@ -1,7 +1,6 @@
|
||||
--luacheck: ignore
|
||||
--Towny balance things by Gerkiz --
|
||||
|
||||
local player_ammo_starting_modifiers = {
|
||||
--[[ local player_ammo_starting_modifiers = {
|
||||
['artillery-shell'] = -0.75,
|
||||
['biological'] = -0.5,
|
||||
['bullet'] = -0.25,
|
||||
@ -18,8 +17,7 @@ local player_ammo_starting_modifiers = {
|
||||
['railgun'] = 1,
|
||||
['rocket'] = -0.75,
|
||||
['shotgun-shell'] = -0.20
|
||||
}
|
||||
|
||||
} ]]
|
||||
local player_gun_speed_modifiers = {
|
||||
['artillery-shell'] = -0.75,
|
||||
['biological'] = -0.5,
|
||||
@ -101,7 +99,7 @@ local enemy_ammo_evolution_modifiers = {
|
||||
--['rocket'] = 1,
|
||||
--['shotgun-shell'] = 1
|
||||
}
|
||||
|
||||
--[[
|
||||
function init_player_weapon_damage(force)
|
||||
for k, v in pairs(player_ammo_starting_modifiers) do
|
||||
force.set_ammo_damage_modifier(k, v)
|
||||
@ -111,8 +109,8 @@ function init_player_weapon_damage(force)
|
||||
force.set_gun_speed_modifier(k, v)
|
||||
end
|
||||
end
|
||||
|
||||
function init_enemy_weapon_damage()
|
||||
]]
|
||||
local function init_enemy_weapon_damage()
|
||||
local e_force = game.forces['enemy']
|
||||
|
||||
for k, v in pairs(enemy_ammo_starting_modifiers) do
|
||||
|
@ -1,6 +1,6 @@
|
||||
local math_random = math.random
|
||||
local Evolution = require 'modules.scrap_towny_ffa.evolution'
|
||||
local Building = require 'modules.scrap_towny_ffa.building'
|
||||
local Town_center = require 'modules.scrap_towny_ffa.town_center'
|
||||
local Scrap = require 'modules.scrap_towny_ffa.scrap'
|
||||
local unearthing_worm = require 'modules.scrap_towny_ffa.unearthing_worm'
|
||||
local unearthing_biters = require 'modules.scrap_towny_ffa.unearthing_biters'
|
||||
@ -8,29 +8,24 @@ local tick_tack_trap = require 'modules.scrap_towny_ffa.tick_tack_trap'
|
||||
|
||||
local function trap(entity)
|
||||
-- check if within 32 blocks of market
|
||||
if entity.type == 'tree' or Scrap.is_scrap(entity) then
|
||||
if entity.type == 'tree' or Scrap.is_scrap(entity) and not Town_center.in_any_town(entity.position) then
|
||||
if math_random(1, 1024) == 1 then
|
||||
if not Building.near_town(entity.position, entity.surface, 32) then
|
||||
tick_tack_trap(entity.surface, entity.position)
|
||||
return
|
||||
end
|
||||
tick_tack_trap(entity.surface, entity.position)
|
||||
end
|
||||
if math_random(1, 256) == 1 then
|
||||
if not Building.near_town(entity.position, entity.surface, 32) then
|
||||
unearthing_worm(entity.surface, entity.position, Evolution.get_worm_evolution(entity))
|
||||
end
|
||||
unearthing_worm(entity.surface, entity.position, Evolution.get_worm_evolution(entity))
|
||||
end
|
||||
if math_random(1, 128) == 1 then
|
||||
if not Building.near_town(entity.position, entity.surface, 32) then
|
||||
unearthing_biters(entity.surface, entity.position, math_random(4, 8), Evolution.get_biter_evolution(entity))
|
||||
end
|
||||
unearthing_biters(entity.surface, entity.position, math_random(4, 8), Evolution.get_biter_evolution(entity))
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function on_player_mined_entity(event)
|
||||
local entity = event.entity
|
||||
trap(entity)
|
||||
if entity and entity.valid then
|
||||
trap(entity)
|
||||
end
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
|
@ -6,10 +6,10 @@ local Scrap = require 'modules.scrap_towny_ffa.scrap'
|
||||
-- loot chances and amounts for scrap entities
|
||||
|
||||
local entity_loot_chance = {
|
||||
{name = 'advanced-circuit', chance = 5},
|
||||
{name = 'advanced-circuit', chance = 15},
|
||||
--{name = "artillery-shell", chance = 1},
|
||||
{name = 'battery', chance = 20},
|
||||
{name = 'cannon-shell', chance = 2},
|
||||
{name = 'battery', chance = 15},
|
||||
{name = 'cannon-shell', chance = 4},
|
||||
--{name = "cluster-grenade", chance = 2},
|
||||
{name = 'construction-robot', chance = 1},
|
||||
{name = 'copper-cable', chance = 250},
|
||||
@ -19,9 +19,9 @@ local entity_loot_chance = {
|
||||
{name = 'destroyer-capsule', chance = 1},
|
||||
{name = 'distractor-capsule', chance = 2},
|
||||
{name = 'electric-engine-unit', chance = 2},
|
||||
{name = 'electronic-circuit', chance = 200},
|
||||
{name = 'electronic-circuit', chance = 150},
|
||||
{name = 'empty-barrel', chance = 10},
|
||||
{name = 'engine-unit', chance = 4},
|
||||
{name = 'engine-unit', chance = 5},
|
||||
{name = 'explosive-cannon-shell', chance = 2},
|
||||
--{name = "explosive-rocket", chance = 3},
|
||||
--{name = "explosive-uranium-cannon-shell", chance = 1},
|
||||
@ -55,15 +55,16 @@ local entity_loot_chance = {
|
||||
--{name = "uranium-fuel-cell", chance = 1},
|
||||
--{name = "used-up-uranium-fuel-cell", chance = 1},
|
||||
{name = 'water-barrel', chance = 10},
|
||||
{name = 'tank', chance = 1},
|
||||
{name = 'car', chance = 1}
|
||||
{name = 'tank', chance = 2},
|
||||
{name = 'car', chance = 3}
|
||||
}
|
||||
|
||||
-- positive numbers can scale, 0 is disabled, and negative numbers are fixed absolute values
|
||||
local entity_loot_amounts = {
|
||||
['advanced-circuit'] = 2,
|
||||
['advanced-circuit'] = 6,
|
||||
--["artillery-shell"] = 0.3,
|
||||
['battery'] = 2,
|
||||
['cannon-shell'] = 2,
|
||||
['cannon-shell'] = 4,
|
||||
--["cluster-grenade"] = 0.3,
|
||||
['construction-robot'] = 0.3,
|
||||
['copper-cable'] = 24,
|
||||
@ -81,13 +82,13 @@ local entity_loot_amounts = {
|
||||
--["explosive-uranium-cannon-shell"] = 2,
|
||||
['explosives'] = 4,
|
||||
['green-wire'] = 8,
|
||||
['grenade'] = 2,
|
||||
['grenade'] = 6,
|
||||
['heat-pipe'] = 1,
|
||||
['heavy-oil-barrel'] = 3,
|
||||
['iron-gear-wheel'] = 8,
|
||||
['iron-plate'] = 16,
|
||||
['iron-stick'] = 16,
|
||||
['land-mine'] = 1,
|
||||
['land-mine'] = 6,
|
||||
['light-oil-barrel'] = 3,
|
||||
['logistic-robot'] = 0.3,
|
||||
['low-density-structure'] = 0.3,
|
||||
@ -97,7 +98,7 @@ local entity_loot_amounts = {
|
||||
['pipe'] = 8,
|
||||
['pipe-to-ground'] = 1,
|
||||
['plastic-bar'] = 4,
|
||||
['processing-unit'] = 1,
|
||||
['processing-unit'] = 2,
|
||||
['red-wire'] = 8,
|
||||
--["rocket"] = 2,
|
||||
--["rocket-control-unit"] = 0.3,
|
||||
@ -109,8 +110,8 @@ local entity_loot_amounts = {
|
||||
--["uranium-fuel-cell"] = 0.3,
|
||||
--["used-up-uranium-fuel-cell"] = 1,
|
||||
['water-barrel'] = 3,
|
||||
['tank'] = 1,
|
||||
['car'] = 1
|
||||
['tank'] = -1,
|
||||
['car'] = -1
|
||||
}
|
||||
|
||||
local scrap_raffle = {}
|
||||
@ -141,9 +142,16 @@ local function on_player_mined_entity(event)
|
||||
local scrap = scrap_raffle[math.random(1, size_of_scrap_raffle)]
|
||||
|
||||
local amount_bonus = (game.forces.enemy.evolution_factor * 2) + (game.forces.player.mining_drill_productivity_bonus * 2)
|
||||
local r1 = math.ceil(entity_loot_amounts[scrap] * (0.3 + (amount_bonus * 0.3)))
|
||||
local r2 = math.ceil(entity_loot_amounts[scrap] * (1.7 + (amount_bonus * 1.7)))
|
||||
local amount = math.random(r1, r2)
|
||||
local amount
|
||||
if entity_loot_amounts[scrap] <= 0 then
|
||||
amount = math.abs(entity_loot_amounts[scrap])
|
||||
else
|
||||
local m1 = 0.3 + (amount_bonus * 0.3)
|
||||
local m2 = 1.7 + (amount_bonus * 1.7)
|
||||
local r1 = math.ceil(entity_loot_amounts[scrap] * m1)
|
||||
local r2 = math.ceil(entity_loot_amounts[scrap] * m2)
|
||||
amount = math.random(r1, r2)
|
||||
end
|
||||
|
||||
local player = game.players[event.player_index]
|
||||
local inserted_count = player.insert({name = scrap, count = amount})
|
||||
|
@ -1048,7 +1048,7 @@ local function check_group_positions()
|
||||
fill_tiles(group, 30)
|
||||
remove_rocks(group)
|
||||
remove_trees(group)
|
||||
if ugp[group.group_number].index >= 4 then
|
||||
if valid(group) and ugp[group.group_number].index >= 4 then
|
||||
generated_units.unit_group_pos.positions[group.group_number] = nil
|
||||
reform_group(group)
|
||||
end
|
||||
|
@ -4,6 +4,7 @@ local math_floor = math.floor
|
||||
local math_abs = math.abs
|
||||
|
||||
local get_noise = require 'utils.get_noise'
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
local Scrap = require 'modules.scrap_towny_ffa.scrap'
|
||||
require 'modules.no_deconstruction_of_neutral_entities'
|
||||
|
||||
@ -75,6 +76,7 @@ local container_loot_chance = {
|
||||
{name = 'cannon-shell', chance = 2},
|
||||
{name = 'cliff-explosives', chance = 5},
|
||||
--{name = "cluster-grenade", chance = 2},
|
||||
{name = 'coin', chance = 1},
|
||||
{name = 'construction-robot', chance = 1},
|
||||
{name = 'copper-cable', chance = 250},
|
||||
{name = 'copper-plate', chance = 500},
|
||||
@ -128,6 +130,7 @@ local container_loot_amounts = {
|
||||
['cannon-shell'] = 2,
|
||||
['cliff-explosives'] = 2,
|
||||
--["cluster-grenade"] = 0.3,
|
||||
['coin'] = 2,
|
||||
['construction-robot'] = 0.3,
|
||||
['copper-cable'] = 24,
|
||||
['copper-plate'] = 16,
|
||||
@ -184,6 +187,10 @@ end
|
||||
local size_of_scrap_raffle = #scrap_raffle
|
||||
|
||||
local function place_scrap(surface, position)
|
||||
local ffatable = Table.get_table()
|
||||
if ffatable.spaceships == nil then
|
||||
ffatable.spaceships = {}
|
||||
end
|
||||
-- place turrets
|
||||
if math_random(1, 700) == 1 then
|
||||
if position.x ^ 2 + position.x ^ 2 > 4096 then
|
||||
@ -195,17 +202,19 @@ local function place_scrap(surface, position)
|
||||
end
|
||||
end
|
||||
|
||||
-- place spaceship with loot
|
||||
if math_random(1, 8192) == 1 then
|
||||
local e = surface.create_entity({name = 'crash-site-spaceship', position = position, force = 'neutral'})
|
||||
e.minable = true
|
||||
local i = e.get_inventory(defines.inventory.chest)
|
||||
if i then
|
||||
for _ = 1, math_random(1, 5), 1 do
|
||||
local loot = scrap_raffle[math_random(1, size_of_scrap_raffle)]
|
||||
local amount = container_loot_amounts[loot]
|
||||
local count = math_floor(amount * math_random(5, 35) * 0.1) + 1
|
||||
i.insert({name = loot, count = count})
|
||||
-- place market spaceship
|
||||
if math_random(1, 4096) == 1 then
|
||||
local spaceship = {}
|
||||
if surface.can_place_entity({name = 'crash-site-spaceship-market', position = position, force = 'neutral'}) then
|
||||
spaceship.market = surface.create_entity({name = 'crash-site-spaceship-market', position = position, force = 'neutral'})
|
||||
spaceship.market.minable = false
|
||||
spaceship.max_health = 300
|
||||
spaceship.health = spaceship.max_health
|
||||
if spaceship.market and spaceship.market.valid then
|
||||
if ffatable.spaceships[position.x] == nil then
|
||||
ffatable.spaceships[position.x] = {}
|
||||
end
|
||||
ffatable.spaceships[position.x][position.y] = spaceship
|
||||
end
|
||||
end
|
||||
return
|
||||
@ -294,12 +303,51 @@ end
|
||||
local function on_chunk_generated(event)
|
||||
--log("scrap_towny_ffa::on_chunk_generated")
|
||||
local surface = event.surface
|
||||
if (surface.name ~= 'nauvis') then
|
||||
return
|
||||
end
|
||||
local seed = surface.map_gen_settings.seed
|
||||
local left_top_x = event.area.left_top.x
|
||||
local left_top_y = event.area.left_top.y
|
||||
--log(" chunk = {" .. left_top_x/32 .. ", " .. left_top_y/32 .. "}")
|
||||
|
||||
local position
|
||||
local noise
|
||||
|
||||
local chunk_position = event.position
|
||||
--log('chunk_position = {' .. chunk_position.x .. ',' .. chunk_position.y .. '}')
|
||||
if chunk_position.x >= -33 and chunk_position.x <= 32 and chunk_position.y >= -33 and chunk_position.y <= 32 then
|
||||
if chunk_position.x == -33 or chunk_position.x == 32 or chunk_position.y == -33 or chunk_position.y == 32 then
|
||||
local area = {{x = left_top_x, y = left_top_y}, {x = left_top_x + 31, y = left_top_y + 31}}
|
||||
local entities = surface.find_entities(area)
|
||||
for _, e in pairs(entities) do
|
||||
e.destroy()
|
||||
end
|
||||
for x = 0, 31, 1 do
|
||||
for y = 0, 31, 1 do
|
||||
position = {x = left_top_x + x, y = left_top_y + y}
|
||||
if not surface.get_tile(position).collides_with('water-tile') then
|
||||
surface.set_tiles({{name = 'water-shallow', position = position}}, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
end
|
||||
if chunk_position.x < -33 or chunk_position.x > 32 or chunk_position.y < -33 or chunk_position.y > 32 then
|
||||
local area = {{x = left_top_x, y = left_top_y}, {x = left_top_x + 31, y = left_top_y + 31}}
|
||||
local entities = surface.find_entities(area)
|
||||
for _, e in pairs(entities) do
|
||||
e.destroy()
|
||||
end
|
||||
for x = 0, 31, 1 do
|
||||
for y = 0, 31, 1 do
|
||||
position = {x = left_top_x + x, y = left_top_y + y}
|
||||
surface.set_tiles({{name = 'deepwater', position = position}}, true)
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
for x = 0, 31, 1 do
|
||||
for y = 0, 31, 1 do
|
||||
if math_random(1, 3) > 1 then
|
||||
|
42
utils/ai.lua
42
utils/ai.lua
@ -109,7 +109,7 @@ end
|
||||
|
||||
local function _shoot_at(ent, trgt)
|
||||
ent.shooting_state = {
|
||||
state = defines.shooting.shooting_selected,
|
||||
state = defines.shooting.shooting_enemies,
|
||||
position = trgt.position
|
||||
}
|
||||
end
|
||||
@ -137,7 +137,11 @@ local function set_noise_hostile_hook(ent)
|
||||
end
|
||||
|
||||
local function _do_job_seek_and_destroy_player(data)
|
||||
local surf = data.surface
|
||||
local active_surface = data.active_surface
|
||||
local surf = game.get_surface(active_surface)
|
||||
if not surf or not surf.valid then
|
||||
return
|
||||
end
|
||||
local force = data.force
|
||||
local players = game.connected_players
|
||||
|
||||
@ -188,8 +192,13 @@ local function _do_job_seek_and_destroy_player(data)
|
||||
end
|
||||
|
||||
local function _do_job_attack_objects(data)
|
||||
local surf = data.surface
|
||||
local active_surface = data.active_surface
|
||||
local surf = game.get_surface(active_surface)
|
||||
if not surf or not surf.valid then
|
||||
return
|
||||
end
|
||||
local force = data.force
|
||||
local args = data.args
|
||||
local position = data.position
|
||||
|
||||
if type(surf) == 'number' then
|
||||
@ -241,7 +250,16 @@ local function _do_job_attack_objects(data)
|
||||
if #closest ~= 0 then
|
||||
target = CommonFunctions.get_closest_neighbour(agent.position, closest)
|
||||
else
|
||||
goto continue
|
||||
if not args or not args.objects then
|
||||
goto continue
|
||||
end
|
||||
|
||||
if #args.objects == 0 then
|
||||
_shoot_stop(agent)
|
||||
goto continue
|
||||
end
|
||||
|
||||
target = CommonFunctions.get_closest_neighbour(agent.position, args.objects)
|
||||
end
|
||||
|
||||
if target == nil or not target.valid then
|
||||
@ -311,10 +329,22 @@ Public.do_job = function(surf, command, args, force)
|
||||
args = {}
|
||||
end
|
||||
|
||||
if not surf and not surf.valid then
|
||||
return
|
||||
end
|
||||
|
||||
if command == Public.command.seek_and_destroy_player then
|
||||
_do_job_seek_and_destroy_player(surf, force)
|
||||
local data = {
|
||||
active_surface = surf.index,
|
||||
force = force
|
||||
}
|
||||
_do_job_seek_and_destroy_player(data)
|
||||
elseif command == Public.command.attack_objects then
|
||||
_do_job_attack_objects(surf, args)
|
||||
local data = {
|
||||
active_surface = surf.index,
|
||||
args = args
|
||||
}
|
||||
_do_job_attack_objects(data)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -25,7 +25,7 @@ function get_game_version()
|
||||
end
|
||||
|
||||
function is_loaded(module)
|
||||
local res = package.loaded[module]
|
||||
local res = _G.package.loaded[module]
|
||||
if res then
|
||||
return res
|
||||
else
|
||||
|
@ -1,9 +1,12 @@
|
||||
local Global = require 'utils.global'
|
||||
local Event = require 'utils.event'
|
||||
|
||||
local Public = {}
|
||||
|
||||
local this = {
|
||||
created_items = {},
|
||||
respawn_items = {},
|
||||
disabled = false,
|
||||
skip_intro = true,
|
||||
chart_distance = 0,
|
||||
disable_crashsite = true,
|
||||
@ -74,6 +77,9 @@ local on_player_created = function(event)
|
||||
if not this.modded then
|
||||
return
|
||||
end
|
||||
if this.disabled then
|
||||
return
|
||||
end
|
||||
local player = game.get_player(event.player_index)
|
||||
util.insert_safe(player, this.created_items)
|
||||
|
||||
@ -103,6 +109,9 @@ local on_player_respawned = function(event)
|
||||
if not this.modded then
|
||||
return
|
||||
end
|
||||
if this.disabled then
|
||||
return
|
||||
end
|
||||
local player = game.players[event.player_index]
|
||||
util.insert_safe(player, this.respawn_items)
|
||||
end
|
||||
@ -111,6 +120,9 @@ local on_cutscene_waypoint_reached = function(event)
|
||||
if not this.modded then
|
||||
return
|
||||
end
|
||||
if this.disabled then
|
||||
return
|
||||
end
|
||||
if not crash_site.is_crash_site_cutscene(event) then
|
||||
return
|
||||
end
|
||||
@ -131,6 +143,10 @@ local skip_crash_site_cutscene = function(event)
|
||||
return
|
||||
end
|
||||
|
||||
if this.disabled then
|
||||
return
|
||||
end
|
||||
|
||||
if event.player_index ~= 1 then
|
||||
return
|
||||
end
|
||||
@ -154,6 +170,10 @@ local on_cutscene_cancelled = function(event)
|
||||
return
|
||||
end
|
||||
|
||||
if this.disabled then
|
||||
return
|
||||
end
|
||||
|
||||
local player = game.get_player(event.player_index)
|
||||
if player.gui.screen.skip_cutscene_label then
|
||||
player.gui.screen.skip_cutscene_label.destroy()
|
||||
@ -208,6 +228,25 @@ if not remote.interfaces['freeplay'] then
|
||||
remote.add_interface('freeplay', freeplay_interface)
|
||||
end
|
||||
|
||||
function Public.get(key)
|
||||
if key then
|
||||
return this[key]
|
||||
else
|
||||
return this
|
||||
end
|
||||
end
|
||||
|
||||
function Public.set(key, value)
|
||||
if key and (value or value == false) then
|
||||
this[key] = value
|
||||
return this[key]
|
||||
elseif key then
|
||||
return this[key]
|
||||
else
|
||||
return this
|
||||
end
|
||||
end
|
||||
|
||||
Event.on_init(
|
||||
function()
|
||||
local game_has_mods = is_game_modded()
|
||||
@ -240,3 +279,5 @@ Event.add(defines.events.on_player_respawned, on_player_respawned)
|
||||
Event.add(defines.events.on_cutscene_waypoint_reached, on_cutscene_waypoint_reached)
|
||||
Event.add('crash-site-skip-cutscene', skip_crash_site_cutscene)
|
||||
Event.add(defines.events.on_cutscene_cancelled, on_cutscene_cancelled)
|
||||
|
||||
return Public
|
||||
|
@ -116,7 +116,13 @@ local noises = {
|
||||
{modifier = 0.004, weight = 1},
|
||||
{modifier = 0.02, weight = 0.05}
|
||||
},
|
||||
['journey_swamps'] = {{modifier = 0.02, weight = 1}, {modifier = 0.04, weight = 0.35}, {modifier = 0.1, weight = 0.08}},
|
||||
['scrap_towny_ffa'] = {
|
||||
{modifier = 0.005, weight = 1},
|
||||
{modifier = 0.025, weight = 0.25},
|
||||
{modifier = 0.1, weight = 0.125},
|
||||
{modifier = 0.01, weight = 0.025}
|
||||
},
|
||||
['journey_swamps'] = {{modifier = 0.02, weight = 1}, {modifier = 0.04, weight = 0.35}, {modifier = 0.1, weight = 0.08}}
|
||||
}
|
||||
|
||||
--returns a float number between -1 and 1
|
||||
|
@ -6,7 +6,7 @@ local this = {
|
||||
prevent_spam = {}, -- the default table where all player indexes will be stored
|
||||
default_tick = 10, -- this defines the default tick to check whether or not a user is spamming a button.
|
||||
debug_text = false,
|
||||
debug_spam = true
|
||||
debug_spam = false
|
||||
}
|
||||
|
||||
local main_text = '[Spam Info] '
|
||||
|
Loading…
Reference in New Issue
Block a user