mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2025-02-07 13:31:40 +02:00
Merge pull request #228 from klugemonkey/master
Initial Commit for Scrap Towny FFA Map
This commit is contained in:
commit
a80fa1c9af
@ -205,6 +205,7 @@ require 'modules.autostash'
|
||||
--require 'maps.cube'
|
||||
--require 'maps.mountain_race.main'
|
||||
--require 'maps.native_war.main'
|
||||
--require 'maps.scrap_towny_ffa.main'
|
||||
---------------------------------------------------------------
|
||||
|
||||
---------------- MORE MODULES HERE ----------------
|
||||
@ -225,6 +226,7 @@ require 'modules.autostash'
|
||||
--require 'terrain_layouts.scrap_02'
|
||||
--require 'terrain_layouts.watery_world'
|
||||
--require 'terrain_layouts.tree_01'
|
||||
--require 'terrain_layouts.scrap_towny_ffa'
|
||||
---------------------------------------------------------------
|
||||
|
||||
if _DUMP_ENV then
|
||||
|
139
maps/scrap_towny_ffa/main.lua
Normal file
139
maps/scrap_towny_ffa/main.lua
Normal file
@ -0,0 +1,139 @@
|
||||
require "modules.custom_death_messages"
|
||||
require "modules.flashlight_toggle_button"
|
||||
require "modules.global_chat_toggle"
|
||||
require "modules.worms_create_oil_patches"
|
||||
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.town_center"
|
||||
require "modules.scrap_towny_ffa.market"
|
||||
require "modules.scrap_towny_ffa.slots"
|
||||
require "modules.scrap_towny_ffa.wreckage_yields_scrap"
|
||||
require "modules.scrap_towny_ffa.rocks_yield_ore_veins"
|
||||
require "modules.scrap_towny_ffa.spawners_contain_biters"
|
||||
require "modules.scrap_towny_ffa.explosives_are_explosive"
|
||||
require "modules.scrap_towny_ffa.fluids_are_explosive"
|
||||
require "modules.scrap_towny_ffa.trap"
|
||||
require "modules.scrap_towny_ffa.turrets_drop_ammo"
|
||||
require "modules.scrap_towny_ffa.combat_balance"
|
||||
|
||||
local Table = require "modules.scrap_towny_ffa.table"
|
||||
local Nauvis = require "modules.scrap_towny_ffa.nauvis"
|
||||
local Biters = require "modules.scrap_towny_ffa.biters"
|
||||
local Pollution = require "modules.scrap_towny_ffa.pollution"
|
||||
local Fish = require "modules.scrap_towny_ffa.fish_reproduction"
|
||||
local Info = require "modules.scrap_towny_ffa.info"
|
||||
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"
|
||||
|
||||
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]
|
||||
|
||||
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.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
|
||||
player.teleport({ 0, 0 }, game.surfaces["limbo"])
|
||||
Team.give_outlander_items(player)
|
||||
Team.give_key(player)
|
||||
-- first time spawn point
|
||||
local spawn_point = Spawn.get_spawn_point(player, surface)
|
||||
Spawn.clear_spawn_point(spawn_point, surface)
|
||||
player.teleport(spawn_point, surface)
|
||||
return
|
||||
end
|
||||
|
||||
if not ffatable.requests[player.index] then return end
|
||||
if ffatable.requests[player.index] ~= "kill-character" then return end
|
||||
if player.character then
|
||||
if player.character.valid then
|
||||
player.character.die()
|
||||
end
|
||||
end
|
||||
ffatable.requests[player.index] = nil
|
||||
end
|
||||
|
||||
local function on_player_respawned(event)
|
||||
local ffatable = Table.get_table()
|
||||
local player = game.players[event.player_index]
|
||||
local surface = player.surface
|
||||
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) 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
|
||||
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)
|
||||
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
|
||||
end
|
||||
|
||||
local function on_init()
|
||||
local ffatable = Table.get_table()
|
||||
--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 = {}
|
||||
|
||||
Nauvis.initialize()
|
||||
Team.initialize()
|
||||
|
||||
end
|
||||
|
||||
local tick_actions = {
|
||||
[60 * 0] = Radar.reset, -- each minute, at 00 seconds
|
||||
[60 * 5] = Team.update_town_chart_tags, -- each minute, at 05 seconds
|
||||
[60 * 10] = Team.set_all_player_colors, -- each minute, at 10 seconds
|
||||
[60 * 15] = Fish.reproduce, -- each minute, at 15 seconds
|
||||
[60 * 25] = Biters.unit_groups_start_moving, -- each minute, at 25 seconds
|
||||
[60 * 30] = Radar.reset, -- each minute, at 30 seconds
|
||||
[60 * 45] = Biters.validate_swarms, -- each minute, at 45 seconds
|
||||
[60 * 50] = Biters.swarm, -- each minute, at 50 seconds
|
||||
[60 * 55] = Pollution.market_scent -- each minute, at 55 seconds
|
||||
}
|
||||
|
||||
local function on_nth_tick(event)
|
||||
-- run each second
|
||||
local tick = event.tick
|
||||
local seconds = tick % 3600 -- tick will recycle minute
|
||||
if not tick_actions[seconds] then return end
|
||||
tick_actions[seconds]()
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
|
||||
Event.on_init(on_init)
|
||||
Event.on_nth_tick(60, on_nth_tick) -- once every second
|
||||
Event.add(defines.events.on_player_joined_game, on_player_joined_game)
|
||||
Event.add(defines.events.on_player_respawned, on_player_respawned)
|
||||
Event.add(defines.events.on_player_died, on_player_died)
|
||||
|
||||
|
210
modules/scrap_towny_ffa/biters.lua
Normal file
210
modules/scrap_towny_ffa/biters.lua
Normal file
@ -0,0 +1,210 @@
|
||||
local Public = {}
|
||||
local math_random = math.random
|
||||
local math_floor = math.floor
|
||||
local math_sqrt = math.sqrt
|
||||
local math_round = math.round
|
||||
local table_size = table.size
|
||||
local table_insert = table.insert
|
||||
local table_remove = table.remove
|
||||
local table_shuffle = table.shuffle_table
|
||||
|
||||
local Global = require 'utils.global'
|
||||
|
||||
local tick_schedule = {}
|
||||
Global.register(
|
||||
tick_schedule,
|
||||
function(t)
|
||||
tick_schedule = t
|
||||
end
|
||||
)
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
local Evolution = require "modules.scrap_towny_ffa.evolution"
|
||||
|
||||
local function get_commmands(target, group)
|
||||
local commands = {}
|
||||
local group_position = { x = group.position.x, y = group.position.y }
|
||||
local step_length = 128
|
||||
|
||||
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 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
|
||||
group_position.x = group_position.x + vector[1]
|
||||
group_position.y = group_position.y + vector[2]
|
||||
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,
|
||||
destination = { x = position.x, y = position.y },
|
||||
radius = 16,
|
||||
distraction = defines.distraction.by_damage
|
||||
}
|
||||
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_anything,
|
||||
}
|
||||
|
||||
return commands
|
||||
end
|
||||
|
||||
local function roll_market()
|
||||
local ffatable = Table.get_table()
|
||||
local town_centers = ffatable.town_centers
|
||||
if town_centers == nil or table_size(town_centers) == 0 then return end
|
||||
local keyset = {}
|
||||
for town_name, _ in pairs(town_centers) do
|
||||
table_insert(keyset, town_name)
|
||||
end
|
||||
local tc = math_random(1, #keyset)
|
||||
return town_centers[keyset[tc]]
|
||||
end
|
||||
|
||||
local function get_random_close_spawner(surface, market, radius)
|
||||
local units = surface.find_enemy_units(market.position, radius, market.force)
|
||||
if units ~= nil and #units > 0 then
|
||||
-- found units, shuffle the list
|
||||
table_shuffle(units)
|
||||
while units[1] do
|
||||
local unit = units[1]
|
||||
if unit.spawner then return unit.spawner end
|
||||
table_remove(units, 1)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function is_swarm_valid(swarm)
|
||||
local group = swarm.group
|
||||
if not group then return end
|
||||
if not group.valid then return end
|
||||
if game.tick >= swarm.timeout then
|
||||
group.destroy()
|
||||
return
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function Public.validate_swarms()
|
||||
local ffatable = Table.get_table()
|
||||
for k, swarm in pairs(ffatable.swarms) do
|
||||
if not is_swarm_valid(swarm) then
|
||||
table_remove(ffatable.swarms, k)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Public.unit_groups_start_moving()
|
||||
local ffatable = Table.get_table()
|
||||
for _, swarm in pairs(ffatable.swarms) do
|
||||
if swarm.group then
|
||||
if swarm.group.valid then
|
||||
swarm.group.start_moving()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Public.swarm(town_center, radius)
|
||||
if town_center == nil then return end
|
||||
local ffatable = Table.get_table()
|
||||
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 return end
|
||||
|
||||
-- skip if we have to many swarms already
|
||||
local count = table_size(ffatable.swarms)
|
||||
local towns = table_size(ffatable.town_centers)
|
||||
if count > 3 * towns then return end
|
||||
|
||||
local market = tc.market
|
||||
local surface = market.surface
|
||||
|
||||
-- find a spawner
|
||||
local spawner = get_random_close_spawner(surface, market, r)
|
||||
if not spawner then
|
||||
r = r + 16
|
||||
local future = game.tick + 1
|
||||
-- schedule to run this method again with a higher radius on next tick
|
||||
if not tick_schedule[future] then tick_schedule[future] = {} end
|
||||
tick_schedule[future][#tick_schedule[future] + 1] = {
|
||||
callback = 'swarm',
|
||||
params = { tc, r }
|
||||
}
|
||||
return
|
||||
end
|
||||
|
||||
-- get our evolution
|
||||
local evolution = 0
|
||||
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
|
||||
local count2 = (evolution * 124) + 4
|
||||
|
||||
local units = spawner.surface.find_enemy_units(spawner.position, 16, market.force)
|
||||
if #units < count2 then
|
||||
units = spawner.surface.find_enemy_units(spawner.position, 32, market.force)
|
||||
end
|
||||
if #units < count2 then
|
||||
units = spawner.surface.find_enemy_units(spawner.position, 64, market.force)
|
||||
end
|
||||
if #units < count2 then
|
||||
units = spawner.surface.find_enemy_units(spawner.position, 128, market.force)
|
||||
end
|
||||
if not units[1] then return end
|
||||
|
||||
local unit_group_position = surface.find_non_colliding_position("biter-spawner", units[1].position, 256, 1)
|
||||
if not unit_group_position then return end
|
||||
local unit_group = surface.create_unit_group({ position = unit_group_position, force = units[1].force })
|
||||
|
||||
for key, unit in pairs(units) do
|
||||
if key > count2 then break end
|
||||
unit_group.add_member(unit)
|
||||
end
|
||||
|
||||
unit_group.set_command({
|
||||
type = defines.command.compound,
|
||||
structure_type = defines.compound_command.return_last,
|
||||
commands = get_commmands(market, unit_group)
|
||||
})
|
||||
table_insert(ffatable.swarms, { group = unit_group, timeout = game.tick + 36000 })
|
||||
end
|
||||
|
||||
local function on_tick()
|
||||
if not tick_schedule[game.tick] then return end
|
||||
for _, token in pairs(tick_schedule[game.tick]) do
|
||||
local callback = token.callback
|
||||
local params = token.params
|
||||
if callback == 'swarm' then Public.swarm(params[1], params[2]) end
|
||||
end
|
||||
tick_schedule[game.tick] = nil
|
||||
end
|
||||
|
||||
local on_init = function ()
|
||||
local ffatable = Table.get_table()
|
||||
ffatable.swarms = {}
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.on_init(on_init)
|
||||
Event.add(defines.events.on_tick, on_tick)
|
||||
|
||||
return Public
|
269
modules/scrap_towny_ffa/building.lua
Normal file
269
modules/scrap_towny_ffa/building.lua
Normal file
@ -0,0 +1,269 @@
|
||||
local Public = {}
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
|
||||
local town_radius = 27
|
||||
local connection_radius = 7
|
||||
|
||||
local neutral_whitelist = {
|
||||
["wooden-chest"] = true,
|
||||
["iron-chest"] = true,
|
||||
["steel-chest"] = true,
|
||||
["raw-fish"] = true,
|
||||
}
|
||||
|
||||
local entity_type_whitelist = {
|
||||
["accumulator"] = true,
|
||||
["ammo-turret"] = true,
|
||||
["arithmetic-combinator"] = true,
|
||||
["artillery-turret"] = true,
|
||||
["assembling-machine"] = true,
|
||||
["boiler"] = true,
|
||||
["constant-combinator"] = true,
|
||||
["container"] = true,
|
||||
["curved-rail"] = true,
|
||||
["decider-combinator"] = true,
|
||||
["electric-pole"] = true,
|
||||
["electric-turret"] = true,
|
||||
["fluid-turret"] = true,
|
||||
["furnace"] = true,
|
||||
["gate"] = true,
|
||||
["generator"] = true,
|
||||
["heat-interface"] = true,
|
||||
["heat-pipe"] = true,
|
||||
["infinity-container"] = true,
|
||||
["infinity-pipe"] = true,
|
||||
["inserter"] = true,
|
||||
["lab"] = true,
|
||||
["lamp"] = true,
|
||||
["land-mine"] = true,
|
||||
["loader"] = true,
|
||||
["logistic-container"] = true,
|
||||
["market"] = true,
|
||||
["mining-drill"] = true,
|
||||
["offshore-pump"] = true,
|
||||
["pipe"] = true,
|
||||
["pipe-to-ground"] = 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,
|
||||
}
|
||||
|
||||
local function isolated(surface, force, position)
|
||||
local position_x = position.x
|
||||
local position_y = position.y
|
||||
local area = { { position_x - connection_radius, position_y - connection_radius }, { position_x + connection_radius, position_y + connection_radius } }
|
||||
local count = 0
|
||||
|
||||
for _, e in pairs(surface.find_entities_filtered({ area = area, force = force.name })) do
|
||||
if entity_type_whitelist[e.type] then
|
||||
count = count + 1
|
||||
if count > 1 then return false end -- are there more than one team entities in the area?
|
||||
end
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
local function refund_item(event, item_name)
|
||||
if item_name == "blueprint" then return end
|
||||
if event.player_index then
|
||||
game.players[event.player_index].insert({ name = item_name, count = 1 })
|
||||
return
|
||||
end
|
||||
|
||||
if event.robot then
|
||||
local inventory = event.robot.get_inventory(defines.inventory.robot_cargo)
|
||||
inventory.insert({ name = item_name, count = 1 })
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local function error_floaty(surface, position, msg)
|
||||
surface.create_entity({
|
||||
name = "flying-text",
|
||||
position = position,
|
||||
text = msg,
|
||||
color = { r = 0.77, g = 0.0, b = 0.0 }
|
||||
})
|
||||
end
|
||||
|
||||
local function in_range(pos1, pos2, radius)
|
||||
if pos1 == nil then return false end
|
||||
if pos2 == nil then return false end
|
||||
if radius < 1 then return true end
|
||||
local dx = pos1.x - pos2.x
|
||||
local dy = pos1.y - pos2.y
|
||||
if dx ^ 2 + dy ^ 2 < radius ^ 2 then
|
||||
return true
|
||||
end
|
||||
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
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function in_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
|
||||
end
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function prevent_isolation_entity(event, player)
|
||||
local p = player 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 return end
|
||||
local surface = entity.surface
|
||||
local error = false
|
||||
if not in_town(force, position) and isolated(surface, force, position) then
|
||||
error = true
|
||||
entity.destroy()
|
||||
if entity_name ~= "entity-ghost" and entity_name ~= "tile-ghost" 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 })
|
||||
end
|
||||
error_floaty(surface, position, "Building is not connected to town!")
|
||||
end
|
||||
end
|
||||
|
||||
local function prevent_isolation_tile(event, player)
|
||||
local p = player or nil
|
||||
local tile = event.tile
|
||||
if 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
|
||||
else
|
||||
force = event.robot.force
|
||||
end
|
||||
local error = 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" end
|
||||
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 })
|
||||
end
|
||||
error_floaty(surface, position, "Tile is not connected to town!")
|
||||
end
|
||||
end
|
||||
|
||||
local function restrictions(event, player)
|
||||
local p = player or nil
|
||||
local entity = event.created_entity
|
||||
if not entity.valid then return end
|
||||
local entity_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
|
||||
entity.destroy()
|
||||
if entity_name ~= "entity-ghost" then
|
||||
refund_item(event, event.stack.name)
|
||||
end
|
||||
else
|
||||
entity.force = game.forces["neutral"]
|
||||
end
|
||||
return
|
||||
end
|
||||
if error == true then
|
||||
if p ~= nil then
|
||||
p.play_sound({ path = "utility/cannot_build", position = p.position, volume_modifier = 0.75 })
|
||||
end
|
||||
error_floaty(surface, position, "Can't build near town!")
|
||||
end
|
||||
|
||||
if not neutral_whitelist[entity.type] then return 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 return end
|
||||
restrictions(event, player)
|
||||
end
|
||||
|
||||
local function on_robot_built_entity(event)
|
||||
if prevent_isolation_entity(event) then return end
|
||||
restrictions(event)
|
||||
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)
|
||||
end
|
||||
|
||||
local function on_robot_built_tile(event)
|
||||
prevent_isolation_tile(event)
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
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)
|
||||
|
||||
return Public
|
50
modules/scrap_towny_ffa/combat_balance.lua
Normal file
50
modules/scrap_towny_ffa/combat_balance.lua
Normal file
@ -0,0 +1,50 @@
|
||||
local string_sub = string.sub
|
||||
local string_len = string.len
|
||||
|
||||
-- ammo damage modifiers are static values that increase with research
|
||||
-- modifier is multiplied by base damage and then added to damage, so a negative value will reduce base damage and a positive value will increase damage
|
||||
local balance_functions = {
|
||||
["land-mine"] = function(force_name)
|
||||
-- landmines normally have a modifier of 0, so have them start at 25% of normal
|
||||
if force_name ~= nil then
|
||||
game.forces[force_name].set_ammo_damage_modifier("landmine", -0.75)
|
||||
end
|
||||
end,
|
||||
["military-2"] = function(force_name)
|
||||
-- grenades normally have a modifier of 0, so have them start at 50% of normal
|
||||
if force_name ~= nil then
|
||||
game.forces[force_name].set_ammo_damage_modifier("grenade", -0.5)
|
||||
end
|
||||
end,
|
||||
["military-4"] = function(force_name)
|
||||
-- cluster-grenades normally have a modifier of 0, so have them start at 50% of normal
|
||||
if force_name ~= nil then
|
||||
game.forces[force_name].set_ammo_damage_modifier("grenade", -0.5)
|
||||
end
|
||||
end,
|
||||
["stronger-explosives"] = function(force_name)
|
||||
-- landmines should never increase in damage with stronger explosives
|
||||
if force_name ~= nil then
|
||||
game.forces[force_name].set_ammo_damage_modifier("landmine", -0.75)
|
||||
-- allow grenades to increase by 10%
|
||||
game.forces[force_name].set_ammo_damage_modifier("grenade", game.forces[force_name].get_ammo_damage_modifier("grenade") + 0.1)
|
||||
end
|
||||
end,
|
||||
}
|
||||
|
||||
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)
|
||||
if balance_functions[key] then
|
||||
balance_functions[key](force_name)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.add(defines.events.on_research_finished, on_research_finished)
|
||||
|
63
modules/scrap_towny_ffa/enemy.lua
Normal file
63
modules/scrap_towny_ffa/enemy.lua
Normal file
@ -0,0 +1,63 @@
|
||||
local Public = {}
|
||||
|
||||
function Public.clear_enemies(position, surface, radius)
|
||||
--log("clear_enemies {" .. position.x .. "," .. position.y .. "}")
|
||||
-- clear enemies
|
||||
for _, e in pairs(surface.find_entities_filtered({ force = "enemy", type = { "unit-spawner", "unit", "turret" }, position = position, radius = radius })) do
|
||||
e.destroy()
|
||||
end
|
||||
-- clear gun turrets
|
||||
for _, e in pairs(surface.find_entities_filtered({ force = "enemy", name = { "gun-turret" }, position = position, radius = radius })) do
|
||||
e.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
function Public.clear_units(position, surface, radius)
|
||||
--log("clear_units {" .. position.x .. "," .. position.y .. "}")
|
||||
-- clear units
|
||||
for _, e in pairs(surface.find_entities_filtered({ force = "enemy", type = { "unit" }, position = position, radius = radius })) do
|
||||
e.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
function Public.clear_biters(position, surface, radius)
|
||||
--log("clear_units {" .. position.x .. "," .. position.y .. "}")
|
||||
-- clear biters
|
||||
for _, e in pairs(surface.find_entities_filtered({ force = "enemy", name = { "small-biter", "medium-biter", "big-biter", "behemoth-biter" }, position = position, radius = radius })) do
|
||||
e.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
function Public.clear_spitters(position, surface, radius)
|
||||
--log("clear_units {" .. position.x .. "," .. position.y .. "}")
|
||||
-- clear spitters
|
||||
for _, e in pairs(surface.find_entities_filtered({ force = "enemy", name = { "small-spitter", "medium-spitter", "big-spitter", "behemoth-spitter" }, position = position, radius = radius })) do
|
||||
e.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
function Public.clear_nests(position, surface, radius)
|
||||
--log("clear_unit_spawners {" .. position.x .. "," .. position.y .. "}")
|
||||
-- clear enemies
|
||||
for _, e in pairs(surface.find_entities_filtered({ force = "enemy", type = { "unit-spawner" }, position = position, radius = radius })) do
|
||||
e.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
function Public.clear_worms(position, surface, radius)
|
||||
--log("clear_turrets {" .. position.x .. "," .. position.y .. "}")
|
||||
-- clear enemies
|
||||
for _, e in pairs(surface.find_entities_filtered({ force = "enemy", type = { "turret" }, position = position, radius = radius })) do
|
||||
e.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
function Public.clear_gun_turrets(position, surface, radius)
|
||||
--log("clear_gun_turrets {" .. position.x .. "," .. position.y .. "}")
|
||||
-- clear gun turrets
|
||||
for _, e in pairs(surface.find_entities_filtered({ force = "enemy", name = { "gun-turret" }, position = position, radius = radius })) do
|
||||
e.destroy()
|
||||
end
|
||||
end
|
||||
|
||||
return Public
|
585
modules/scrap_towny_ffa/evolution.lua
Normal file
585
modules/scrap_towny_ffa/evolution.lua
Normal file
@ -0,0 +1,585 @@
|
||||
local Public = {}
|
||||
local math_floor = math.floor
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
|
||||
local biters = {
|
||||
[1] = "small-biter",
|
||||
[2] = "medium-biter",
|
||||
[3] = "big-biter",
|
||||
[4] = "behemoth-biter"
|
||||
}
|
||||
|
||||
local spitters = {
|
||||
[1] = "small-spitter",
|
||||
[2] = "medium-spitter",
|
||||
[3] = "big-spitter",
|
||||
[4] = "behemoth-spitter"
|
||||
}
|
||||
|
||||
local worms = {
|
||||
[1] = "small-worm-turret",
|
||||
[2] = "medium-worm-turret",
|
||||
[3] = "big-worm-turret",
|
||||
[4] = "behemoth-worm-turret"
|
||||
}
|
||||
|
||||
-- evolution max distance in tiles
|
||||
local max_evolution_distance = 1024
|
||||
local max_pollution_behemoth = 256
|
||||
local max_pollution_big = 64
|
||||
local max_pollution_medium = 16
|
||||
local max_factor = 0.8
|
||||
|
||||
-- technology weights (biter, spitter, worm)
|
||||
local technology_weights = {
|
||||
['advanced-electronics'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['advanced-electronics-2'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['advanced-material-processing'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['advanced-material-processing-2'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['advanced-oil-processing'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['artillery']={biter=1, spitter=1, worm=1},
|
||||
['artillery-shell-range-1']={biter=1, spitter=1, worm=1},
|
||||
['artillery-shell-speed-1']={biter=1, spitter=1, worm=1},
|
||||
['atomic-bomb']={biter=1, spitter=1, worm=1},
|
||||
['automated-rail-transportation'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['automation'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['automation-2'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['automation-3'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['automobilism'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['battery'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['battery-equipment'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['battery-mk2-equipment'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['belt-immunity-equipment'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['braking-force-1'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['braking-force-2'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['braking-force-3'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['braking-force-4'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['braking-force-5'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['braking-force-6'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['braking-force-7'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['chemical-science-pack'] = { biter = 125, spitter = 125, worm = 125 },
|
||||
['circuit-network'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['cliff-explosives'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['coal-liquefaction'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['concrete'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['construction-robotics'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['defender'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['destroyer'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['discharge-defense-equipment'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['distractor'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['effect-transmission'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['effectivity-module'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['effectivity-module-2'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['effectivity-module-3'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['electric-energy-accumulators'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['electric-energy-distribution-1'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['electric-energy-distribution-2'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['electric-engine'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['electronics'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['energy-shield-equipment'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['energy-shield-mk2-equipment'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['energy-weapons-damage-1'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['energy-weapons-damage-2'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['energy-weapons-damage-3'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['energy-weapons-damage-4'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['energy-weapons-damage-5'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['energy-weapons-damage-6'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['energy-weapons-damage-7'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['engine'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['exoskeleton-equipment'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['explosive-rocketry']={biter=1, spitter=1, worm=1},
|
||||
['explosives'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['fast-inserter'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['flamethrower'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['flammables'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['fluid-handling'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['fluid-wagon'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['follower-robot-count-1'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['follower-robot-count-2'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['follower-robot-count-3'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['follower-robot-count-4'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['follower-robot-count-5'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['follower-robot-count-6'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['follower-robot-count-7'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['fusion-reactor-equipment'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['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 },
|
||||
['inserter-capacity-bonus-5'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['inserter-capacity-bonus-6'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['inserter-capacity-bonus-7'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['kovarex-enrichment-process'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['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-turret'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['logistic-robotics'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['logistic-science-pack'] = { biter = 25, spitter = 25, worm = 25 },
|
||||
['logistic-system'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['logistics'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['logistics-2'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['logistics-3'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['low-density-structure'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['lubricant'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['military'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['military-2'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['military-3'] = { biter = 5, spitter = 5, worm = 51 },
|
||||
['military-4'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['military-science-pack'] = { biter = 50, spitter = 50, worm = 50 },
|
||||
['mining-productivity-1'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['mining-productivity-2'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['mining-productivity-3'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['mining-productivity-4'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['modular-armor'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['modules'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['night-vision-equipment'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['nuclear-fuel-reprocessing'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['nuclear-power'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['oil-processing'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['optics'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['personal-laser-defense-equipment'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['personal-roboport-equipment'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['personal-roboport-mk2-equipment'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['physical-projectile-damage-1'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['physical-projectile-damage-2'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['physical-projectile-damage-3'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['physical-projectile-damage-4'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['physical-projectile-damage-5'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['physical-projectile-damage-6'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['physical-projectile-damage-7'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['plastics'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['power-armor'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['power-armor-mk2'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['production-science-pack'] = { biter = 250, spitter = 250, worm = 250 },
|
||||
['productivity-module'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['productivity-module-2'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['productivity-module-3'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['rail-signals'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['railway'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['refined-flammables-1'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['refined-flammables-2'] = { biter = 5, spitter = 5, worm = 51 },
|
||||
['refined-flammables-3'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['refined-flammables-4'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['refined-flammables-5'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['refined-flammables-6'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['refined-flammables-7'] = { biter = 5, spitter = 5, worm = 51 },
|
||||
['research-speed-1'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['research-speed-2'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['research-speed-3'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['research-speed-4'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['research-speed-5'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['research-speed-6'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['robotics'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['rocket-control-unit'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['rocket-fuel'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['rocket-silo'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['rocketry']={biter=1, spitter=1, worm=1},
|
||||
['solar-energy'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['solar-panel-equipment'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['space-science-pack'] = { biter = 1000, spitter = 1000, worm = 1000 },
|
||||
['speed-module'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['speed-module-2'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['speed-module-3'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['spidertron'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['stack-inserter'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['steel-axe'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['steel-processing'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['stone-wall'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['stronger-explosives-1'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['stronger-explosives-2'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['stronger-explosives-3'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['stronger-explosives-4'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['stronger-explosives-5'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['stronger-explosives-6'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['stronger-explosives-7'] = { biter = 5, spitter = 5, worm = 51 },
|
||||
['sulfur-processing'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['tank'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['toolbelt'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['uranium-ammo'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['uranium-processing'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['utility-science-pack'] = { biter = 500, spitter = 500, worm = 500 },
|
||||
['weapon-shooting-speed-1'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['weapon-shooting-speed-2'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['weapon-shooting-speed-3'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['weapon-shooting-speed-4'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['weapon-shooting-speed-5'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['weapon-shooting-speed-6'] = { biter = 5, spitter = 5, worm = 5 },
|
||||
['worker-robots-speed-1'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['worker-robots-speed-2'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['worker-robots-speed-3'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['worker-robots-speed-4'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['worker-robots-speed-5'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['worker-robots-speed-6'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['worker-robots-storage-1'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['worker-robots-storage-2'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
['worker-robots-storage-3'] = { biter = 1, spitter = 1, worm = 1 },
|
||||
}
|
||||
|
||||
local max_biter_weight = 0
|
||||
local max_spitter_weight = 0
|
||||
local max_worm_weight = 0
|
||||
for _, weight in pairs(technology_weights) do
|
||||
max_biter_weight = max_biter_weight + weight.biter
|
||||
max_spitter_weight = max_spitter_weight + weight.spitter
|
||||
max_worm_weight = max_worm_weight + weight.worm
|
||||
end
|
||||
max_biter_weight = max_biter_weight * max_factor
|
||||
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
|
||||
|
||||
-- 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%
|
||||
-- and curve accordingly in between evo values
|
||||
|
||||
-- magic stuff happens here
|
||||
if (evolution < 0.10) 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 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
|
||||
return 1
|
||||
else
|
||||
if math.random() < r then return 1 else return 2 end
|
||||
end
|
||||
else
|
||||
if math.random() < r then return 2 else return 3 end
|
||||
end
|
||||
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
|
||||
else return 3 end
|
||||
else return 4 end
|
||||
end
|
||||
if (evolution >= 1.0) then return 4 end
|
||||
end
|
||||
|
||||
local function distance_squared(pos1, pos2)
|
||||
-- calculate the distance squared
|
||||
local dx = pos1.x - pos2.x
|
||||
local dy = pos1.y - pos2.y
|
||||
local d2 = dx * dx + dy * dy
|
||||
return d2
|
||||
end
|
||||
|
||||
local function get_relative_biter_evolution(position)
|
||||
local ffatable = Table.get_table()
|
||||
local relative_evolution = 0.0
|
||||
local max_d2 = max_evolution_distance * max_evolution_distance
|
||||
-- for all of the teams
|
||||
local teams = ffatable.town_centers
|
||||
for _, town_center in pairs(teams) do
|
||||
local market_position = town_center.market.position
|
||||
-- calculate the distance squared
|
||||
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;
|
||||
-- get the evolution factor (0.0-1.0)
|
||||
if not town_center.evolution then town_center.evolution = {} end
|
||||
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
|
||||
relative_evolution = math.max(relative_evolution, evo)
|
||||
end
|
||||
end
|
||||
return relative_evolution
|
||||
end
|
||||
|
||||
local function get_relative_spitter_evolution(position)
|
||||
local ffatable = Table.get_table()
|
||||
local relative_evolution = 0.0
|
||||
local max_d2 = max_evolution_distance * max_evolution_distance
|
||||
-- for all of the teams
|
||||
local teams = ffatable.town_centers
|
||||
for _, town_center in pairs(teams) do
|
||||
local market_position = town_center.market.position
|
||||
-- calculate the distance squared
|
||||
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;
|
||||
-- get the evolution factor (0.0-1.0)
|
||||
if not town_center.evolution then town_center.evolution = {} end
|
||||
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
|
||||
relative_evolution = math.max(relative_evolution, evo)
|
||||
end
|
||||
end
|
||||
return relative_evolution
|
||||
end
|
||||
|
||||
local function get_relative_worm_evolution(position)
|
||||
local ffatable = Table.get_table()
|
||||
local relative_evolution = 0.0
|
||||
local max_d2 = max_evolution_distance * max_evolution_distance
|
||||
-- for all of the teams
|
||||
local teams = ffatable.town_centers
|
||||
for _, town_center in pairs(teams) do
|
||||
local market_position = town_center.market.position
|
||||
-- calculate the distance squared
|
||||
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;
|
||||
-- get the evolution factor (0.0-1.0)
|
||||
if not town_center.evolution then town_center.evolution = {} end
|
||||
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
|
||||
relative_evolution = math.max(relative_evolution, evo)
|
||||
end
|
||||
end
|
||||
return relative_evolution
|
||||
end
|
||||
|
||||
function Public.get_evolution(position)
|
||||
return get_relative_biter_evolution(position)
|
||||
end
|
||||
|
||||
function Public.get_biter_evolution(entity)
|
||||
return get_relative_biter_evolution(entity.position)
|
||||
end
|
||||
|
||||
function Public.get_spitter_evolution(entity)
|
||||
return get_relative_spitter_evolution(entity.position)
|
||||
end
|
||||
|
||||
function Public.get_worm_evolution(entity)
|
||||
return get_relative_worm_evolution(entity.position)
|
||||
end
|
||||
|
||||
local function get_nearby_location(position, surface, radius, entity_name)
|
||||
return surface.find_non_colliding_position(entity_name, position, radius, 0.5, false)
|
||||
end
|
||||
|
||||
local function set_biter_type(entity)
|
||||
-- checks nearby evolution levels for bases and returns an appropriately leveled type
|
||||
local position = entity.position
|
||||
local evo = get_relative_biter_evolution(position)
|
||||
local unit_size = get_unit_size(evo)
|
||||
local entity_name = biters[unit_size]
|
||||
if entity.name == entity_name then return end
|
||||
local surface = entity.surface
|
||||
local pollution = surface.get_pollution(position)
|
||||
local behemoth = math_floor(pollution / max_pollution_behemoth)
|
||||
local big = math_floor((pollution - (behemoth * max_pollution_behemoth)) / max_pollution_big)
|
||||
local medium = math_floor((pollution - (behemoth * max_pollution_behemoth) - (big * max_pollution_big)) / max_pollution_medium)
|
||||
local small = pollution - (behemoth * max_pollution_behemoth) - (big * max_pollution_big) - (medium * max_pollution_medium) + 1
|
||||
|
||||
if entity.valid then
|
||||
for _ = 1, behemoth do
|
||||
local e = surface.create_entity({ name = biters[4], position = get_nearby_location(position, surface, 5, biters[4]) })
|
||||
e.copy_settings(entity);
|
||||
e.ai_settings.allow_try_return_to_spawner = true
|
||||
end
|
||||
for _ = 1, big do
|
||||
local e = surface.create_entity({ name = biters[3], position = get_nearby_location(position, surface, 5, biters[3]) })
|
||||
e.copy_settings(entity);
|
||||
e.ai_settings.allow_try_return_to_spawner = true
|
||||
end
|
||||
for _ = 1, medium do
|
||||
local e = surface.create_entity({ name = biters[2], position = get_nearby_location(position, surface, 5, biters[2]) })
|
||||
e.copy_settings(entity);
|
||||
e.ai_settings.allow_try_return_to_spawner = true
|
||||
end
|
||||
for _ = 1, small do
|
||||
local e = surface.create_entity({ name = biters[1], position = get_nearby_location(position, surface, 5, biters[1]) })
|
||||
e.copy_settings(entity);
|
||||
e.ai_settings.allow_try_return_to_spawner = true
|
||||
end
|
||||
local e = surface.create_entity({ name = entity_name, position = get_nearby_location(position, surface, 5, entity_name) })
|
||||
e.copy_settings(entity);
|
||||
e.ai_settings.allow_try_return_to_spawner = true
|
||||
entity.destroy()
|
||||
--log("spawned " .. entity_name)
|
||||
end
|
||||
end
|
||||
|
||||
local function set_spitter_type(entity)
|
||||
-- checks nearby evolution levels for bases and returns an appropriately leveled type
|
||||
local position = entity.position
|
||||
local evo = get_relative_spitter_evolution(position)
|
||||
local unit_size = get_unit_size(evo)
|
||||
local entity_name = spitters[unit_size]
|
||||
if entity.name == entity_name then return end
|
||||
local surface = entity.surface
|
||||
local pollution = surface.get_pollution(position)
|
||||
local behemoth = math_floor(pollution / max_pollution_behemoth)
|
||||
local big = math_floor((pollution - (behemoth * max_pollution_behemoth)) / max_pollution_big)
|
||||
local medium = math_floor((pollution - (behemoth * max_pollution_behemoth) - (big * max_pollution_big)) / max_pollution_medium)
|
||||
local small = pollution - (behemoth * max_pollution_behemoth) - (big * max_pollution_big) - (medium * max_pollution_medium) + 1
|
||||
|
||||
if entity.valid then
|
||||
for _ = 1, behemoth do
|
||||
local e = surface.create_entity({ name = spitters[4], position = get_nearby_location(position, surface, 5, spitters[4]) })
|
||||
e.copy_settings(entity);
|
||||
e.ai_settings.allow_try_return_to_spawner = true
|
||||
end
|
||||
for _ = 1, big do
|
||||
local e = surface.create_entity({ name = spitters[3], position = get_nearby_location(position, surface, 5, spitters[3]) })
|
||||
e.copy_settings(entity);
|
||||
e.ai_settings.allow_try_return_to_spawner = true
|
||||
end
|
||||
for _ = 1, medium do
|
||||
local e = surface.create_entity({ name = spitters[2], position = get_nearby_location(position, surface, 5, spitters[2]) })
|
||||
e.copy_settings(entity);
|
||||
e.ai_settings.allow_try_return_to_spawner = true
|
||||
end
|
||||
for _ = 1, small do
|
||||
local e = surface.create_entity({ name = spitters[1], position = get_nearby_location(position, surface, 5, spitters[1]) })
|
||||
e.copy_settings(entity);
|
||||
e.ai_settings.allow_try_return_to_spawner = true
|
||||
end
|
||||
local e = surface.create_entity({ name = entity_name, position = get_nearby_location(position, surface, 5, entity_name) })
|
||||
e.copy_settings(entity);
|
||||
e.ai_settings.allow_try_return_to_spawner = true
|
||||
entity.destroy()
|
||||
--log("spawned " .. entity_name)
|
||||
end
|
||||
end
|
||||
|
||||
local function set_worm_type(entity)
|
||||
-- checks nearby evolution levels for bases and returns an appropriately leveled type
|
||||
local position = entity.position
|
||||
local evo = get_relative_worm_evolution(position)
|
||||
local unit_size = get_unit_size(evo)
|
||||
local entity_name = worms[unit_size]
|
||||
if entity.name == entity_name then return end
|
||||
local surface = entity.surface
|
||||
if entity.valid then
|
||||
entity.destroy()
|
||||
surface.create_entity({ name = entity_name, position = position })
|
||||
--log("spawned " .. entity_name)
|
||||
end
|
||||
end
|
||||
|
||||
local function is_biter(entity)
|
||||
if entity == nil or not entity.valid then return false end
|
||||
if entity.name == 'small-biter' or entity.name == 'medium-biter' or entity.name == 'big-biter' or entity.name == 'behemoth-biter' then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function is_spitter(entity)
|
||||
if entity == nil or not entity.valid then return false end
|
||||
if entity.name == 'small-spitter' or entity.name == 'medium-spitter' or entity.name == 'big-spitter' or entity.name == 'behemoth-spitter' then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function is_worm(entity)
|
||||
if entity == nil or not entity.valid then return false end
|
||||
if entity.name == 'small-worm-turret' or entity.name == 'medium-worm-turret' or entity.name == 'big-worm-turret' or entity.name == 'behemoth-worm-turret' then
|
||||
return true
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
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 return end
|
||||
-- initialize if not already
|
||||
local evo = town_center.evolution
|
||||
-- get the weights for this technology
|
||||
local weight = technology_weights[technology]
|
||||
if weight == nil then
|
||||
log("no technology_weights for " .. technology)
|
||||
return
|
||||
end
|
||||
local biter_weight = weight.biter
|
||||
local spitter_weight = weight.spitter
|
||||
local worm_weight = weight.worm
|
||||
-- update the evolution values (0.0 to 1.0)
|
||||
local b = (biter_weight / max_biter_weight)
|
||||
local s = (spitter_weight / max_spitter_weight)
|
||||
local w = (worm_weight / max_worm_weight)
|
||||
b = b + evo.biters
|
||||
s = s + evo.spitters
|
||||
w = w + evo.worms
|
||||
evo.biters = b
|
||||
evo.spitters = s
|
||||
evo.worms = w
|
||||
end
|
||||
|
||||
local function on_research_finished(event)
|
||||
local research = event.research
|
||||
local force_name = research.force.name
|
||||
local technology = research.name
|
||||
update_evolution(force_name, technology)
|
||||
end
|
||||
|
||||
local function on_entity_spawned(event)
|
||||
local entity = event.entity
|
||||
-- check the unit type and handle appropriately
|
||||
if is_biter(entity) then
|
||||
set_biter_type(entity)
|
||||
end
|
||||
if is_spitter(entity) then
|
||||
set_spitter_type(entity)
|
||||
end
|
||||
if is_worm(entity) then
|
||||
set_worm_type(entity)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_biter_base_built(event)
|
||||
local entity = event.entity
|
||||
if is_worm(entity) then
|
||||
set_worm_type(entity)
|
||||
end
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.add(defines.events.on_research_finished, on_research_finished)
|
||||
Event.add(defines.events.on_entity_spawned, on_entity_spawned)
|
||||
Event.add(defines.events.on_biter_base_built, on_biter_base_built)
|
||||
|
||||
return Public
|
228
modules/scrap_towny_ffa/explosives_are_explosive.lua
Normal file
228
modules/scrap_towny_ffa/explosives_are_explosive.lua
Normal file
@ -0,0 +1,228 @@
|
||||
--This will add a new game mechanic so that containers with explosives actually go boom when they get damaged.
|
||||
--Made by MewMew
|
||||
local math_min = math.min
|
||||
local math_random = math.random
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
local Pollution = require "modules.scrap_towny_ffa.pollution"
|
||||
|
||||
--local damage_per_explosive = 100
|
||||
local damage_per_explosive = 50
|
||||
local empty_tile_damage_decay = 100
|
||||
local out_of_map_tile_health = 1500
|
||||
local max_volatility = 20
|
||||
|
||||
local explosive_items = {
|
||||
["explosives"] = 1,
|
||||
["land-mine"] = 1,
|
||||
["grenade"] = 1,
|
||||
["cluster-grenade"] = 3,
|
||||
["artillery-shell"] = 5,
|
||||
["cannon-shell"] = 3,
|
||||
["explosive-cannon-shell"] = 5,
|
||||
["explosive-uranium-cannon-shell"] = 5,
|
||||
["uranium-cannon-shell"] = 5,
|
||||
-- ["atomic-bomb"] = 100,
|
||||
["explosive-rocket"] = 5,
|
||||
["rocket"] = 2,
|
||||
["flamethrower-ammo"] = 2,
|
||||
["petroleum-gas-barrel"] = 2,
|
||||
-- ["crude-oil-barrel"] = 2,
|
||||
-- ["light-oil-barrel"] = 2,
|
||||
-- ["heavy-oil-barrel"] = 2,
|
||||
-- ["lubricant-barrel"] = 1,
|
||||
-- ["shotgun-shell"] = 1,
|
||||
-- ["piercing-shotgun-shell"] = 1,
|
||||
-- ["firearm-magazine"] = 1,
|
||||
-- ["piercing-rounds-magazine"] = 1,
|
||||
-- ["uranium-rounds-magazine"] = 1,
|
||||
["cliff-explosives"] = 2,
|
||||
-- ["solid-fuel"] = 1
|
||||
}
|
||||
|
||||
local circle_coordinates = {
|
||||
[1] = { { x = 0, y = 0 } },
|
||||
[2] = { { x = -1, y = -1 }, { x = 1, y = -1 }, { x = 0, y = -1 }, { x = -1, y = 0 }, { x = -1, y = 1 }, { x = 0, y = 1 }, { x = 1, y = 1 }, { x = 1, y = 0 } },
|
||||
[3] = { { x = -2, y = -1 }, { x = -1, y = -2 }, { x = 1, y = -2 }, { x = 0, y = -2 }, { x = 2, y = -1 }, { x = -2, y = 1 }, { x = -2, y = 0 }, { x = 2, y = 1 }, { x = 2, y = 0 }, { x = -1, y = 2 }, { x = 1, y = 2 }, { x = 0, y = 2 } },
|
||||
[4] = { { x = -1, y = -3 }, { x = 1, y = -3 }, { x = 0, y = -3 }, { x = -3, y = -1 }, { x = -2, y = -2 }, { x = 3, y = -1 }, { x = 2, y = -2 }, { x = -3, y = 0 }, { x = -3, y = 1 }, { x = 3, y = 1 }, { x = 3, y = 0 }, { x = -2, y = 2 }, { x = -1, y = 3 }, { x = 0, y = 3 }, { x = 1, y = 3 }, { x = 2, y = 2 } },
|
||||
[5] = { { x = -3, y = -3 }, { x = -2, y = -3 }, { x = -1, y = -4 }, { x = -2, y = -4 }, { x = 1, y = -4 }, { x = 0, y = -4 }, { x = 2, y = -3 }, { x = 3, y = -3 }, { x = 2, y = -4 }, { x = -3, y = -2 }, { x = -4, y = -1 }, { x = -4, y = -2 }, { x = 3, y = -2 }, { x = 4, y = -1 }, { x = 4, y = -2 }, { x = -4, y = 1 }, { x = -4, y = 0 }, { x = 4, y = 1 }, { x = 4, y = 0 }, { x = -3, y = 3 }, { x = -3, y = 2 }, { x = -4, y = 2 }, { x = -2, y = 3 }, { x = 2, y = 3 }, { x = 3, y = 3 }, { x = 3, y = 2 }, { x = 4, y = 2 }, { x = -2, y = 4 }, { x = -1, y = 4 }, { x = 0, y = 4 }, { x = 1, y = 4 }, { x = 2, y = 4 } },
|
||||
[6] = { { x = -1, y = -5 }, { x = -2, y = -5 }, { x = 1, y = -5 }, { x = 0, y = -5 }, { x = 2, y = -5 }, { x = -3, y = -4 }, { x = -4, y = -3 }, { x = 3, y = -4 }, { x = 4, y = -3 }, { x = -5, y = -1 }, { x = -5, y = -2 }, { x = 5, y = -1 }, { x = 5, y = -2 }, { x = -5, y = 1 }, { x = -5, y = 0 }, { x = 5, y = 1 }, { x = 5, y = 0 }, { x = -5, y = 2 }, { x = -4, y = 3 }, { x = 4, y = 3 }, { x = 5, y = 2 }, { x = -3, y = 4 }, { x = -2, y = 5 }, { x = -1, y = 5 }, { x = 0, y = 5 }, { x = 1, y = 5 }, { x = 3, y = 4 }, { x = 2, y = 5 } },
|
||||
[7] = { { x = -4, y = -5 }, { x = -3, y = -5 }, { x = -2, y = -6 }, { x = -1, y = -6 }, { x = 0, y = -6 }, { x = 1, y = -6 }, { x = 3, y = -5 }, { x = 2, y = -6 }, { x = 4, y = -5 }, { x = -5, y = -4 }, { x = -5, y = -3 }, { x = -4, y = -4 }, { x = 4, y = -4 }, { x = 5, y = -4 }, { x = 5, y = -3 }, { x = -6, y = -1 }, { x = -6, y = -2 }, { x = 6, y = -1 }, { x = 6, y = -2 }, { x = -6, y = 1 }, { x = -6, y = 0 }, { x = 6, y = 1 }, { x = 6, y = 0 }, { x = -5, y = 3 }, { x = -6, y = 2 }, { x = 5, y = 3 }, { x = 6, y = 2 }, { x = -5, y = 4 }, { x = -4, y = 4 }, { x = -4, y = 5 }, { x = -3, y = 5 }, { x = 3, y = 5 }, { x = 4, y = 4 }, { x = 5, y = 4 }, { x = 4, y = 5 }, { x = -1, y = 6 }, { x = -2, y = 6 }, { x = 1, y = 6 }, { x = 0, y = 6 }, { x = 2, y = 6 } },
|
||||
[8] = { { x = -1, y = -7 }, { x = -2, y = -7 }, { x = 1, y = -7 }, { x = 0, y = -7 }, { x = 2, y = -7 }, { x = -5, y = -5 }, { x = -4, y = -6 }, { x = -3, y = -6 }, { x = 3, y = -6 }, { x = 4, y = -6 }, { x = 5, y = -5 }, { x = -6, y = -3 }, { x = -6, y = -4 }, { x = 6, y = -4 }, { x = 6, y = -3 }, { x = -7, y = -1 }, { x = -7, y = -2 }, { x = 7, y = -1 }, { x = 7, y = -2 }, { x = -7, y = 1 }, { x = -7, y = 0 }, { x = 7, y = 1 }, { x = 7, y = 0 }, { x = -7, y = 2 }, { x = -6, y = 3 }, { x = 6, y = 3 }, { x = 7, y = 2 }, { x = -5, y = 5 }, { x = -6, y = 4 }, { x = 5, y = 5 }, { x = 6, y = 4 }, { x = -3, y = 6 }, { x = -4, y = 6 }, { x = -2, y = 7 }, { x = -1, y = 7 }, { x = 0, y = 7 }, { x = 1, y = 7 }, { x = 3, y = 6 }, { x = 2, y = 7 }, { x = 4, y = 6 } },
|
||||
[9] = { { x = -4, y = -7 }, { x = -3, y = -7 }, { x = -2, y = -8 }, { x = -1, y = -8 }, { x = 0, y = -8 }, { x = 1, y = -8 }, { x = 3, y = -7 }, { x = 2, y = -8 }, { x = 4, y = -7 }, { x = -5, y = -6 }, { x = -6, y = -6 }, { x = -6, y = -5 }, { x = 5, y = -6 }, { x = 6, y = -5 }, { x = 6, y = -6 }, { x = -7, y = -4 }, { x = -7, y = -3 }, { x = 7, y = -4 }, { x = 7, y = -3 }, { x = -8, y = -2 }, { x = -8, y = -1 }, { x = 8, y = -1 }, { x = 8, y = -2 }, { x = -8, y = 0 }, { x = -8, y = 1 }, { x = 8, y = 1 }, { x = 8, y = 0 }, { x = -7, y = 3 }, { x = -8, y = 2 }, { x = 7, y = 3 }, { x = 8, y = 2 }, { x = -7, y = 4 }, { x = -6, y = 5 }, { x = 6, y = 5 }, { x = 7, y = 4 }, { x = -5, y = 6 }, { x = -6, y = 6 }, { x = -4, y = 7 }, { x = -3, y = 7 }, { x = 3, y = 7 }, { x = 5, y = 6 }, { x = 4, y = 7 }, { x = 6, y = 6 }, { x = -2, y = 8 }, { x = -1, y = 8 }, { x = 0, y = 8 }, { x = 1, y = 8 }, { x = 2, y = 8 } },
|
||||
[10] = { { x = -3, y = -9 }, { x = -1, y = -9 }, { x = -2, y = -9 }, { x = 1, y = -9 }, { x = 0, y = -9 }, { x = 3, y = -9 }, { x = 2, y = -9 }, { x = -5, y = -7 }, { x = -6, y = -7 }, { x = -5, y = -8 }, { x = -4, y = -8 }, { x = -3, y = -8 }, { x = 3, y = -8 }, { x = 5, y = -7 }, { x = 5, y = -8 }, { x = 4, y = -8 }, { x = 6, y = -7 }, { x = -7, y = -5 }, { x = -7, y = -6 }, { x = -8, y = -5 }, { x = 7, y = -5 }, { x = 7, y = -6 }, { x = 8, y = -5 }, { x = -9, y = -3 }, { x = -8, y = -4 }, { x = -8, y = -3 }, { x = 8, y = -4 }, { x = 8, y = -3 }, { x = 9, y = -3 }, { x = -9, y = -1 }, { x = -9, y = -2 }, { x = 9, y = -1 }, { x = 9, y = -2 }, { x = -9, y = 1 }, { x = -9, y = 0 }, { x = 9, y = 1 }, { x = 9, y = 0 }, { x = -9, y = 3 }, { x = -9, y = 2 }, { x = -8, y = 3 }, { x = 8, y = 3 }, { x = 9, y = 3 }, { x = 9, y = 2 }, { x = -7, y = 5 }, { x = -8, y = 5 }, { x = -8, y = 4 }, { x = 7, y = 5 }, { x = 8, y = 5 }, { x = 8, y = 4 }, { x = -7, y = 6 }, { x = -6, y = 7 }, { x = -5, y = 7 }, { x = 5, y = 7 }, { x = 7, y = 6 }, { x = 6, y = 7 }, { x = -5, y = 8 }, { x = -4, y = 8 }, { x = -3, y = 8 }, { x = -3, y = 9 }, { x = -2, y = 9 }, { x = -1, y = 9 }, { x = 0, y = 9 }, { x = 1, y = 9 }, { x = 3, y = 8 }, { x = 2, y = 9 }, { x = 3, y = 9 }, { x = 5, y = 8 }, { x = 4, y = 8 } },
|
||||
[11] = { { x = -5, y = -9 }, { x = -4, y = -9 }, { x = -3, y = -10 }, { x = -1, y = -10 }, { x = -2, y = -10 }, { x = 1, y = -10 }, { x = 0, y = -10 }, { x = 3, y = -10 }, { x = 2, y = -10 }, { x = 5, y = -9 }, { x = 4, y = -9 }, { x = -7, y = -7 }, { x = -6, y = -8 }, { x = 7, y = -7 }, { x = 6, y = -8 }, { x = -9, y = -5 }, { x = -8, y = -6 }, { x = 9, y = -5 }, { x = 8, y = -6 }, { x = -9, y = -4 }, { x = -10, y = -3 }, { x = 9, y = -4 }, { x = 10, y = -3 }, { x = -10, y = -2 }, { x = -10, y = -1 }, { x = 10, y = -1 }, { x = 10, y = -2 }, { x = -10, y = 0 }, { x = -10, y = 1 }, { x = 10, y = 1 }, { x = 10, y = 0 }, { x = -10, y = 2 }, { x = -10, y = 3 }, { x = 10, y = 3 }, { x = 10, y = 2 }, { x = -9, y = 4 }, { x = -9, y = 5 }, { x = 9, y = 5 }, { x = 9, y = 4 }, { x = -8, y = 6 }, { x = -7, y = 7 }, { x = 7, y = 7 }, { x = 8, y = 6 }, { x = -6, y = 8 }, { x = -5, y = 9 }, { x = -4, y = 9 }, { x = 4, y = 9 }, { x = 5, y = 9 }, { x = 6, y = 8 }, { x = -3, y = 10 }, { x = -2, y = 10 }, { x = -1, y = 10 }, { x = 0, y = 10 }, { x = 1, y = 10 }, { x = 2, y = 10 }, { x = 3, y = 10 } },
|
||||
[12] = { { x = -3, y = -11 }, { x = -2, y = -11 }, { x = -1, y = -11 }, { x = 0, y = -11 }, { x = 1, y = -11 }, { x = 2, y = -11 }, { x = 3, y = -11 }, { x = -7, y = -9 }, { x = -6, y = -9 }, { x = -5, y = -10 }, { x = -4, y = -10 }, { x = 5, y = -10 }, { x = 4, y = -10 }, { x = 7, y = -9 }, { x = 6, y = -9 }, { x = -9, y = -7 }, { x = -7, y = -8 }, { x = -8, y = -8 }, { x = -8, y = -7 }, { x = 7, y = -8 }, { x = 8, y = -7 }, { x = 8, y = -8 }, { x = 9, y = -7 }, { x = -9, y = -6 }, { x = -10, y = -5 }, { x = 9, y = -6 }, { x = 10, y = -5 }, { x = -11, y = -3 }, { x = -10, y = -4 }, { x = 10, y = -4 }, { x = 11, y = -3 }, { x = -11, y = -2 }, { x = -11, y = -1 }, { x = 11, y = -1 }, { x = 11, y = -2 }, { x = -11, y = 0 }, { x = -11, y = 1 }, { x = 11, y = 1 }, { x = 11, y = 0 }, { x = -11, y = 2 }, { x = -11, y = 3 }, { x = 11, y = 3 }, { x = 11, y = 2 }, { x = -10, y = 5 }, { x = -10, y = 4 }, { x = 10, y = 5 }, { x = 10, y = 4 }, { x = -9, y = 7 }, { x = -9, y = 6 }, { x = -8, y = 7 }, { x = 8, y = 7 }, { x = 9, y = 7 }, { x = 9, y = 6 }, { x = -8, y = 8 }, { x = -7, y = 8 }, { x = -7, y = 9 }, { x = -6, y = 9 }, { x = 7, y = 8 }, { x = 7, y = 9 }, { x = 6, y = 9 }, { x = 8, y = 8 }, { x = -5, y = 10 }, { x = -4, y = 10 }, { x = -3, y = 11 }, { x = -2, y = 11 }, { x = -1, y = 11 }, { x = 0, y = 11 }, { x = 1, y = 11 }, { x = 2, y = 11 }, { x = 3, y = 11 }, { x = 4, y = 10 }, { x = 5, y = 10 } },
|
||||
[13] = { { x = -5, y = -11 }, { x = -4, y = -11 }, { x = -3, y = -12 }, { x = -1, y = -12 }, { x = -2, y = -12 }, { x = 1, y = -12 }, { x = 0, y = -12 }, { x = 3, y = -12 }, { x = 2, y = -12 }, { x = 4, y = -11 }, { x = 5, y = -11 }, { x = -8, y = -9 }, { x = -7, y = -10 }, { x = -6, y = -10 }, { x = 6, y = -10 }, { x = 7, y = -10 }, { x = 8, y = -9 }, { x = -10, y = -7 }, { x = -9, y = -8 }, { x = 9, y = -8 }, { x = 10, y = -7 }, { x = -11, y = -5 }, { x = -10, y = -6 }, { x = 10, y = -6 }, { x = 11, y = -5 }, { x = -11, y = -4 }, { x = -12, y = -3 }, { x = 11, y = -4 }, { x = 12, y = -3 }, { x = -12, y = -1 }, { x = -12, y = -2 }, { x = 12, y = -1 }, { x = 12, y = -2 }, { x = -12, y = 1 }, { x = -12, y = 0 }, { x = 12, y = 1 }, { x = 12, y = 0 }, { x = -12, y = 3 }, { x = -12, y = 2 }, { x = 12, y = 3 }, { x = 12, y = 2 }, { x = -11, y = 5 }, { x = -11, y = 4 }, { x = 11, y = 4 }, { x = 11, y = 5 }, { x = -10, y = 7 }, { x = -10, y = 6 }, { x = 10, y = 6 }, { x = 10, y = 7 }, { x = -9, y = 8 }, { x = -8, y = 9 }, { x = 9, y = 8 }, { x = 8, y = 9 }, { x = -7, y = 10 }, { x = -5, y = 11 }, { x = -6, y = 10 }, { x = -4, y = 11 }, { x = 5, y = 11 }, { x = 4, y = 11 }, { x = 7, y = 10 }, { x = 6, y = 10 }, { x = -3, y = 12 }, { x = -2, y = 12 }, { x = -1, y = 12 }, { x = 0, y = 12 }, { x = 1, y = 12 }, { x = 2, y = 12 }, { x = 3, y = 12 } },
|
||||
[14] = { { x = -3, y = -13 }, { x = -1, y = -13 }, { x = -2, y = -13 }, { x = 1, y = -13 }, { x = 0, y = -13 }, { x = 3, y = -13 }, { x = 2, y = -13 }, { x = -7, y = -11 }, { x = -6, y = -11 }, { x = -5, y = -12 }, { x = -6, y = -12 }, { x = -4, y = -12 }, { x = 5, y = -12 }, { x = 4, y = -12 }, { x = 7, y = -11 }, { x = 6, y = -11 }, { x = 6, y = -12 }, { x = -10, y = -9 }, { x = -9, y = -9 }, { x = -9, y = -10 }, { x = -8, y = -10 }, { x = 9, y = -9 }, { x = 9, y = -10 }, { x = 8, y = -10 }, { x = 10, y = -9 }, { x = -11, y = -7 }, { x = -10, y = -8 }, { x = 11, y = -7 }, { x = 10, y = -8 }, { x = -11, y = -6 }, { x = -12, y = -6 }, { x = -12, y = -5 }, { x = 11, y = -6 }, { x = 12, y = -6 }, { x = 12, y = -5 }, { x = -13, y = -3 }, { x = -12, y = -4 }, { x = 12, y = -4 }, { x = 13, y = -3 }, { x = -13, y = -2 }, { x = -13, y = -1 }, { x = 13, y = -1 }, { x = 13, y = -2 }, { x = -13, y = 0 }, { x = -13, y = 1 }, { x = 13, y = 1 }, { x = 13, y = 0 }, { x = -13, y = 2 }, { x = -13, y = 3 }, { x = 13, y = 3 }, { x = 13, y = 2 }, { x = -12, y = 5 }, { x = -12, y = 4 }, { x = 12, y = 5 }, { x = 12, y = 4 }, { x = -11, y = 6 }, { x = -11, y = 7 }, { x = -12, y = 6 }, { x = 11, y = 7 }, { x = 11, y = 6 }, { x = 12, y = 6 }, { x = -10, y = 8 }, { x = -10, y = 9 }, { x = -9, y = 9 }, { x = 9, y = 9 }, { x = 10, y = 9 }, { x = 10, y = 8 }, { x = -9, y = 10 }, { x = -8, y = 10 }, { x = -7, y = 11 }, { x = -6, y = 11 }, { x = 7, y = 11 }, { x = 6, y = 11 }, { x = 8, y = 10 }, { x = 9, y = 10 }, { x = -6, y = 12 }, { x = -5, y = 12 }, { x = -4, y = 12 }, { x = -3, y = 13 }, { x = -2, y = 13 }, { x = -1, y = 13 }, { x = 0, y = 13 }, { x = 1, y = 13 }, { x = 2, y = 13 }, { x = 3, y = 13 }, { x = 5, y = 12 }, { x = 4, y = 12 }, { x = 6, y = 12 } },
|
||||
[15] = { { x = -5, y = -13 }, { x = -6, y = -13 }, { x = -4, y = -13 }, { x = -3, y = -14 }, { x = -1, y = -14 }, { x = -2, y = -14 }, { x = 1, y = -14 }, { x = 0, y = -14 }, { x = 3, y = -14 }, { x = 2, y = -14 }, { x = 5, y = -13 }, { x = 4, y = -13 }, { x = 6, y = -13 }, { x = -9, y = -11 }, { x = -8, y = -11 }, { x = -8, y = -12 }, { x = -7, y = -12 }, { x = 7, y = -12 }, { x = 8, y = -12 }, { x = 8, y = -11 }, { x = 9, y = -11 }, { x = -11, y = -9 }, { x = -10, y = -10 }, { x = 10, y = -10 }, { x = 11, y = -9 }, { x = -12, y = -7 }, { x = -11, y = -8 }, { x = -12, y = -8 }, { x = 11, y = -8 }, { x = 12, y = -8 }, { x = 12, y = -7 }, { x = -13, y = -5 }, { x = -13, y = -6 }, { x = 13, y = -5 }, { x = 13, y = -6 }, { x = -13, y = -4 }, { x = -14, y = -3 }, { x = 13, y = -4 }, { x = 14, y = -3 }, { x = -14, y = -2 }, { x = -14, y = -1 }, { x = 14, y = -1 }, { x = 14, y = -2 }, { x = -14, y = 0 }, { x = -14, y = 1 }, { x = 14, y = 1 }, { x = 14, y = 0 }, { x = -14, y = 2 }, { x = -14, y = 3 }, { x = 14, y = 3 }, { x = 14, y = 2 }, { x = -13, y = 4 }, { x = -13, y = 5 }, { x = 13, y = 5 }, { x = 13, y = 4 }, { x = -13, y = 6 }, { x = -12, y = 7 }, { x = 12, y = 7 }, { x = 13, y = 6 }, { x = -11, y = 9 }, { x = -11, y = 8 }, { x = -12, y = 8 }, { x = 11, y = 8 }, { x = 11, y = 9 }, { x = 12, y = 8 }, { x = -9, y = 11 }, { x = -10, y = 10 }, { x = -8, y = 11 }, { x = 9, y = 11 }, { x = 8, y = 11 }, { x = 10, y = 10 }, { x = -7, y = 12 }, { x = -8, y = 12 }, { x = -6, y = 13 }, { x = -5, y = 13 }, { x = -4, y = 13 }, { x = 5, y = 13 }, { x = 4, y = 13 }, { x = 7, y = 12 }, { x = 6, y = 13 }, { x = 8, y = 12 }, { x = -3, y = 14 }, { x = -2, y = 14 }, { x = -1, y = 14 }, { x = 0, y = 14 }, { x = 1, y = 14 }, { x = 2, y = 14 }, { x = 3, y = 14 } },
|
||||
[16] = { { x = -3, y = -15 }, { x = -1, y = -15 }, { x = -2, y = -15 }, { x = 1, y = -15 }, { x = 0, y = -15 }, { x = 3, y = -15 }, { x = 2, y = -15 }, { x = -7, y = -13 }, { x = -8, y = -13 }, { x = -5, y = -14 }, { x = -6, y = -14 }, { x = -4, y = -14 }, { x = 5, y = -14 }, { x = 4, y = -14 }, { x = 7, y = -13 }, { x = 6, y = -14 }, { x = 8, y = -13 }, { x = -9, y = -12 }, { x = -10, y = -11 }, { x = 9, y = -12 }, { x = 10, y = -11 }, { x = -11, y = -10 }, { x = -12, y = -9 }, { x = 11, y = -10 }, { x = 12, y = -9 }, { x = -13, y = -7 }, { x = -13, y = -8 }, { x = 13, y = -7 }, { x = 13, y = -8 }, { x = -14, y = -6 }, { x = -14, y = -5 }, { x = 14, y = -5 }, { x = 14, y = -6 }, { x = -15, y = -3 }, { x = -14, y = -4 }, { x = 15, y = -3 }, { x = 14, y = -4 }, { x = -15, y = -2 }, { x = -15, y = -1 }, { x = 15, y = -1 }, { x = 15, y = -2 }, { x = -15, y = 0 }, { x = -15, y = 1 }, { x = 15, y = 1 }, { x = 15, y = 0 }, { x = -15, y = 2 }, { x = -15, y = 3 }, { x = 15, y = 3 }, { x = 15, y = 2 }, { x = -14, y = 5 }, { x = -14, y = 4 }, { x = 14, y = 5 }, { x = 14, y = 4 }, { x = -13, y = 7 }, { x = -14, y = 6 }, { x = 13, y = 7 }, { x = 14, y = 6 }, { x = -13, y = 8 }, { x = -12, y = 9 }, { x = 12, y = 9 }, { x = 13, y = 8 }, { x = -11, y = 10 }, { x = -10, y = 11 }, { x = 10, y = 11 }, { x = 11, y = 10 }, { x = -9, y = 12 }, { x = -8, y = 13 }, { x = -7, y = 13 }, { x = 7, y = 13 }, { x = 8, y = 13 }, { x = 9, y = 12 }, { x = -6, y = 14 }, { x = -5, y = 14 }, { x = -4, y = 14 }, { x = -3, y = 15 }, { x = -2, y = 15 }, { x = -1, y = 15 }, { x = 0, y = 15 }, { x = 1, y = 15 }, { x = 2, y = 15 }, { x = 3, y = 15 }, { x = 4, y = 14 }, { x = 5, y = 14 }, { x = 6, y = 14 } },
|
||||
[17] = { { x = -5, y = -15 }, { x = -6, y = -15 }, { x = -3, y = -16 }, { x = -4, y = -16 }, { x = -4, y = -15 }, { x = -1, y = -16 }, { x = -2, y = -16 }, { x = 1, y = -16 }, { x = 0, y = -16 }, { x = 3, y = -16 }, { x = 2, y = -16 }, { x = 5, y = -15 }, { x = 4, y = -15 }, { x = 4, y = -16 }, { x = 6, y = -15 }, { x = -9, y = -13 }, { x = -10, y = -13 }, { x = -8, y = -14 }, { x = -7, y = -14 }, { x = 7, y = -14 }, { x = 9, y = -13 }, { x = 8, y = -14 }, { x = 10, y = -13 }, { x = -11, y = -12 }, { x = -11, y = -11 }, { x = -12, y = -11 }, { x = -10, y = -12 }, { x = 11, y = -11 }, { x = 11, y = -12 }, { x = 10, y = -12 }, { x = 12, y = -11 }, { x = -13, y = -10 }, { x = -13, y = -9 }, { x = -12, y = -10 }, { x = 13, y = -9 }, { x = 13, y = -10 }, { x = 12, y = -10 }, { x = -14, y = -7 }, { x = -14, y = -8 }, { x = 14, y = -7 }, { x = 14, y = -8 }, { x = -15, y = -6 }, { x = -15, y = -5 }, { x = 15, y = -5 }, { x = 15, y = -6 }, { x = -15, y = -4 }, { x = -16, y = -4 }, { x = -16, y = -3 }, { x = 15, y = -4 }, { x = 16, y = -3 }, { x = 16, y = -4 }, { x = -16, y = -2 }, { x = -16, y = -1 }, { x = 16, y = -1 }, { x = 16, y = -2 }, { x = -16, y = 0 }, { x = -16, y = 1 }, { x = 16, y = 1 }, { x = 16, y = 0 }, { x = -16, y = 2 }, { x = -16, y = 3 }, { x = 16, y = 3 }, { x = 16, y = 2 }, { x = -16, y = 4 }, { x = -15, y = 4 }, { x = -15, y = 5 }, { x = 15, y = 5 }, { x = 15, y = 4 }, { x = 16, y = 4 }, { x = -15, y = 6 }, { x = -14, y = 7 }, { x = 14, y = 7 }, { x = 15, y = 6 }, { x = -13, y = 9 }, { x = -14, y = 8 }, { x = 13, y = 9 }, { x = 14, y = 8 }, { x = -13, y = 10 }, { x = -12, y = 10 }, { x = -12, y = 11 }, { x = -11, y = 11 }, { x = 11, y = 11 }, { x = 12, y = 11 }, { x = 12, y = 10 }, { x = 13, y = 10 }, { x = -11, y = 12 }, { x = -10, y = 12 }, { x = -10, y = 13 }, { x = -9, y = 13 }, { x = 9, y = 13 }, { x = 10, y = 13 }, { x = 10, y = 12 }, { x = 11, y = 12 }, { x = -8, y = 14 }, { x = -7, y = 14 }, { x = -6, y = 15 }, { x = -5, y = 15 }, { x = -4, y = 15 }, { x = 4, y = 15 }, { x = 5, y = 15 }, { x = 7, y = 14 }, { x = 6, y = 15 }, { x = 8, y = 14 }, { x = -4, y = 16 }, { x = -3, y = 16 }, { x = -2, y = 16 }, { x = -1, y = 16 }, { x = 0, y = 16 }, { x = 1, y = 16 }, { x = 2, y = 16 }, { x = 3, y = 16 }, { x = 4, y = 16 } },
|
||||
[18] = { { x = -3, y = -17 }, { x = -4, y = -17 }, { x = -1, y = -17 }, { x = -2, y = -17 }, { x = 1, y = -17 }, { x = 0, y = -17 }, { x = 3, y = -17 }, { x = 2, y = -17 }, { x = 4, y = -17 }, { x = -9, y = -15 }, { x = -8, y = -15 }, { x = -7, y = -15 }, { x = -7, y = -16 }, { x = -6, y = -16 }, { x = -5, y = -16 }, { x = 5, y = -16 }, { x = 7, y = -15 }, { x = 7, y = -16 }, { x = 6, y = -16 }, { x = 9, y = -15 }, { x = 8, y = -15 }, { x = -11, y = -13 }, { x = -10, y = -14 }, { x = -9, y = -14 }, { x = 9, y = -14 }, { x = 11, y = -13 }, { x = 10, y = -14 }, { x = -13, y = -11 }, { x = -12, y = -12 }, { x = 13, y = -11 }, { x = 12, y = -12 }, { x = -15, y = -9 }, { x = -14, y = -10 }, { x = -14, y = -9 }, { x = 14, y = -10 }, { x = 14, y = -9 }, { x = 15, y = -9 }, { x = -15, y = -8 }, { x = -15, y = -7 }, { x = -16, y = -7 }, { x = 15, y = -8 }, { x = 15, y = -7 }, { x = 16, y = -7 }, { x = -16, y = -6 }, { x = -16, y = -5 }, { x = 16, y = -5 }, { x = 16, y = -6 }, { x = -17, y = -3 }, { x = -17, y = -4 }, { x = 17, y = -3 }, { x = 17, y = -4 }, { x = -17, y = -1 }, { x = -17, y = -2 }, { x = 17, y = -1 }, { x = 17, y = -2 }, { x = -17, y = 1 }, { x = -17, y = 0 }, { x = 17, y = 1 }, { x = 17, y = 0 }, { x = -17, y = 3 }, { x = -17, y = 2 }, { x = 17, y = 3 }, { x = 17, y = 2 }, { x = -17, y = 4 }, { x = -16, y = 5 }, { x = 16, y = 5 }, { x = 17, y = 4 }, { x = -15, y = 7 }, { x = -16, y = 7 }, { x = -16, y = 6 }, { x = 15, y = 7 }, { x = 16, y = 7 }, { x = 16, y = 6 }, { x = -15, y = 9 }, { x = -15, y = 8 }, { x = -14, y = 9 }, { x = 14, y = 9 }, { x = 15, y = 9 }, { x = 15, y = 8 }, { x = -14, y = 10 }, { x = -13, y = 11 }, { x = 13, y = 11 }, { x = 14, y = 10 }, { x = -12, y = 12 }, { x = -11, y = 13 }, { x = 11, y = 13 }, { x = 12, y = 12 }, { x = -10, y = 14 }, { x = -9, y = 14 }, { x = -9, y = 15 }, { x = -8, y = 15 }, { x = -7, y = 15 }, { x = 7, y = 15 }, { x = 9, y = 14 }, { x = 9, y = 15 }, { x = 8, y = 15 }, { x = 10, y = 14 }, { x = -7, y = 16 }, { x = -6, y = 16 }, { x = -5, y = 16 }, { x = -4, y = 17 }, { x = -3, y = 17 }, { x = -2, y = 17 }, { x = -1, y = 17 }, { x = 0, y = 17 }, { x = 1, y = 17 }, { x = 2, y = 17 }, { x = 3, y = 17 }, { x = 4, y = 17 }, { x = 5, y = 16 }, { x = 6, y = 16 }, { x = 7, y = 16 } },
|
||||
[19] = { { x = -7, y = -17 }, { x = -6, y = -17 }, { x = -5, y = -17 }, { x = -3, y = -18 }, { x = -4, y = -18 }, { x = -1, y = -18 }, { x = -2, y = -18 }, { x = 1, y = -18 }, { x = 0, y = -18 }, { x = 3, y = -18 }, { x = 2, y = -18 }, { x = 5, y = -17 }, { x = 4, y = -18 }, { x = 7, y = -17 }, { x = 6, y = -17 }, { x = -10, y = -15 }, { x = -9, y = -16 }, { x = -8, y = -16 }, { x = 9, y = -16 }, { x = 8, y = -16 }, { x = 10, y = -15 }, { x = -13, y = -13 }, { x = -11, y = -14 }, { x = -12, y = -14 }, { x = -12, y = -13 }, { x = 11, y = -14 }, { x = 13, y = -13 }, { x = 12, y = -13 }, { x = 12, y = -14 }, { x = -13, y = -12 }, { x = -14, y = -12 }, { x = -14, y = -11 }, { x = 13, y = -12 }, { x = 14, y = -11 }, { x = 14, y = -12 }, { x = -15, y = -10 }, { x = -16, y = -9 }, { x = 15, y = -10 }, { x = 16, y = -9 }, { x = -17, y = -7 }, { x = -16, y = -8 }, { x = 16, y = -8 }, { x = 17, y = -7 }, { x = -17, y = -5 }, { x = -17, y = -6 }, { x = 17, y = -6 }, { x = 17, y = -5 }, { x = -18, y = -3 }, { x = -18, y = -4 }, { x = 18, y = -4 }, { x = 18, y = -3 }, { x = -18, y = -1 }, { x = -18, y = -2 }, { x = 18, y = -2 }, { x = 18, y = -1 }, { x = -18, y = 1 }, { x = -18, y = 0 }, { x = 18, y = 0 }, { x = 18, y = 1 }, { x = -18, y = 3 }, { x = -18, y = 2 }, { x = 18, y = 2 }, { x = 18, y = 3 }, { x = -17, y = 5 }, { x = -18, y = 4 }, { x = 17, y = 5 }, { x = 18, y = 4 }, { x = -17, y = 7 }, { x = -17, y = 6 }, { x = 17, y = 7 }, { x = 17, y = 6 }, { x = -16, y = 9 }, { x = -16, y = 8 }, { x = 16, y = 9 }, { x = 16, y = 8 }, { x = -15, y = 10 }, { x = -14, y = 11 }, { x = 14, y = 11 }, { x = 15, y = 10 }, { x = -14, y = 12 }, { x = -13, y = 12 }, { x = -13, y = 13 }, { x = -12, y = 13 }, { x = 12, y = 13 }, { x = 13, y = 13 }, { x = 13, y = 12 }, { x = 14, y = 12 }, { x = -12, y = 14 }, { x = -11, y = 14 }, { x = -10, y = 15 }, { x = 10, y = 15 }, { x = 11, y = 14 }, { x = 12, y = 14 }, { x = -9, y = 16 }, { x = -7, y = 17 }, { x = -8, y = 16 }, { x = -5, y = 17 }, { x = -6, y = 17 }, { x = 5, y = 17 }, { x = 7, y = 17 }, { x = 6, y = 17 }, { x = 8, y = 16 }, { x = 9, y = 16 }, { x = -3, y = 18 }, { x = -4, y = 18 }, { x = -1, y = 18 }, { x = -2, y = 18 }, { x = 1, y = 18 }, { x = 0, y = 18 }, { x = 3, y = 18 }, { x = 2, y = 18 }, { x = 4, y = 18 } },
|
||||
[20] = { { x = -3, y = -19 }, { x = -4, y = -19 }, { x = -1, y = -19 }, { x = -2, y = -19 }, { x = 1, y = -19 }, { x = 0, y = -19 }, { x = 3, y = -19 }, { x = 2, y = -19 }, { x = 4, y = -19 }, { x = -9, y = -17 }, { x = -7, y = -18 }, { x = -8, y = -17 }, { x = -5, y = -18 }, { x = -6, y = -18 }, { x = 5, y = -18 }, { x = 7, y = -18 }, { x = 6, y = -18 }, { x = 9, y = -17 }, { x = 8, y = -17 }, { x = -11, y = -16 }, { x = -11, y = -15 }, { x = -12, y = -15 }, { x = -10, y = -16 }, { x = 11, y = -15 }, { x = 11, y = -16 }, { x = 10, y = -16 }, { x = 12, y = -15 }, { x = -13, y = -14 }, { x = -14, y = -13 }, { x = 13, y = -14 }, { x = 14, y = -13 }, { x = -15, y = -12 }, { x = -15, y = -11 }, { x = -16, y = -11 }, { x = 15, y = -11 }, { x = 15, y = -12 }, { x = 16, y = -11 }, { x = -17, y = -9 }, { x = -16, y = -10 }, { x = 16, y = -10 }, { x = 17, y = -9 }, { x = -17, y = -8 }, { x = -18, y = -7 }, { x = 17, y = -8 }, { x = 18, y = -7 }, { x = -18, y = -6 }, { x = -18, y = -5 }, { x = 18, y = -5 }, { x = 18, y = -6 }, { x = -19, y = -4 }, { x = -19, y = -3 }, { x = 19, y = -3 }, { x = 19, y = -4 }, { x = -19, y = -2 }, { x = -19, y = -1 }, { x = 19, y = -1 }, { x = 19, y = -2 }, { x = -19, y = 0 }, { x = -19, y = 1 }, { x = 19, y = 1 }, { x = 19, y = 0 }, { x = -19, y = 2 }, { x = -19, y = 3 }, { x = 19, y = 3 }, { x = 19, y = 2 }, { x = -19, y = 4 }, { x = -18, y = 5 }, { x = 18, y = 5 }, { x = 19, y = 4 }, { x = -18, y = 7 }, { x = -18, y = 6 }, { x = 18, y = 7 }, { x = 18, y = 6 }, { x = -17, y = 9 }, { x = -17, y = 8 }, { x = 17, y = 9 }, { x = 17, y = 8 }, { x = -16, y = 10 }, { x = -16, y = 11 }, { x = -15, y = 11 }, { x = 15, y = 11 }, { x = 16, y = 11 }, { x = 16, y = 10 }, { x = -15, y = 12 }, { x = -14, y = 13 }, { x = 14, y = 13 }, { x = 15, y = 12 }, { x = -13, y = 14 }, { x = -12, y = 15 }, { x = -11, y = 15 }, { x = 11, y = 15 }, { x = 12, y = 15 }, { x = 13, y = 14 }, { x = -11, y = 16 }, { x = -10, y = 16 }, { x = -9, y = 17 }, { x = -8, y = 17 }, { x = 9, y = 17 }, { x = 8, y = 17 }, { x = 10, y = 16 }, { x = 11, y = 16 }, { x = -7, y = 18 }, { x = -5, y = 18 }, { x = -6, y = 18 }, { x = -4, y = 19 }, { x = -3, y = 19 }, { x = -2, y = 19 }, { x = -1, y = 19 }, { x = 0, y = 19 }, { x = 1, y = 19 }, { x = 2, y = 19 }, { x = 3, y = 19 }, { x = 4, y = 19 }, { x = 5, y = 18 }, { x = 7, y = 18 }, { x = 6, y = 18 } },
|
||||
[21] = { { x = -7, y = -19 }, { x = -5, y = -19 }, { x = -6, y = -19 }, { x = -3, y = -20 }, { x = -4, y = -20 }, { x = -1, y = -20 }, { x = -2, y = -20 }, { x = 1, y = -20 }, { x = 0, y = -20 }, { x = 3, y = -20 }, { x = 2, y = -20 }, { x = 5, y = -19 }, { x = 4, y = -20 }, { x = 7, y = -19 }, { x = 6, y = -19 }, { x = -11, y = -17 }, { x = -10, y = -17 }, { x = -9, y = -18 }, { x = -8, y = -18 }, { x = 9, y = -18 }, { x = 8, y = -18 }, { x = 10, y = -17 }, { x = 11, y = -17 }, { x = -13, y = -15 }, { x = -14, y = -15 }, { x = -12, y = -16 }, { x = 13, y = -15 }, { x = 12, y = -16 }, { x = 14, y = -15 }, { x = -15, y = -14 }, { x = -15, y = -13 }, { x = -14, y = -14 }, { x = 15, y = -13 }, { x = 15, y = -14 }, { x = 14, y = -14 }, { x = -17, y = -11 }, { x = -16, y = -12 }, { x = 16, y = -12 }, { x = 17, y = -11 }, { x = -17, y = -10 }, { x = -18, y = -9 }, { x = 17, y = -10 }, { x = 18, y = -9 }, { x = -19, y = -7 }, { x = -18, y = -8 }, { x = 18, y = -8 }, { x = 19, y = -7 }, { x = -19, y = -6 }, { x = -19, y = -5 }, { x = 19, y = -6 }, { x = 19, y = -5 }, { x = -20, y = -4 }, { x = -20, y = -3 }, { x = 20, y = -3 }, { x = 20, y = -4 }, { x = -20, y = -2 }, { x = -20, y = -1 }, { x = 20, y = -1 }, { x = 20, y = -2 }, { x = -20, y = 0 }, { x = -20, y = 1 }, { x = 20, y = 1 }, { x = 20, y = 0 }, { x = -20, y = 2 }, { x = -20, y = 3 }, { x = 20, y = 3 }, { x = 20, y = 2 }, { x = -20, y = 4 }, { x = -19, y = 5 }, { x = 19, y = 5 }, { x = 20, y = 4 }, { x = -19, y = 7 }, { x = -19, y = 6 }, { x = 19, y = 7 }, { x = 19, y = 6 }, { x = -18, y = 9 }, { x = -18, y = 8 }, { x = 18, y = 9 }, { x = 18, y = 8 }, { x = -17, y = 11 }, { x = -17, y = 10 }, { x = 17, y = 11 }, { x = 17, y = 10 }, { x = -16, y = 12 }, { x = -15, y = 13 }, { x = 15, y = 13 }, { x = 16, y = 12 }, { x = -15, y = 14 }, { x = -14, y = 14 }, { x = -14, y = 15 }, { x = -13, y = 15 }, { x = 13, y = 15 }, { x = 14, y = 15 }, { x = 14, y = 14 }, { x = 15, y = 14 }, { x = -12, y = 16 }, { x = -11, y = 17 }, { x = -10, y = 17 }, { x = 11, y = 17 }, { x = 10, y = 17 }, { x = 12, y = 16 }, { x = -9, y = 18 }, { x = -8, y = 18 }, { x = -7, y = 19 }, { x = -5, y = 19 }, { x = -6, y = 19 }, { x = 5, y = 19 }, { x = 6, y = 19 }, { x = 7, y = 19 }, { x = 9, y = 18 }, { x = 8, y = 18 }, { x = -4, y = 20 }, { x = -3, y = 20 }, { x = -2, y = 20 }, { x = -1, y = 20 }, { x = 0, y = 20 }, { x = 1, y = 20 }, { x = 2, y = 20 }, { x = 3, y = 20 }, { x = 4, y = 20 } },
|
||||
[22] = { { x = -3, y = -21 }, { x = -4, y = -21 }, { x = -1, y = -21 }, { x = -2, y = -21 }, { x = 1, y = -21 }, { x = 0, y = -21 }, { x = 3, y = -21 }, { x = 2, y = -21 }, { x = 4, y = -21 }, { x = -10, y = -19 }, { x = -9, y = -19 }, { x = -8, y = -19 }, { x = -7, y = -20 }, { x = -5, y = -20 }, { x = -6, y = -20 }, { x = 5, y = -20 }, { x = 7, y = -20 }, { x = 6, y = -20 }, { x = 9, y = -19 }, { x = 8, y = -19 }, { x = 10, y = -19 }, { x = -13, y = -17 }, { x = -12, y = -17 }, { x = -11, y = -18 }, { x = -10, y = -18 }, { x = 11, y = -18 }, { x = 10, y = -18 }, { x = 13, y = -17 }, { x = 12, y = -17 }, { x = -15, y = -15 }, { x = -13, y = -16 }, { x = -14, y = -16 }, { x = 13, y = -16 }, { x = 15, y = -15 }, { x = 14, y = -16 }, { x = -17, y = -13 }, { x = -16, y = -14 }, { x = -16, y = -13 }, { x = 17, y = -13 }, { x = 16, y = -13 }, { x = 16, y = -14 }, { x = -17, y = -12 }, { x = -18, y = -11 }, { x = 17, y = -12 }, { x = 18, y = -11 }, { x = -19, y = -10 }, { x = -19, y = -9 }, { x = -18, y = -10 }, { x = 18, y = -10 }, { x = 19, y = -10 }, { x = 19, y = -9 }, { x = -19, y = -8 }, { x = -20, y = -7 }, { x = 19, y = -8 }, { x = 20, y = -7 }, { x = -20, y = -6 }, { x = -20, y = -5 }, { x = 20, y = -6 }, { x = 20, y = -5 }, { x = -21, y = -4 }, { x = -21, y = -3 }, { x = 21, y = -3 }, { x = 21, y = -4 }, { x = -21, y = -2 }, { x = -21, y = -1 }, { x = 21, y = -1 }, { x = 21, y = -2 }, { x = -21, y = 0 }, { x = -21, y = 1 }, { x = 21, y = 1 }, { x = 21, y = 0 }, { x = -21, y = 2 }, { x = -21, y = 3 }, { x = 21, y = 3 }, { x = 21, y = 2 }, { x = -21, y = 4 }, { x = -20, y = 5 }, { x = 20, y = 5 }, { x = 21, y = 4 }, { x = -20, y = 7 }, { x = -20, y = 6 }, { x = 20, y = 7 }, { x = 20, y = 6 }, { x = -19, y = 9 }, { x = -19, y = 8 }, { x = 19, y = 9 }, { x = 19, y = 8 }, { x = -19, y = 10 }, { x = -18, y = 11 }, { x = -18, y = 10 }, { x = 18, y = 11 }, { x = 18, y = 10 }, { x = 19, y = 10 }, { x = -17, y = 13 }, { x = -17, y = 12 }, { x = -16, y = 13 }, { x = 16, y = 13 }, { x = 17, y = 13 }, { x = 17, y = 12 }, { x = -16, y = 14 }, { x = -15, y = 15 }, { x = 15, y = 15 }, { x = 16, y = 14 }, { x = -14, y = 16 }, { x = -13, y = 16 }, { x = -13, y = 17 }, { x = -12, y = 17 }, { x = 13, y = 16 }, { x = 13, y = 17 }, { x = 12, y = 17 }, { x = 14, y = 16 }, { x = -11, y = 18 }, { x = -10, y = 18 }, { x = -10, y = 19 }, { x = -9, y = 19 }, { x = -8, y = 19 }, { x = 9, y = 19 }, { x = 8, y = 19 }, { x = 11, y = 18 }, { x = 10, y = 18 }, { x = 10, y = 19 }, { x = -7, y = 20 }, { x = -6, y = 20 }, { x = -5, y = 20 }, { x = -3, y = 21 }, { x = -4, y = 21 }, { x = -1, y = 21 }, { x = -2, y = 21 }, { x = 1, y = 21 }, { x = 0, y = 21 }, { x = 3, y = 21 }, { x = 2, y = 21 }, { x = 4, y = 21 }, { x = 5, y = 20 }, { x = 7, y = 20 }, { x = 6, y = 20 } },
|
||||
[23] = { { x = -8, y = -21 }, { x = -7, y = -21 }, { x = -6, y = -21 }, { x = -5, y = -21 }, { x = -3, y = -22 }, { x = -4, y = -22 }, { x = -1, y = -22 }, { x = -2, y = -22 }, { x = 1, y = -22 }, { x = 0, y = -22 }, { x = 3, y = -22 }, { x = 2, y = -22 }, { x = 5, y = -21 }, { x = 4, y = -22 }, { x = 7, y = -21 }, { x = 6, y = -21 }, { x = 8, y = -21 }, { x = -12, y = -19 }, { x = -11, y = -19 }, { x = -10, y = -20 }, { x = -9, y = -20 }, { x = -8, y = -20 }, { x = 9, y = -20 }, { x = 8, y = -20 }, { x = 11, y = -19 }, { x = 10, y = -20 }, { x = 12, y = -19 }, { x = -14, y = -17 }, { x = -13, y = -18 }, { x = -12, y = -18 }, { x = 13, y = -18 }, { x = 12, y = -18 }, { x = 14, y = -17 }, { x = -15, y = -16 }, { x = -16, y = -15 }, { x = 15, y = -16 }, { x = 16, y = -15 }, { x = -17, y = -14 }, { x = -18, y = -13 }, { x = 17, y = -14 }, { x = 18, y = -13 }, { x = -19, y = -12 }, { x = -19, y = -11 }, { x = -18, y = -12 }, { x = 18, y = -12 }, { x = 19, y = -12 }, { x = 19, y = -11 }, { x = -20, y = -10 }, { x = -20, y = -9 }, { x = 20, y = -10 }, { x = 20, y = -9 }, { x = -21, y = -8 }, { x = -21, y = -7 }, { x = -20, y = -8 }, { x = 20, y = -8 }, { x = 21, y = -8 }, { x = 21, y = -7 }, { x = -21, y = -6 }, { x = -21, y = -5 }, { x = 21, y = -6 }, { x = 21, y = -5 }, { x = -22, y = -4 }, { x = -22, y = -3 }, { x = 22, y = -3 }, { x = 22, y = -4 }, { x = -22, y = -2 }, { x = -22, y = -1 }, { x = 22, y = -1 }, { x = 22, y = -2 }, { x = -22, y = 0 }, { x = -22, y = 1 }, { x = 22, y = 1 }, { x = 22, y = 0 }, { x = -22, y = 2 }, { x = -22, y = 3 }, { x = 22, y = 3 }, { x = 22, y = 2 }, { x = -22, y = 4 }, { x = -21, y = 5 }, { x = 21, y = 5 }, { x = 22, y = 4 }, { x = -21, y = 7 }, { x = -21, y = 6 }, { x = 21, y = 7 }, { x = 21, y = 6 }, { x = -21, y = 8 }, { x = -20, y = 9 }, { x = -20, y = 8 }, { x = 20, y = 8 }, { x = 20, y = 9 }, { x = 21, y = 8 }, { x = -19, y = 11 }, { x = -20, y = 10 }, { x = 19, y = 11 }, { x = 20, y = 10 }, { x = -19, y = 12 }, { x = -18, y = 13 }, { x = -18, y = 12 }, { x = 18, y = 13 }, { x = 18, y = 12 }, { x = 19, y = 12 }, { x = -17, y = 14 }, { x = -16, y = 15 }, { x = 16, y = 15 }, { x = 17, y = 14 }, { x = -15, y = 16 }, { x = -14, y = 17 }, { x = 14, y = 17 }, { x = 15, y = 16 }, { x = -13, y = 18 }, { x = -12, y = 18 }, { x = -12, y = 19 }, { x = -11, y = 19 }, { x = 11, y = 19 }, { x = 13, y = 18 }, { x = 12, y = 18 }, { x = 12, y = 19 }, { x = -10, y = 20 }, { x = -9, y = 20 }, { x = -8, y = 20 }, { x = -8, y = 21 }, { x = -7, y = 21 }, { x = -6, y = 21 }, { x = -5, y = 21 }, { x = 5, y = 21 }, { x = 7, y = 21 }, { x = 6, y = 21 }, { x = 8, y = 20 }, { x = 9, y = 20 }, { x = 8, y = 21 }, { x = 10, y = 20 }, { x = -4, y = 22 }, { x = -3, y = 22 }, { x = -2, y = 22 }, { x = -1, y = 22 }, { x = 0, y = 22 }, { x = 1, y = 22 }, { x = 2, y = 22 }, { x = 3, y = 22 }, { x = 4, y = 22 } }
|
||||
}
|
||||
|
||||
local function process_explosion_tile(pos, explosion_index, current_radius)
|
||||
local ffatable = Table.get_table()
|
||||
local surface = game.surfaces[ffatable.explosion_schedule[explosion_index].surface]
|
||||
local target_entities = surface.find_entities_filtered({ area = { { pos.x - 0.5, pos.y - 0.5 }, { pos.x + 0.499, pos.y + 0.499 } } })
|
||||
local explosion_animation = "explosion"
|
||||
|
||||
local tile = surface.get_tile(pos)
|
||||
if tile.name == "out-of-map" then
|
||||
if ffatable.explosion_schedule[explosion_index].damage_remaining >= out_of_map_tile_health then
|
||||
explosion_animation = "big-explosion"
|
||||
surface.set_tiles({ { name = "dirt-5", position = pos } }, true)
|
||||
end
|
||||
ffatable.explosion_schedule[explosion_index].damage_remaining = ffatable.explosion_schedule[explosion_index].damage_remaining - out_of_map_tile_health
|
||||
else
|
||||
local decay_explosion = true
|
||||
for _, entity in pairs(target_entities) do
|
||||
if entity.health then
|
||||
decay_explosion = false
|
||||
end
|
||||
end
|
||||
if decay_explosion then ffatable.explosion_schedule[explosion_index].damage_remaining = ffatable.explosion_schedule[explosion_index].damage_remaining - empty_tile_damage_decay end
|
||||
end
|
||||
|
||||
for _, entity in pairs(target_entities) do
|
||||
if entity.valid then
|
||||
if entity.health then
|
||||
if entity.health < ffatable.explosion_schedule[explosion_index].damage_remaining then
|
||||
explosion_animation = "big-explosion"
|
||||
if entity.health > 500 then explosion_animation = "big-artillery-explosion" end
|
||||
ffatable.explosion_schedule[explosion_index].damage_remaining = ffatable.explosion_schedule[explosion_index].damage_remaining - entity.health
|
||||
if entity.name ~= "character" then
|
||||
entity.damage(2097152, "player", "explosion")
|
||||
else
|
||||
entity.die("player")
|
||||
end
|
||||
else
|
||||
entity.damage(ffatable.explosion_schedule[explosion_index].damage_remaining, "player", "explosion")
|
||||
if entity.valid then
|
||||
ffatable.explosion_schedule[explosion_index].damage_remaining = ffatable.explosion_schedule[explosion_index].damage_remaining - entity.health
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if ffatable.explosion_schedule[explosion_index].damage_remaining > 5000 and current_radius < 2 then
|
||||
if math_random(1, 2) == 1 then
|
||||
explosion_animation = "big-explosion"
|
||||
else
|
||||
explosion_animation = "big-artillery-explosion"
|
||||
end
|
||||
end
|
||||
|
||||
surface.create_entity({ name = explosion_animation, position = pos })
|
||||
Pollution.explosion(pos, surface, explosion_animation)
|
||||
|
||||
if ffatable.explosion_schedule[explosion_index].damage_remaining <= 0 then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
local function volatility(inventory)
|
||||
local result = 0
|
||||
for item, v in pairs(explosive_items) do
|
||||
local c = inventory.get_item_count(item)
|
||||
result = result + (c * v)
|
||||
end
|
||||
return math_min(max_volatility, result)
|
||||
end
|
||||
|
||||
local function create_explosion_schedule(entity)
|
||||
local ffatable = Table.get_table()
|
||||
local inventory = defines.inventory.chest
|
||||
if entity.type == "car" then inventory = defines.inventory.car_trunk end
|
||||
local i = entity.get_inventory(inventory)
|
||||
local explosives_amount = volatility(i)
|
||||
if explosives_amount < 1 then return end
|
||||
local center_position = entity.position
|
||||
|
||||
if not ffatable.explosion_schedule then ffatable.explosion_schedule = {} end
|
||||
ffatable.explosion_schedule[#ffatable.explosion_schedule + 1] = {}
|
||||
ffatable.explosion_schedule[#ffatable.explosion_schedule].surface = entity.surface.name
|
||||
ffatable.explosion_schedule[#ffatable.explosion_schedule].damage_remaining = damage_per_explosive * explosives_amount
|
||||
|
||||
for current_radius = 1, 23, 1 do
|
||||
|
||||
ffatable.explosion_schedule[#ffatable.explosion_schedule][current_radius] = {}
|
||||
ffatable.explosion_schedule[#ffatable.explosion_schedule][current_radius].trigger_tick = game.tick + (current_radius * 8)
|
||||
|
||||
local circle_coords = circle_coordinates[current_radius]
|
||||
|
||||
for index, tile_position in pairs(circle_coords) do
|
||||
local pos = { x = center_position.x + tile_position.x, y = center_position.y + tile_position.y }
|
||||
ffatable.explosion_schedule[#ffatable.explosion_schedule][current_radius][index] = { x = pos.x, y = pos.y }
|
||||
end
|
||||
|
||||
end
|
||||
entity.die("player")
|
||||
end
|
||||
|
||||
local function on_entity_damaged(event)
|
||||
local entity = event.entity
|
||||
if not entity.valid then return end
|
||||
if not entity.health then return end
|
||||
if entity.health > entity.prototype.max_health * 0.75 then return end
|
||||
|
||||
if entity.type == "container" or entity.type == "logistic-container" then
|
||||
if math_random(1, 3) == 1 or entity.health <= 0 then
|
||||
create_explosion_schedule(event.entity)
|
||||
return
|
||||
end
|
||||
end
|
||||
if entity.type == "cargo-wagon" or entity.type == "car" then
|
||||
if entity.health <= 0 then
|
||||
create_explosion_schedule(entity)
|
||||
return
|
||||
end
|
||||
if entity.health < 150 and math_random(1, 3) == 1 then
|
||||
create_explosion_schedule(entity)
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function on_tick(event)
|
||||
local ffatable = Table.get_table()
|
||||
local tick = event.tick
|
||||
if ffatable.explosion_schedule then
|
||||
local explosion_schedule_is_alive = false
|
||||
for explosion_index = 1, #ffatable.explosion_schedule, 1 do
|
||||
if #ffatable.explosion_schedule[explosion_index] > 0 then
|
||||
explosion_schedule_is_alive = true
|
||||
for radius = 1, #ffatable.explosion_schedule[explosion_index], 1 do
|
||||
if ffatable.explosion_schedule[explosion_index][radius].trigger_tick == tick then
|
||||
for tile_index = 1, #ffatable.explosion_schedule[explosion_index][radius], 1 do
|
||||
local continue_explosion = process_explosion_tile(ffatable.explosion_schedule[explosion_index][radius][tile_index], explosion_index, radius)
|
||||
if not continue_explosion then
|
||||
ffatable.explosion_schedule[explosion_index] = {}
|
||||
break
|
||||
end
|
||||
end
|
||||
if radius == #ffatable.explosion_schedule[explosion_index] then ffatable.explosion_schedule[explosion_index] = {} end
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if not explosion_schedule_is_alive then ffatable.explosion_schedule = nil end
|
||||
end
|
||||
end
|
||||
|
||||
local on_init = function ()
|
||||
local ffatable = Table.get_table()
|
||||
ffatable.explosion_schedule = {}
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.on_init(on_init)
|
||||
Event.add(defines.events.on_entity_damaged, on_entity_damaged)
|
||||
Event.add(defines.events.on_tick, on_tick)
|
67
modules/scrap_towny_ffa/fish_reproduction.lua
Normal file
67
modules/scrap_towny_ffa/fish_reproduction.lua
Normal file
@ -0,0 +1,67 @@
|
||||
local Public = {}
|
||||
local math_random = math.random
|
||||
local math_floor = math.floor
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
|
||||
function Public.reproduce()
|
||||
local ffatable = Table.get_table()
|
||||
for _, town_center in pairs(ffatable.town_centers) do
|
||||
local surface = town_center.market.surface
|
||||
local position = town_center.market.position
|
||||
local fishes = surface.find_entities_filtered({ name = "fish", position = position, radius = 27 })
|
||||
if #fishes == 0 then return end
|
||||
if #fishes >= 100 then return end
|
||||
-- pick a random fish
|
||||
local t = math_random(1, #fishes)
|
||||
local fish = fishes[t]
|
||||
-- test against all other fishes
|
||||
local guppy = false
|
||||
for i, f in pairs(fishes) do
|
||||
if i ~= t then
|
||||
if math_floor(fish.position.x) == math_floor(f.position.x) and math_floor(fish.position.y) == math_floor(f.position.y) then
|
||||
guppy = true
|
||||
end
|
||||
end
|
||||
end
|
||||
if guppy == true then
|
||||
--log("fish spawn {" .. fish.position.x .. "," .. fish.position.y .. "}")
|
||||
surface.create_entity({ name = "water-splash", position = fish.position })
|
||||
surface.create_entity({ name = "fish", position = fish.position })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function on_player_used_capsule(event)
|
||||
if event.item.name ~= "raw-fish" then return end
|
||||
local player = game.players[event.player_index]
|
||||
local surface = player.surface
|
||||
local position = event.position
|
||||
local tile = player.surface.get_tile(position.x, position.y)
|
||||
|
||||
-- return back some of the health if not healthy
|
||||
if player.character.health < 250 then
|
||||
player.surface.play_sound({ path = "utility/armor_insert", position = player.position, volume_modifier = 1 })
|
||||
return
|
||||
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
|
||||
-- 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
|
||||
end
|
||||
-- otherwise return the fish and make no sound
|
||||
player.insert({ name = "raw-fish", count = 1 })
|
||||
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.add(defines.events.on_player_used_capsule, on_player_used_capsule)
|
||||
|
||||
return Public
|
194
modules/scrap_towny_ffa/fluids_are_explosive.lua
Normal file
194
modules/scrap_towny_ffa/fluids_are_explosive.lua
Normal file
@ -0,0 +1,194 @@
|
||||
--This will add a new game mechanic so that containers with certain fluids explode when they get damaged or are destroyed.
|
||||
--Made by MewMew
|
||||
local math_random = math.random
|
||||
local math_floor = math.floor
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
local Pollution = require "modules.scrap_towny_ffa.pollution"
|
||||
|
||||
local empty_tile_damage_decay = 50
|
||||
local out_of_map_tile_health = 1500
|
||||
|
||||
local container_types = {
|
||||
["storage-tank"] = true,
|
||||
["pipe"] = true,
|
||||
["pipe-to-ground"] = true
|
||||
}
|
||||
|
||||
local fluid_damages = { -- Fluid Whitelist -- add fluid and a damage value to enable
|
||||
["lubricant"] = 5,
|
||||
["crude-oil"] = 5,
|
||||
["gasoline"] = 8,
|
||||
["heavy-oil"] = 6,
|
||||
["light-oil"] = 7,
|
||||
["petroleum-gas"] = 8,
|
||||
}
|
||||
|
||||
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 process_explosion_tile(pos, explosion_index, current_radius)
|
||||
local ffatable = Table.get_table()
|
||||
local surface = game.surfaces[ffatable.fluid_explosion_schedule[explosion_index].surface]
|
||||
local target_entities = surface.find_entities_filtered({ area = { { pos.x - 0.5, pos.y - 0.5 }, { pos.x + 0.499, pos.y + 0.499 } } })
|
||||
local explosion_animation = "explosion"
|
||||
|
||||
local tile = surface.get_tile(pos)
|
||||
if tile.name == "out-of-map" then
|
||||
if ffatable.fluid_explosion_schedule[explosion_index].damage_remaining >= out_of_map_tile_health then
|
||||
explosion_animation = "big-explosion"
|
||||
surface.set_tiles({ { name = "dirt-5", position = pos } }, true)
|
||||
end
|
||||
ffatable.fluid_explosion_schedule[explosion_index].damage_remaining = ffatable.fluid_explosion_schedule[explosion_index].damage_remaining - out_of_map_tile_health
|
||||
else
|
||||
local decay_explosion = true
|
||||
for _, entity in pairs(target_entities) do
|
||||
if entity.health then
|
||||
decay_explosion = false
|
||||
end
|
||||
end
|
||||
if decay_explosion then ffatable.fluid_explosion_schedule[explosion_index].damage_remaining = ffatable.fluid_explosion_schedule[explosion_index].damage_remaining - empty_tile_damage_decay end
|
||||
end
|
||||
|
||||
for _, entity in pairs(target_entities) do
|
||||
if entity.valid then
|
||||
if entity.health then
|
||||
if entity.health <= ffatable.fluid_explosion_schedule[explosion_index].damage_remaining then
|
||||
explosion_animation = "big-explosion"
|
||||
if entity.health > 500 then explosion_animation = "big-artillery-explosion" end
|
||||
ffatable.fluid_explosion_schedule[explosion_index].damage_remaining = ffatable.fluid_explosion_schedule[explosion_index].damage_remaining - entity.health
|
||||
if entity.name ~= "character" then
|
||||
entity.damage(2097152, "player", "explosion")
|
||||
else
|
||||
entity.die("player")
|
||||
end
|
||||
else
|
||||
entity.damage(ffatable.fluid_explosion_schedule[explosion_index].damage_remaining, "player", "explosion")
|
||||
ffatable.fluid_explosion_schedule[explosion_index].damage_remaining = 0
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if ffatable.fluid_explosion_schedule[explosion_index].damage_remaining > 5000 and current_radius < 2 then
|
||||
if math_random(1, 2) == 1 then
|
||||
explosion_animation = "big-explosion"
|
||||
else
|
||||
explosion_animation = "big-artillery-explosion"
|
||||
end
|
||||
end
|
||||
|
||||
surface.create_entity({ name = explosion_animation, position = pos })
|
||||
Pollution.explosion(pos, surface, explosion_animation)
|
||||
|
||||
if ffatable.fluid_explosion_schedule[explosion_index].damage_remaining <= 0 then return false end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
local function create_explosion_schedule(entity)
|
||||
local ffatable = Table.get_table()
|
||||
local explosives_amount = math_floor(entity.fluidbox[1].amount)
|
||||
|
||||
if explosives_amount < 1 then return end
|
||||
local center_position = entity.position
|
||||
|
||||
if not ffatable.fluid_explosion_schedule then ffatable.fluid_explosion_schedule = {} end
|
||||
ffatable.fluid_explosion_schedule[#ffatable.fluid_explosion_schedule + 1] = {}
|
||||
ffatable.fluid_explosion_schedule[#ffatable.fluid_explosion_schedule].surface = entity.surface.name
|
||||
|
||||
ffatable.fluid_explosion_schedule[#ffatable.fluid_explosion_schedule].damage_remaining = fluid_damages[entity.fluidbox[1].name] * explosives_amount
|
||||
|
||||
local circle_coordinates = {
|
||||
[1] = { { x = 0, y = 0 } },
|
||||
[2] = { { x = -1, y = -1 }, { x = 1, y = -1 }, { x = 0, y = -1 }, { x = -1, y = 0 }, { x = -1, y = 1 }, { x = 0, y = 1 }, { x = 1, y = 1 }, { x = 1, y = 0 } },
|
||||
[3] = { { x = -2, y = -1 }, { x = -1, y = -2 }, { x = 1, y = -2 }, { x = 0, y = -2 }, { x = 2, y = -1 }, { x = -2, y = 1 }, { x = -2, y = 0 }, { x = 2, y = 1 }, { x = 2, y = 0 }, { x = -1, y = 2 }, { x = 1, y = 2 }, { x = 0, y = 2 } },
|
||||
[4] = { { x = -1, y = -3 }, { x = 1, y = -3 }, { x = 0, y = -3 }, { x = -3, y = -1 }, { x = -2, y = -2 }, { x = 3, y = -1 }, { x = 2, y = -2 }, { x = -3, y = 0 }, { x = -3, y = 1 }, { x = 3, y = 1 }, { x = 3, y = 0 }, { x = -2, y = 2 }, { x = -1, y = 3 }, { x = 0, y = 3 }, { x = 1, y = 3 }, { x = 2, y = 2 } },
|
||||
[5] = { { x = -3, y = -3 }, { x = -2, y = -3 }, { x = -1, y = -4 }, { x = -2, y = -4 }, { x = 1, y = -4 }, { x = 0, y = -4 }, { x = 2, y = -3 }, { x = 3, y = -3 }, { x = 2, y = -4 }, { x = -3, y = -2 }, { x = -4, y = -1 }, { x = -4, y = -2 }, { x = 3, y = -2 }, { x = 4, y = -1 }, { x = 4, y = -2 }, { x = -4, y = 1 }, { x = -4, y = 0 }, { x = 4, y = 1 }, { x = 4, y = 0 }, { x = -3, y = 3 }, { x = -3, y = 2 }, { x = -4, y = 2 }, { x = -2, y = 3 }, { x = 2, y = 3 }, { x = 3, y = 3 }, { x = 3, y = 2 }, { x = 4, y = 2 }, { x = -2, y = 4 }, { x = -1, y = 4 }, { x = 0, y = 4 }, { x = 1, y = 4 }, { x = 2, y = 4 } },
|
||||
[6] = { { x = -1, y = -5 }, { x = -2, y = -5 }, { x = 1, y = -5 }, { x = 0, y = -5 }, { x = 2, y = -5 }, { x = -3, y = -4 }, { x = -4, y = -3 }, { x = 3, y = -4 }, { x = 4, y = -3 }, { x = -5, y = -1 }, { x = -5, y = -2 }, { x = 5, y = -1 }, { x = 5, y = -2 }, { x = -5, y = 1 }, { x = -5, y = 0 }, { x = 5, y = 1 }, { x = 5, y = 0 }, { x = -5, y = 2 }, { x = -4, y = 3 }, { x = 4, y = 3 }, { x = 5, y = 2 }, { x = -3, y = 4 }, { x = -2, y = 5 }, { x = -1, y = 5 }, { x = 0, y = 5 }, { x = 1, y = 5 }, { x = 3, y = 4 }, { x = 2, y = 5 } },
|
||||
[7] = { { x = -4, y = -5 }, { x = -3, y = -5 }, { x = -2, y = -6 }, { x = -1, y = -6 }, { x = 0, y = -6 }, { x = 1, y = -6 }, { x = 3, y = -5 }, { x = 2, y = -6 }, { x = 4, y = -5 }, { x = -5, y = -4 }, { x = -5, y = -3 }, { x = -4, y = -4 }, { x = 4, y = -4 }, { x = 5, y = -4 }, { x = 5, y = -3 }, { x = -6, y = -1 }, { x = -6, y = -2 }, { x = 6, y = -1 }, { x = 6, y = -2 }, { x = -6, y = 1 }, { x = -6, y = 0 }, { x = 6, y = 1 }, { x = 6, y = 0 }, { x = -5, y = 3 }, { x = -6, y = 2 }, { x = 5, y = 3 }, { x = 6, y = 2 }, { x = -5, y = 4 }, { x = -4, y = 4 }, { x = -4, y = 5 }, { x = -3, y = 5 }, { x = 3, y = 5 }, { x = 4, y = 4 }, { x = 5, y = 4 }, { x = 4, y = 5 }, { x = -1, y = 6 }, { x = -2, y = 6 }, { x = 1, y = 6 }, { x = 0, y = 6 }, { x = 2, y = 6 } },
|
||||
[8] = { { x = -1, y = -7 }, { x = -2, y = -7 }, { x = 1, y = -7 }, { x = 0, y = -7 }, { x = 2, y = -7 }, { x = -5, y = -5 }, { x = -4, y = -6 }, { x = -3, y = -6 }, { x = 3, y = -6 }, { x = 4, y = -6 }, { x = 5, y = -5 }, { x = -6, y = -3 }, { x = -6, y = -4 }, { x = 6, y = -4 }, { x = 6, y = -3 }, { x = -7, y = -1 }, { x = -7, y = -2 }, { x = 7, y = -1 }, { x = 7, y = -2 }, { x = -7, y = 1 }, { x = -7, y = 0 }, { x = 7, y = 1 }, { x = 7, y = 0 }, { x = -7, y = 2 }, { x = -6, y = 3 }, { x = 6, y = 3 }, { x = 7, y = 2 }, { x = -5, y = 5 }, { x = -6, y = 4 }, { x = 5, y = 5 }, { x = 6, y = 4 }, { x = -3, y = 6 }, { x = -4, y = 6 }, { x = -2, y = 7 }, { x = -1, y = 7 }, { x = 0, y = 7 }, { x = 1, y = 7 }, { x = 3, y = 6 }, { x = 2, y = 7 }, { x = 4, y = 6 } },
|
||||
[9] = { { x = -4, y = -7 }, { x = -3, y = -7 }, { x = -2, y = -8 }, { x = -1, y = -8 }, { x = 0, y = -8 }, { x = 1, y = -8 }, { x = 3, y = -7 }, { x = 2, y = -8 }, { x = 4, y = -7 }, { x = -5, y = -6 }, { x = -6, y = -6 }, { x = -6, y = -5 }, { x = 5, y = -6 }, { x = 6, y = -5 }, { x = 6, y = -6 }, { x = -7, y = -4 }, { x = -7, y = -3 }, { x = 7, y = -4 }, { x = 7, y = -3 }, { x = -8, y = -2 }, { x = -8, y = -1 }, { x = 8, y = -1 }, { x = 8, y = -2 }, { x = -8, y = 0 }, { x = -8, y = 1 }, { x = 8, y = 1 }, { x = 8, y = 0 }, { x = -7, y = 3 }, { x = -8, y = 2 }, { x = 7, y = 3 }, { x = 8, y = 2 }, { x = -7, y = 4 }, { x = -6, y = 5 }, { x = 6, y = 5 }, { x = 7, y = 4 }, { x = -5, y = 6 }, { x = -6, y = 6 }, { x = -4, y = 7 }, { x = -3, y = 7 }, { x = 3, y = 7 }, { x = 5, y = 6 }, { x = 4, y = 7 }, { x = 6, y = 6 }, { x = -2, y = 8 }, { x = -1, y = 8 }, { x = 0, y = 8 }, { x = 1, y = 8 }, { x = 2, y = 8 } },
|
||||
[10] = { { x = -3, y = -9 }, { x = -1, y = -9 }, { x = -2, y = -9 }, { x = 1, y = -9 }, { x = 0, y = -9 }, { x = 3, y = -9 }, { x = 2, y = -9 }, { x = -5, y = -7 }, { x = -6, y = -7 }, { x = -5, y = -8 }, { x = -4, y = -8 }, { x = -3, y = -8 }, { x = 3, y = -8 }, { x = 5, y = -7 }, { x = 5, y = -8 }, { x = 4, y = -8 }, { x = 6, y = -7 }, { x = -7, y = -5 }, { x = -7, y = -6 }, { x = -8, y = -5 }, { x = 7, y = -5 }, { x = 7, y = -6 }, { x = 8, y = -5 }, { x = -9, y = -3 }, { x = -8, y = -4 }, { x = -8, y = -3 }, { x = 8, y = -4 }, { x = 8, y = -3 }, { x = 9, y = -3 }, { x = -9, y = -1 }, { x = -9, y = -2 }, { x = 9, y = -1 }, { x = 9, y = -2 }, { x = -9, y = 1 }, { x = -9, y = 0 }, { x = 9, y = 1 }, { x = 9, y = 0 }, { x = -9, y = 3 }, { x = -9, y = 2 }, { x = -8, y = 3 }, { x = 8, y = 3 }, { x = 9, y = 3 }, { x = 9, y = 2 }, { x = -7, y = 5 }, { x = -8, y = 5 }, { x = -8, y = 4 }, { x = 7, y = 5 }, { x = 8, y = 5 }, { x = 8, y = 4 }, { x = -7, y = 6 }, { x = -6, y = 7 }, { x = -5, y = 7 }, { x = 5, y = 7 }, { x = 7, y = 6 }, { x = 6, y = 7 }, { x = -5, y = 8 }, { x = -4, y = 8 }, { x = -3, y = 8 }, { x = -3, y = 9 }, { x = -2, y = 9 }, { x = -1, y = 9 }, { x = 0, y = 9 }, { x = 1, y = 9 }, { x = 3, y = 8 }, { x = 2, y = 9 }, { x = 3, y = 9 }, { x = 5, y = 8 }, { x = 4, y = 8 } },
|
||||
[11] = { { x = -5, y = -9 }, { x = -4, y = -9 }, { x = -3, y = -10 }, { x = -1, y = -10 }, { x = -2, y = -10 }, { x = 1, y = -10 }, { x = 0, y = -10 }, { x = 3, y = -10 }, { x = 2, y = -10 }, { x = 5, y = -9 }, { x = 4, y = -9 }, { x = -7, y = -7 }, { x = -6, y = -8 }, { x = 7, y = -7 }, { x = 6, y = -8 }, { x = -9, y = -5 }, { x = -8, y = -6 }, { x = 9, y = -5 }, { x = 8, y = -6 }, { x = -9, y = -4 }, { x = -10, y = -3 }, { x = 9, y = -4 }, { x = 10, y = -3 }, { x = -10, y = -2 }, { x = -10, y = -1 }, { x = 10, y = -1 }, { x = 10, y = -2 }, { x = -10, y = 0 }, { x = -10, y = 1 }, { x = 10, y = 1 }, { x = 10, y = 0 }, { x = -10, y = 2 }, { x = -10, y = 3 }, { x = 10, y = 3 }, { x = 10, y = 2 }, { x = -9, y = 4 }, { x = -9, y = 5 }, { x = 9, y = 5 }, { x = 9, y = 4 }, { x = -8, y = 6 }, { x = -7, y = 7 }, { x = 7, y = 7 }, { x = 8, y = 6 }, { x = -6, y = 8 }, { x = -5, y = 9 }, { x = -4, y = 9 }, { x = 4, y = 9 }, { x = 5, y = 9 }, { x = 6, y = 8 }, { x = -3, y = 10 }, { x = -2, y = 10 }, { x = -1, y = 10 }, { x = 0, y = 10 }, { x = 1, y = 10 }, { x = 2, y = 10 }, { x = 3, y = 10 } },
|
||||
[12] = { { x = -3, y = -11 }, { x = -2, y = -11 }, { x = -1, y = -11 }, { x = 0, y = -11 }, { x = 1, y = -11 }, { x = 2, y = -11 }, { x = 3, y = -11 }, { x = -7, y = -9 }, { x = -6, y = -9 }, { x = -5, y = -10 }, { x = -4, y = -10 }, { x = 5, y = -10 }, { x = 4, y = -10 }, { x = 7, y = -9 }, { x = 6, y = -9 }, { x = -9, y = -7 }, { x = -7, y = -8 }, { x = -8, y = -8 }, { x = -8, y = -7 }, { x = 7, y = -8 }, { x = 8, y = -7 }, { x = 8, y = -8 }, { x = 9, y = -7 }, { x = -9, y = -6 }, { x = -10, y = -5 }, { x = 9, y = -6 }, { x = 10, y = -5 }, { x = -11, y = -3 }, { x = -10, y = -4 }, { x = 10, y = -4 }, { x = 11, y = -3 }, { x = -11, y = -2 }, { x = -11, y = -1 }, { x = 11, y = -1 }, { x = 11, y = -2 }, { x = -11, y = 0 }, { x = -11, y = 1 }, { x = 11, y = 1 }, { x = 11, y = 0 }, { x = -11, y = 2 }, { x = -11, y = 3 }, { x = 11, y = 3 }, { x = 11, y = 2 }, { x = -10, y = 5 }, { x = -10, y = 4 }, { x = 10, y = 5 }, { x = 10, y = 4 }, { x = -9, y = 7 }, { x = -9, y = 6 }, { x = -8, y = 7 }, { x = 8, y = 7 }, { x = 9, y = 7 }, { x = 9, y = 6 }, { x = -8, y = 8 }, { x = -7, y = 8 }, { x = -7, y = 9 }, { x = -6, y = 9 }, { x = 7, y = 8 }, { x = 7, y = 9 }, { x = 6, y = 9 }, { x = 8, y = 8 }, { x = -5, y = 10 }, { x = -4, y = 10 }, { x = -3, y = 11 }, { x = -2, y = 11 }, { x = -1, y = 11 }, { x = 0, y = 11 }, { x = 1, y = 11 }, { x = 2, y = 11 }, { x = 3, y = 11 }, { x = 4, y = 10 }, { x = 5, y = 10 } },
|
||||
[13] = { { x = -5, y = -11 }, { x = -4, y = -11 }, { x = -3, y = -12 }, { x = -1, y = -12 }, { x = -2, y = -12 }, { x = 1, y = -12 }, { x = 0, y = -12 }, { x = 3, y = -12 }, { x = 2, y = -12 }, { x = 4, y = -11 }, { x = 5, y = -11 }, { x = -8, y = -9 }, { x = -7, y = -10 }, { x = -6, y = -10 }, { x = 6, y = -10 }, { x = 7, y = -10 }, { x = 8, y = -9 }, { x = -10, y = -7 }, { x = -9, y = -8 }, { x = 9, y = -8 }, { x = 10, y = -7 }, { x = -11, y = -5 }, { x = -10, y = -6 }, { x = 10, y = -6 }, { x = 11, y = -5 }, { x = -11, y = -4 }, { x = -12, y = -3 }, { x = 11, y = -4 }, { x = 12, y = -3 }, { x = -12, y = -1 }, { x = -12, y = -2 }, { x = 12, y = -1 }, { x = 12, y = -2 }, { x = -12, y = 1 }, { x = -12, y = 0 }, { x = 12, y = 1 }, { x = 12, y = 0 }, { x = -12, y = 3 }, { x = -12, y = 2 }, { x = 12, y = 3 }, { x = 12, y = 2 }, { x = -11, y = 5 }, { x = -11, y = 4 }, { x = 11, y = 4 }, { x = 11, y = 5 }, { x = -10, y = 7 }, { x = -10, y = 6 }, { x = 10, y = 6 }, { x = 10, y = 7 }, { x = -9, y = 8 }, { x = -8, y = 9 }, { x = 9, y = 8 }, { x = 8, y = 9 }, { x = -7, y = 10 }, { x = -5, y = 11 }, { x = -6, y = 10 }, { x = -4, y = 11 }, { x = 5, y = 11 }, { x = 4, y = 11 }, { x = 7, y = 10 }, { x = 6, y = 10 }, { x = -3, y = 12 }, { x = -2, y = 12 }, { x = -1, y = 12 }, { x = 0, y = 12 }, { x = 1, y = 12 }, { x = 2, y = 12 }, { x = 3, y = 12 } },
|
||||
[14] = { { x = -3, y = -13 }, { x = -1, y = -13 }, { x = -2, y = -13 }, { x = 1, y = -13 }, { x = 0, y = -13 }, { x = 3, y = -13 }, { x = 2, y = -13 }, { x = -7, y = -11 }, { x = -6, y = -11 }, { x = -5, y = -12 }, { x = -6, y = -12 }, { x = -4, y = -12 }, { x = 5, y = -12 }, { x = 4, y = -12 }, { x = 7, y = -11 }, { x = 6, y = -11 }, { x = 6, y = -12 }, { x = -10, y = -9 }, { x = -9, y = -9 }, { x = -9, y = -10 }, { x = -8, y = -10 }, { x = 9, y = -9 }, { x = 9, y = -10 }, { x = 8, y = -10 }, { x = 10, y = -9 }, { x = -11, y = -7 }, { x = -10, y = -8 }, { x = 11, y = -7 }, { x = 10, y = -8 }, { x = -11, y = -6 }, { x = -12, y = -6 }, { x = -12, y = -5 }, { x = 11, y = -6 }, { x = 12, y = -6 }, { x = 12, y = -5 }, { x = -13, y = -3 }, { x = -12, y = -4 }, { x = 12, y = -4 }, { x = 13, y = -3 }, { x = -13, y = -2 }, { x = -13, y = -1 }, { x = 13, y = -1 }, { x = 13, y = -2 }, { x = -13, y = 0 }, { x = -13, y = 1 }, { x = 13, y = 1 }, { x = 13, y = 0 }, { x = -13, y = 2 }, { x = -13, y = 3 }, { x = 13, y = 3 }, { x = 13, y = 2 }, { x = -12, y = 5 }, { x = -12, y = 4 }, { x = 12, y = 5 }, { x = 12, y = 4 }, { x = -11, y = 6 }, { x = -11, y = 7 }, { x = -12, y = 6 }, { x = 11, y = 7 }, { x = 11, y = 6 }, { x = 12, y = 6 }, { x = -10, y = 8 }, { x = -10, y = 9 }, { x = -9, y = 9 }, { x = 9, y = 9 }, { x = 10, y = 9 }, { x = 10, y = 8 }, { x = -9, y = 10 }, { x = -8, y = 10 }, { x = -7, y = 11 }, { x = -6, y = 11 }, { x = 7, y = 11 }, { x = 6, y = 11 }, { x = 8, y = 10 }, { x = 9, y = 10 }, { x = -6, y = 12 }, { x = -5, y = 12 }, { x = -4, y = 12 }, { x = -3, y = 13 }, { x = -2, y = 13 }, { x = -1, y = 13 }, { x = 0, y = 13 }, { x = 1, y = 13 }, { x = 2, y = 13 }, { x = 3, y = 13 }, { x = 5, y = 12 }, { x = 4, y = 12 }, { x = 6, y = 12 } },
|
||||
[15] = { { x = -5, y = -13 }, { x = -6, y = -13 }, { x = -4, y = -13 }, { x = -3, y = -14 }, { x = -1, y = -14 }, { x = -2, y = -14 }, { x = 1, y = -14 }, { x = 0, y = -14 }, { x = 3, y = -14 }, { x = 2, y = -14 }, { x = 5, y = -13 }, { x = 4, y = -13 }, { x = 6, y = -13 }, { x = -9, y = -11 }, { x = -8, y = -11 }, { x = -8, y = -12 }, { x = -7, y = -12 }, { x = 7, y = -12 }, { x = 8, y = -12 }, { x = 8, y = -11 }, { x = 9, y = -11 }, { x = -11, y = -9 }, { x = -10, y = -10 }, { x = 10, y = -10 }, { x = 11, y = -9 }, { x = -12, y = -7 }, { x = -11, y = -8 }, { x = -12, y = -8 }, { x = 11, y = -8 }, { x = 12, y = -8 }, { x = 12, y = -7 }, { x = -13, y = -5 }, { x = -13, y = -6 }, { x = 13, y = -5 }, { x = 13, y = -6 }, { x = -13, y = -4 }, { x = -14, y = -3 }, { x = 13, y = -4 }, { x = 14, y = -3 }, { x = -14, y = -2 }, { x = -14, y = -1 }, { x = 14, y = -1 }, { x = 14, y = -2 }, { x = -14, y = 0 }, { x = -14, y = 1 }, { x = 14, y = 1 }, { x = 14, y = 0 }, { x = -14, y = 2 }, { x = -14, y = 3 }, { x = 14, y = 3 }, { x = 14, y = 2 }, { x = -13, y = 4 }, { x = -13, y = 5 }, { x = 13, y = 5 }, { x = 13, y = 4 }, { x = -13, y = 6 }, { x = -12, y = 7 }, { x = 12, y = 7 }, { x = 13, y = 6 }, { x = -11, y = 9 }, { x = -11, y = 8 }, { x = -12, y = 8 }, { x = 11, y = 8 }, { x = 11, y = 9 }, { x = 12, y = 8 }, { x = -9, y = 11 }, { x = -10, y = 10 }, { x = -8, y = 11 }, { x = 9, y = 11 }, { x = 8, y = 11 }, { x = 10, y = 10 }, { x = -7, y = 12 }, { x = -8, y = 12 }, { x = -6, y = 13 }, { x = -5, y = 13 }, { x = -4, y = 13 }, { x = 5, y = 13 }, { x = 4, y = 13 }, { x = 7, y = 12 }, { x = 6, y = 13 }, { x = 8, y = 12 }, { x = -3, y = 14 }, { x = -2, y = 14 }, { x = -1, y = 14 }, { x = 0, y = 14 }, { x = 1, y = 14 }, { x = 2, y = 14 }, { x = 3, y = 14 } },
|
||||
[16] = { { x = -3, y = -15 }, { x = -1, y = -15 }, { x = -2, y = -15 }, { x = 1, y = -15 }, { x = 0, y = -15 }, { x = 3, y = -15 }, { x = 2, y = -15 }, { x = -7, y = -13 }, { x = -8, y = -13 }, { x = -5, y = -14 }, { x = -6, y = -14 }, { x = -4, y = -14 }, { x = 5, y = -14 }, { x = 4, y = -14 }, { x = 7, y = -13 }, { x = 6, y = -14 }, { x = 8, y = -13 }, { x = -9, y = -12 }, { x = -10, y = -11 }, { x = 9, y = -12 }, { x = 10, y = -11 }, { x = -11, y = -10 }, { x = -12, y = -9 }, { x = 11, y = -10 }, { x = 12, y = -9 }, { x = -13, y = -7 }, { x = -13, y = -8 }, { x = 13, y = -7 }, { x = 13, y = -8 }, { x = -14, y = -6 }, { x = -14, y = -5 }, { x = 14, y = -5 }, { x = 14, y = -6 }, { x = -15, y = -3 }, { x = -14, y = -4 }, { x = 15, y = -3 }, { x = 14, y = -4 }, { x = -15, y = -2 }, { x = -15, y = -1 }, { x = 15, y = -1 }, { x = 15, y = -2 }, { x = -15, y = 0 }, { x = -15, y = 1 }, { x = 15, y = 1 }, { x = 15, y = 0 }, { x = -15, y = 2 }, { x = -15, y = 3 }, { x = 15, y = 3 }, { x = 15, y = 2 }, { x = -14, y = 5 }, { x = -14, y = 4 }, { x = 14, y = 5 }, { x = 14, y = 4 }, { x = -13, y = 7 }, { x = -14, y = 6 }, { x = 13, y = 7 }, { x = 14, y = 6 }, { x = -13, y = 8 }, { x = -12, y = 9 }, { x = 12, y = 9 }, { x = 13, y = 8 }, { x = -11, y = 10 }, { x = -10, y = 11 }, { x = 10, y = 11 }, { x = 11, y = 10 }, { x = -9, y = 12 }, { x = -8, y = 13 }, { x = -7, y = 13 }, { x = 7, y = 13 }, { x = 8, y = 13 }, { x = 9, y = 12 }, { x = -6, y = 14 }, { x = -5, y = 14 }, { x = -4, y = 14 }, { x = -3, y = 15 }, { x = -2, y = 15 }, { x = -1, y = 15 }, { x = 0, y = 15 }, { x = 1, y = 15 }, { x = 2, y = 15 }, { x = 3, y = 15 }, { x = 4, y = 14 }, { x = 5, y = 14 }, { x = 6, y = 14 } }
|
||||
}
|
||||
|
||||
for current_radius = 1, 16, 1 do
|
||||
|
||||
ffatable.fluid_explosion_schedule[#ffatable.fluid_explosion_schedule][current_radius] = {}
|
||||
ffatable.fluid_explosion_schedule[#ffatable.fluid_explosion_schedule][current_radius].trigger_tick = game.tick + (current_radius * 8)
|
||||
|
||||
local circle_coords = circle_coordinates[current_radius]
|
||||
circle_coords = shuffle(circle_coords)
|
||||
|
||||
for index, tile_position in pairs(circle_coords) do
|
||||
local pos = { x = center_position.x + tile_position.x, y = center_position.y + tile_position.y }
|
||||
ffatable.fluid_explosion_schedule[#ffatable.fluid_explosion_schedule][current_radius][index] = { x = pos.x, y = pos.y }
|
||||
end
|
||||
|
||||
end
|
||||
entity.die("player")
|
||||
end
|
||||
|
||||
local function on_entity_damaged(event)
|
||||
local entity = event.entity
|
||||
if not entity.valid then return end
|
||||
if not entity.health then return end
|
||||
if not container_types[entity.type] then return end
|
||||
if not entity.fluidbox[1] then return end
|
||||
if not fluid_damages[entity.fluidbox[1].name] then return end
|
||||
if entity.health > entity.prototype.max_health * 0.75 then return end
|
||||
|
||||
if math.random(1, 3) == 1 or entity.health <= 0 then
|
||||
create_explosion_schedule(entity)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
local function on_tick(event)
|
||||
local ffatable = Table.get_table()
|
||||
local tick = event.tick
|
||||
if ffatable.fluid_explosion_schedule then
|
||||
local explosion_schedule_is_alive = false
|
||||
for explosion_index = 1, #ffatable.fluid_explosion_schedule, 1 do
|
||||
if #ffatable.fluid_explosion_schedule[explosion_index] > 0 then
|
||||
explosion_schedule_is_alive = true
|
||||
for radius = 1, #ffatable.fluid_explosion_schedule[explosion_index], 1 do
|
||||
if ffatable.fluid_explosion_schedule[explosion_index][radius].trigger_tick == tick then
|
||||
for tile_index = 1, #ffatable.fluid_explosion_schedule[explosion_index][radius], 1 do
|
||||
local continue_explosion = process_explosion_tile(ffatable.fluid_explosion_schedule[explosion_index][radius][tile_index], explosion_index, radius)
|
||||
if not continue_explosion then
|
||||
ffatable.fluid_explosion_schedule[explosion_index] = {}
|
||||
break
|
||||
end
|
||||
end
|
||||
if radius == #ffatable.fluid_explosion_schedule[explosion_index] then ffatable.fluid_explosion_schedule[explosion_index] = {} end
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
if not explosion_schedule_is_alive then ffatable.fluid_explosion_schedule = nil end
|
||||
end
|
||||
end
|
||||
|
||||
local on_init = function ()
|
||||
local ffatable = Table.get_table()
|
||||
ffatable.fluid_explosion_schedule = {}
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.on_init(on_init)
|
||||
Event.add(defines.events.on_entity_damaged, on_entity_damaged)
|
||||
Event.add(defines.events.on_tick, on_tick)
|
125
modules/scrap_towny_ffa/info.lua
Normal file
125
modules/scrap_towny_ffa/info.lua
Normal file
@ -0,0 +1,125 @@
|
||||
local Public = {}
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
|
||||
local info = [[You are an "outlander" stuck on this god-forsaken planet with a bunch of other desolate fools. You can choose to join
|
||||
an existing town if accepted, or go at it alone, building your own outpost or living as an "outlander".
|
||||
|
||||
The local inhabitants are indifferent to you at first, so long as you don't build or pollute, but become increasingly aggressive
|
||||
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.
|
||||
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.
|
||||
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
|
||||
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.
|
||||
|
||||
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
|
||||
town falls, members will be disbanded, and all buildings will become neutral and lootable.
|
||||
|
||||
When building your town, note that you may only build nearby existing structures such as your town market and walls and
|
||||
any other structure you have placed. Beware that biters and spitters become more aggressive towards towns that are
|
||||
advanced in research. Their evolution will scale around technology progress in any nearby towns and pollution levels.
|
||||
|
||||
This is a FFA ("Free-For-All") world. Short of bullying and derogatory remarks, anything goes. Griefing is encouraged,
|
||||
so best to setup proper defenses for your town or outpost to fend off enemies when you are there and away.
|
||||
|
||||
Have fun and be comfy ^.^]]
|
||||
|
||||
function Public.toggle_button(player)
|
||||
if player.gui.top["towny_map_intro_button"] then return end
|
||||
local b = player.gui.top.add({ type = "sprite-button", caption = "Towny", name = "towny_map_intro_button", tooltip = "Show Info" })
|
||||
b.style.font_color = { r = 0.5, g = 0.3, b = 0.99 }
|
||||
b.style.font = "heading-1"
|
||||
b.style.minimal_height = 38
|
||||
b.style.minimal_width = 80
|
||||
b.style.top_padding = 1
|
||||
b.style.left_padding = 1
|
||||
b.style.right_padding = 1
|
||||
b.style.bottom_padding = 1
|
||||
end
|
||||
|
||||
function Public.show(player)
|
||||
local ffatable = Table.get_table()
|
||||
if player.gui.center["towny_map_intro_frame"] then player.gui.center["towny_map_intro_frame"].destroy() end
|
||||
local frame = player.gui.center.add { type = "frame", name = "towny_map_intro_frame" }
|
||||
frame = frame.add { type = "frame", direction = "vertical" }
|
||||
|
||||
local t = frame.add { type = "table", column_count = 2 }
|
||||
|
||||
local label = t.add { type = "label", caption = "Active Factions:" }
|
||||
label.style.font = "heading-1"
|
||||
label.style.font_color = { r = 0.85, g = 0.85, b = 0.85 }
|
||||
label.style.right_padding = 8
|
||||
|
||||
t = t.add { type = "table", column_count = 4 }
|
||||
|
||||
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 .. ")" }
|
||||
label3.style.font = "heading-3"
|
||||
label3.style.minimal_width = 80
|
||||
label3.style.font_color = town_center.color
|
||||
end
|
||||
|
||||
frame.add { type = "line" }
|
||||
|
||||
local l = frame.add { type = "label", caption = "Instructions:" }
|
||||
l.style.font = "heading-1"
|
||||
l.style.font_color = { r = 0.85, g = 0.85, b = 0.85 }
|
||||
|
||||
local l2 = frame.add { type = "label", caption = info }
|
||||
l2.style.single_line = false
|
||||
l2.style.font = "heading-2"
|
||||
l2.style.font_color = { r = 0.8, g = 0.7, b = 0.99 }
|
||||
end
|
||||
|
||||
function Public.close(event)
|
||||
if not event.element then return end
|
||||
if not event.element.valid then return end
|
||||
local parent = event.element.parent
|
||||
for _ = 1, 4, 1 do
|
||||
if not parent then return end
|
||||
if parent.name == "towny_map_intro_frame" then
|
||||
parent.destroy()
|
||||
return
|
||||
end
|
||||
parent = parent.parent
|
||||
end
|
||||
end
|
||||
|
||||
function Public.toggle(event)
|
||||
if not event.element then return end
|
||||
if not event.element.valid then return end
|
||||
if event.element.name == "towny_map_intro_button" then
|
||||
local player = game.players[event.player_index]
|
||||
if player.gui.center["towny_map_intro_frame"] then
|
||||
player.gui.center["towny_map_intro_frame"].destroy()
|
||||
else
|
||||
Public.show(player)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function on_gui_click(event)
|
||||
Public.close(event)
|
||||
Public.toggle(event)
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.add(defines.events.on_gui_click, on_gui_click)
|
||||
|
||||
return Public
|
15
modules/scrap_towny_ffa/limited_radar.lua
Normal file
15
modules/scrap_towny_ffa/limited_radar.lua
Normal file
@ -0,0 +1,15 @@
|
||||
local Public = {}
|
||||
|
||||
function Public.reset()
|
||||
for index = 1, table.size(game.forces), 1 do
|
||||
local force = game.forces[index]
|
||||
if force ~= nil then
|
||||
force.clear_chart("nauvis")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
--local Event = require 'utils.event'
|
||||
--Event.add(defines.events.on_chunk_charted, on_chunk_charted)
|
||||
|
||||
return Public
|
295
modules/scrap_towny_ffa/market.lua
Normal file
295
modules/scrap_towny_ffa/market.lua
Normal file
@ -0,0 +1,295 @@
|
||||
local table_insert = table.insert
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
local Town_center = require 'modules.scrap_towny_ffa.town_center'
|
||||
|
||||
local upgrade_functions = {
|
||||
-- Upgrade Town Center Health
|
||||
[1] = function(town_center, player)
|
||||
local market = town_center.market
|
||||
local surface = market.surface
|
||||
if town_center.max_health > 500000 then return 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 })
|
||||
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 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 })
|
||||
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 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 })
|
||||
end,
|
||||
-- Laser Turret Slot
|
||||
[4] = 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 })
|
||||
end,
|
||||
-- Set Spawn Point
|
||||
[5] = function(town_center, player)
|
||||
local ffatable = Table.get_table()
|
||||
local market = town_center.market
|
||||
local force = market.force
|
||||
local surface = market.surface
|
||||
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 })
|
||||
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(town_center)
|
||||
local market = town_center.market
|
||||
local force = market.force
|
||||
|
||||
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!" }
|
||||
end
|
||||
if force.character_inventory_slots_bonus <= 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!" }
|
||||
end
|
||||
if town_center.upgrades.mining_prod < 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!" }
|
||||
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 }
|
||||
local spawn_point = "Set Spawn Point"
|
||||
special_offers[5] = { { { "coin", 1 } }, spawn_point }
|
||||
|
||||
local market_items = {}
|
||||
|
||||
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', 1 } }, offer = { type = 'give-item', item = 'wood', count = 6 } })
|
||||
table_insert(market_items, { price = { { 'coin', 1 } }, offer = { type = 'give-item', item = 'iron-ore', count = 6 } })
|
||||
table_insert(market_items, { price = { { 'coin', 1 } }, offer = { type = 'give-item', item = 'copper-ore', count = 6 } })
|
||||
table_insert(market_items, { price = { { 'coin', 1 } }, offer = { type = 'give-item', item = 'stone', count = 6 } })
|
||||
table_insert(market_items, { price = { { 'coin', 1 } }, offer = { type = 'give-item', item = 'coal', count = 6 } })
|
||||
table_insert(market_items, { price = { { 'coin', 1 } }, offer = { type = 'give-item', item = 'uranium-ore', count = 4 } })
|
||||
table_insert(market_items, { price = { { 'coin', 300 } }, offer = { type = 'give-item', item = 'loader', count = 1 } })
|
||||
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 = { { '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 } })
|
||||
table_insert(market_items, { price = { { 'stone', 7 } }, offer = { type = 'give-item', item = 'coin', count = 1 } })
|
||||
table_insert(market_items, { price = { { 'coal', 7 } }, offer = { type = 'give-item', item = 'coin', count = 1 } })
|
||||
table_insert(market_items, { price = { { 'uranium-ore', 5 } }, 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 = { { 'iron-gear-wheel', 3 } }, 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 = { { 'empty-barrel', 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 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 ~= "market" then return end
|
||||
local town_center = ffatable.town_centers[market.force.name]
|
||||
if not town_center then return end
|
||||
clear_offers(market)
|
||||
set_offers(town_center)
|
||||
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 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
|
||||
local offers = market.get_market_items()
|
||||
local price = offers[offer_index].price[1].amount
|
||||
player.insert({ name = "coin", count = price * (count - 1) })
|
||||
end
|
||||
end
|
||||
|
||||
local function on_gui_opened(event)
|
||||
local gui_type = event.gui_type
|
||||
if gui_type ~= defines.gui_type.entity then return end
|
||||
local entity = event.entity
|
||||
if entity == nil or not entity.valid then return end
|
||||
if entity.type == "market" then refresh_offers(event) end
|
||||
end
|
||||
|
||||
local function on_market_item_purchased(event)
|
||||
offer_purchased(event)
|
||||
refresh_offers(event)
|
||||
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 end
|
||||
local items = { "burner-inserter", "inserter", "long-handed-inserter", "fast-inserter",
|
||||
"filter-inserter", "stack-inserter", "stack-filter-inserter",
|
||||
"loader", "fast-loader", "express-loader" }
|
||||
for _, town_center in pairs(ffatable.town_centers) do
|
||||
local market = town_center.market
|
||||
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
|
||||
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
|
||||
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)
|
||||
Event.add(defines.events.on_market_item_purchased, on_market_item_purchased)
|
||||
|
98
modules/scrap_towny_ffa/mining.lua
Normal file
98
modules/scrap_towny_ffa/mining.lua
Normal file
@ -0,0 +1,98 @@
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
|
||||
local crash_site = {
|
||||
-- simple entity with owner
|
||||
"crash-site-spaceship-wreck-small-1",
|
||||
"crash-site-spaceship-wreck-small-2",
|
||||
"crash-site-spaceship-wreck-small-3",
|
||||
"crash-site-spaceship-wreck-small-4",
|
||||
"crash-site-spaceship-wreck-small-5",
|
||||
"crash-site-spaceship-wreck-small-6",
|
||||
-- containers
|
||||
"big-ship-wreck-1",
|
||||
"big-ship-wreck-2",
|
||||
"big-ship-wreck-3",
|
||||
"crash-site-chest-1",
|
||||
"crash-site-chest-2",
|
||||
"crash-site-spaceship-wreck-medium-1",
|
||||
"crash-site-spaceship-wreck-medium-2",
|
||||
"crash-site-spaceship-wreck-medium-3",
|
||||
"crash-site-spaceship-wreck-big-1",
|
||||
"crash-site-spaceship-wreck-big-2",
|
||||
"crash-site-spaceship"
|
||||
}
|
||||
|
||||
local function is_crash_site(entity)
|
||||
if not entity.valid then return false end
|
||||
local f = false
|
||||
for i = 1, #crash_site, 1 do
|
||||
if entity.name == crash_site[i] then f = true end
|
||||
end
|
||||
return f
|
||||
end
|
||||
|
||||
local function mining_sound(player)
|
||||
if game.tick % 15 ~= 0 then return end
|
||||
local target = player.selected
|
||||
if target == nil or not target.valid then return end
|
||||
local surface = target.surface
|
||||
local position = target.position
|
||||
local path = "entity-mining/" .. target.name
|
||||
surface.play_sound({path = path, position = position, volume_modifier = 1, override_sound_type = "game-effect" })
|
||||
end
|
||||
|
||||
local function on_tick()
|
||||
local ffatable = Table.get_table()
|
||||
for index, player in pairs(game.players) do
|
||||
if player.character ~= nil then
|
||||
local mining = player.mining_state.mining
|
||||
if ffatable.mining[index] ~= mining then
|
||||
ffatable.mining[index] = mining
|
||||
-- state change
|
||||
if mining == true then
|
||||
--log(player.name .. " started mining")
|
||||
local target = player.selected
|
||||
if target ~= nil and target.valid then
|
||||
--log("target name = " .. target.prototype.name)
|
||||
--log("position = " .. serpent.block(target.position))
|
||||
--log("mineable_properties = " .. serpent.block(target.prototype.mineable_properties))
|
||||
if is_crash_site(target) then
|
||||
-- mining crash site
|
||||
mining_sound(player)
|
||||
ffatable.mining_target[index] = target
|
||||
end
|
||||
end
|
||||
else
|
||||
--log(player.name .. " stopped mining")
|
||||
local target = ffatable.mining_target[index]
|
||||
if target ~= nil then
|
||||
ffatable.mining_target[index] = nil
|
||||
end
|
||||
end
|
||||
else
|
||||
if mining == true then
|
||||
local target = player.selected
|
||||
if target ~= nil and target.valid then
|
||||
--local progress = player.character_mining_progress
|
||||
--log("progress = " .. progress)
|
||||
if is_crash_site(target) then
|
||||
-- mining crash site
|
||||
mining_sound(player)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local on_init = function ()
|
||||
local ffatable = Table.get_table()
|
||||
ffatable.mining = {}
|
||||
ffatable.mining_entity = {}
|
||||
ffatable.mining_target = {}
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.on_init(on_init)
|
||||
Event.add(defines.events.on_tick, on_tick)
|
203
modules/scrap_towny_ffa/nauvis.lua
Normal file
203
modules/scrap_towny_ffa/nauvis.lua
Normal file
@ -0,0 +1,203 @@
|
||||
local Public = {}
|
||||
local math_random = math.random
|
||||
|
||||
local function create_limbo()
|
||||
game.create_surface("limbo")
|
||||
end
|
||||
|
||||
local function initialize_nauvis()
|
||||
local surface = game.surfaces["nauvis"]
|
||||
|
||||
-- this overrides what is in the map_gen_settings.json file
|
||||
local mgs = surface.map_gen_settings
|
||||
mgs.default_enable_all_autoplace_controls = true -- don't mess with this!
|
||||
mgs.autoplace_controls = {
|
||||
coal = { frequency = "none", size = 1, richness = "normal" },
|
||||
stone = { frequency = "none", size = 1, richness = "normal" },
|
||||
["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" },
|
||||
trees = { frequency = 2, size = "normal", richness = "normal" },
|
||||
["enemy-base"] = { frequency = 8, size = 1, richness = "normal" }
|
||||
}
|
||||
mgs.autoplace_settings = {
|
||||
entity = {
|
||||
settings = {
|
||||
["rock-huge"] = { frequency = 3, 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" },
|
||||
}
|
||||
},
|
||||
decorative = {
|
||||
settings = {
|
||||
["rock-tiny"] = { frequency = 10, size = "normal", richness = "normal" },
|
||||
["rock-small"] = { frequency = 5, size = "normal", richness = "normal" },
|
||||
["rock-medium"] = { frequency = 2, size = "normal", richness = "normal" },
|
||||
["sand-rock-small"] = { frequency = 10, size = "normal", richness = "normal" },
|
||||
["sand-rock-medium"] = { frequency = 5, size = "normal", richness = "normal" }
|
||||
}
|
||||
}
|
||||
}
|
||||
mgs.cliff_settings = {
|
||||
name = "cliff",
|
||||
cliff_elevation_0 = 5,
|
||||
cliff_elevation_interval = 10,
|
||||
richness = 0.4
|
||||
}
|
||||
-- water = 0 means no water allowed
|
||||
-- water = 1 means elevation is not reduced when calculating water tiles (elevation < 0)
|
||||
-- water = 2 means elevation is reduced by 10 when calculating water tiles (elevation < 0)
|
||||
-- or rather, the water table is 10 above the normal elevation
|
||||
mgs.water = 0.5
|
||||
mgs.peaceful_mode = false
|
||||
mgs.starting_area = "none"
|
||||
mgs.terrain_segmentation = 8
|
||||
mgs.width = 2048
|
||||
mgs.height = 2048
|
||||
--mgs.starting_points = {
|
||||
-- {x = 0, y = 0}
|
||||
--}
|
||||
mgs.research_queue_from_the_start = "always"
|
||||
-- here we put the named noise expressions for the specific noise-layer if we want to override them
|
||||
mgs.property_expression_names = {
|
||||
-- here we are overriding the moisture noise-layer with a fixed value of 0 to keep moisture consistently dry across the map
|
||||
-- it allows to free up the moisture noise expression
|
||||
-- low moisture
|
||||
--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
|
||||
-- aux should be not sand, nor red sand
|
||||
--aux = 0.5,
|
||||
|
||||
-- here we are overriding the temperature noise-layer with a fixed value to keep temperature consistent across the map
|
||||
-- it allows to free up the temperature noise expression
|
||||
-- temperature should be 20C or 68F
|
||||
--temperature = 20,
|
||||
|
||||
-- here we are overriding the cliffiness noise-layer with a fixed value of 0 to disable cliffs
|
||||
-- it allows to free up the cliffiness noise expression (which may or may not be useful)
|
||||
-- disable cliffs
|
||||
--cliffiness = 0,
|
||||
|
||||
-- we can disable starting lakes two ways, one by setting starting-lake-noise-amplitude = 0
|
||||
-- or by making the elevation a very large number
|
||||
-- make sure starting lake amplitude is 0 to disable starting lakes
|
||||
["starting-lake-noise-amplitude"] = 0,
|
||||
|
||||
-- allow enemies to get up close on spawn
|
||||
["starting-area"] = 0,
|
||||
|
||||
-- this accepts a string representing a named noise expression
|
||||
-- or number to determine the elevation based on x, y and distance from starting points
|
||||
-- we can not add a named noise expression at this point, we can only reference existing ones
|
||||
-- if we have any custom noise expressions defined from a mod, we will be able to use them here
|
||||
-- setting it to a fixed number would mean a flat map
|
||||
-- elevation < 0 means there is water unless the water table has been changed
|
||||
--elevation = -1,
|
||||
--elevation = 0,
|
||||
--elevation-persistence = 0,
|
||||
|
||||
-- testing
|
||||
--["control-setting:moisture:bias"] = 0.5,
|
||||
--["control-setting:moisture:frequency:multiplier"] = 0,
|
||||
--["control-setting:aux:bias"] = 0.5,
|
||||
--["control-setting:aux:frequency:multiplier"] = 1,
|
||||
--["control-setting:temperature:bias"] = 0.01,
|
||||
--["control-setting:temperature:frequency:multiplier"] = 100,
|
||||
|
||||
--["tile:water:probability"] = -1000,
|
||||
--["tile:deep-water:probability"] = -1000,
|
||||
|
||||
-- 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,
|
||||
|
||||
-- this will make and average base radius around 12 tiles
|
||||
["enemy-base-radius"] = 12
|
||||
}
|
||||
mgs.seed = math_random(10000, 99999)
|
||||
surface.map_gen_settings = mgs
|
||||
surface.peaceful_mode = false
|
||||
surface.always_day = false
|
||||
surface.freeze_daytime = false
|
||||
surface.clear(true)
|
||||
surface.regenerate_entity({ "rock-huge", "rock-big", "sand-rock-big" })
|
||||
surface.regenerate_decorative()
|
||||
end
|
||||
|
||||
function Public.initialize()
|
||||
-- difficulty settings
|
||||
game.difficulty_settings.recipe_difficulty = defines.difficulty_settings.recipe_difficulty.normal
|
||||
game.difficulty_settings.technology_difficulty = defines.difficulty_settings.technology_difficulty.normal
|
||||
game.difficulty_settings.technology_price_multiplier = 0.50
|
||||
|
||||
-- pollution settings
|
||||
game.map_settings.pollution.enabled = true
|
||||
game.map_settings.pollution.diffusion_ratio = 0.02 -- amount that is diffused to neighboring chunk each second
|
||||
game.map_settings.pollution.min_to_diffuse = 15 -- minimum number of pollution units on the chunk to start diffusing
|
||||
game.map_settings.pollution.ageing = 1 -- percent of pollution eaten by a chunk's tiles per second
|
||||
game.map_settings.pollution.expected_max_per_chunk = 150 -- anything greater than this number of pollution units is visualized similarly
|
||||
game.map_settings.pollution.min_to_show_per_chunk = 50
|
||||
game.map_settings.pollution.min_pollution_to_damage_trees = 60
|
||||
game.map_settings.pollution.pollution_with_max_forest_damage = 150
|
||||
game.map_settings.pollution.pollution_per_tree_damage = 50
|
||||
game.map_settings.pollution.pollution_restored_per_tree_damage = 10
|
||||
game.map_settings.pollution.max_pollution_to_restore_trees = 20
|
||||
game.map_settings.pollution.enemy_attack_pollution_consumption_modifier = 1
|
||||
|
||||
-- enemy evolution settings
|
||||
game.map_settings.enemy_evolution.enabled = true
|
||||
game.map_settings.enemy_evolution.time_factor = 0.0 -- percent increase in the evolution factor per second
|
||||
game.map_settings.enemy_evolution.destroy_factor = 0.0 -- percent increase in the evolution factor for each spawner destroyed
|
||||
game.map_settings.enemy_evolution.pollution_factor = 0.0 -- percent increase in the evolution factor for each pollution unit
|
||||
|
||||
-- enemy expansion settings
|
||||
game.map_settings.enemy_expansion.enabled = true
|
||||
game.map_settings.enemy_expansion.max_expansion_distance = 7 -- maximum distance in chunks from the nearest base (4 = 128 tiles)
|
||||
game.map_settings.enemy_expansion.friendly_base_influence_radius = 4 -- consider other nests within radius number of chunks (2 = 64 tiles)
|
||||
game.map_settings.enemy_expansion.other_base_coefficient = 2.0 -- multiply by coefficient for friendly bases
|
||||
game.map_settings.enemy_expansion.neighbouring_base_chunk_coefficient = 0.4 -- multiply by coefficient for friendly bases (^distance)
|
||||
game.map_settings.enemy_expansion.enemy_building_influence_radius = 4 -- consider player buildings within radius number of chunks
|
||||
game.map_settings.enemy_expansion.building_coefficient = 1.0 -- multiply by coefficient for player buildings
|
||||
game.map_settings.enemy_expansion.neighbouring_chunk_coefficient = 0.5 -- multiply by coefficient for player buildings (^distance)
|
||||
game.map_settings.enemy_expansion.max_colliding_tiles_coefficient = 0.9 -- percent of unbuildable tiles to not be considered a candidate
|
||||
game.map_settings.enemy_expansion.settler_group_min_size = 4 -- min size of group for building a base (multiplied by evo factor, so need evo > 0)
|
||||
game.map_settings.enemy_expansion.settler_group_max_size = 12 -- max size of group for building a base (multiplied by evo factor, so need evo > 0)
|
||||
game.map_settings.enemy_expansion.min_expansion_cooldown = 1200 -- minimum time before next expansion
|
||||
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.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
|
||||
game.map_settings.unit_group.max_member_speedup_when_behind = 1.4
|
||||
game.map_settings.unit_group.max_member_slowdown_when_ahead = 0.6
|
||||
game.map_settings.unit_group.max_group_slowdown_factor = 0.3
|
||||
game.map_settings.unit_group.max_group_member_fallback_factor = 3
|
||||
game.map_settings.unit_group.member_disown_distance = 10
|
||||
game.map_settings.unit_group.tick_tolerance_when_member_arrives = 60
|
||||
game.map_settings.unit_group.max_gathering_unit_groups = 30
|
||||
game.map_settings.unit_group.max_unit_group_size = 200
|
||||
|
||||
---- steering settings
|
||||
--game.map_settings.steering.default.radius = 1.2
|
||||
--game.map_settings.steering.default.separation_force = 0.005
|
||||
--game.map_settings.steering.default.separation_factor = 1.2
|
||||
--game.map_settings.steering.default.force_unit_fuzzy_goto_behavior = false
|
||||
--game.map_settings.steering.moving.radius = 3
|
||||
--game.map_settings.steering.moving.separation_force = 0.01
|
||||
--game.map_settings.steering.moving.separation_factor = 3
|
||||
--game.map_settings.steering.moving.force_unit_fuzzy_goto_behavior = false
|
||||
|
||||
create_limbo()
|
||||
initialize_nauvis()
|
||||
|
||||
end
|
||||
|
||||
return Public
|
19
modules/scrap_towny_ffa/on_tick_schedule.lua
Normal file
19
modules/scrap_towny_ffa/on_tick_schedule.lua
Normal file
@ -0,0 +1,19 @@
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
|
||||
local function on_tick()
|
||||
local ffatable = Table.get_table()
|
||||
if not ffatable.on_tick_schedule[game.tick] then return end
|
||||
for _, schedule in pairs(ffatable.on_tick_schedule[game.tick]) do
|
||||
schedule.func(unpack(schedule.args))
|
||||
end
|
||||
ffatable.on_tick_schedule[game.tick] = nil
|
||||
end
|
||||
|
||||
local on_init = function ()
|
||||
local ffatable = Table.get_table()
|
||||
ffatable.on_tick_schedule = {}
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.on_init(on_init)
|
||||
Event.add(defines.events.on_tick, on_tick)
|
99
modules/scrap_towny_ffa/pollution.lua
Normal file
99
modules/scrap_towny_ffa/pollution.lua
Normal file
@ -0,0 +1,99 @@
|
||||
local Public = {}
|
||||
local math_random = math.random
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
local Scrap = require 'modules.scrap_towny_ffa.scrap'
|
||||
|
||||
local pollution_index = {
|
||||
["small-biter"] = { min = 0.1, max = 0.1 },
|
||||
["medium-biter"] = { min = 0.1, max = 0.2 },
|
||||
["big-biter"] = { min = 0.1, max = 0.3 },
|
||||
["behemoth-biter"] = { min = 0.1, max = 0.4 },
|
||||
["small-spitter"] = { min = 0.1, max = 0.1 },
|
||||
["medium-spitter"] = { min = 0.1, max = 0.2 },
|
||||
["big-spitter"] = { min = 0.1, max = 0.3 },
|
||||
["behemoth-spitter"] = { min = 0.2, max = 0.4 },
|
||||
["small-worm-turret"] = { min = 0.1, max = 0.1 },
|
||||
["medium-worm-turret"] = { min = 0.1, max = 0.2 },
|
||||
["big-worm-turret"] = { min = 0.1, max = 0.3 },
|
||||
["behemoth-worm-turret"] = { min = 0.2, max = 0.4 },
|
||||
["biter-spawner"] = { min = 0.5, max = 2.5 },
|
||||
["spitter-spawner"] = { min = 0.5, max = 2.5 },
|
||||
["mineable-wreckage"] = { min = 0.1, max = 0.1 },
|
||||
["small-ship-wreck"] = { min = 0.1, max = 0.1 },
|
||||
["medium-ship-wreck"] = { min = 0.1, max = 0.1 },
|
||||
["crash-site-spaceship-wreck-small-1"] = { min = 0.1, max = 0.1 },
|
||||
["crash-site-spaceship-wreck-small-2"] = { min = 0.1, max = 0.1 },
|
||||
["crash-site-spaceship-wreck-small-3"] = { min = 0.1, max = 0.1 },
|
||||
["crash-site-spaceship-wreck-small-4"] = { min = 0.1, max = 0.1 },
|
||||
["crash-site-spaceship-wreck-small-5"] = { min = 0.1, max = 0.1 },
|
||||
["crash-site-spaceship-wreck-small-6"] = { min = 0.1, max = 0.1 },
|
||||
["big-ship-wreck-1"] = { min = 0.2, max = 0.4 },
|
||||
["big-ship-wreck-2"] = { min = 0.2, max = 0.4 },
|
||||
["big-ship-wreck-3"] = { min = 0.2, max = 0.4 },
|
||||
["crash-site-chest-1"] = { min = 0.1, max = 0.2 },
|
||||
["crash-site-chest-2"] = { min = 0.1, max = 0.2 },
|
||||
["crash-site-spaceship-wreck-medium-1"] = { min = 0.1, max = 0.2 },
|
||||
["crash-site-spaceship-wreck-medium-2"] = { min = 0.1, max = 0.2 },
|
||||
["crash-site-spaceship-wreck-medium-3"] = { min = 0.1, max = 0.2 },
|
||||
["crash-site-spaceship-wreck-big-1"] = { min = 0.2, max = 0.4 },
|
||||
["crash-site-spaceship-wreck-big-2"] = { min = 0.2, max = 0.4 },
|
||||
["crash-site-spaceship"] = { min = 0.5, max = 2.5 },
|
||||
["explosion"] = { min = 0.1, max = 0.1 },
|
||||
["big-explosion"] = { min = 0.2, max = 0.2 },
|
||||
["big-artillery-explosion"] = { min = 0.5, max = 0.5 },
|
||||
["market"] = { min = 10, max = 50 },
|
||||
}
|
||||
|
||||
function Public.market_scent()
|
||||
local ffatable = Table.get_table()
|
||||
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)
|
||||
end
|
||||
end
|
||||
|
||||
function Public.explosion(position, surface, animation)
|
||||
local pollution = pollution_index[animation]
|
||||
if pollution == nil then return end
|
||||
local amount = math_random(pollution.min, pollution.max)
|
||||
surface.pollute(position, amount)
|
||||
end
|
||||
|
||||
local function on_player_mined_entity(event)
|
||||
local entity = event.entity
|
||||
if Scrap.is_scrap(entity) == true then
|
||||
local pollution = pollution_index[entity.name]
|
||||
local amount = math_random(pollution.min, pollution.max)
|
||||
entity.surface.pollute(entity.position, amount)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_entity_damaged(event)
|
||||
local entity = event.entity
|
||||
if not entity.valid then return end
|
||||
local pollution = pollution_index[entity.name]
|
||||
if pollution == nil then return end
|
||||
local amount = math_random(pollution.min, pollution.max)
|
||||
entity.surface.pollute(entity.position, amount)
|
||||
end
|
||||
|
||||
local function on_entity_died(event)
|
||||
local entity = event.entity
|
||||
if not entity.valid then return end
|
||||
local pollution = pollution_index[entity.name]
|
||||
if pollution == nil then return end
|
||||
local amount = math_random(pollution.min, pollution.max) * 10
|
||||
entity.surface.pollute(entity.position, amount)
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.add(defines.events.on_player_mined_entity, on_player_mined_entity)
|
||||
Event.add(defines.events.on_entity_damaged, on_entity_damaged)
|
||||
Event.add(defines.events.on_entity_died, on_entity_died)
|
||||
|
||||
return Public
|
173
modules/scrap_towny_ffa/rocks_yield_ore_veins.lua
Normal file
173
modules/scrap_towny_ffa/rocks_yield_ore_veins.lua
Normal file
@ -0,0 +1,173 @@
|
||||
local math_random = math.random
|
||||
local math_floor = math.floor
|
||||
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,
|
||||
["rock-huge"] = true,
|
||||
["sand-rock-big"] = true
|
||||
}
|
||||
|
||||
local size_raffle = {
|
||||
{ "giant", 128, 256 },
|
||||
{ "huge", 64, 128 },
|
||||
{ "big", 32, 64 },
|
||||
{ "small", 16, 32 },
|
||||
{ "tiny", 8, 16 },
|
||||
}
|
||||
|
||||
local function get_chances()
|
||||
local chances = {}
|
||||
table_insert(chances, { "iron-ore", 25 })
|
||||
table_insert(chances, { "copper-ore", 18 })
|
||||
table_insert(chances, { "mixed", 15 })
|
||||
table_insert(chances, { "coal", 14 })
|
||||
table_insert(chances, { "stone", 8 })
|
||||
table_insert(chances, { "uranium-ore", 3 })
|
||||
return chances
|
||||
end
|
||||
|
||||
local function set_raffle()
|
||||
local ffatable = Table.get_table()
|
||||
ffatable.rocks_yield_ore_veins.raffle = {}
|
||||
for _, t in pairs(get_chances()) do
|
||||
for _ = 1, t[2], 1 do
|
||||
table_insert(ffatable.rocks_yield_ore_veins.raffle, t[1])
|
||||
end
|
||||
end
|
||||
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))
|
||||
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 r = math_random(1, #ore_entities)
|
||||
local position = { x = ore_entities[r].position.x, y = ore_entities[r].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] }
|
||||
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
|
||||
end
|
||||
else
|
||||
if surface.can_fast_replace({ name = name, position = p }) 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] = { name = name, position = p, amount = get_amount(p), fast_replace = true }
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function ore_vein(event)
|
||||
local ffatable = Table.get_table()
|
||||
local surface = event.entity.surface
|
||||
local size = size_raffle[math_random(1, #size_raffle)]
|
||||
local ore = ffatable.rocks_yield_ore_veins.raffle[math_random(1, #ffatable.rocks_yield_ore_veins.raffle)]
|
||||
local icon
|
||||
if game.entity_prototypes[ore] then
|
||||
icon = "[img=entity/" .. ore .. "]"
|
||||
else
|
||||
icon = " "
|
||||
end
|
||||
|
||||
local player = game.players[event.player_index]
|
||||
for _, p in pairs(game.connected_players) do
|
||||
if p.index == player.index then
|
||||
p.print(
|
||||
{ "rocks_yield_ore_veins.player_print",
|
||||
{ "rocks_yield_ore_veins_colors." .. ore },
|
||||
{ "rocks_yield_ore_veins." .. size[1] },
|
||||
{ "rocks_yield_ore_veins." .. ore },
|
||||
icon
|
||||
},
|
||||
{ r = 0.80, g = 0.80, b = 0.80 }
|
||||
)
|
||||
else
|
||||
if p.force == player.force then
|
||||
game.print(
|
||||
{ "rocks_yield_ore_veins.game_print",
|
||||
"[color=" .. player.chat_color.r .. "," .. player.chat_color.g .. "," .. player.chat_color.b .. "]" .. player.name .. "[/color]",
|
||||
{ "rocks_yield_ore_veins." .. size[1] },
|
||||
{ "rocks_yield_ore_veins." .. ore },
|
||||
icon
|
||||
},
|
||||
{ r = 0.80, g = 0.80, b = 0.80 }
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local position = event.entity.position
|
||||
local ore_entities = { { name = ore, position = { x = position.x, y = position.y }, amount = get_amount(position) } }
|
||||
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) } }
|
||||
end
|
||||
|
||||
local ore_positions = { [event.entity.position.x .. "_" .. event.entity.position.y] = true }
|
||||
local count = math_random(size[2], size[3])
|
||||
|
||||
for _ = 1, 128, 1 do
|
||||
local c = math_random(math_floor(size[2] * 0.25) + 1, size[2])
|
||||
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)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_player_mined_entity(event)
|
||||
local ffatable = Table.get_table()
|
||||
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 return end
|
||||
ore_vein(event)
|
||||
end
|
||||
|
||||
local function on_init()
|
||||
local ffatable = Table.get_table()
|
||||
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
|
||||
set_raffle()
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.on_init(on_init)
|
||||
Event.add(defines.events.on_player_mined_entity, on_player_mined_entity)
|
36
modules/scrap_towny_ffa/scrap.lua
Normal file
36
modules/scrap_towny_ffa/scrap.lua
Normal file
@ -0,0 +1,36 @@
|
||||
local Public = {}
|
||||
|
||||
local scrapable = {
|
||||
-- simple entity
|
||||
"small-ship-wreck",
|
||||
"medium-ship-wreck",
|
||||
-- simple entity with owner
|
||||
"crash-site-spaceship-wreck-small-1",
|
||||
"crash-site-spaceship-wreck-small-2",
|
||||
"crash-site-spaceship-wreck-small-3",
|
||||
"crash-site-spaceship-wreck-small-4",
|
||||
"crash-site-spaceship-wreck-small-5",
|
||||
"crash-site-spaceship-wreck-small-6",
|
||||
"big-ship-wreck-1",
|
||||
"big-ship-wreck-2",
|
||||
"big-ship-wreck-3",
|
||||
"crash-site-chest-1",
|
||||
"crash-site-chest-2",
|
||||
"crash-site-spaceship-wreck-medium-1",
|
||||
"crash-site-spaceship-wreck-medium-2",
|
||||
"crash-site-spaceship-wreck-medium-3",
|
||||
"crash-site-spaceship-wreck-big-1",
|
||||
"crash-site-spaceship-wreck-big-2",
|
||||
"crash-site-spaceship"
|
||||
}
|
||||
|
||||
function Public.is_scrap(entity)
|
||||
if not entity.valid then return false end
|
||||
local f = false
|
||||
for i = 1, #scrapable, 1 do
|
||||
if entity.name == scrapable[i] then f = true end
|
||||
end
|
||||
return f
|
||||
end
|
||||
|
||||
return Public
|
103
modules/scrap_towny_ffa/slots.lua
Normal file
103
modules/scrap_towny_ffa/slots.lua
Normal file
@ -0,0 +1,103 @@
|
||||
local table_size = table.size
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
|
||||
-- called whenever a player places an item
|
||||
local function on_built_entity(event)
|
||||
local ffatable = Table.get_table()
|
||||
local entity = event.created_entity
|
||||
if not entity.valid then return end
|
||||
if entity.name ~= "laser-turret" then return end
|
||||
local player = game.players[event.player_index]
|
||||
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
|
||||
surface.create_entity({
|
||||
name = "flying-text",
|
||||
position = entity.position,
|
||||
text = "You are not acclimated to this technology!",
|
||||
color = { r = 0.77, g = 0.0, b = 0.0 }
|
||||
})
|
||||
player.insert({ name = "laser-turret", count = 1 })
|
||||
entity.destroy()
|
||||
return
|
||||
end
|
||||
local slots = town_center.upgrades.laser_turret.slots
|
||||
local locations = town_center.upgrades.laser_turret.locations
|
||||
if table_size(locations) >= slots then
|
||||
surface.create_entity({
|
||||
name = "flying-text",
|
||||
position = entity.position,
|
||||
text = "You do not have enough slots!",
|
||||
color = { r = 0.77, g = 0.0, b = 0.0 }
|
||||
})
|
||||
player.insert({ name = "laser-turret", count = 1 })
|
||||
entity.destroy()
|
||||
return
|
||||
end
|
||||
local position = entity.position
|
||||
local key = tostring("{" .. position.x .. "," .. position.y .. "}")
|
||||
locations[key] = true
|
||||
end
|
||||
|
||||
-- called whenever a player places an item
|
||||
local function on_robot_built_entity(event)
|
||||
local ffatable = Table.get_table()
|
||||
local entity = event.created_entity
|
||||
if not entity.valid then return end
|
||||
if entity.name ~= "laser-turret" then return end
|
||||
local robot = event.robot
|
||||
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
|
||||
surface.create_entity({
|
||||
name = "flying-text",
|
||||
position = entity.position,
|
||||
text = "Robot not acclimated to this technology!",
|
||||
color = { r = 0.77, g = 0.0, b = 0.0 }
|
||||
})
|
||||
robot.insert({ name = "laser-turret", count = 1 })
|
||||
entity.destroy()
|
||||
return
|
||||
end
|
||||
local slots = town_center.upgrades.laser_turret.slots
|
||||
local locations = town_center.upgrades.laser_turret.locations
|
||||
if table_size(locations) >= slots then
|
||||
surface.create_entity({
|
||||
name = "flying-text",
|
||||
position = entity.position,
|
||||
text = "Town does not have enough slots!",
|
||||
color = { r = 0.77, g = 0.0, b = 0.0 }
|
||||
})
|
||||
robot.insert({ name = "laser-turret", count = 1 })
|
||||
entity.destroy()
|
||||
return
|
||||
end
|
||||
local position = entity.position
|
||||
local key = tostring("{" .. position.x .. "," .. position.y .. "}")
|
||||
locations[key] = true
|
||||
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)
|
||||
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 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)
|
183
modules/scrap_towny_ffa/spawn.lua
Normal file
183
modules/scrap_towny_ffa/spawn.lua
Normal file
@ -0,0 +1,183 @@
|
||||
local Public = {}
|
||||
|
||||
local table_size = table.size
|
||||
local table_insert = table.insert
|
||||
local math_random = math.random
|
||||
local math_rad = math.rad
|
||||
local math_sin = math.sin
|
||||
local math_cos = math.cos
|
||||
local math_floor = math.floor
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
local Enemy = require "modules.scrap_towny_ffa.enemy"
|
||||
local Building = require "modules.scrap_towny_ffa.building"
|
||||
|
||||
-- don't spawn if town is within this range
|
||||
local spawn_point_town_buffer = 256
|
||||
-- clear enemies within this distance from spawn
|
||||
local spawn_point_safety = 16
|
||||
-- incremental spawn distance from existing town
|
||||
-- this is how much each attempt is incremented by for checking a pollution free area
|
||||
local spawn_point_incremental_distance = 16
|
||||
|
||||
local function force_load(position, surface, radius)
|
||||
--log("is_chunk_generated = " .. tostring(surface.is_chunk_generated(position)))
|
||||
surface.request_to_generate_chunks(position, radius)
|
||||
--log("force load position = {" .. position.x .. "," .. position.y .. "}")
|
||||
surface.force_generate_chunk_requests()
|
||||
end
|
||||
|
||||
-- gets an area (might not be even amount)
|
||||
local function get_area(position, w, h)
|
||||
local x1 = math_floor(w / 2)
|
||||
local x2 = w - x1
|
||||
local y1 = math_floor(h / 2)
|
||||
local y2 = h - y1
|
||||
return { { position.x - x1, position.y - y1 }, { position.x + x2, position.y + y2 } }
|
||||
end
|
||||
|
||||
local function clear_spawn(position, surface, w, h)
|
||||
--log("clear_spawn {" .. position.x .. "," .. position.y .. "}")
|
||||
local area = get_area(position, w, h)
|
||||
for _, e in pairs(surface.find_entities_filtered({ area = area })) do
|
||||
if e.type ~= "character" then
|
||||
e.destroy()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- does the position have any pollution
|
||||
local function has_pollution(position, surface)
|
||||
local result = surface.get_pollution(position) > 0.0
|
||||
--log("has_pollution = " .. tostring(result))
|
||||
return result
|
||||
end
|
||||
|
||||
-- is the position already used
|
||||
local function in_use(position)
|
||||
local ffatable = Table.get_table()
|
||||
local result = false
|
||||
for _, v in pairs(ffatable.spawn_point) do
|
||||
if v == position then result = true end
|
||||
end
|
||||
--log("in_use = " .. tostring(result))
|
||||
return result
|
||||
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 return false end
|
||||
local tiles = surface.count_tiles_filtered({ position = position, radius = tile_radius, collision_mask = "water-tile" })
|
||||
--log("water-tiles = " .. tiles)
|
||||
if tiles > 0 then return false end
|
||||
local result = surface.can_place_entity({ name = "character", position = position })
|
||||
--log("is_empty = " .. tostring(result))
|
||||
return result
|
||||
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 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)
|
||||
if in_use(position) == false then
|
||||
if Building.near_town(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 .. "}")
|
||||
return position
|
||||
end
|
||||
end
|
||||
end
|
||||
-- otherwise find a nearby town
|
||||
local keyset = {}
|
||||
for town_name, _ in pairs(ffatable.town_centers) do
|
||||
table_insert(keyset, town_name)
|
||||
end
|
||||
local count = table_size(keyset)
|
||||
if count > 0 then
|
||||
local town_name = keyset[math_random(1, count)]
|
||||
local town_center = ffatable.town_centers[town_name]
|
||||
if town_center ~= nil then
|
||||
position = town_center.market.position
|
||||
end
|
||||
--log("town center is {" .. position.x .. "," .. position.y .. "}")
|
||||
end
|
||||
-- and start checking around it for a suitable spawn position
|
||||
local tries = 0
|
||||
local radius = spawn_point_town_buffer
|
||||
local angle
|
||||
while (tries < 100) do
|
||||
-- 8 attempts each position
|
||||
for _ = 1, 8 do
|
||||
-- position on the circle radius
|
||||
angle = math_random(0, 360)
|
||||
local t = math_rad(angle)
|
||||
local x = math_floor(position.x + math_cos(t) * radius)
|
||||
local y = math_floor(position.y + math_sin(t) * radius)
|
||||
local target = { x = x, y = y }
|
||||
--log("testing {" .. target.x .. "," .. target.y .. "}")
|
||||
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 is_empty(target, surface) == true then
|
||||
--log("found valid spawn point at {" .. target.x .. "," .. target.y .. "}")
|
||||
position = target
|
||||
return position
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
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 }
|
||||
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)
|
||||
-- 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 .. "}")
|
||||
return position
|
||||
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
|
||||
-- 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
|
||||
end
|
||||
end
|
||||
-- otherwise get a new spawn point
|
||||
return Public.get_new_spawn_point(player, surface)
|
||||
end
|
||||
|
||||
function Public.clear_spawn_point(position, surface)
|
||||
Enemy.clear_worms(position, surface, spawn_point_safety) -- behemoth worms can attack from a range of 48, clear first time only
|
||||
Enemy.clear_enemies(position, surface, spawn_point_safety) -- behemoth worms can attack from a range of 48
|
||||
clear_spawn(position, surface, 7, 9)
|
||||
end
|
||||
|
||||
return Public
|
33
modules/scrap_towny_ffa/spawners_contain_biters.lua
Normal file
33
modules/scrap_towny_ffa/spawners_contain_biters.lua
Normal file
@ -0,0 +1,33 @@
|
||||
-- spawners release biters on death -- by mewmew
|
||||
local math_random = math.random
|
||||
|
||||
local Evolution = require "modules.scrap_towny_ffa.evolution"
|
||||
|
||||
local biter_building_inhabitants = {
|
||||
[1] = { { "small-biter", 8, 16 } },
|
||||
[2] = { { "small-biter", 12, 24 } },
|
||||
[3] = { { "small-biter", 8, 16 }, { "medium-biter", 1, 2 } },
|
||||
[4] = { { "small-biter", 4, 8 }, { "medium-biter", 4, 8 } },
|
||||
[5] = { { "small-biter", 3, 5 }, { "medium-biter", 8, 12 } },
|
||||
[6] = { { "small-biter", 3, 5 }, { "medium-biter", 5, 7 }, { "big-biter", 1, 2 } },
|
||||
[7] = { { "medium-biter", 6, 8 }, { "big-biter", 3, 5 } },
|
||||
[8] = { { "medium-biter", 2, 4 }, { "big-biter", 6, 8 } },
|
||||
[9] = { { "medium-biter", 2, 3 }, { "big-biter", 7, 9 } },
|
||||
[10] = { { "big-biter", 4, 8 }, { "behemoth-biter", 3, 4 } }
|
||||
}
|
||||
|
||||
local function on_entity_died(event)
|
||||
if not event.entity.valid then return end
|
||||
if event.entity.type ~= "unit-spawner" then return end
|
||||
local e = math.ceil(Evolution.get_biter_evolution(event.entity) * 10)
|
||||
if e < 1 then e = 1 end
|
||||
for _, t in pairs(biter_building_inhabitants[e]) do
|
||||
for _ = 1, math_random(t[2], t[3]), 1 do
|
||||
local p = event.entity.surface.find_non_colliding_position(t[1], event.entity.position, 6, 1)
|
||||
if p then event.entity.surface.create_entity { name = t[1], position = p, force = event.entity.force.name } end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.add(defines.events.on_entity_died, on_entity_died)
|
30
modules/scrap_towny_ffa/table.lua
Normal file
30
modules/scrap_towny_ffa/table.lua
Normal file
@ -0,0 +1,30 @@
|
||||
local Public = {}
|
||||
|
||||
-- one table to rule them all!
|
||||
local Global = require 'utils.global'
|
||||
local ffatable = {}
|
||||
Global.register(
|
||||
ffatable,
|
||||
function(tbl)
|
||||
ffatable = tbl
|
||||
end
|
||||
)
|
||||
|
||||
function Public.reset_table()
|
||||
for k, _ in pairs(ffatable) do
|
||||
ffatable[k] = nil
|
||||
end
|
||||
end
|
||||
|
||||
function Public.get_table()
|
||||
return ffatable
|
||||
end
|
||||
|
||||
local on_init = function ()
|
||||
Public.reset_table()
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.on_init(on_init)
|
||||
|
||||
return Public
|
681
modules/scrap_towny_ffa/team.lua
Normal file
681
modules/scrap_towny_ffa/team.lua
Normal file
@ -0,0 +1,681 @@
|
||||
local Public = {}
|
||||
|
||||
local table_size = table.size
|
||||
local string_match = string.match
|
||||
local string_lower = string.lower
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
|
||||
local outlander_color = { 150, 150, 150 }
|
||||
local outlander_chat_color = { 170, 170, 170 }
|
||||
local rogue_color = { 150, 150, 150 }
|
||||
local rogue_chat_color = { 170, 170, 170 }
|
||||
local item_drop_radius = 1.65
|
||||
|
||||
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 end
|
||||
|
||||
for _, town in pairs(town_centers) do
|
||||
member_limit = member_limit + table_size(town.market.force.connected_players)
|
||||
end
|
||||
member_limit = math.floor(member_limit / size_of_town_centers) + 4
|
||||
|
||||
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)
|
||||
local ffatable = Table.get_table()
|
||||
if player == nil then return false end
|
||||
return ffatable.key[player]
|
||||
end
|
||||
|
||||
function Public.give_key(player)
|
||||
local ffatable = Table.get_table()
|
||||
if player == nil then return end
|
||||
ffatable.key[player] = true
|
||||
end
|
||||
|
||||
function Public.remove_key(player)
|
||||
local ffatable = Table.get_table()
|
||||
if player == nil then return end
|
||||
ffatable.key[player] = false
|
||||
end
|
||||
|
||||
function Public.set_player_color(player)
|
||||
local ffatable = Table.get_table()
|
||||
if player.force == game.forces["player"] then
|
||||
player.color = outlander_color
|
||||
player.chat_color = outlander_chat_color
|
||||
return
|
||||
end
|
||||
if player.force == game.forces["rogue"] then
|
||||
player.color = rogue_color
|
||||
player.chat_color = rogue_chat_color
|
||||
return
|
||||
end
|
||||
local town_center = ffatable.town_centers[player.force.name]
|
||||
if not town_center then return end
|
||||
player.color = town_center.color
|
||||
player.chat_color = town_center.color
|
||||
end
|
||||
|
||||
local function set_town_color(event)
|
||||
local ffatable = Table.get_table()
|
||||
if event.command ~= "color" then return end
|
||||
local player = game.players[event.player_index]
|
||||
local force = player.force
|
||||
local town_center = ffatable.town_centers[force.name]
|
||||
if not town_center then
|
||||
Public.set_player_color(player)
|
||||
return
|
||||
end
|
||||
town_center.color = { player.color.r, player.color.g, player.color.b }
|
||||
rendering.set_color(town_center.town_caption, town_center.color)
|
||||
for _, p in pairs(force.players) do
|
||||
Public.set_player_color(p)
|
||||
end
|
||||
end
|
||||
|
||||
function Public.set_all_player_colors()
|
||||
for _, p in pairs(game.connected_players) do
|
||||
Public.set_player_color(p)
|
||||
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
|
||||
player.force = market.force
|
||||
Public.remove_key(player)
|
||||
ffatable.spawn_point[player.name] = force.get_spawn_position(surface)
|
||||
game.permissions.get_group(force.name).add_player(player)
|
||||
player.tag = ""
|
||||
Public.set_player_color(player)
|
||||
end
|
||||
|
||||
function Public.give_outlander_items(player)
|
||||
player.insert({ name = "stone-furnace", count = 1 })
|
||||
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
|
||||
end
|
||||
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]"
|
||||
Public.set_player_color(player)
|
||||
Public.give_key(player)
|
||||
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
|
||||
end
|
||||
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]"
|
||||
Public.set_player_color(player)
|
||||
end
|
||||
|
||||
local function ally_outlander(player, target)
|
||||
local ffatable = Table.get_table()
|
||||
local requesting_force = player.force
|
||||
local target_force = target.force
|
||||
|
||||
-- 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 end
|
||||
|
||||
-- don't handle request to another town if already in a town
|
||||
if is_towny(requesting_force) and is_towny(target_force) then return false end
|
||||
|
||||
-- handle the request
|
||||
if not is_towny(requesting_force) and is_towny(target_force) then
|
||||
ffatable.requests[player.index] = target_force.name
|
||||
|
||||
local target_player = false
|
||||
if target.type == "character" then
|
||||
target_player = target.player
|
||||
else
|
||||
target_player = game.players[target_force.name]
|
||||
end
|
||||
|
||||
if target_player then
|
||||
if ffatable.requests[target_player.index] then
|
||||
if ffatable.requests[target_player.index] == player.name then
|
||||
if ffatable.town_centers[target_force.name] then
|
||||
if not can_force_accept_member(target_force) then return true end
|
||||
game.print(">> " .. player.name .. " has settled in " .. target_force.name .. "'s Town!", { 255, 255, 0 })
|
||||
Public.add_player_to_town(player, ffatable.town_centers[target_force.name])
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
game.print(">> " .. player.name .. " wants to settle in " .. target_force.name .. " Town!", { 255, 255, 0 })
|
||||
return true
|
||||
end
|
||||
|
||||
-- handle the approval
|
||||
if is_towny(requesting_force) and not is_towny(target_force) then
|
||||
if target.type ~= "character" then return true end
|
||||
local target_player = target.player
|
||||
if not target_player then return true end
|
||||
ffatable.requests[player.index] = target_player.name
|
||||
|
||||
if ffatable.requests[target_player.index] then
|
||||
if ffatable.requests[target_player.index] == player.force.name then
|
||||
if not can_force_accept_member(player.force) then return true end
|
||||
if player.force.name == player.name then
|
||||
game.print(">> " .. player.name .. " has accepted " .. target_player.name .. " into their Town!", { 255, 255, 0 })
|
||||
else
|
||||
game.print(">> " .. player.name .. " has accepted " .. target_player.name .. " into" .. player.force.name .. "'s Town!", { 255, 255, 0 })
|
||||
end
|
||||
Public.add_player_to_town(target_player, ffatable.town_centers[player.force.name])
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
if player.force.name == player.name then
|
||||
game.print(">> " .. player.name .. " is inviting " .. target_player.name .. " into their Town!", { 255, 255, 0 })
|
||||
else
|
||||
game.print(">> " .. player.name .. " is inviting " .. target_player.name .. " into " .. player.force.name .. "'s Town!", { 255, 255, 0 })
|
||||
end
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
local function ally_neighbour_towns(player, target)
|
||||
local requesting_force = player.force
|
||||
local target_force = target.force
|
||||
|
||||
if target_force.get_friend(requesting_force) and requesting_force.get_friend(target_force) then return end
|
||||
|
||||
requesting_force.set_friend(target_force, true)
|
||||
game.print(">> Town " .. requesting_force.name .. " has set " .. target_force.name .. " as their friend!", { 255, 255, 0 })
|
||||
|
||||
if target_force.get_friend(requesting_force) then
|
||||
game.print(">> The towns " .. requesting_force.name .. " and " .. target_force.name .. " have formed an alliance!", { 255, 255, 0 })
|
||||
end
|
||||
end
|
||||
|
||||
local function ally_town(player, item)
|
||||
local position = item.position
|
||||
local surface = player.surface
|
||||
local area = { { position.x - item_drop_radius, position.y - item_drop_radius }, { position.x + item_drop_radius, position.y + item_drop_radius } }
|
||||
local requesting_force = player.force
|
||||
local target = false
|
||||
|
||||
for _, e in pairs(surface.find_entities_filtered({ type = { "character", "market" }, area = area })) do
|
||||
if e.force.name ~= requesting_force.name then
|
||||
target = e
|
||||
break
|
||||
end
|
||||
end
|
||||
|
||||
if not target then return end
|
||||
if target.force == game.forces["enemy"] or target.force == game.forces["neutral"] then return end
|
||||
|
||||
if ally_outlander(player, target) then return end
|
||||
ally_neighbour_towns(player, target)
|
||||
end
|
||||
|
||||
local function declare_war(player, item)
|
||||
local ffatable = Table.get_table()
|
||||
local position = item.position
|
||||
local surface = player.surface
|
||||
local area = { { position.x - item_drop_radius, position.y - item_drop_radius }, { position.x + item_drop_radius, position.y + item_drop_radius } }
|
||||
|
||||
local requesting_force = player.force
|
||||
local target = surface.find_entities_filtered({ type = { "character", "market" }, area = area })[1]
|
||||
|
||||
if not target then return end
|
||||
local target_force = target.force
|
||||
if not is_towny(target_force) then return end
|
||||
|
||||
if requesting_force.name == target_force.name then
|
||||
if player.name ~= target.force.name then
|
||||
Public.set_player_to_outlander(player)
|
||||
game.print(">> " .. player.name .. " has abandoned " .. target_force.name .. "'s Town!", { 255, 255, 0 })
|
||||
ffatable.requests[player.index] = nil
|
||||
end
|
||||
if player.name == target.force.name then
|
||||
if target.type ~= "character" then return end
|
||||
local target_player = target.player
|
||||
if not target_player then return end
|
||||
if target_player.index == player.index then return end
|
||||
Public.set_player_to_outlander(target_player)
|
||||
game.print(">> " .. player.name .. " has banished " .. target_player.name .. " from their Town!", { 255, 255, 0 })
|
||||
ffatable.requests[player.index] = nil
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if not is_towny(requesting_force) then return end
|
||||
|
||||
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 })
|
||||
end
|
||||
|
||||
local function delete_chart_tag_for_all_forces(market)
|
||||
local forces = game.forces
|
||||
local position = market.position
|
||||
local surface = market.surface
|
||||
for _, force in pairs(forces) do
|
||||
local tags = force.find_chart_tags(surface, { { position.x - 0.1, position.y - 0.1 }, { position.x + 0.1, position.y + 0.1 } })
|
||||
local tag = tags[1]
|
||||
if tag then
|
||||
if tag.icon.name == "stone-furnace" then
|
||||
tag.destroy()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Public.add_chart_tag(force, market)
|
||||
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" })
|
||||
end
|
||||
|
||||
function Public.update_town_chart_tags()
|
||||
local ffatable = Table.get_table()
|
||||
local town_centers = ffatable.town_centers
|
||||
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)
|
||||
end
|
||||
end
|
||||
end
|
||||
if game.forces["player"] ~= nil then game.forces["player"].clear_chart(game.surfaces["nauvis"]) end
|
||||
if game.forces["rogue"] ~= nil then game.forces["rogue"].clear_chart(game.surfaces["nauvis"]) end
|
||||
end
|
||||
|
||||
local function reset_permissions(permission_group)
|
||||
for action_name, _ in pairs(defines.input_action) do
|
||||
permission_group.set_allows_action(defines.input_action[action_name], true)
|
||||
end
|
||||
end
|
||||
|
||||
local function disable_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,
|
||||
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, false) end
|
||||
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
|
||||
end
|
||||
|
||||
local function disable_artillery(force, permission_group)
|
||||
permission_group.set_allows_action(defines.input_action.use_artillery_remote, false)
|
||||
force.technologies["artillery"].enabled = false
|
||||
force.technologies["artillery-shell-range-1"].enabled = false
|
||||
force.technologies["artillery-shell-speed-1"].enabled = false
|
||||
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_spidertron(force, permission_group)
|
||||
permission_group.set_allows_action(defines.input_action.send_spidertron, false)
|
||||
force.technologies["spidertron"].enabled = false
|
||||
force.recipes["spidertron"].enabled = false
|
||||
force.recipes["spidertron-remote"].enabled = false
|
||||
end
|
||||
|
||||
local function disable_rockets(force)
|
||||
force.technologies["rocketry"].enabled = false
|
||||
force.technologies["explosive-rocketry"].enabled = false
|
||||
force.recipes["rocket-launcher"].enabled = false
|
||||
force.recipes["rocket"].enabled = false
|
||||
force.recipes["explosive-rocket"].enabled = false
|
||||
end
|
||||
|
||||
local function disable_nukes(force)
|
||||
force.technologies["atomic-bomb"].enabled = false
|
||||
force.recipes["atomic-bomb"].enabled = false
|
||||
end
|
||||
|
||||
local function disable_cluster_grenades(force)
|
||||
force.recipes["cluster-grenade"].enabled = false
|
||||
end
|
||||
|
||||
local function enable_radar(force)
|
||||
force.recipes["radar"].enabled = true
|
||||
force.share_chart = true
|
||||
force.clear_chart("nauvis")
|
||||
end
|
||||
|
||||
local function disable_radar(force)
|
||||
force.recipes["radar"].enabled = false
|
||||
force.share_chart = false
|
||||
force.clear_chart("nauvis")
|
||||
end
|
||||
|
||||
local function disable_achievements(permission_group)
|
||||
permission_group.set_allows_action(defines.input_action.open_achievements_gui, false)
|
||||
end
|
||||
|
||||
local function disable_tips_and_tricks(permission_group)
|
||||
permission_group.set_allows_action(defines.input_action.open_tips_and_tricks_gui, false)
|
||||
end
|
||||
|
||||
-- setup a team force
|
||||
function Public.add_new_force(force_name)
|
||||
-- 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_artillery(force, permission_group)
|
||||
disable_spidertron(force, permission_group)
|
||||
disable_rockets(force)
|
||||
disable_nukes(force)
|
||||
disable_cluster_grenades(force)
|
||||
enable_radar(force)
|
||||
disable_achievements(permission_group)
|
||||
disable_tips_and_tricks(permission_group)
|
||||
-- friendly fire
|
||||
force.friendly_fire = true
|
||||
-- disable technologies
|
||||
force.research_queue_enabled = true
|
||||
-- balance initial combat
|
||||
force.set_ammo_damage_modifier("landmine", -0.75)
|
||||
force.set_ammo_damage_modifier("grenade", -0.5)
|
||||
end
|
||||
|
||||
local function kill_force(force_name)
|
||||
local ffatable = Table.get_table()
|
||||
local force = game.forces[force_name]
|
||||
local market = ffatable.town_centers[force_name].market
|
||||
local surface = market.surface
|
||||
surface.create_entity({ name = "big-artillery-explosion", position = market.position })
|
||||
for _, player in pairs(force.players) do
|
||||
if player.character then
|
||||
player.character.die()
|
||||
else
|
||||
ffatable.requests[player.index] = "kill-character"
|
||||
end
|
||||
player.force = game.forces.player
|
||||
Public.set_player_color(player)
|
||||
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
|
||||
e.die()
|
||||
end
|
||||
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
|
||||
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 })
|
||||
end
|
||||
|
||||
local player_force_disabled_recipes = { "lab", "automation-science-pack", "stone-brick", "radar" }
|
||||
local player_force_enabled_recipes = { "submachine-gun", "assembling-machine-1", "small-lamp", "shotgun", "shotgun-shell", "underground-belt", "splitter", "steel-plate", "car", "cargo-wagon", "constant-combinator", "engine-unit", "green-wire", "locomotive", "rail", "train-stop", "arithmetic-combinator", "decider-combinator" }
|
||||
|
||||
-- setup the player force (this is the default for Outlanders)
|
||||
local function setup_player_force()
|
||||
local force = game.forces.player
|
||||
local permission_group = game.permissions.create_group("outlander")
|
||||
-- disable permissions
|
||||
reset_permissions(permission_group)
|
||||
disable_blueprints(permission_group)
|
||||
disable_artillery(force, permission_group)
|
||||
disable_spidertron(force, permission_group)
|
||||
disable_rockets(force)
|
||||
disable_nukes(force)
|
||||
disable_cluster_grenades(force)
|
||||
disable_radar(force)
|
||||
disable_achievements(permission_group)
|
||||
disable_tips_and_tricks(permission_group)
|
||||
-- disable research
|
||||
force.disable_research()
|
||||
force.research_queue_enabled = false
|
||||
-- friendly fire
|
||||
force.friendly_fire = true
|
||||
-- disable recipes
|
||||
local recipes = force.recipes
|
||||
for _, recipe_name in pairs(player_force_disabled_recipes) do
|
||||
recipes[recipe_name].enabled = false
|
||||
end
|
||||
for _, recipe_name in pairs(player_force_enabled_recipes) do
|
||||
recipes[recipe_name].enabled = true
|
||||
end
|
||||
force.set_ammo_damage_modifier("landmine", -0.75)
|
||||
force.set_ammo_damage_modifier("grenade", -0.5)
|
||||
end
|
||||
|
||||
local function setup_rogue_force()
|
||||
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_artillery(force, permission_group)
|
||||
disable_spidertron(force, permission_group)
|
||||
disable_rockets(force)
|
||||
disable_nukes(force)
|
||||
disable_cluster_grenades(force)
|
||||
disable_radar(force)
|
||||
disable_achievements(permission_group)
|
||||
disable_tips_and_tricks(permission_group)
|
||||
-- disable research
|
||||
force.disable_research()
|
||||
force.research_queue_enabled = false
|
||||
-- friendly fire
|
||||
force.friendly_fire = true
|
||||
-- disable recipes
|
||||
local recipes = force.recipes
|
||||
for _, recipe_name in pairs(player_force_disabled_recipes) do
|
||||
recipes[recipe_name].enabled = false
|
||||
end
|
||||
for _, recipe_name in pairs(player_force_enabled_recipes) do
|
||||
recipes[recipe_name].enabled = true
|
||||
end
|
||||
force.set_ammo_damage_modifier("landmine", -0.75)
|
||||
force.set_ammo_damage_modifier("grenade", -0.5)
|
||||
end
|
||||
|
||||
local function setup_enemy_force()
|
||||
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
|
||||
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
|
||||
ally_town(player, entity)
|
||||
return
|
||||
end
|
||||
if entity.stack.name == "coal" then
|
||||
declare_war(player, entity)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
---- when a player dies, reveal their base to everyone
|
||||
--local function on_player_died(event)
|
||||
-- local player = game.players[event.player_index]
|
||||
-- if not player.character then return end
|
||||
-- if not player.character.valid then return end
|
||||
-- reveal_entity_to_all(player.character)
|
||||
--end
|
||||
|
||||
local function on_entity_damaged(event)
|
||||
local entity = event.entity
|
||||
if not entity.valid then return end
|
||||
local cause = event.cause
|
||||
local force = event.force
|
||||
|
||||
-- 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
|
||||
local player = cause.player
|
||||
if force == game.forces["player"] then
|
||||
-- set the force of the player to rogue until they die or create a town
|
||||
set_player_to_rogue(player)
|
||||
end
|
||||
end
|
||||
-- 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
|
||||
-- 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
|
||||
-- set the force of the player to rogue until they die or create a town
|
||||
set_player_to_rogue(passenger)
|
||||
end
|
||||
end
|
||||
-- trains
|
||||
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
|
||||
set_player_to_rogue(passenger)
|
||||
end
|
||||
end
|
||||
end
|
||||
-- combat robots
|
||||
if cause.type == "combat-robot" and force == game.forces["player"] 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)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function on_entity_died(event)
|
||||
local entity = event.entity
|
||||
if entity.name == "market" then
|
||||
kill_force(entity.force.name)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_post_entity_died(event)
|
||||
local prototype = event.prototype.type
|
||||
if prototype ~= "character" then return end
|
||||
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)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function on_console_command(event)
|
||||
set_town_color(event)
|
||||
end
|
||||
|
||||
local function on_console_chat(event)
|
||||
local player = game.players[event.player_index]
|
||||
if string_match(string_lower(event.message), "%[armor%=") then
|
||||
player.clear_console()
|
||||
game.print(">> " .. player.name .. " is trying to gain an unfair advantage!")
|
||||
end
|
||||
end
|
||||
|
||||
function Public.initialize()
|
||||
setup_player_force()
|
||||
setup_rogue_force()
|
||||
setup_enemy_force()
|
||||
end
|
||||
|
||||
local on_init = function ()
|
||||
local ffatable = Table.get_table()
|
||||
ffatable.key = {}
|
||||
ffatable.spawn_point = {}
|
||||
ffatable.requests = {}
|
||||
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.on_init(on_init)
|
||||
Event.add(defines.events.on_player_dropped_item, on_player_dropped_item)
|
||||
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_post_entity_died, on_post_entity_died)
|
||||
Event.add(defines.events.on_console_command, on_console_command)
|
||||
Event.add(defines.events.on_console_chat, on_console_chat)
|
||||
|
||||
return Public
|
92
modules/scrap_towny_ffa/tick_tack_trap.lua
Normal file
92
modules/scrap_towny_ffa/tick_tack_trap.lua
Normal file
@ -0,0 +1,92 @@
|
||||
-- timer traps -- by mewmew
|
||||
local table_insert = table.insert
|
||||
local math_random = math.random
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
|
||||
local tick_tacks = { "*tick*", "*tick*", "*tack*", "*tak*", "*tik*", "*tok*" }
|
||||
|
||||
local kaboom_weights = {
|
||||
{ name = "grenade", chance = 7 },
|
||||
{ name = "cluster-grenade", chance = 1 },
|
||||
{ name = "destroyer-capsule", chance = 1 },
|
||||
{ name = "defender-capsule", chance = 4 },
|
||||
{ name = "distractor-capsule", chance = 3 },
|
||||
{ name = "poison-capsule", chance = 2 },
|
||||
{ name = "explosive-uranium-cannon-projectile", chance = 3 },
|
||||
{ name = "explosive-cannon-projectile", chance = 5 },
|
||||
}
|
||||
|
||||
local kabooms = {}
|
||||
for _, t in pairs(kaboom_weights) do
|
||||
for _ = 1, t.chance, 1 do
|
||||
table_insert(kabooms, t.name)
|
||||
end
|
||||
end
|
||||
|
||||
local function create_flying_text(surface, position, text)
|
||||
surface.create_entity({
|
||||
name = "flying-text",
|
||||
position = position,
|
||||
text = text,
|
||||
color = { r = 0.75, g = 0.75, b = 0.75 }
|
||||
})
|
||||
if text == "..." then return end
|
||||
surface.play_sound({ path = "utility/armor_insert", position = position, volume_modifier = 0.75 })
|
||||
end
|
||||
|
||||
local function create_kaboom(surface, position, name)
|
||||
local target = position
|
||||
local speed = 0.5
|
||||
if name == "defender-capsule" or name == "destroyer-capsule" or name == "distractor-capsule" then
|
||||
surface.create_entity({
|
||||
name = "flying-text",
|
||||
position = position,
|
||||
text = "(((Sentries Engaging Target)))",
|
||||
color = { r = 0.8, g = 0.0, b = 0.0 }
|
||||
})
|
||||
local nearest_player_unit = surface.find_nearest_enemy({ position = position, max_distance = 128, force = "enemy" })
|
||||
if nearest_player_unit then target = nearest_player_unit.position end
|
||||
speed = 0.001
|
||||
end
|
||||
surface.create_entity({
|
||||
name = name,
|
||||
position = position,
|
||||
force = "enemy",
|
||||
target = target,
|
||||
speed = speed
|
||||
})
|
||||
end
|
||||
|
||||
local function tick_tack_trap(surface, position)
|
||||
local ffatable = Table.get_table()
|
||||
if not surface then return end
|
||||
if not position then return end
|
||||
if not position.x then return end
|
||||
if not position.y then return end
|
||||
local tick_tack_count = math_random(5, 9)
|
||||
for t = 60, tick_tack_count * 60, 60 do
|
||||
if not ffatable.on_tick_schedule[game.tick + t] then ffatable.on_tick_schedule[game.tick + t] = {} end
|
||||
|
||||
if t < tick_tack_count * 60 then
|
||||
ffatable.on_tick_schedule[game.tick + t][#ffatable.on_tick_schedule[game.tick + t] + 1] = {
|
||||
func = create_flying_text,
|
||||
args = { surface, { x = position.x, y = position.y }, tick_tacks[math_random(1, #tick_tacks)] }
|
||||
}
|
||||
else
|
||||
if math_random(1, 10) == 1 then
|
||||
ffatable.on_tick_schedule[game.tick + t][#ffatable.on_tick_schedule[game.tick + t] + 1] = {
|
||||
func = create_flying_text,
|
||||
args = { surface, { x = position.x, y = position.y }, "..." }
|
||||
}
|
||||
else
|
||||
ffatable.on_tick_schedule[game.tick + t][#ffatable.on_tick_schedule[game.tick + t] + 1] = {
|
||||
func = create_kaboom,
|
||||
args = { surface, { x = position.x, y = position.y }, kabooms[math_random(1, #kabooms)] }
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return tick_tack_trap
|
523
modules/scrap_towny_ffa/town_center.lua
Normal file
523
modules/scrap_towny_ffa/town_center.lua
Normal file
@ -0,0 +1,523 @@
|
||||
local Public = {}
|
||||
|
||||
local math_random = math.random
|
||||
local table_insert = table.insert
|
||||
local math_floor = math.floor
|
||||
local table_shuffle = table.shuffle_table
|
||||
|
||||
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 town_radius = 27
|
||||
local radius_between_towns = 160
|
||||
local ore_amount = 250
|
||||
|
||||
local colors = {}
|
||||
local c1 = 250
|
||||
local c2 = 210
|
||||
local c3 = -40
|
||||
for v = c1, c2, c3 do
|
||||
table_insert(colors, { 0, 0, v })
|
||||
end
|
||||
for v = c1, c2, c3 do
|
||||
table_insert(colors, { 0, v, 0 })
|
||||
end
|
||||
for v = c1, c2, c3 do
|
||||
table_insert(colors, { v, 0, 0 })
|
||||
end
|
||||
for v = c1, c2, c3 do
|
||||
table_insert(colors, { 0, v, v })
|
||||
end
|
||||
for v = c1, c2, c3 do
|
||||
table_insert(colors, { v, v, 0 })
|
||||
end
|
||||
for v = c1, c2, c3 do
|
||||
table_insert(colors, { v, 0, v })
|
||||
end
|
||||
|
||||
local town_wall_vectors = {}
|
||||
for x = 2, town_radius, 1 do
|
||||
table_insert(town_wall_vectors, { x, town_radius })
|
||||
table_insert(town_wall_vectors, { x * -1, town_radius })
|
||||
table_insert(town_wall_vectors, { x, town_radius * -1 })
|
||||
table_insert(town_wall_vectors, { x * -1, town_radius * -1 })
|
||||
end
|
||||
for y = 2, town_radius - 1, 1 do
|
||||
table_insert(town_wall_vectors, { town_radius, y })
|
||||
table_insert(town_wall_vectors, { town_radius, y * -1 })
|
||||
table_insert(town_wall_vectors, { town_radius * -1, y })
|
||||
table_insert(town_wall_vectors, { town_radius * -1, y * -1 })
|
||||
end
|
||||
|
||||
local gate_vectors_horizontal = {}
|
||||
for x = -1, 1, 1 do
|
||||
table_insert(gate_vectors_horizontal, { x, town_radius })
|
||||
table_insert(gate_vectors_horizontal, { x, town_radius * -1 })
|
||||
end
|
||||
local gate_vectors_vertical = {}
|
||||
for y = -1, 1, 1 do
|
||||
table_insert(gate_vectors_vertical, { town_radius, y })
|
||||
table_insert(gate_vectors_vertical, { town_radius * -1, y })
|
||||
end
|
||||
|
||||
local resource_vectors = {}
|
||||
resource_vectors[1] = {}
|
||||
for x = 7, 24, 1 do
|
||||
for y = 7, 24, 1 do
|
||||
table_insert(resource_vectors[1], { x, y })
|
||||
end
|
||||
end
|
||||
resource_vectors[2] = {}
|
||||
for _, vector in pairs(resource_vectors[1]) do table_insert(resource_vectors[2], { vector[1] * -1, vector[2] }) end
|
||||
resource_vectors[3] = {}
|
||||
for _, vector in pairs(resource_vectors[1]) do table_insert(resource_vectors[3], { vector[1] * -1, vector[2] * -1 }) end
|
||||
resource_vectors[4] = {}
|
||||
for _, vector in pairs(resource_vectors[1]) do table_insert(resource_vectors[4], { vector[1], vector[2] * -1 }) end
|
||||
|
||||
local additional_resource_vectors = {}
|
||||
additional_resource_vectors[1] = {}
|
||||
for x = 10, 22, 1 do
|
||||
for y = -4, 4, 1 do
|
||||
table_insert(additional_resource_vectors[1], { x, y })
|
||||
end
|
||||
end
|
||||
additional_resource_vectors[2] = {}
|
||||
for _, vector in pairs(additional_resource_vectors[1]) do table_insert(additional_resource_vectors[2], { vector[1] * -1, vector[2] }) end
|
||||
additional_resource_vectors[3] = {}
|
||||
for y = 10, 22, 1 do
|
||||
for x = -4, 4, 1 do
|
||||
table_insert(additional_resource_vectors[3], { x, y })
|
||||
end
|
||||
end
|
||||
additional_resource_vectors[4] = {}
|
||||
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 starter_supplies = {
|
||||
{ name = "raw-fish", count = 3 },
|
||||
{ name = "grenade", count = 3 },
|
||||
{ name = "stone", count = 32 },
|
||||
{ name = "land-mine", count = 4 },
|
||||
{ name = "iron-gear-wheel", count = 16 },
|
||||
{ name = "iron-plate", count = 32 },
|
||||
{ name = "copper-plate", count = 16 },
|
||||
{ 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
|
||||
count = count + e.amount
|
||||
end
|
||||
return count
|
||||
end
|
||||
|
||||
local function draw_town_spawn(player_name)
|
||||
local ffatable = Table.get_table()
|
||||
local market = ffatable.town_centers[player_name].market
|
||||
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) } }
|
||||
|
||||
-- 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
|
||||
|
||||
-- create walls
|
||||
for _, vector in pairs(gate_vectors_horizontal) do
|
||||
local p = { position.x + vector[1], position.y + vector[2] }
|
||||
--p = surface.find_non_colliding_position("gate", p, 64, 1)
|
||||
if p then
|
||||
surface.create_entity({ name = "gate", position = p, force = player_name, direction = 2 })
|
||||
end
|
||||
end
|
||||
for _, vector in pairs(gate_vectors_vertical) do
|
||||
local p = { position.x + vector[1], position.y + vector[2] }
|
||||
--p = surface.find_non_colliding_position("gate", p, 64, 1)
|
||||
if p then
|
||||
surface.create_entity({ name = "gate", position = p, force = player_name, direction = 0 })
|
||||
end
|
||||
end
|
||||
|
||||
for _, vector in pairs(town_wall_vectors) do
|
||||
local p = { position.x + vector[1], position.y + vector[2] }
|
||||
--p = surface.find_non_colliding_position("stone-wall", p, 64, 1)
|
||||
if p then
|
||||
surface.create_entity({ name = "stone-wall", position = p, force = player_name })
|
||||
end
|
||||
end
|
||||
|
||||
-- ore patches
|
||||
local ores = { "iron-ore", "copper-ore", "stone", "coal" }
|
||||
table_shuffle(ores)
|
||||
|
||||
for i = 1, 4, 1 do
|
||||
if count_nearby_ore(surface, position, ores[i]) < 200000 then
|
||||
for _, vector in pairs(resource_vectors[i]) do
|
||||
local p = { position.x + vector[1], position.y + vector[2] }
|
||||
p = surface.find_non_colliding_position(ores[i], p, 64, 1)
|
||||
if p then
|
||||
surface.create_entity({ name = ores[i], position = p, amount = ore_amount })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- starter chests
|
||||
for _, item_stack in pairs(starter_supplies) do
|
||||
local m1 = -8 + math_random(0, 16)
|
||||
local m2 = -8 + math_random(0, 16)
|
||||
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 inventory = e.get_inventory(defines.inventory.chest)
|
||||
inventory.insert(item_stack)
|
||||
end
|
||||
end
|
||||
|
||||
local vector_indexes = { 1, 2, 3, 4 }
|
||||
table_shuffle(vector_indexes)
|
||||
|
||||
-- trees
|
||||
--local tree = "tree-0" .. math_random(1, 9)
|
||||
--for _, vector in pairs(additional_resource_vectors[vector_indexes[1]]) do
|
||||
-- if math_random(1, 6) == 1 then
|
||||
-- local p = {position.x + vector[1], position.y + vector[2]}
|
||||
-- p = surface.find_non_colliding_position(tree, p, 64, 1)
|
||||
-- if p then
|
||||
-- surface.create_entity({name = tree, position = p})
|
||||
-- end
|
||||
-- end
|
||||
--end
|
||||
|
||||
--local area = {{position.x - town_radius * 1.5, position.y - town_radius * 1.5}, {position.x + town_radius * 1.5, position.y + town_radius * 1.5}}
|
||||
|
||||
-- pond
|
||||
for _, vector in pairs(additional_resource_vectors[vector_indexes[2]]) do
|
||||
local x = position.x + vector[1]
|
||||
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 } })
|
||||
end
|
||||
end
|
||||
|
||||
-- fish
|
||||
for _, vector in pairs(additional_resource_vectors[vector_indexes[2]]) do
|
||||
local x = position.x + vector[1] + 0.5
|
||||
local y = position.y + vector[2] + 0.5
|
||||
local p = { x = x, y = y }
|
||||
if math_random(1, 5) == 1 then
|
||||
if surface.can_place_entity({ name = "fish", position = p }) then
|
||||
surface.create_entity({ name = "water-splash", position = p })
|
||||
surface.create_entity({ name = "fish", position = p })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- uranium ore
|
||||
--if count_nearby_ore(surface, position, "uranium-ore") < 100000 then
|
||||
-- for _, vector in pairs(additional_resource_vectors[vector_indexes[3]]) do
|
||||
-- local p = {position.x + vector[1], position.y + vector[2]}
|
||||
-- p = surface.find_non_colliding_position("uranium-ore", p, 64, 1)
|
||||
-- if p then
|
||||
-- surface.create_entity({name = "uranium-ore", position = p, amount = ore_amount * 2})
|
||||
-- end
|
||||
-- end
|
||||
--end
|
||||
|
||||
-- oil patches
|
||||
--local vectors = additional_resource_vectors[vector_indexes[4]]
|
||||
--for _ = 1, 3, 1 do
|
||||
-- local vector = vectors[math_random(1, #vectors)]
|
||||
-- local p = {position.x + vector[1], position.y + vector[2]}
|
||||
-- p = surface.find_non_colliding_position("crude-oil", p, 64, 1)
|
||||
-- if p then
|
||||
-- surface.create_entity({name = "crude-oil", position = p, amount = 500000})
|
||||
-- end
|
||||
--end
|
||||
end
|
||||
|
||||
local function is_valid_location(surface, position)
|
||||
local ffatable = Table.get_table()
|
||||
|
||||
if not surface.can_place_entity({ name = "market", position = position }) then
|
||||
surface.create_entity({
|
||||
name = "flying-text",
|
||||
position = position,
|
||||
text = "Position is obstructed - no room for market!",
|
||||
color = { r = 0.77, g = 0.0, b = 0.0 }
|
||||
})
|
||||
return false
|
||||
end
|
||||
|
||||
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
|
||||
surface.create_entity({
|
||||
name = "flying-text",
|
||||
position = position,
|
||||
text = "Town would be off-map!",
|
||||
color = { r = 0.77, g = 0.0, b = 0.0 }
|
||||
})
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
if ffatable.size_of_town_centers > 48 then
|
||||
surface.create_entity({
|
||||
name = "flying-text",
|
||||
position = position,
|
||||
text = "Too many town centers 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
|
||||
surface.create_entity({
|
||||
name = "flying-text",
|
||||
position = position,
|
||||
text = "Town location is too close to another town center!",
|
||||
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.set_market_health(entity, final_damage_amount)
|
||||
local ffatable = Table.get_table()
|
||||
local town_center = ffatable.town_centers[entity.force.name]
|
||||
town_center.health = math_floor(town_center.health - final_damage_amount)
|
||||
if town_center.health > town_center.max_health then town_center.health = town_center.max_health end
|
||||
local m = town_center.health / town_center.max_health
|
||||
entity.health = 150 * m
|
||||
rendering.set_text(town_center.health_text, "HP: " .. town_center.health .. " / " .. town_center.max_health)
|
||||
end
|
||||
|
||||
function Public.update_coin_balance(force)
|
||||
local ffatable = Table.get_table()
|
||||
local town_center = ffatable.town_centers[force.name]
|
||||
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
|
||||
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
|
||||
|
||||
local surface = entity.surface
|
||||
local ffatable = Table.get_table()
|
||||
|
||||
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,
|
||||
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
|
||||
end
|
||||
end
|
||||
|
||||
local position = entity.position
|
||||
entity.destroy()
|
||||
|
||||
if not is_valid_location(surface, position) then
|
||||
player.insert({ name = "stone-furnace", count = 1 })
|
||||
return true
|
||||
end
|
||||
|
||||
Team.add_new_force(force_name)
|
||||
|
||||
ffatable.town_centers[force_name] = {}
|
||||
local town_center = ffatable.town_centers[force_name]
|
||||
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.coin_balance = 0
|
||||
town_center.input_buffer = {}
|
||||
town_center.output_buffer = {}
|
||||
town_center.health = town_center.max_health
|
||||
town_center.color = get_color()
|
||||
town_center.research_counter = 1
|
||||
town_center.upgrades = {}
|
||||
town_center.upgrades.mining_prod = 0
|
||||
town_center.upgrades.laser_turret = {}
|
||||
town_center.upgrades.laser_turret.slots = 0
|
||||
town_center.upgrades.laser_turret.locations = {}
|
||||
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.town_caption = rendering.draw_text {
|
||||
text = player.name .. "'s Town",
|
||||
surface = surface,
|
||||
target = town_center.market,
|
||||
target_offset = { 0, -4.25 },
|
||||
color = town_center.color,
|
||||
scale = 1.30,
|
||||
font = "default-game",
|
||||
alignment = "center",
|
||||
scale_with_zoom = false
|
||||
}
|
||||
|
||||
ffatable.size_of_town_centers = ffatable.size_of_town_centers + 1
|
||||
|
||||
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)
|
||||
|
||||
game.print(">> " .. player.name .. " has founded a new town!", { 255, 255, 0 })
|
||||
return true
|
||||
end
|
||||
|
||||
local function on_built_entity(event)
|
||||
found_town(event)
|
||||
end
|
||||
|
||||
local function on_player_repaired_entity(event)
|
||||
local entity = event.entity
|
||||
if entity.name == "market" then
|
||||
Public.set_market_health(entity, -4)
|
||||
end
|
||||
end
|
||||
|
||||
--local function on_robot_repaired_entity(event)
|
||||
-- local entity = event.entity
|
||||
-- if entity.name == "market" then
|
||||
-- Public.set_market_health(entity, -4)
|
||||
-- end
|
||||
--end
|
||||
|
||||
local function on_entity_damaged(event)
|
||||
local entity = event.entity
|
||||
if not entity.valid then return end
|
||||
if entity.name == "market" then
|
||||
Public.set_market_health(entity, event.final_damage_amount)
|
||||
end
|
||||
end
|
||||
|
||||
local on_init = function ()
|
||||
local ffatable = Table.get_table()
|
||||
ffatable.town_centers = {}
|
||||
ffatable.size_of_town_centers = 0
|
||||
ffatable.cooldowns_town_placement = {}
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.on_init(on_init)
|
||||
Event.add(defines.events.on_built_entity, on_built_entity)
|
||||
Event.add(defines.events.on_player_repaired_entity, on_player_repaired_entity)
|
||||
--Event.add(defines.events.on_robot_repaired_entity, on_robot_repaired_entity)
|
||||
Event.add(defines.events.on_entity_damaged, on_entity_damaged)
|
||||
|
||||
return Public
|
176
modules/scrap_towny_ffa/towny_balance.lua
Normal file
176
modules/scrap_towny_ffa/towny_balance.lua
Normal file
@ -0,0 +1,176 @@
|
||||
--Towny balance things by Gerkiz --
|
||||
|
||||
local player_ammo_starting_modifiers = {
|
||||
['artillery-shell'] = -0.75,
|
||||
['biological'] = -0.5,
|
||||
['bullet'] = -0.25,
|
||||
['cannon-shell'] = -0.75,
|
||||
['capsule'] = -0.5,
|
||||
['combat-robot-beam'] = -0.5,
|
||||
['combat-robot-laser'] = -0.5,
|
||||
['electric'] = -0.5,
|
||||
['flamethrower'] = -0.75,
|
||||
['grenade'] = -0.5,
|
||||
['landmine'] = -0.33,
|
||||
['laser-turret'] = -0.75,
|
||||
['melee'] = 2,
|
||||
['railgun'] = 1,
|
||||
['rocket'] = -0.75,
|
||||
['shotgun-shell'] = -0.20
|
||||
}
|
||||
|
||||
local player_gun_speed_modifiers = {
|
||||
['artillery-shell'] = -0.75,
|
||||
['biological'] = -0.5,
|
||||
['bullet'] = -0.55,
|
||||
['cannon-shell'] = -0.75,
|
||||
['capsule'] = -0.5,
|
||||
['combat-robot-beam'] = -0.5,
|
||||
['combat-robot-laser'] = -0.5,
|
||||
['electric'] = -0.5,
|
||||
['flamethrower'] = -0.75,
|
||||
['grenade'] = -0.5,
|
||||
['landmine'] = -0.33,
|
||||
['laser-turret'] = -0.75,
|
||||
['melee'] = 1,
|
||||
['railgun'] = 0,
|
||||
['rocket'] = -0.75,
|
||||
['shotgun-shell'] = -0.50
|
||||
}
|
||||
|
||||
local player_ammo_research_modifiers = {
|
||||
['artillery-shell'] = -0.75,
|
||||
['biological'] = -0.5,
|
||||
['bullet'] = -0.5,
|
||||
['cannon-shell'] = -0.85,
|
||||
['capsule'] = -0.5,
|
||||
['combat-robot-beam'] = -0.5,
|
||||
['combat-robot-laser'] = -0.5,
|
||||
['electric'] = -0.6,
|
||||
['flamethrower'] = -0.75,
|
||||
['grenade'] = -0.5,
|
||||
['landmine'] = -0.5,
|
||||
['laser-turret'] = -0.75,
|
||||
['melee'] = -0.5,
|
||||
['railgun'] = -0.5,
|
||||
['rocket'] = -0.5,
|
||||
['shotgun-shell'] = -0.20
|
||||
}
|
||||
|
||||
local player_turrets_research_modifiers = {
|
||||
['gun-turret'] = -0.75,
|
||||
['laser-turret'] = -0.75,
|
||||
['flamethrower-turret'] = -0.75
|
||||
}
|
||||
|
||||
local enemy_ammo_starting_modifiers = {
|
||||
['artillery-shell'] = 0,
|
||||
['biological'] = 0,
|
||||
['bullet'] = 0,
|
||||
['cannon-shell'] = 0,
|
||||
['capsule'] = 0,
|
||||
['combat-robot-beam'] = 0,
|
||||
['combat-robot-laser'] = 0,
|
||||
['electric'] = 0,
|
||||
['flamethrower'] = 0,
|
||||
['grenade'] = 0,
|
||||
['landmine'] = 0,
|
||||
['laser-turret'] = 0,
|
||||
['melee'] = 0,
|
||||
['railgun'] = 0,
|
||||
['rocket'] = 0,
|
||||
['shotgun-shell'] = 0
|
||||
}
|
||||
|
||||
local enemy_ammo_evolution_modifiers = {
|
||||
['artillery-shell'] = 1,
|
||||
['biological'] = 2,
|
||||
['bullet'] = 1,
|
||||
--['cannon-shell'] = 1,
|
||||
--['capsule'] = 1,
|
||||
--['combat-robot-beam'] = 1,
|
||||
--['combat-robot-laser'] = 1,
|
||||
--['electric'] = 1,
|
||||
['flamethrower'] = 2,
|
||||
--['grenade'] = 1,
|
||||
--['landmine'] = 1,
|
||||
['laser-turret'] = 2,
|
||||
['melee'] = 2
|
||||
--['railgun'] = 1,
|
||||
--['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)
|
||||
end
|
||||
|
||||
for k, v in pairs(player_gun_speed_modifiers) do
|
||||
force.set_gun_speed_modifier(k, v)
|
||||
end
|
||||
end
|
||||
|
||||
function init_enemy_weapon_damage()
|
||||
local e_force = game.forces["enemy"]
|
||||
|
||||
for k, v in pairs(enemy_ammo_starting_modifiers) do
|
||||
e_force.set_ammo_damage_modifier(k, v)
|
||||
end
|
||||
end
|
||||
|
||||
local function enemy_weapon_damage()
|
||||
local f = game.forces.enemy
|
||||
|
||||
local ef = f.evolution_factor
|
||||
|
||||
for k, v in pairs(enemy_ammo_evolution_modifiers) do
|
||||
local base = enemy_ammo_starting_modifiers[k]
|
||||
|
||||
local new = base + v * ef
|
||||
f.set_ammo_damage_modifier(k, new)
|
||||
end
|
||||
end
|
||||
|
||||
local function research_finished(event)
|
||||
local r = event.research
|
||||
local p_force = r.force
|
||||
|
||||
for _, e in ipairs(r.effects) do
|
||||
local t = e.type
|
||||
|
||||
if t == 'ammo-damage' then
|
||||
local category = e.ammo_category
|
||||
local factor = player_ammo_research_modifiers[category]
|
||||
|
||||
if factor then
|
||||
local current_m = p_force.get_ammo_damage_modifier(category)
|
||||
local m = e.modifier
|
||||
p_force.set_ammo_damage_modifier(category, current_m + factor * m)
|
||||
end
|
||||
elseif t == 'turret-attack' then
|
||||
local category = e.turret_id
|
||||
local factor = player_turrets_research_modifiers[category]
|
||||
|
||||
if factor then
|
||||
local current_m = p_force.get_turret_attack_modifier(category)
|
||||
local m = e.modifier
|
||||
p_force.set_turret_attack_modifier(category, current_m + factor * m)
|
||||
end
|
||||
elseif t == 'gun-speed' then
|
||||
local category = e.ammo_category
|
||||
local factor = player_gun_speed_modifiers[category]
|
||||
|
||||
if factor then
|
||||
local current_m = p_force.get_gun_speed_modifier(category)
|
||||
local m = e.modifier
|
||||
p_force.set_gun_speed_modifier(category, current_m + factor * m)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.on_init(init_enemy_weapon_damage)
|
||||
Event.on_nth_tick(18000, enemy_weapon_damage)
|
||||
Event.add(defines.events.on_research_finished, research_finished)
|
37
modules/scrap_towny_ffa/trap.lua
Normal file
37
modules/scrap_towny_ffa/trap.lua
Normal file
@ -0,0 +1,37 @@
|
||||
local math_random = math.random
|
||||
local Evolution = require "modules.scrap_towny_ffa.evolution"
|
||||
local Building = require "modules.scrap_towny_ffa.building"
|
||||
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"
|
||||
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 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
|
||||
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
|
||||
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
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function on_player_mined_entity(event)
|
||||
local entity = event.entity
|
||||
trap(entity)
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.add(defines.events.on_player_mined_entity, on_player_mined_entity)
|
17
modules/scrap_towny_ffa/turrets_drop_ammo.lua
Normal file
17
modules/scrap_towny_ffa/turrets_drop_ammo.lua
Normal file
@ -0,0 +1,17 @@
|
||||
local math_random = math.random
|
||||
local math_min = math.min
|
||||
|
||||
local function on_entity_died(event)
|
||||
local entity = event.entity
|
||||
local surface = entity.surface
|
||||
if entity.type == "ammo-turret" and entity.force.name == "enemy" then
|
||||
local min = math_min(entity.get_item_count("piercing-rounds-magazine"), 20)
|
||||
if min > 0 then
|
||||
surface.spill_item_stack(entity.position, { name = "piercing-rounds-magazine", count = math_random(1, min) }, true)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.add(defines.events.on_entity_died, on_entity_died)
|
||||
|
84
modules/scrap_towny_ffa/unearthing_biters.lua
Normal file
84
modules/scrap_towny_ffa/unearthing_biters.lua
Normal file
@ -0,0 +1,84 @@
|
||||
local math_random = math.random
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
|
||||
local function create_particles(surface, position, amount)
|
||||
if not surface.valid then return end
|
||||
for _ = 1, amount, 1 do
|
||||
local m = math_random(6, 12)
|
||||
local m2 = m * 0.005
|
||||
|
||||
surface.create_particle({
|
||||
name = "stone-particle",
|
||||
position = position,
|
||||
frame_speed = 0.1,
|
||||
vertical_speed = 0.1,
|
||||
height = 0.1,
|
||||
movement = { m2 - (math_random(0, m) * 0.01), m2 - (math_random(0, m) * 0.01) }
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
local function spawn_biter(surface, position, evolution)
|
||||
if not surface.valid then return end
|
||||
local evo = math.floor(evolution * 1000)
|
||||
|
||||
local biter_chances = {
|
||||
{ name = "small-biter", chance = math.floor(1000 - (evo * 1.6)) },
|
||||
{ name = "small-spitter", chance = math.floor(500 - evo * 0.8) },
|
||||
{ name = "medium-biter", chance = -150 + evo },
|
||||
{ name = "medium-spitter", chance = -75 + math.floor(evo * 0.5) },
|
||||
{ name = "big-biter", chance = math.floor((evo - 500) * 3) },
|
||||
{ name = "big-spitter", chance = math.floor((evo - 500) * 2) },
|
||||
{ name = "behemoth-biter", chance = math.floor((evo - 800) * 6) },
|
||||
{ name = "behemoth-spitter", chance = math.floor((evo - 800) * 4) }
|
||||
}
|
||||
|
||||
local max_chance = 0
|
||||
for i = 1, 8, 1 do
|
||||
if biter_chances[i].chance < 0 then biter_chances[i].chance = 0 end
|
||||
max_chance = max_chance + biter_chances[i].chance
|
||||
end
|
||||
local r = math_random(1, max_chance)
|
||||
local current_chance = 0
|
||||
for i = 1, 8, 1 do
|
||||
current_chance = current_chance + biter_chances[i].chance
|
||||
if r <= current_chance then
|
||||
local biter_name = biter_chances[i].name
|
||||
local p = surface.find_non_colliding_position(biter_name, position, 10, 1)
|
||||
if not p then return end
|
||||
surface.create_entity({ name = biter_name, position = p, force = "enemy" })
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function unearthing_biters(surface, position, amount, relative_evolution)
|
||||
local ffatable = Table.get_table()
|
||||
if not surface then return end
|
||||
if not position then return end
|
||||
if not position.x then return end
|
||||
if not position.y then return end
|
||||
|
||||
local ticks = amount * 30
|
||||
ticks = ticks + 90
|
||||
for t = 1, ticks, 1 do
|
||||
if not ffatable.on_tick_schedule[game.tick + t] then ffatable.on_tick_schedule[game.tick + t] = {} end
|
||||
|
||||
ffatable.on_tick_schedule[game.tick + t][#ffatable.on_tick_schedule[game.tick + t] + 1] = {
|
||||
func = create_particles,
|
||||
args = { surface, { x = position.x, y = position.y }, 4 }
|
||||
}
|
||||
|
||||
if t > 90 then
|
||||
if t % 30 == 29 then
|
||||
ffatable.on_tick_schedule[game.tick + t][#ffatable.on_tick_schedule[game.tick + t] + 1] = {
|
||||
func = spawn_biter,
|
||||
args = { surface, { x = position.x, y = position.y }, relative_evolution }
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return unearthing_biters
|
69
modules/scrap_towny_ffa/unearthing_worm.lua
Normal file
69
modules/scrap_towny_ffa/unearthing_worm.lua
Normal file
@ -0,0 +1,69 @@
|
||||
local math_random = math.random
|
||||
local math_ceil = math.ceil
|
||||
|
||||
local Table = require 'modules.scrap_towny_ffa.table'
|
||||
|
||||
local function create_particles(surface, position, amount)
|
||||
if not surface.valid then return end
|
||||
for _ = 1, amount, 1 do
|
||||
local m = math_random(8, 24)
|
||||
local m2 = m * 0.005
|
||||
|
||||
surface.create_particle({
|
||||
name = "stone-particle",
|
||||
position = position,
|
||||
frame_speed = 0.1,
|
||||
vertical_speed = 0.1,
|
||||
height = 0.1,
|
||||
movement = { m2 - (math_random(0, m) * 0.01), m2 - (math_random(0, m) * 0.01) }
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
local function spawn_worm(surface, position, evolution_index)
|
||||
if not surface.valid then return end
|
||||
local worm_raffle_table = {
|
||||
[1] = { "small-worm-turret", "small-worm-turret", "small-worm-turret", "small-worm-turret", "small-worm-turret", "small-worm-turret" },
|
||||
[2] = { "small-worm-turret", "small-worm-turret", "small-worm-turret", "small-worm-turret", "small-worm-turret", "medium-worm-turret" },
|
||||
[3] = { "small-worm-turret", "small-worm-turret", "small-worm-turret", "small-worm-turret", "medium-worm-turret", "medium-worm-turret" },
|
||||
[4] = { "small-worm-turret", "small-worm-turret", "small-worm-turret", "medium-worm-turret", "medium-worm-turret", "medium-worm-turret" },
|
||||
[5] = { "small-worm-turret", "small-worm-turret", "medium-worm-turret", "medium-worm-turret", "medium-worm-turret", "big-worm-turret" },
|
||||
[6] = { "small-worm-turret", "medium-worm-turret", "medium-worm-turret", "medium-worm-turret", "medium-worm-turret", "big-worm-turret" },
|
||||
[7] = { "medium-worm-turret", "medium-worm-turret", "medium-worm-turret", "medium-worm-turret", "big-worm-turret", "big-worm-turret" },
|
||||
[8] = { "medium-worm-turret", "medium-worm-turret", "medium-worm-turret", "medium-worm-turret", "big-worm-turret", "big-worm-turret" },
|
||||
[9] = { "medium-worm-turret", "medium-worm-turret", "medium-worm-turret", "big-worm-turret", "big-worm-turret", "big-worm-turret" },
|
||||
[10] = { "medium-worm-turret", "medium-worm-turret", "medium-worm-turret", "big-worm-turret", "big-worm-turret", "big-worm-turret" }
|
||||
}
|
||||
local raffle = worm_raffle_table[evolution_index]
|
||||
local worm_name = raffle[math_random(1, #raffle)]
|
||||
surface.create_entity({ name = worm_name, position = position })
|
||||
end
|
||||
|
||||
local function unearthing_worm(surface, position, relative_evolution)
|
||||
local ffatable = Table.get_table()
|
||||
if not surface then return end
|
||||
if not position then return end
|
||||
if not position.x then return end
|
||||
if not position.y then return end
|
||||
|
||||
local evolution_index = math.ceil(relative_evolution * 10)
|
||||
if evolution_index < 1 then evolution_index = 1 end
|
||||
|
||||
for t = 1, 330, 1 do
|
||||
if not ffatable.on_tick_schedule[game.tick + t] then ffatable.on_tick_schedule[game.tick + t] = {} end
|
||||
|
||||
ffatable.on_tick_schedule[game.tick + t][#ffatable.on_tick_schedule[game.tick + t] + 1] = {
|
||||
func = create_particles,
|
||||
args = { surface, { x = position.x, y = position.y }, math_ceil(t * 0.05) }
|
||||
}
|
||||
|
||||
if t == 330 then
|
||||
ffatable.on_tick_schedule[game.tick + t][#ffatable.on_tick_schedule[game.tick + t] + 1] = {
|
||||
func = spawn_worm,
|
||||
args = { surface, { x = position.x, y = position.y }, evolution_index }
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return unearthing_worm
|
159
modules/scrap_towny_ffa/wreckage_yields_scrap.lua
Normal file
159
modules/scrap_towny_ffa/wreckage_yields_scrap.lua
Normal file
@ -0,0 +1,159 @@
|
||||
--wreckage yields scrap
|
||||
local table_insert = table.insert
|
||||
|
||||
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 = "artillery-shell", chance = 1},
|
||||
{name = "battery", chance = 20},
|
||||
{name = "cannon-shell", chance = 2},
|
||||
--{name = "cluster-grenade", chance = 2},
|
||||
{name = "construction-robot", chance = 1},
|
||||
{name = "copper-cable", chance = 250},
|
||||
{name = "copper-plate", chance = 500},
|
||||
{name = "crude-oil-barrel", chance = 30},
|
||||
{name = "defender-capsule", chance = 5},
|
||||
{name = "destroyer-capsule", chance = 1},
|
||||
{name = "distractor-capsule", chance = 2},
|
||||
{name = "electric-engine-unit", chance = 2},
|
||||
{name = "electronic-circuit", chance = 200},
|
||||
{name = "empty-barrel", chance = 10},
|
||||
{name = "engine-unit", chance = 4},
|
||||
{name = "explosive-cannon-shell", chance = 2},
|
||||
--{name = "explosive-rocket", chance = 3},
|
||||
--{name = "explosive-uranium-cannon-shell", chance = 1},
|
||||
{name = "explosives", chance = 5},
|
||||
{name = "green-wire", chance = 10},
|
||||
{name = "grenade", chance = 10},
|
||||
{name = "heat-pipe", chance = 1},
|
||||
{name = "heavy-oil-barrel", chance = 15},
|
||||
{name = "iron-gear-wheel", chance = 500},
|
||||
{name = "iron-plate", chance = 750},
|
||||
{name = "iron-stick", chance = 50},
|
||||
{name = "land-mine", chance = 3},
|
||||
{name = "light-oil-barrel", chance = 15},
|
||||
{name = "logistic-robot", chance = 1},
|
||||
{name = "low-density-structure", chance = 1},
|
||||
{name = "lubricant-barrel", chance = 20},
|
||||
--{name = "nuclear-fuel", chance = 1},
|
||||
{name = "petroleum-gas-barrel", chance = 15},
|
||||
{name = "pipe", chance = 100},
|
||||
{name = "pipe-to-ground", chance = 10},
|
||||
{name = "plastic-bar", chance = 5},
|
||||
{name = "processing-unit", chance = 2},
|
||||
{name = "red-wire", chance = 10},
|
||||
--{name = "rocket", chance = 3},
|
||||
--{name = "rocket-control-unit", chance = 1},
|
||||
--{name = "rocket-fuel", chance = 3},
|
||||
{name = "solid-fuel", chance = 100},
|
||||
{name = "steel-plate", chance = 150},
|
||||
{name = "sulfuric-acid-barrel", chance = 15},
|
||||
--{name = "uranium-cannon-shell", chance = 1},
|
||||
--{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}
|
||||
}
|
||||
|
||||
local entity_loot_amounts = {
|
||||
["advanced-circuit"] = 2,
|
||||
--["artillery-shell"] = 0.3,
|
||||
["battery"] = 2,
|
||||
["cannon-shell"] = 2,
|
||||
--["cluster-grenade"] = 0.3,
|
||||
["construction-robot"] = 0.3,
|
||||
["copper-cable"] = 24,
|
||||
["copper-plate"] = 16,
|
||||
["crude-oil-barrel"] = 3,
|
||||
["defender-capsule"] = 2,
|
||||
["destroyer-capsule"] = 0.3,
|
||||
["distractor-capsule"] = 0.3,
|
||||
["electric-engine-unit"] = 2,
|
||||
["electronic-circuit"] = 8,
|
||||
["empty-barrel"] = 3,
|
||||
["engine-unit"] = 2,
|
||||
["explosive-cannon-shell"] = 2,
|
||||
--["explosive-rocket"] = 2,
|
||||
--["explosive-uranium-cannon-shell"] = 2,
|
||||
["explosives"] = 4,
|
||||
["green-wire"] = 8,
|
||||
["grenade"] = 2,
|
||||
["heat-pipe"] = 1,
|
||||
["heavy-oil-barrel"] = 3,
|
||||
["iron-gear-wheel"] = 8,
|
||||
["iron-plate"] = 16,
|
||||
["iron-stick"] = 16,
|
||||
["land-mine"] = 1,
|
||||
["light-oil-barrel"] = 3,
|
||||
["logistic-robot"] = 0.3,
|
||||
["low-density-structure"] = 0.3,
|
||||
["lubricant-barrel"] = 3,
|
||||
--["nuclear-fuel"] = 0.1,
|
||||
["petroleum-gas-barrel"] = 3,
|
||||
["pipe"] = 8,
|
||||
["pipe-to-ground"] = 1,
|
||||
["plastic-bar"] = 4,
|
||||
["processing-unit"] = 1,
|
||||
["red-wire"] = 8,
|
||||
--["rocket"] = 2,
|
||||
--["rocket-control-unit"] = 0.3,
|
||||
--["rocket-fuel"] = 0.3,
|
||||
["solid-fuel"] = 4,
|
||||
["steel-plate"] = 4,
|
||||
["sulfuric-acid-barrel"] = 3,
|
||||
--["uranium-cannon-shell"] = 2,
|
||||
--["uranium-fuel-cell"] = 0.3,
|
||||
--["used-up-uranium-fuel-cell"] = 1,
|
||||
["water-barrel"] = 3,
|
||||
["tank"] = 1,
|
||||
["car"] = 1,
|
||||
}
|
||||
|
||||
local scrap_raffle = {}
|
||||
for _, t in pairs (entity_loot_chance) do
|
||||
for _ = 1, t.chance, 1 do
|
||||
table_insert(scrap_raffle, t.name)
|
||||
end
|
||||
end
|
||||
|
||||
local size_of_scrap_raffle = #scrap_raffle
|
||||
|
||||
local function on_player_mined_entity(event)
|
||||
local entity = event.entity
|
||||
if not entity.valid then return end
|
||||
local position = entity.position
|
||||
if Scrap.is_scrap(entity) == false then return end
|
||||
if entity.name == 'crash-site-chest-1' or entity.name == 'crash-site-chest-2' then return end
|
||||
|
||||
-- scrap entities drop loot
|
||||
event.buffer.clear()
|
||||
|
||||
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 player = game.players[event.player_index]
|
||||
local inserted_count = player.insert({name = scrap, count = amount})
|
||||
|
||||
if inserted_count ~= amount then
|
||||
local amount_to_spill = amount - inserted_count
|
||||
entity.surface.spill_item_stack(position, {name = scrap, count = amount_to_spill}, true)
|
||||
end
|
||||
|
||||
entity.surface.create_entity({
|
||||
name = "flying-text",
|
||||
position = position,
|
||||
text = "+" .. amount .. " [img=item/" .. scrap .. "]",
|
||||
color = {r=0.98, g=0.66, b=0.22}
|
||||
})
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.add(defines.events.on_player_mined_entity, on_player_mined_entity)
|
104
modules/worms_create_oil_patches.lua
Normal file
104
modules/worms_create_oil_patches.lua
Normal file
@ -0,0 +1,104 @@
|
||||
local math_random = math.random
|
||||
|
||||
local Global = require 'utils.global'
|
||||
local tick_schedule = {}
|
||||
Global.register(
|
||||
tick_schedule,
|
||||
function(t)
|
||||
tick_schedule = t
|
||||
end
|
||||
)
|
||||
|
||||
local death_animation_ticks = 120
|
||||
local decay_ticks = 2
|
||||
|
||||
local worms = {
|
||||
["small-worm-turret"] = { corpse="small-worm-corpse", patch_size = { min=30000, max=90000} },
|
||||
["medium-worm-turret"] = { corpse="medium-worm-corpse", patch_size = { min=60000, max=120000 } },
|
||||
["big-worm-turret"] = { corpse="big-worm-corpse", patch_size = { min=90000, max=300000 } },
|
||||
["behemoth-worm-turret"] = { corpse="behemoth-worm-corpse", patch_size = { min=120000, max=600000 } }
|
||||
}
|
||||
|
||||
local function destroy_worm(name, position, surface)
|
||||
local entity = surface.find_entity(name, position)
|
||||
if entity ~= nil and entity.valid then entity.destroy() end
|
||||
local corpse = worms[name].corpse
|
||||
local remains = surface.find_entity(corpse, position)
|
||||
if remains ~= nil and remains.valid then
|
||||
-- show an animation
|
||||
if math_random(1,40) == 1 then surface.create_entity({name = "explosion", position = {x = position.x + (3 - (math_random(1,60) * 0.1)), y = position.y + (3 - (math_random(1,60) * 0.1))}}) end
|
||||
if math_random(1,32) == 1 then surface.create_entity({name = "blood-explosion-huge", position = position}) end
|
||||
if math_random(1,16) == 1 then surface.create_entity({name = "blood-explosion-big", position = position}) end
|
||||
if math_random(1,8) == 1 then surface.create_entity({name = "blood-explosion-small", position = position}) end
|
||||
end
|
||||
end
|
||||
|
||||
local function remove_corpse(name, position, surface)
|
||||
local corpse = worms[name].corpse
|
||||
local remains = surface.find_entity(corpse, position)
|
||||
if remains ~= nil and remains.valid then remains.destroy() end
|
||||
end
|
||||
|
||||
-- place an oil patch at the worm location
|
||||
local function create_oil_patch(name, position, surface)
|
||||
local min = worms[name].patch_size.min
|
||||
local max = worms[name].patch_size.max
|
||||
surface.create_entity({name="crude-oil", position=position, amount=math_random(min,max)})
|
||||
end
|
||||
|
||||
-- worms create oil patches when killed
|
||||
local function process_worm(entity)
|
||||
local name = entity.name
|
||||
local position = entity.position
|
||||
local surface = entity.surface
|
||||
|
||||
local tick1 = game.tick + death_animation_ticks
|
||||
if not tick_schedule[tick1] then tick_schedule[tick1] = {} end
|
||||
tick_schedule[tick1][#tick_schedule[tick1] + 1] = {
|
||||
callback = 'destroy_worm',
|
||||
params = {name, position, surface}
|
||||
}
|
||||
local tick2 = game.tick + death_animation_ticks + decay_ticks
|
||||
if not tick_schedule[tick2] then tick_schedule[tick2] = {} end
|
||||
tick_schedule[tick2][#tick_schedule[tick2] + 1] = {
|
||||
callback = 'remove_corpse',
|
||||
params = {name, position, surface}
|
||||
}
|
||||
if math_random(1,4) == 1 then
|
||||
local tick3 = game.tick + death_animation_ticks + decay_ticks + 1
|
||||
if not tick_schedule[tick3] then tick_schedule[tick3] = {} end
|
||||
tick_schedule[tick3][#tick_schedule[tick3] + 1] = {
|
||||
callback = 'create_oil_patch',
|
||||
params = {name, position, surface}
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
local function on_entity_died(event)
|
||||
local entity = event.entity
|
||||
local test = {
|
||||
["small-worm-turret"] = true,
|
||||
["medium-worm-turret"] = true,
|
||||
["big-worm-turret"] = true,
|
||||
["behemoth-worm-turret"] = true
|
||||
}
|
||||
if test[entity.name] ~= nil then
|
||||
process_worm(entity)
|
||||
end
|
||||
end
|
||||
|
||||
local function on_tick()
|
||||
if not tick_schedule[game.tick] then return end
|
||||
for _, token in pairs(tick_schedule[game.tick]) do
|
||||
local callback = token.callback
|
||||
local params = token.params
|
||||
if callback == 'destroy_worm' then destroy_worm(params[1], params[2], params[3]) end
|
||||
if callback == 'remove_corpse' then remove_corpse(params[1], params[2], params[3]) end
|
||||
if callback == 'create_oil_patch' then create_oil_patch(params[1], params[2], params[3]) end
|
||||
end
|
||||
tick_schedule[game.tick] = nil
|
||||
end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
Event.add(defines.events.on_tick, on_tick)
|
||||
Event.add(defines.events.on_entity_died, on_entity_died)
|
330
terrain_layouts/scrap_towny_ffa.lua
Normal file
330
terrain_layouts/scrap_towny_ffa.lua
Normal file
@ -0,0 +1,330 @@
|
||||
local table_insert = table.insert
|
||||
local math_random = math.random
|
||||
local math_floor = math.floor
|
||||
local math_abs = math.abs
|
||||
|
||||
local get_noise = require 'utils.get_noise'
|
||||
local Scrap = require 'modules.scrap_towny_ffa.scrap'
|
||||
require 'modules.no_deconstruction_of_neutral_entities'
|
||||
|
||||
local scrap_entities = {
|
||||
-- simple entity
|
||||
{name = "small-ship-wreck"}, -- these are not mineable normally
|
||||
{name = "small-ship-wreck"}, -- these are not mineable normally
|
||||
{name = "small-ship-wreck"}, -- these are not mineable normally
|
||||
{name = "small-ship-wreck"}, -- these are not mineable normally
|
||||
{name = "small-ship-wreck"}, -- these are not mineable normally
|
||||
{name = "small-ship-wreck"}, -- these are not mineable normally
|
||||
{name = "small-ship-wreck"}, -- these are not mineable normally
|
||||
{name = "small-ship-wreck"}, -- these are not mineable normally
|
||||
{name = "medium-ship-wreck"}, -- these are not mineable normally
|
||||
{name = "medium-ship-wreck"}, -- these are not mineable normally
|
||||
{name = "medium-ship-wreck"}, -- these are not mineable normally
|
||||
{name = "medium-ship-wreck"}, -- these are not mineable normally
|
||||
-- simple entity with owner
|
||||
{name = "crash-site-spaceship-wreck-small-1"}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-small-1"}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-small-2"}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-small-3"}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-small-4"}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-small-5"}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-small-6"} -- these do not have mining animation
|
||||
}
|
||||
|
||||
local scrap_entities_index = table.size(scrap_entities)
|
||||
|
||||
local scrap_containers = {
|
||||
-- containers
|
||||
{name = "big-ship-wreck-1", size = 3}, -- these are not mineable normally
|
||||
{name = "big-ship-wreck-1", size = 3}, -- these are not mineable normally
|
||||
{name = "big-ship-wreck-1", size = 3}, -- these are not mineable normally
|
||||
{name = "big-ship-wreck-2", size = 3}, -- these are not mineable normally
|
||||
{name = "big-ship-wreck-2", size = 3}, -- these are not mineable normally
|
||||
{name = "big-ship-wreck-2", size = 3}, -- these are not mineable normally
|
||||
{name = "big-ship-wreck-3", size = 3}, -- these are not mineable normally
|
||||
{name = "big-ship-wreck-3", size = 3}, -- these are not mineable normally
|
||||
{name = "big-ship-wreck-3", size = 3}, -- these are not mineable normally
|
||||
{name = "crash-site-chest-1", size = 8}, -- these do not have mining animation
|
||||
{name = "crash-site-chest-2", size = 8}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-medium-1", size = 1}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-medium-1", size = 1}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-medium-1", size = 1}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-medium-1", size = 1}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-medium-2", size = 1}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-medium-2", size = 1}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-medium-2", size = 1}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-medium-2", size = 1}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-medium-3", size = 1}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-medium-3", size = 1}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-medium-3", size = 1}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-medium-3", size = 1}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-big-1", size = 2}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-big-1", size = 2}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-big-1", size = 2}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-big-2", size = 2}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-big-2", size = 2}, -- these do not have mining animation
|
||||
{name = "crash-site-spaceship-wreck-big-2", size = 2}, -- these do not have mining animation
|
||||
}
|
||||
local scrap_containers_index = table.size(scrap_containers)
|
||||
|
||||
-- loot chances and amounts for scrap containers
|
||||
|
||||
local container_loot_chance = {
|
||||
{name = "advanced-circuit", chance = 5},
|
||||
{name = "artillery-shell", chance = 1},
|
||||
{name = "cannon-shell", chance = 2},
|
||||
{name = "cliff-explosives", chance = 5},
|
||||
--{name = "cluster-grenade", chance = 2},
|
||||
{name = "construction-robot", chance = 1},
|
||||
{name = "copper-cable", chance = 250},
|
||||
{name = "copper-plate", chance = 500},
|
||||
{name = "crude-oil-barrel", chance = 30},
|
||||
{name = "defender-capsule", chance = 5},
|
||||
{name = "destroyer-capsule", chance = 1},
|
||||
{name = "distractor-capsule", chance = 2},
|
||||
{name = "electric-engine-unit", chance = 2},
|
||||
{name = "electronic-circuit", chance = 200},
|
||||
{name = "empty-barrel", chance = 10},
|
||||
{name = "engine-unit", chance = 7},
|
||||
{name = "explosive-cannon-shell", chance = 2},
|
||||
--{name = "explosive-rocket", chance = 3},
|
||||
{name = "explosive-uranium-cannon-shell", chance = 1},
|
||||
{name = "explosives", chance = 5},
|
||||
{name = "green-wire", chance = 10},
|
||||
{name = "grenade", chance = 10},
|
||||
{name = "heat-pipe", chance = 1},
|
||||
{name = "heavy-oil-barrel", chance = 15},
|
||||
{name = "iron-gear-wheel", chance = 500},
|
||||
{name = "iron-plate", chance = 750},
|
||||
{name = "iron-stick", chance = 50},
|
||||
{name = "land-mine", chance = 3},
|
||||
{name = "light-oil-barrel", chance = 15},
|
||||
{name = "logistic-robot", chance = 1},
|
||||
{name = "low-density-structure", chance = 1},
|
||||
{name = "lubricant-barrel", chance = 20},
|
||||
{name = "nuclear-fuel", chance = 1},
|
||||
{name = "petroleum-gas-barrel", chance = 15},
|
||||
{name = "pipe", chance = 100},
|
||||
{name = "pipe-to-ground", chance = 10},
|
||||
{name = "plastic-bar", chance = 5},
|
||||
{name = "processing-unit", chance = 2},
|
||||
{name = "red-wire", chance = 10},
|
||||
--{name = "rocket", chance = 3}, {name = "battery", chance = 20},
|
||||
{name = "rocket-control-unit", chance = 1},
|
||||
{name = "rocket-fuel", chance = 3},
|
||||
{name = "solid-fuel", chance = 100},
|
||||
{name = "steel-plate", chance = 150},
|
||||
{name = "sulfuric-acid-barrel", chance = 15},
|
||||
{name = "uranium-cannon-shell", chance = 1},
|
||||
{name = "uranium-fuel-cell", chance = 1},
|
||||
{name = "used-up-uranium-fuel-cell", chance = 1},
|
||||
{name = "water-barrel", chance = 10}
|
||||
}
|
||||
|
||||
local container_loot_amounts = {
|
||||
["advanced-circuit"] = 2,
|
||||
["artillery-shell"] = 0.3,
|
||||
["battery"] = 2,
|
||||
["cannon-shell"] = 2,
|
||||
["cliff-explosives"] = 2,
|
||||
--["cluster-grenade"] = 0.3,
|
||||
["construction-robot"] = 0.3,
|
||||
["copper-cable"] = 24,
|
||||
["copper-plate"] = 16,
|
||||
["crude-oil-barrel"] = 3,
|
||||
["defender-capsule"] = 2,
|
||||
["destroyer-capsule"] = 0.3,
|
||||
["distractor-capsule"] = 0.3,
|
||||
["electric-engine-unit"] = 2,
|
||||
["electronic-circuit"] = 8,
|
||||
["empty-barrel"] = 3,
|
||||
["engine-unit"] = 2,
|
||||
["explosive-cannon-shell"] = 2,
|
||||
--["explosive-rocket"] = 2,
|
||||
["explosive-uranium-cannon-shell"] = 2,
|
||||
["explosives"] = 4,
|
||||
["green-wire"] = 8,
|
||||
["grenade"] = 2,
|
||||
["heat-pipe"] = 1,
|
||||
["heavy-oil-barrel"] = 3,
|
||||
["iron-gear-wheel"] = 8,
|
||||
["iron-plate"] = 16,
|
||||
["iron-stick"] = 16,
|
||||
["land-mine"] = 1,
|
||||
["light-oil-barrel"] = 3,
|
||||
["logistic-robot"] = 0.3,
|
||||
["low-density-structure"] = 0.3,
|
||||
["lubricant-barrel"] = 3,
|
||||
["nuclear-fuel"] = 0.1,
|
||||
["petroleum-gas-barrel"] = 3,
|
||||
["pipe"] = 8,
|
||||
["pipe-to-ground"] = 1,
|
||||
["plastic-bar"] = 4,
|
||||
["processing-unit"] = 1,
|
||||
["red-wire"] = 8,
|
||||
--["rocket"] = 2,
|
||||
["rocket-control-unit"] = 0.3,
|
||||
["rocket-fuel"] = 0.3,
|
||||
["solid-fuel"] = 4,
|
||||
["steel-plate"] = 4,
|
||||
["sulfuric-acid-barrel"] = 3,
|
||||
["uranium-cannon-shell"] = 2,
|
||||
["uranium-fuel-cell"] = 0.3,
|
||||
["used-up-uranium-fuel-cell"] = 1,
|
||||
["water-barrel"] = 3
|
||||
}
|
||||
|
||||
local scrap_raffle = {}
|
||||
for _, t in pairs(container_loot_chance) do
|
||||
for _ = 1, t.chance, 1 do
|
||||
table_insert(scrap_raffle, t.name)
|
||||
end
|
||||
end
|
||||
|
||||
local size_of_scrap_raffle = #scrap_raffle
|
||||
|
||||
local function place_scrap(surface, position)
|
||||
-- place turrets
|
||||
if math_random(1, 700) == 1 then
|
||||
if position.x ^ 2 + position.x ^ 2 > 4096 then
|
||||
local e = surface.create_entity({name = "gun-turret", position = position, force = "enemy"})
|
||||
e.minable = false
|
||||
e.operable = false
|
||||
e.insert({name = "piercing-rounds-magazine", count = 100})
|
||||
return
|
||||
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})
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- place scrap containers with loot
|
||||
if math_random(1, 128) == 1 then
|
||||
local scrap = scrap_containers[math_random(1, scrap_containers_index)]
|
||||
local e = surface.create_entity({name = scrap.name, position = position, force = "neutral"})
|
||||
e.minable = true
|
||||
local i = e.get_inventory(defines.inventory.chest)
|
||||
if i then
|
||||
local size = scrap.size
|
||||
for _ = 1, math_random(1, size), 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})
|
||||
end
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
-- place scrap entities with loot
|
||||
local scrap = scrap_entities[math_random(1, scrap_entities_index)]
|
||||
local e = surface.create_entity({name = scrap.name, position = position, force = "neutral"})
|
||||
e.minable = true
|
||||
end
|
||||
|
||||
local function is_scrap_area(n)
|
||||
if n > 0.5 then return true end
|
||||
if n < -0.5 then return true end
|
||||
end
|
||||
|
||||
local function move_away_biteys(surface, area)
|
||||
for _, e in pairs(surface.find_entities_filtered({type = {"unit-spawner", "turret", "unit"}, area = area})) do
|
||||
local position = surface.find_non_colliding_position(e.name, e.position, 96, 4)
|
||||
if position then
|
||||
surface.create_entity({name = e.name, position = position, force = "enemy"})
|
||||
e.destroy()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local vectors = {{0,0}, {1,0}, {-1,0}, {0,1}, {0,-1}}
|
||||
|
||||
local function landfill_under(entity)
|
||||
-- landfill the area under the entity
|
||||
local surface = entity.surface
|
||||
for _, v in pairs(vectors) do
|
||||
local position = {entity.position.x + v[1], entity.position.y + v[2]}
|
||||
if not surface.get_tile(position).collides_with("resource-layer") then
|
||||
surface.set_tiles({{name = "landfill", position = position}}, true)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
local function on_player_mined_entity(event)
|
||||
local entity = event.entity
|
||||
if not entity.valid then return end
|
||||
if Scrap.is_scrap(entity) then landfill_under(entity) end
|
||||
end
|
||||
|
||||
local function on_entity_died(event)
|
||||
local entity = event.entity
|
||||
if not entity.valid then return end
|
||||
if Scrap.is_scrap(entity) then landfill_under(entity) end
|
||||
end
|
||||
|
||||
--local function on_init(event)
|
||||
--
|
||||
--end
|
||||
|
||||
local function on_chunk_generated(event)
|
||||
--log("scrap_towny_ffa::on_chunk_generated")
|
||||
local surface = event.surface
|
||||
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
|
||||
for x = 0, 31, 1 do
|
||||
for y = 0, 31, 1 do
|
||||
if math_random(1, 3) > 1 then
|
||||
position = {x = left_top_x + x, y = left_top_y + y}
|
||||
if not surface.get_tile(position).collides_with("resource-layer") then
|
||||
noise = get_noise("scrap_towny_ffa", position, seed)
|
||||
if is_scrap_area(noise) then
|
||||
surface.set_tiles({{name = "dirt-" .. math_floor(math_abs(noise) * 6) % 6 + 2, position = position}}, true)
|
||||
place_scrap(surface, position)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
move_away_biteys(surface, event.area)
|
||||
--ffatable.chunk_generated[key] = true
|
||||
end
|
||||
|
||||
local function on_chunk_charted(event)
|
||||
local force = event.force
|
||||
local surface = game.surfaces[event.surface_index]
|
||||
if force.valid then
|
||||
if force == game.forces["player"] or force == game.forces["rogue"] then
|
||||
force.clear_chart(surface)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- local on_init = function ()
|
||||
-- local ffatable = Table.get_table()
|
||||
-- ffatable.chunk_generated = {}
|
||||
-- end
|
||||
|
||||
local Event = require 'utils.event'
|
||||
-- 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_player_mined_entity, on_player_mined_entity)
|
||||
Event.add(defines.events.on_entity_died, on_entity_died)
|
Loading…
x
Reference in New Issue
Block a user