mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2024-12-30 23:17:53 +02:00
1902 lines
49 KiB
Lua
1902 lines
49 KiB
Lua
-- map by Cogito
|
|
-- heavily modified by Gerkiz
|
|
|
|
local Global = require 'utils.global'
|
|
local Session = require 'utils.datastore.session_data'
|
|
local Event = require 'utils.event'
|
|
local Freeplay = require 'utils.freeplay'
|
|
local Server = require 'utils.server'
|
|
local MapFuntions = require 'tools.map_functions'
|
|
local CommonFunctions = require 'utils.common'
|
|
local LayersFunctions = require 'maps.planet_prison.mod.layers'
|
|
local AIFunctions = require 'maps.planet_prison.ai'
|
|
local Blueprints = require 'maps.planet_prison.mod.bp'
|
|
local AfkFunctions = require 'maps.planet_prison.mod.afk'
|
|
local Timers = require 'utils.timers'
|
|
local ClaimsFunctions = require 'maps.planet_prison.mod.claims'
|
|
local MapConfig = require 'maps.planet_prison.config'
|
|
local Token = require 'utils.token'
|
|
local Color = require 'utils.color_presets'
|
|
-- require 'modules.thirst'
|
|
|
|
local this = {
|
|
entities_cache = nil,
|
|
active_surface = nil,
|
|
last_friend = nil,
|
|
remove_offline_players = {
|
|
players = {},
|
|
time = 216000, -- 1h
|
|
enabled = true
|
|
}
|
|
}
|
|
local floor = math.floor
|
|
local ceil = math.ceil
|
|
local Public = {}
|
|
local insert = table.insert
|
|
local remove = table.remove
|
|
local random = math.random
|
|
|
|
Global.register(
|
|
this,
|
|
function(tbl)
|
|
this = tbl
|
|
end
|
|
)
|
|
|
|
this.maps = {
|
|
{
|
|
name = 'flooded-metropolia',
|
|
height = 2000,
|
|
width = 2000,
|
|
water = 1,
|
|
terrain_segmentation = 8,
|
|
property_expression_names = {
|
|
moisture = 0,
|
|
temperature = 30.
|
|
},
|
|
cliff_settings = {
|
|
richness = 0
|
|
},
|
|
starting_area = 'none',
|
|
autoplace_controls = {
|
|
['iron-ore'] = {
|
|
frequency = 0
|
|
},
|
|
['copper-ore'] = {
|
|
frequency = 0
|
|
},
|
|
['uranium-ore'] = {
|
|
frequency = 0
|
|
},
|
|
['stone'] = {
|
|
frequency = 0
|
|
},
|
|
['coal'] = {
|
|
frequency = 0
|
|
},
|
|
['crude-oil'] = {
|
|
frequency = 1000,
|
|
size = 1
|
|
},
|
|
['trees'] = {
|
|
frequency = 4
|
|
},
|
|
['enemy-base'] = {
|
|
frequency = 0
|
|
}
|
|
}
|
|
},
|
|
{
|
|
name = 'swampy-rivers',
|
|
height = 2500,
|
|
width = 2500,
|
|
water = 1,
|
|
terrain_segmentation = 6,
|
|
property_expression_names = {
|
|
moisture = 0,
|
|
temperature = 25.
|
|
},
|
|
cliff_settings = {
|
|
richness = 0
|
|
},
|
|
starting_area = 'none',
|
|
autoplace_controls = {
|
|
['iron-ore'] = {
|
|
frequency = 0
|
|
},
|
|
['copper-ore'] = {
|
|
frequency = 0
|
|
},
|
|
['uranium-ore'] = {
|
|
frequency = 0
|
|
},
|
|
['stone'] = {
|
|
frequency = 0
|
|
},
|
|
['coal'] = {
|
|
frequency = 0
|
|
},
|
|
['crude-oil'] = {
|
|
frequency = 900,
|
|
size = 1
|
|
},
|
|
['trees'] = {
|
|
frequency = 4
|
|
},
|
|
['enemy-base'] = {
|
|
frequency = 0
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
local function assign_perks(player)
|
|
this.perks[player.name] = {
|
|
flashlight_enable = true,
|
|
minimap = false,
|
|
chat_global = true
|
|
}
|
|
return this.perks[player.name]
|
|
end
|
|
|
|
local assign_camouflage = function(ent, common)
|
|
local shade = common.rand_range(20, 200)
|
|
ent.color = {
|
|
r = shade,
|
|
g = shade,
|
|
b = shade
|
|
}
|
|
ent.disable_flashlight()
|
|
end
|
|
|
|
local set_noise_hostile_hook =
|
|
Token.register(
|
|
function(data)
|
|
local ent = data
|
|
if not ent or not ent.valid then
|
|
return
|
|
end
|
|
ent.force = 'enemy'
|
|
if ent.name == 'character' then
|
|
assign_camouflage(ent, CommonFunctions)
|
|
|
|
if CommonFunctions.rand_range(1, 5) == 1 then
|
|
ent.insert({name = 'shotgun', count = 1})
|
|
ent.insert({name = 'shotgun-shell', count = 20})
|
|
else
|
|
ent.insert({name = 'pistol', count = 1})
|
|
ent.insert({name = 'firearm-magazine', count = 20})
|
|
end
|
|
else
|
|
ent.insert({name = 'firearm-magazine', count = 200})
|
|
end
|
|
end
|
|
)
|
|
|
|
local set_neutral_to_entity =
|
|
Token.register(
|
|
function(entity)
|
|
entity.force = 'neutral'
|
|
end
|
|
)
|
|
|
|
local fetch_common =
|
|
Token.register(
|
|
function()
|
|
return CommonFunctions
|
|
end
|
|
)
|
|
|
|
local industrial_zone_layers = {
|
|
{
|
|
type = 'LuaTile',
|
|
name = 'concrete',
|
|
objects = {
|
|
'concrete'
|
|
},
|
|
elevation = 0.3,
|
|
resolution = 0.2,
|
|
hook = nil,
|
|
deps = nil
|
|
},
|
|
{
|
|
type = 'LuaTile',
|
|
name = 'stones',
|
|
objects = {
|
|
'stone-path'
|
|
},
|
|
elevation = 0.2,
|
|
resolution = 0.4,
|
|
hook = nil,
|
|
deps = nil
|
|
},
|
|
{
|
|
type = 'LuaTile',
|
|
name = 'shallows',
|
|
objects = {
|
|
'water-shallow'
|
|
},
|
|
elevation = 0.7,
|
|
resolution = 0.01,
|
|
hook = nil,
|
|
deps = nil
|
|
},
|
|
{
|
|
type = 'LuaEntity',
|
|
name = 'scrap',
|
|
objects = {
|
|
'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'
|
|
},
|
|
elevation = 0.5,
|
|
resolution = 0.1,
|
|
hook = set_neutral_to_entity,
|
|
deps = nil
|
|
},
|
|
{
|
|
type = 'LuaEntity',
|
|
name = 'walls',
|
|
objects = {
|
|
'stone-wall'
|
|
},
|
|
elevation = 0.5,
|
|
resolution = 0.09,
|
|
hook = set_neutral_to_entity,
|
|
deps = nil
|
|
},
|
|
{
|
|
type = 'LuaEntity',
|
|
name = 'hostile',
|
|
objects = {
|
|
'character',
|
|
'gun-turret'
|
|
},
|
|
elevation = 0.92,
|
|
resolution = 0.99,
|
|
hook = set_noise_hostile_hook,
|
|
deps = fetch_common
|
|
},
|
|
{
|
|
type = 'LuaEntity',
|
|
name = 'structures',
|
|
objects = {
|
|
'big-electric-pole',
|
|
'medium-electric-pole'
|
|
},
|
|
elevation = 0.9,
|
|
resolution = 0.9,
|
|
hook = set_neutral_to_entity,
|
|
deps = nil
|
|
}
|
|
}
|
|
|
|
local industrial_zone_layers_modded = {
|
|
{
|
|
type = 'LuaTile',
|
|
name = 'concrete',
|
|
objects = {
|
|
'concrete'
|
|
},
|
|
elevation = 0.3,
|
|
resolution = 0.2,
|
|
hook = nil,
|
|
deps = nil
|
|
},
|
|
{
|
|
type = 'LuaTile',
|
|
name = 'stones',
|
|
objects = {
|
|
'stone-path'
|
|
},
|
|
elevation = 0.2,
|
|
resolution = 0.4,
|
|
hook = nil,
|
|
deps = nil
|
|
},
|
|
{
|
|
type = 'LuaTile',
|
|
name = 'shallows',
|
|
objects = {
|
|
'water-shallow'
|
|
},
|
|
elevation = 0.7,
|
|
resolution = 0.01,
|
|
hook = nil,
|
|
deps = nil
|
|
},
|
|
{
|
|
type = 'LuaEntity',
|
|
name = 'scrap',
|
|
objects = {
|
|
'mineable-wreckage'
|
|
},
|
|
elevation = 0.5,
|
|
resolution = 0.1,
|
|
hook = set_neutral_to_entity,
|
|
deps = nil
|
|
},
|
|
{
|
|
type = 'LuaEntity',
|
|
name = 'walls',
|
|
objects = {
|
|
'stone-wall'
|
|
},
|
|
elevation = 0.5,
|
|
resolution = 0.09,
|
|
hook = set_neutral_to_entity,
|
|
deps = nil
|
|
},
|
|
{
|
|
type = 'LuaEntity',
|
|
name = 'hostile',
|
|
objects = {
|
|
'character',
|
|
'gun-turret'
|
|
},
|
|
elevation = 0.92,
|
|
resolution = 0.99,
|
|
hook = set_noise_hostile_hook,
|
|
deps = fetch_common
|
|
},
|
|
{
|
|
type = 'LuaEntity',
|
|
name = 'structures',
|
|
objects = {
|
|
'big-electric-pole',
|
|
'medium-electric-pole'
|
|
},
|
|
elevation = 0.9,
|
|
resolution = 0.9,
|
|
hook = set_neutral_to_entity,
|
|
deps = nil
|
|
}
|
|
}
|
|
|
|
local swampy_rivers_layers = {
|
|
{
|
|
type = 'LuaTile',
|
|
name = 'speedy_tiles',
|
|
objects = {
|
|
'black-refined-concrete'
|
|
},
|
|
elevation = 0.3,
|
|
resolution = 0.2,
|
|
hook = nil,
|
|
deps = nil
|
|
},
|
|
{
|
|
type = 'LuaTile',
|
|
name = 'nuclear',
|
|
objects = {
|
|
'nuclear-ground'
|
|
},
|
|
elevation = 0.2,
|
|
resolution = 0.4,
|
|
hook = nil,
|
|
deps = nil
|
|
},
|
|
{
|
|
type = 'LuaTile',
|
|
name = 'shallows',
|
|
objects = {
|
|
'water-shallow'
|
|
},
|
|
elevation = 0.7,
|
|
resolution = 0.01,
|
|
hook = nil,
|
|
deps = nil
|
|
},
|
|
{
|
|
type = 'LuaEntity',
|
|
name = 'rocky',
|
|
objects = {
|
|
'sand-rock-big',
|
|
'rock-big',
|
|
'rock-huge'
|
|
},
|
|
elevation = 0.5,
|
|
resolution = 0.1,
|
|
hook = set_neutral_to_entity,
|
|
deps = nil
|
|
},
|
|
{
|
|
type = 'LuaEntity',
|
|
name = 'walls',
|
|
objects = {
|
|
'stone-wall'
|
|
},
|
|
elevation = 0.5,
|
|
resolution = 0.09,
|
|
hook = set_neutral_to_entity,
|
|
deps = nil
|
|
},
|
|
{
|
|
type = 'LuaEntity',
|
|
name = 'hostile',
|
|
objects = {
|
|
'character',
|
|
'gun-turret'
|
|
},
|
|
elevation = 0.92,
|
|
resolution = 0.99,
|
|
hook = set_noise_hostile_hook,
|
|
deps = fetch_common
|
|
},
|
|
{
|
|
type = 'LuaEntity',
|
|
name = 'structures',
|
|
objects = {
|
|
'big-electric-pole',
|
|
'medium-electric-pole'
|
|
},
|
|
elevation = 0.9,
|
|
resolution = 0.9,
|
|
hook = set_neutral_to_entity,
|
|
deps = nil
|
|
}
|
|
}
|
|
|
|
this.presets = {
|
|
['flooded-metropolia'] = industrial_zone_layers,
|
|
['swampy-rivers'] = swampy_rivers_layers
|
|
}
|
|
|
|
this.presets_modded = {
|
|
['flooded-metropolia'] = industrial_zone_layers_modded,
|
|
['swampy-rivers'] = swampy_rivers_layers
|
|
}
|
|
|
|
local function pick_map()
|
|
return this.maps[CommonFunctions.rand_range(1, #this.maps)]
|
|
end
|
|
|
|
local function find_force(name)
|
|
for _, f in pairs(game.forces) do
|
|
if f.name == name then
|
|
return f
|
|
end
|
|
end
|
|
|
|
return nil
|
|
end
|
|
|
|
local init_player_ship_bp =
|
|
Token.register(
|
|
function(data)
|
|
local player = data.player
|
|
local entity = data.entity
|
|
entity.force = player.force
|
|
if entity.name == 'crash-site-chest-1' then
|
|
for _, stack in pairs(MapConfig.player_ship_loot) do
|
|
entity.insert(stack)
|
|
end
|
|
end
|
|
end
|
|
)
|
|
|
|
this.events = {
|
|
merchant = {
|
|
alive = false,
|
|
moving = false,
|
|
spawn_tick = 0,
|
|
embark_tick = 0,
|
|
position = {x = 0, y = 0},
|
|
offer = MapConfig.merchant_offer
|
|
}
|
|
}
|
|
|
|
local init_merchant_bp =
|
|
Token.register(
|
|
function(data)
|
|
local entity = data.entity
|
|
entity.force = 'merchant'
|
|
entity.rotatable = false
|
|
entity.minable = false
|
|
if entity.name ~= 'market' then
|
|
entity.operable = false
|
|
else
|
|
for _, entry in pairs(this.events.merchant.offer) do
|
|
entity.add_market_item(entry)
|
|
end
|
|
end
|
|
end
|
|
)
|
|
|
|
local function create_orbit_group()
|
|
local orbit = game.permissions.create_group('orbit')
|
|
for _, perm in pairs(MapConfig.permission_orbit) do
|
|
orbit.set_allows_action(perm, false)
|
|
end
|
|
end
|
|
|
|
this.bp = {
|
|
player_ship = require('planet_prison.bp.player_ship'),
|
|
merchant = require('planet_prison.bp.merchant')
|
|
}
|
|
local function init_game()
|
|
Freeplay.set('disabled', true)
|
|
LayersFunctions.init()
|
|
ClaimsFunctions.init(MapConfig.claim_markers, MapConfig.claim_max_distance)
|
|
|
|
local map = pick_map()
|
|
local preset
|
|
if is_game_modded() then
|
|
preset = this.presets_modded[map.name]
|
|
else
|
|
preset = this.presets[map.name]
|
|
end
|
|
local surface = game.create_surface('arena', map)
|
|
surface.brightness_visual_weights = {
|
|
1 / 0.85,
|
|
1 / 0.85,
|
|
1 / 0.85
|
|
}
|
|
surface.ticks_per_day = 25000 * 4
|
|
this.active_surface = surface.index
|
|
this.perks = {}
|
|
this.events.merchant.spawn_tick = game.tick + 5000
|
|
this.events.raid_groups = {}
|
|
this.events.raid_init = false
|
|
this.events.annihilation = false
|
|
this.events.reset_time = nil
|
|
|
|
create_orbit_group()
|
|
game.map_settings.pollution.enabled = false
|
|
game.map_settings.enemy_evolution.enabled = false
|
|
game.difficulty_settings.technology_price_multiplier = 0.3
|
|
game.difficulty_settings.research_queue_setting = 'always'
|
|
|
|
LayersFunctions.set_collision_mask({'water-tile'})
|
|
|
|
for _, layer in pairs(preset) do
|
|
LayersFunctions.add_noise_layer(layer.type, layer.name, layer.objects, layer.elevation, layer.resolution)
|
|
if layer.hook ~= nil then
|
|
if layer.hook and type(layer.hook) == 'number' then
|
|
LayersFunctions.add_noise_layer_hook(layer.name, layer.hook)
|
|
else
|
|
local token = Token.register(layer.hook)
|
|
LayersFunctions.add_noise_layer_hook(layer.name, token)
|
|
end
|
|
end
|
|
|
|
if layer.deps ~= nil then
|
|
if layer.deps and type(layer.deps) == 'number' then
|
|
LayersFunctions.add_noise_layer_dependency(layer.name, layer.deps)
|
|
else
|
|
local token = Token.register(layer.deps)
|
|
LayersFunctions.add_noise_layer_dependency(layer.name, token)
|
|
end
|
|
end
|
|
end
|
|
|
|
Blueprints.push_blueprint('player_ship', this.bp.player_ship)
|
|
Blueprints.set_blueprint_hook('player_ship', init_player_ship_bp)
|
|
Blueprints.push_blueprint('merchant', this.bp.merchant)
|
|
Blueprints.set_blueprint_hook('merchant', init_merchant_bp)
|
|
end
|
|
|
|
local explode_ship_update =
|
|
Token.register(
|
|
function(data)
|
|
local id = data.id
|
|
local time_left = data.time_left
|
|
local ship = data.ship
|
|
local time = CommonFunctions.get_time(time_left)
|
|
for _, ent in pairs(ship.entities) do
|
|
if not ent.valid then
|
|
return false
|
|
end
|
|
end
|
|
|
|
rendering.set_text(id, time)
|
|
return true
|
|
end
|
|
)
|
|
|
|
local explode_ship =
|
|
Token.register(
|
|
function(data)
|
|
local ship = data.ship
|
|
local id = data.id
|
|
local active_surface = data.active_surface
|
|
local surface = game.get_surface(active_surface)
|
|
if not surface or not surface.valid then
|
|
return
|
|
end
|
|
|
|
for _, ent in pairs(Blueprints.reference_get_entities(ship)) do
|
|
if not ent.valid then
|
|
goto continue
|
|
end
|
|
|
|
local explosion = {
|
|
name = 'massive-explosion',
|
|
position = ent.position
|
|
}
|
|
surface.create_entity(explosion)
|
|
|
|
::continue::
|
|
end
|
|
|
|
local bb = Blueprints.reference_get_bounding_box(ship)
|
|
LayersFunctions.remove_excluding_bounding_box(bb)
|
|
Blueprints.destroy_reference(surface, ship)
|
|
rendering.destroy(id)
|
|
end
|
|
)
|
|
|
|
local function do_spawn_point(player)
|
|
local point = {
|
|
x = CommonFunctions.get_axis(player.position, 'x'),
|
|
y = CommonFunctions.get_axis(player.position, 'y') - 2
|
|
}
|
|
local instance = Blueprints.build(player.surface, 'player_ship', point, player)
|
|
LayersFunctions.push_excluding_bounding_box(instance.bb)
|
|
local time_left = MapConfig.self_explode
|
|
|
|
local object = {
|
|
text = CommonFunctions.get_time(time_left),
|
|
surface = player.surface,
|
|
color = {
|
|
r = 255,
|
|
g = 20,
|
|
b = 20
|
|
},
|
|
target = {
|
|
x = point.x - 2,
|
|
y = point.y - 3
|
|
},
|
|
scale = 2.0
|
|
}
|
|
|
|
local id = rendering.draw_text(object)
|
|
local data = {id = id, time_left = time_left, ship = instance, active_surface = player.surface.index}
|
|
|
|
local timer = Timers.set_timer(time_left, explode_ship)
|
|
Timers.set_timer_on_update(timer, explode_ship_update)
|
|
Timers.set_timer_dependency(timer, data)
|
|
Timers.set_timer_start(timer)
|
|
end
|
|
|
|
local function get_non_obstructed_position(s, radius)
|
|
local chunk
|
|
|
|
for i = 1, 32 do
|
|
chunk = s.get_random_chunk()
|
|
chunk.x = chunk.x * 32
|
|
chunk.y = chunk.y * 32
|
|
|
|
local search_info = {
|
|
position = chunk,
|
|
radius = radius
|
|
}
|
|
|
|
local tiles = s.find_tiles_filtered(search_info)
|
|
for _, tile in pairs(tiles) do
|
|
if string.find(tile.name, 'water') ~= nil or string.find(tile.name, 'out') ~= nil then
|
|
goto continue
|
|
end
|
|
end
|
|
|
|
search_info = {
|
|
position = chunk,
|
|
radius = radius,
|
|
force = {'neutral', 'enemy'},
|
|
invert = true
|
|
}
|
|
local ents = s.find_entities_filtered(search_info)
|
|
if not ents or #ents == 0 then
|
|
break
|
|
end
|
|
|
|
::continue::
|
|
end
|
|
|
|
return chunk
|
|
end
|
|
|
|
local function draw_normal_gui(player)
|
|
local button
|
|
local merchant = this.events.merchant
|
|
if merchant.alive then
|
|
button = {
|
|
type = 'button',
|
|
name = 'merchant_find',
|
|
caption = 'Merchant'
|
|
}
|
|
player.gui.left.add(button)
|
|
end
|
|
|
|
button = {
|
|
type = 'button',
|
|
name = 'flashlight_toggle',
|
|
caption = 'Toggle flashlight'
|
|
}
|
|
player.gui.left.add(button)
|
|
end
|
|
|
|
local function draw_common_gui(player)
|
|
local perks = this.perks[player.name]
|
|
if not perks then
|
|
perks = assign_perks(player)
|
|
end
|
|
local chat_type = 'Global chat'
|
|
if not perks.chat_global then
|
|
chat_type = 'NAP chat'
|
|
end
|
|
|
|
local button = {
|
|
type = 'button',
|
|
name = 'manual_toggle',
|
|
caption = 'Manual'
|
|
}
|
|
player.gui.left.add(button)
|
|
|
|
button = {
|
|
type = 'button',
|
|
name = 'chat_toggle',
|
|
caption = chat_type
|
|
}
|
|
player.gui.left.add(button)
|
|
end
|
|
|
|
local function draw_orbit_gui(player)
|
|
local button = {
|
|
type = 'button',
|
|
name = 'annihilate',
|
|
caption = 'Annihilate'
|
|
}
|
|
player.gui.left.add(button)
|
|
end
|
|
|
|
local function redraw_gui(player)
|
|
player.gui.left.clear()
|
|
draw_common_gui(player)
|
|
if player.spectator == true then
|
|
draw_orbit_gui(player)
|
|
else
|
|
draw_normal_gui(player)
|
|
end
|
|
end
|
|
|
|
local function print_merchant_position(player)
|
|
local position = this.events.merchant.position
|
|
local perks = this.perks[player.name]
|
|
if not perks then
|
|
perks = assign_perks(player)
|
|
end
|
|
if perks and perks.minimap then
|
|
player.print(string.format('>> You received a broadcast with [gps=%d,%d,%s] coordinates', position.x, position.y, player.surface.name))
|
|
else
|
|
player.print(string.format('>> You were able to spot him %s from your location', CommonFunctions.get_readable_direction(player.position, position)))
|
|
end
|
|
end
|
|
|
|
local function on_tick_reset()
|
|
if this.events.reset_time == nil then
|
|
return
|
|
end
|
|
|
|
if this.events.reset_time > game.tick then
|
|
return
|
|
end
|
|
|
|
Server.start_scenario('planet_prison')
|
|
this.events.reset_time = nil
|
|
end
|
|
|
|
local function annihilate(caller)
|
|
this.events.annihilation = true
|
|
for _, player in pairs(game.connected_players) do
|
|
if player.name == caller.name then
|
|
goto continue
|
|
end
|
|
|
|
local coeff
|
|
for i = 1, 5 do
|
|
if i % 2 == 0 then
|
|
coeff = -1
|
|
else
|
|
coeff = 1
|
|
end
|
|
|
|
local query = {
|
|
name = 'atomic-rocket',
|
|
position = {
|
|
player.position.x - 100,
|
|
player.position.y - 100
|
|
},
|
|
target = {
|
|
player.position.x + (8 * i * coeff),
|
|
player.position.y + (8 * i * coeff)
|
|
},
|
|
speed = 0.1
|
|
}
|
|
|
|
player.surface.create_entity(query)
|
|
player.print('>> Annihilation in progress...')
|
|
end
|
|
::continue::
|
|
end
|
|
|
|
this.events.reset_time = game.tick + (60 * 15)
|
|
end
|
|
|
|
local function on_gui_click(e)
|
|
local elem = e.element
|
|
local p = game.players[e.player_index]
|
|
local perks = this.perks[p.name]
|
|
if not perks then
|
|
perks = assign_perks(p)
|
|
end
|
|
|
|
if not elem.valid then
|
|
return
|
|
end
|
|
|
|
if elem.name == 'chat_toggle' then
|
|
if perks.chat_global then
|
|
elem.caption = 'NAP chat'
|
|
perks.chat_global = false
|
|
p.print('Global chat is disabled.', Color.success)
|
|
else
|
|
elem.caption = 'Global chat'
|
|
perks.chat_global = true
|
|
p.print('Global chat is enabled.', Color.success)
|
|
end
|
|
elseif elem.name == 'flashlight_toggle' then
|
|
if perks.flashlight_enable then
|
|
perks.flashlight_enable = false
|
|
if p.character and p.character.valid then
|
|
p.character.disable_flashlight()
|
|
p.print('Flashlight is disabled.', Color.success)
|
|
end
|
|
else
|
|
perks.flashlight_enable = true
|
|
if p.character and p.character.valid then
|
|
p.character.enable_flashlight()
|
|
p.print('Flashlight is enabled.', Color.success)
|
|
end
|
|
end
|
|
elseif elem.name == 'merchant_find' then
|
|
print_merchant_position(p)
|
|
elseif elem.name == 'manual_toggle' then
|
|
local children = p.gui.center.children
|
|
if #children >= 1 then
|
|
p.gui.center.clear()
|
|
return
|
|
end
|
|
|
|
local text_box = {
|
|
type = 'text-box',
|
|
text = MapConfig.manual,
|
|
name = 'manual_toggle_frame'
|
|
}
|
|
text_box = p.gui.center.add(text_box)
|
|
text_box.style.minimal_width = 512
|
|
text_box.read_only = true
|
|
text_box.word_wrap = true
|
|
elseif elem.name == 'manual_toggle_frame' then
|
|
local children = p.gui.center.children
|
|
if #children >= 1 then
|
|
p.gui.center.clear()
|
|
return
|
|
end
|
|
elseif elem.name == 'annihilate' then
|
|
if this.events.annihilation == true then
|
|
return
|
|
end
|
|
|
|
elem.destroy()
|
|
annihilate(p)
|
|
end
|
|
end
|
|
|
|
local function init_player(p)
|
|
p.teleport({0, 0}, 'arena')
|
|
local s = p.surface
|
|
local position = get_non_obstructed_position(s, 10)
|
|
|
|
this.perks[p.name] = nil
|
|
p.teleport(position, 'arena')
|
|
--p.name = get_random_name() --player name is read only
|
|
local pf = game.forces[p.name]
|
|
if not pf then
|
|
p.force = game.create_force(p.name)
|
|
else
|
|
p.force = pf
|
|
end
|
|
p.force.set_friend('neutral', true)
|
|
p.force.set_friend('player', false)
|
|
p.force.share_chart = false
|
|
this.perks[p.name] = {
|
|
flashlight_enable = true,
|
|
minimap = false,
|
|
chat_global = true,
|
|
init = true
|
|
}
|
|
|
|
for i = 1, 7 do
|
|
p.force.technologies['inserter-capacity-bonus-' .. i].enabled = false
|
|
p.force.technologies['inserter-capacity-bonus-' .. i].researched = false
|
|
end
|
|
|
|
if not p.character or not p.character.valid then
|
|
p.set_controller({type = defines.controllers.god})
|
|
p.create_character()
|
|
end
|
|
|
|
local merch = find_force('merchant')
|
|
if merch then
|
|
p.force.set_friend(merch, true)
|
|
merch.set_friend(p.force, true)
|
|
end
|
|
|
|
p.force.research_queue_enabled = true
|
|
for _, tech in pairs(p.force.technologies) do
|
|
for name, status in pairs(MapConfig.technologies) do
|
|
if tech.name == name then
|
|
tech.researched = status
|
|
tech.enabled = status
|
|
end
|
|
end
|
|
end
|
|
|
|
p.minimap_enabled = false
|
|
redraw_gui(p)
|
|
do_spawn_point(p)
|
|
end
|
|
|
|
local function player_reconnected(connected)
|
|
local offline_players = this.remove_offline_players
|
|
if not offline_players then
|
|
return
|
|
end
|
|
if not offline_players.enabled then
|
|
return
|
|
end
|
|
if #offline_players.players > 0 then
|
|
for i = 1, #offline_players.players do
|
|
if offline_players.players[i] then
|
|
local player = game.get_player(offline_players.players[i].index)
|
|
if player and player.valid and player.index == connected.index then
|
|
offline_players.players[i] = nil
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function on_player_joined_game(e)
|
|
local p = game.players[e.player_index]
|
|
player_reconnected(p)
|
|
redraw_gui(p)
|
|
|
|
if this.perks and this.perks[p.name] and this.perks[p.name].init then
|
|
return
|
|
end
|
|
init_player(p)
|
|
end
|
|
|
|
local function _build_merchant_bp(surf, position)
|
|
local instance = Blueprints.build(surf, 'merchant', position, nil)
|
|
LayersFunctions.push_excluding_bounding_box(instance.bb)
|
|
end
|
|
|
|
local function _remove_merchant_bp(surf)
|
|
local refs = Blueprints.get_references('merchant')
|
|
local bb = Blueprints.reference_get_bounding_box(refs[1])
|
|
LayersFunctions.remove_excluding_bounding_box(bb)
|
|
Blueprints.destroy_references(surf, 'merchant')
|
|
this.events.merchant.position = {
|
|
x = 0,
|
|
y = 0
|
|
}
|
|
end
|
|
|
|
local function spawn_merchant(s)
|
|
local merchant = this.events.merchant
|
|
local position = get_non_obstructed_position(s, 10)
|
|
local merch
|
|
if not merchant.moving then
|
|
merch = game.create_force('merchant')
|
|
else
|
|
merch = find_force('merchant')
|
|
end
|
|
|
|
merchant.position = position
|
|
merchant.alive = true
|
|
merchant.moving = false
|
|
merchant.embark_tick = game.tick + 90000
|
|
_build_merchant_bp(s, position)
|
|
|
|
s.print('>> Merchant appeared in the area')
|
|
for _, p in pairs(game.players) do
|
|
p.force.set_friend(merch, true)
|
|
merch.set_friend(p.force, true)
|
|
print_merchant_position(p)
|
|
redraw_gui(p)
|
|
end
|
|
end
|
|
|
|
local function embark_merchant(s)
|
|
this.events.merchant.alive = false
|
|
this.events.merchant.moving = true
|
|
this.events.merchant.spawn_tick = game.tick + 10000
|
|
|
|
s.print('>> Merchant is moving to new location')
|
|
_remove_merchant_bp(s)
|
|
for _, player in pairs(game.players) do
|
|
redraw_gui(player)
|
|
end
|
|
end
|
|
|
|
local function merchant_event(s)
|
|
local e = this.events
|
|
local m = e.merchant
|
|
if not m.alive and m.spawn_tick <= game.tick then
|
|
spawn_merchant(s)
|
|
end
|
|
|
|
if m.alive and not m.moving and m.embark_tick <= game.tick then
|
|
embark_merchant(s)
|
|
end
|
|
end
|
|
|
|
local function _get_outer_points(surf, x, y, deps)
|
|
local inner = deps.inner
|
|
local points = deps.points
|
|
|
|
local point = {
|
|
x = x,
|
|
y = y
|
|
}
|
|
|
|
if CommonFunctions.point_in_bounding_box(point, inner) then
|
|
return
|
|
end
|
|
|
|
local tile = surf.get_tile(point)
|
|
if string.find(tile.name, 'water') ~= nil or string.find(tile.name, 'out') ~= nil then
|
|
return
|
|
end
|
|
|
|
insert(points, point)
|
|
end
|
|
|
|
local function _calculate_attack_costs(surf, bb)
|
|
local query = {
|
|
area = bb,
|
|
force = {
|
|
'enemy',
|
|
'neutral',
|
|
'player'
|
|
},
|
|
invert = true
|
|
}
|
|
local objects = surf.find_entities_filtered(query)
|
|
if next(objects) == nil then
|
|
return 0
|
|
end
|
|
|
|
local cost = 0
|
|
local costs = MapConfig.base_costs
|
|
for _, obj in pairs(objects) do
|
|
for name, coeff in pairs(costs) do
|
|
if obj.name == name then
|
|
cost = cost + coeff
|
|
end
|
|
end
|
|
end
|
|
|
|
return cost
|
|
end
|
|
|
|
local function _get_raid_info(surf, bb)
|
|
local pick = nil
|
|
local cost = _calculate_attack_costs(surf, bb)
|
|
for _, entry in pairs(MapConfig.raid_costs) do
|
|
if entry.cost <= cost then
|
|
pick = entry
|
|
else
|
|
break
|
|
end
|
|
end
|
|
|
|
return pick
|
|
end
|
|
|
|
local function _create_npc_group(claim, surf)
|
|
local inner = CommonFunctions.create_bounding_box_by_points(claim)
|
|
local info = _get_raid_info(surf, inner)
|
|
if info == nil then
|
|
return {}
|
|
end
|
|
|
|
local outer = CommonFunctions.deepcopy(inner)
|
|
CommonFunctions.enlarge_bounding_box(outer, 10)
|
|
|
|
local points = {}
|
|
local deps = {
|
|
points = points,
|
|
inner = inner
|
|
}
|
|
CommonFunctions.for_bounding_box_extra(surf, outer, _get_outer_points, deps)
|
|
|
|
local agents = {}
|
|
for i, point in ipairs(points) do
|
|
if CommonFunctions.rand_range(1, info.chance) ~= 1 then
|
|
goto continue
|
|
end
|
|
|
|
local query = {
|
|
name = 'character',
|
|
position = point
|
|
}
|
|
|
|
local agent = surf.create_entity(query)
|
|
local stash = {}
|
|
for attr, value in pairs(info.gear[(i % #info.gear) + 1]) do
|
|
local prop = {
|
|
name = value
|
|
}
|
|
|
|
if attr == 'ammo' then
|
|
prop.count = 20
|
|
elseif attr == 'weap' then
|
|
prop.count = 1
|
|
elseif attr == 'armor' then
|
|
prop.count = 1
|
|
end
|
|
|
|
insert(stash, prop)
|
|
end
|
|
|
|
for _, stack in pairs(stash) do
|
|
agent.insert(stack)
|
|
end
|
|
|
|
assign_camouflage(agent, CommonFunctions)
|
|
|
|
insert(agents, agent)
|
|
::continue::
|
|
end
|
|
|
|
return agents
|
|
end
|
|
|
|
local function populate_raid_event(surf)
|
|
local claims, group
|
|
local status = false
|
|
local groups = this.events.raid_groups
|
|
|
|
for _, p in pairs(game.connected_players) do
|
|
groups[p.name] = {}
|
|
claims = ClaimsFunctions.get_claims(p.name)
|
|
for _, claim in pairs(claims) do
|
|
if #claim == 0 then
|
|
goto continue
|
|
end
|
|
|
|
status = true
|
|
group = {
|
|
agents = _create_npc_group(claim, surf),
|
|
objects = claim
|
|
}
|
|
insert(groups[p.name], group)
|
|
|
|
::continue::
|
|
end
|
|
end
|
|
|
|
return status
|
|
end
|
|
|
|
local function on_pre_player_left_game(event)
|
|
local offline_players = this.remove_offline_players
|
|
if not offline_players then
|
|
return
|
|
end
|
|
if not offline_players.enabled then
|
|
return
|
|
end
|
|
local player = game.players[event.player_index]
|
|
local ticker = game.tick
|
|
if player.character then
|
|
offline_players.players[#offline_players.players + 1] = {
|
|
index = event.player_index,
|
|
name = player.name,
|
|
tick = ticker
|
|
}
|
|
end
|
|
end
|
|
|
|
local function remove_offline_players()
|
|
local offline_players = this.remove_offline_players
|
|
if not offline_players then
|
|
return
|
|
end
|
|
if not offline_players.enabled then
|
|
return
|
|
end
|
|
if #offline_players.players > 0 then
|
|
for i = 1, #offline_players.players, 1 do
|
|
if offline_players.players[i] then
|
|
local player = game.get_player(offline_players.players[i].index)
|
|
if player and player.valid then
|
|
if player.connected then
|
|
offline_players.players[i] = nil
|
|
else
|
|
if offline_players.players[i].tick < game.tick - offline_players.time then
|
|
if this.perks and this.perks[player.name] then
|
|
this.perks[player.name] = nil
|
|
end
|
|
ClaimsFunctions.on_player_died(player)
|
|
ClaimsFunctions.clear_player_base(player)
|
|
|
|
if game.forces[player.name] then
|
|
game.merge_forces(player.name, 'neutral')
|
|
end
|
|
Session.clear_player(player)
|
|
game.remove_offline_players({player})
|
|
offline_players.players[i] = nil
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function raid_event(surf)
|
|
local raid_groups = this.events.raid_groups
|
|
if this.events.raid_init then
|
|
if surf.daytime > 0.01 and surf.daytime <= 0.1 then
|
|
for name, groups in pairs(raid_groups) do
|
|
for i = #groups, 1, -1 do
|
|
local group = groups[i]
|
|
local agents = group.agents
|
|
for j = #agents, 1, -1 do
|
|
local agent = agents[j]
|
|
if agent.valid then
|
|
agent.destroy()
|
|
end
|
|
|
|
remove(agents, j)
|
|
end
|
|
|
|
if #agents == 0 then
|
|
remove(group, i)
|
|
end
|
|
end
|
|
|
|
if #groups == 0 then
|
|
raid_groups[name] = nil
|
|
end
|
|
end
|
|
|
|
this.events.raid_init = false
|
|
end
|
|
else
|
|
if surf.daytime < 0.4 or surf.daytime > 0.6 then
|
|
return
|
|
end
|
|
|
|
if populate_raid_event(surf) then
|
|
this.events.raid_init = true
|
|
end
|
|
end
|
|
|
|
if game.tick % 4 ~= 0 then
|
|
return
|
|
end
|
|
|
|
for name, groups in pairs(raid_groups) do
|
|
local exists = false
|
|
for _, p in pairs(game.connected_players) do
|
|
if p.name == name then
|
|
exists = true
|
|
break
|
|
end
|
|
end
|
|
|
|
if not exists then
|
|
raid_groups[name] = nil
|
|
goto continue
|
|
end
|
|
|
|
for _, group in pairs(groups) do
|
|
AIFunctions.do_job(surf, AIFunctions.command.attack_objects, group)
|
|
end
|
|
|
|
::continue::
|
|
end
|
|
end
|
|
|
|
local function cause_event(s)
|
|
merchant_event(s)
|
|
raid_event(s)
|
|
end
|
|
|
|
local function on_tick()
|
|
local s = this.active_surface
|
|
if not s then
|
|
log('on_tick: surface empty!')
|
|
return
|
|
end
|
|
|
|
local tick = game.tick
|
|
|
|
local surf = game.get_surface(this.active_surface)
|
|
if not surf or not surf.valid then
|
|
return
|
|
end
|
|
|
|
if tick % 4 == 0 then
|
|
AIFunctions.do_job(surf, AIFunctions.command.seek_and_destroy_player)
|
|
end
|
|
|
|
LayersFunctions.do_job(surf)
|
|
cause_event(surf)
|
|
|
|
if (tick + 1) % 60 == 0 then
|
|
Timers.do_job()
|
|
end
|
|
if (tick + 1) % 100 == 0 then
|
|
AfkFunctions.on_inactive_players(15)
|
|
end
|
|
if (tick + 1) % 500 == 0 then
|
|
remove_offline_players()
|
|
end
|
|
end
|
|
|
|
local function make_ore_patch(e)
|
|
if CommonFunctions.rand_range(1, 30) ~= 1 then
|
|
return
|
|
end
|
|
|
|
local surf = e.surface
|
|
local point = e.area.left_top
|
|
MapFuntions.draw_entity_circle(point, 'stone', surf, 6, true, 1000000)
|
|
MapFuntions.draw_entity_circle(point, 'coal', surf, 12, true, 1000000)
|
|
MapFuntions.draw_entity_circle(point, 'copper-ore', surf, 18, true, 1000000)
|
|
MapFuntions.draw_entity_circle(point, 'iron-ore', surf, 24, true, 1000000)
|
|
MapFuntions.draw_noise_tile_circle(point, 'water', surf, 4)
|
|
end
|
|
|
|
local function on_chunk_generated(e)
|
|
if e.surface.name ~= 'arena' then
|
|
return
|
|
end
|
|
|
|
make_ore_patch(e)
|
|
LayersFunctions.push_chunk(e.position)
|
|
end
|
|
|
|
local valid_ents = {
|
|
['crash-site-spaceship-wreck-small-1'] = true,
|
|
['crash-site-spaceship-wreck-small-2'] = true,
|
|
['crash-site-spaceship-wreck-small-3'] = true,
|
|
['crash-site-spaceship-wreck-small-4'] = true,
|
|
['crash-site-spaceship-wreck-small-5'] = true,
|
|
['crash-site-spaceship-wreck-small-6'] = true,
|
|
['mineable-wreckage'] = true,
|
|
['sand-rock-big'] = true,
|
|
['rock-big'] = true,
|
|
['rock-huge'] = true
|
|
}
|
|
|
|
local function mined_wreckage(e)
|
|
local ent = e.entity
|
|
if not ent.valid then
|
|
return
|
|
end
|
|
if not valid_ents[ent.name] then
|
|
return
|
|
end
|
|
|
|
e.buffer.clear()
|
|
|
|
local candidates = {}
|
|
|
|
local chance = CommonFunctions.rand_range(0, 1000)
|
|
for name, attrs in pairs(MapConfig.wreck_loot) do
|
|
local prob = attrs.rare * 100
|
|
if prob < chance then
|
|
local cand = {
|
|
name = name,
|
|
count = CommonFunctions.rand_range(attrs.count[1], attrs.count[2])
|
|
}
|
|
insert(candidates, cand)
|
|
end
|
|
end
|
|
|
|
local count = #candidates
|
|
if count == 0 then
|
|
return
|
|
end
|
|
|
|
local cand = candidates[CommonFunctions.rand_range(1, count)]
|
|
if e.buffer and cand then
|
|
e.buffer.insert(cand)
|
|
end
|
|
end
|
|
|
|
local function on_player_mined_entity(e)
|
|
local ent = e.entity
|
|
if not ent.valid then
|
|
return
|
|
end
|
|
|
|
mined_wreckage(e)
|
|
-- ClaimsFunctions.on_player_mined_entity(ent)
|
|
end
|
|
|
|
local function on_player_died(e)
|
|
local index = e.player_index
|
|
if not index then
|
|
return -- banned/kicked somewhere else
|
|
end
|
|
|
|
local p = game.players[index]
|
|
ClaimsFunctions.on_player_died(p)
|
|
ClaimsFunctions.clear_player_base(p)
|
|
|
|
if game.forces[p.name] then
|
|
game.merge_forces(p.name, 'neutral')
|
|
end
|
|
p.force = 'player'
|
|
if p.connected then
|
|
return
|
|
end
|
|
Session.clear_player(p)
|
|
game.remove_offline_players({p})
|
|
end
|
|
|
|
local function on_player_respawned(e)
|
|
local p = game.players[e.player_index]
|
|
init_player(p)
|
|
end
|
|
|
|
local function on_player_dropped_item(e)
|
|
if not this.last_friend then
|
|
this.last_friend = {}
|
|
end
|
|
|
|
local p = game.players[e.player_index]
|
|
local ent = e.entity
|
|
if ent.stack.name == 'raw-fish' then
|
|
local ent_list =
|
|
p.surface.find_entities_filtered(
|
|
{
|
|
name = 'character',
|
|
position = ent.position,
|
|
radius = 2
|
|
}
|
|
)
|
|
if not ent_list then
|
|
return
|
|
end
|
|
|
|
local peer = nil
|
|
for _, char in pairs(ent_list) do
|
|
if char.player and char.player.name ~= p.name then
|
|
peer = char.player
|
|
break
|
|
end
|
|
end
|
|
|
|
if peer == nil then
|
|
return
|
|
end
|
|
|
|
if p.force.get_cease_fire(peer.name) then
|
|
p.print(string.format("You're in the NAP with %s already", peer.name))
|
|
return
|
|
end
|
|
|
|
if this.last_friend[peer.name] == p.name then
|
|
p.force.set_cease_fire(peer.name, true)
|
|
p.force.set_friend(peer.name, true)
|
|
peer.force.set_cease_fire(p.name, true)
|
|
peer.force.set_friend(p.name, true)
|
|
p.print(string.format('The NAP was formed with %s', peer.name))
|
|
peer.print(string.format('The NAP was formed with %s', p.name))
|
|
this.last_friend[p.name] = ''
|
|
this.last_friend[peer.name] = ''
|
|
return
|
|
end
|
|
|
|
this.last_friend[p.name] = peer.name
|
|
p.print(string.format('You want to form the NAP with %s', peer.name))
|
|
peer.print(string.format('The %s wants to form NAP with you', p.name))
|
|
elseif ent.stack.name == 'coal' then
|
|
local ent_list =
|
|
p.surface.find_entities_filtered(
|
|
{
|
|
name = 'character',
|
|
position = ent.position,
|
|
radius = 2
|
|
}
|
|
)
|
|
if not ent_list then
|
|
return
|
|
end
|
|
|
|
local peer = nil
|
|
for _, char in pairs(ent_list) do
|
|
if char.player and char.player.name ~= p.name then
|
|
peer = char.player
|
|
break
|
|
end
|
|
end
|
|
|
|
if peer == nil then
|
|
return
|
|
end
|
|
|
|
if not p.force.get_cease_fire(peer.name) then
|
|
p.print(string.format("You don't have the NAP with %s", p.name))
|
|
return
|
|
end
|
|
|
|
p.force.set_cease_fire(peer.name, false)
|
|
p.force.set_friend(peer.name, false)
|
|
peer.force.set_cease_fire(p.name, false)
|
|
peer.force.set_friend(p.name, false)
|
|
|
|
this.last_friend[p.name] = ''
|
|
this.last_friend[peer.name] = ''
|
|
p.print(string.format("You're no longer in the NAP with %s", peer.name))
|
|
peer.print(string.format("You're no longer in the NAP with %s", p.name))
|
|
end
|
|
end
|
|
|
|
local function on_chunk_charted(e)
|
|
local f_perks = this.perks[e.force.name]
|
|
game.forces.neutral.clear_chart()
|
|
|
|
if not f_perks then
|
|
return
|
|
end
|
|
|
|
if not f_perks.minimap then
|
|
e.force.clear_chart()
|
|
end
|
|
end
|
|
|
|
local function on_entity_damaged(e)
|
|
local ent = e.entity
|
|
|
|
if ent.force.name == 'merchant' then
|
|
if not ent.force.get_friend(e.force) then
|
|
return
|
|
end
|
|
|
|
ent.force.set_friend(e.force, false)
|
|
e.force.set_friend(ent.force, false)
|
|
end
|
|
|
|
if ent.name == 'character' then
|
|
local hp = 1.0 - ent.get_health_ratio()
|
|
local particles = 45 * hp
|
|
local coeff = CommonFunctions.rand_range(-20, 20) / 100.0
|
|
for i = 1, particles do
|
|
local blood = {
|
|
name = 'blood-particle',
|
|
position = {
|
|
x = ent.position.x,
|
|
y = ent.position.y
|
|
},
|
|
movement = {
|
|
(CommonFunctions.rand_range(-20, 20) / 100.0) + coeff,
|
|
(CommonFunctions.rand_range(-20, 20) / 100.0) + coeff
|
|
},
|
|
frame_speed = 0.01,
|
|
vertical_speed = 0.02,
|
|
height = 0.01
|
|
}
|
|
ent.surface.create_particle(blood)
|
|
end
|
|
end
|
|
end
|
|
|
|
local function merchant_death(e)
|
|
local ent = e.entity
|
|
if ent.force.name ~= 'merchant' then
|
|
return false
|
|
end
|
|
|
|
if ent.name ~= 'character' and ent.name ~= 'market' then
|
|
return false
|
|
end
|
|
|
|
local s = ent.surface
|
|
local explosion = {
|
|
name = 'massive-explosion',
|
|
position = ent.position
|
|
}
|
|
s.create_entity(explosion)
|
|
_remove_merchant_bp(s)
|
|
|
|
this.events.merchant.alive = false
|
|
this.events.merchant.moving = false
|
|
this.events.merchant.spawn_tick = game.tick + 1000
|
|
game.merge_forces('merchant', 'neutral')
|
|
|
|
s.print('>> Merchant died')
|
|
for _, player in pairs(game.players) do
|
|
redraw_gui(player)
|
|
end
|
|
|
|
return true
|
|
end
|
|
|
|
local coin_drops = {
|
|
['character'] = true,
|
|
['gun-turret'] = true
|
|
}
|
|
|
|
local function hostile_death(e)
|
|
local ent = e.entity
|
|
local loot = e.loot
|
|
if not coin_drops[ent.name] then
|
|
return false
|
|
end
|
|
|
|
loot.insert({name = 'coin', count = random(30, 70)})
|
|
|
|
return true
|
|
end
|
|
|
|
local function character_death(e)
|
|
local ent = e.entity
|
|
if ent.name ~= 'character' then
|
|
return false
|
|
end
|
|
|
|
local explosion = {
|
|
name = 'blood-explosion-big',
|
|
position = ent.position
|
|
}
|
|
ent.surface.create_entity(explosion)
|
|
end
|
|
|
|
local function on_entity_died(e)
|
|
if not e.entity.valid then
|
|
return
|
|
end
|
|
|
|
if merchant_death(e) then
|
|
return
|
|
end
|
|
|
|
hostile_death(e)
|
|
character_death(e)
|
|
-- ClaimsFunctions.on_entity_died(e.entity)
|
|
|
|
if valid_ents[e.entity.name] then
|
|
e.entity.destroy()
|
|
end
|
|
end
|
|
|
|
local function merchant_exploit_check(ent)
|
|
if ent.type ~= 'electric-pole' then
|
|
return
|
|
end
|
|
|
|
local refs = Blueprints.get_references('merchant')
|
|
if not refs or #refs <= 0 then
|
|
return
|
|
end
|
|
|
|
local bp_ent = Blueprints.reference_get_entities(refs[1])[1]
|
|
local surf = bp_ent.surface
|
|
|
|
local query = {
|
|
type = 'electric-pole',
|
|
position = bp_ent.position,
|
|
radius = 18
|
|
}
|
|
local ents = surf.find_entities_filtered(query)
|
|
for _, s_ent in pairs(ents) do
|
|
if s_ent.valid and s_ent.force.name ~= 'merchant' then
|
|
s_ent.die()
|
|
end
|
|
end
|
|
end
|
|
|
|
local function on_built_entity(e)
|
|
local ent = e.created_entity
|
|
if not ent or not ent.valid then
|
|
return
|
|
end
|
|
|
|
-- ClaimsFunctions.on_built_entity(ent)
|
|
merchant_exploit_check(ent)
|
|
end
|
|
|
|
local function on_market_item_purchased(e)
|
|
local p = game.players[e.player_index]
|
|
local m = e.market
|
|
local o = m.get_market_items()[e.offer_index].offer
|
|
local perks = this.perks[p.name]
|
|
if not perks then
|
|
perks = assign_perks(p)
|
|
end
|
|
|
|
if o.effect_description == 'Construct a GPS receiver' then
|
|
perks.minimap = true
|
|
p.minimap_enabled = true
|
|
end
|
|
end
|
|
|
|
local function stringify_color(color)
|
|
local r, g, b = color.r, color.g, color.b
|
|
if r <= 1 then
|
|
r = floor(r * 255)
|
|
end
|
|
|
|
if g <= 1 then
|
|
g = floor(g * 255)
|
|
end
|
|
|
|
if b <= 1 then
|
|
b = floor(b * 255)
|
|
end
|
|
|
|
return string.format('%d,%d,%d', r, g, b)
|
|
end
|
|
|
|
local function create_console_message(p, message)
|
|
local prefix_fmt = '[color=%s]%s:[/color]'
|
|
local msg_fmt = '[color=%s]%s[/color]'
|
|
local color = stringify_color(p.chat_color)
|
|
local prefix = string.format(prefix_fmt, color, p.name)
|
|
local p_msg = string.format(msg_fmt, color, message)
|
|
|
|
if this.perks[p.name].chat_global then
|
|
msg_fmt = '[color=red]global:[/color] %s %s'
|
|
else
|
|
msg_fmt = '[color=green]nap:[/color] %s %s'
|
|
end
|
|
|
|
return string.format(msg_fmt, prefix, p_msg)
|
|
end
|
|
|
|
local function filter_out_gps(message)
|
|
local msg = string.gsub(message, '%[gps=%-?%d+%,?%s*%-?%d+%]', '[gps]')
|
|
return msg
|
|
end
|
|
|
|
local function on_console_chat(e)
|
|
local pid = e.player_index
|
|
|
|
if not pid then
|
|
return
|
|
end
|
|
|
|
local p = game.players[pid]
|
|
local msg = create_console_message(p, e.message)
|
|
if this.perks[p.name].chat_global then
|
|
for _, peer in pairs(game.players) do
|
|
if peer.name ~= p.name then
|
|
local perks = this.perks[peer.name]
|
|
if not perks then
|
|
perks = assign_perks(peer)
|
|
end
|
|
if perks and perks.minimap then
|
|
peer.print(msg)
|
|
else
|
|
peer.print(filter_out_gps(msg))
|
|
end
|
|
end
|
|
end
|
|
else
|
|
for _, f in pairs(game.forces) do
|
|
if p.force.get_cease_fire(f) then
|
|
local peer = f.players[1]
|
|
if peer.name ~= p.name then
|
|
local perks = this.perks[peer.name]
|
|
if not perks then
|
|
perks = assign_perks(peer)
|
|
end
|
|
if perks and perks.minimap then
|
|
peer.print(msg)
|
|
else
|
|
peer.print(filter_out_gps(msg))
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
local function on_research_finished(e)
|
|
local r = e.research
|
|
if not r.valid then
|
|
return
|
|
end
|
|
|
|
local reward = {
|
|
name = 'coin',
|
|
count = ceil(r.research_unit_count * 3)
|
|
}
|
|
local f = r.force
|
|
for _, player in pairs(f.players) do
|
|
if player.can_insert(reward) then
|
|
player.insert(reward)
|
|
end
|
|
end
|
|
end
|
|
|
|
local function move_to_orbit(player)
|
|
local char = player.character
|
|
player.character = nil
|
|
char.destroy()
|
|
|
|
game.merge_forces(player.name, 'neutral')
|
|
player.spectator = true
|
|
redraw_gui(player)
|
|
|
|
local orbit_perms = game.permissions.get_group('orbit')
|
|
orbit_perms.add_player(player)
|
|
end
|
|
|
|
local function on_marked_for_deconstruction(event)
|
|
local entity = event.entity
|
|
local player = game.get_player(event.player_index)
|
|
if entity and entity.valid and player and player.valid then
|
|
entity.cancel_deconstruction(player.force.name)
|
|
end
|
|
end
|
|
|
|
local function on_rocket_launched(e)
|
|
local surf = game.get_surface(this.active_surface)
|
|
if not surf or not surf.valid then
|
|
return
|
|
end
|
|
|
|
local pid = e.player_index
|
|
surf.print('>> The rocket was launched')
|
|
if pid == nil then
|
|
surf.print('>> Nobody escaped by it')
|
|
else
|
|
local player = game.players[pid]
|
|
surf.print(string.format('>> The %s was able to escape', player.name))
|
|
move_to_orbit(player)
|
|
end
|
|
end
|
|
|
|
Public.explode_ship = explode_ship
|
|
|
|
Event.on_init(init_game)
|
|
Event.add(defines.events.on_built_entity, on_built_entity)
|
|
Event.add(defines.events.on_robot_built_entity, on_built_entity)
|
|
Event.add(defines.events.on_research_finished, on_research_finished)
|
|
Event.add(defines.events.on_player_joined_game, on_player_joined_game)
|
|
Event.add(defines.events.on_chunk_generated, on_chunk_generated)
|
|
Event.add(defines.events.on_player_mined_entity, on_player_mined_entity)
|
|
Event.add(defines.events.on_player_died, on_player_died)
|
|
Event.add(defines.events.on_player_kicked, on_player_died)
|
|
Event.add(defines.events.on_player_banned, on_player_died)
|
|
Event.add(defines.events.on_pre_player_left_game, on_pre_player_left_game)
|
|
Event.add(defines.events.on_player_respawned, on_player_respawned)
|
|
Event.add(defines.events.on_player_dropped_item, on_player_dropped_item)
|
|
Event.add(defines.events.on_marked_for_deconstruction, on_marked_for_deconstruction)
|
|
Event.add(defines.events.on_entity_damaged, on_entity_damaged)
|
|
Event.add(defines.events.on_entity_died, on_entity_died)
|
|
Event.add(defines.events.on_market_item_purchased, on_market_item_purchased)
|
|
Event.add(defines.events.on_chunk_charted, on_chunk_charted)
|
|
Event.add(defines.events.on_console_chat, on_console_chat)
|
|
Event.add(defines.events.on_gui_click, on_gui_click)
|
|
Event.add(defines.events.on_tick, on_tick)
|
|
Event.add(defines.events.on_tick, on_tick_reset)
|
|
Event.add(defines.events.on_rocket_launched, on_rocket_launched)
|
|
|
|
return Public
|