mirror of
https://github.com/ComfyFactory/ComfyFactorio.git
synced 2025-01-10 00:43:27 +02:00
869 lines
23 KiB
Lua
869 lines
23 KiB
Lua
|
global.this = {}
|
||
|
local _global = require("utils.global")
|
||
|
local _evt = require("utils.event")
|
||
|
local _map = require("tools.map_functions")
|
||
|
local _common = require("planet_prison.mod.common")
|
||
|
local _layers = require("planet_prison.mod.layers")
|
||
|
local _ai = require("planet_prison.mod.ai")
|
||
|
local _bp = require("planet_prison.mod.bp")
|
||
|
global.this._config = require("planet_prison.config")
|
||
|
|
||
|
global.this.maps = {
|
||
|
{
|
||
|
name = "Flooded metropolia",
|
||
|
height = 2000,
|
||
|
width = 2000,
|
||
|
water = 1,
|
||
|
terrain_segmentation = 8,
|
||
|
property_expression_names = {
|
||
|
moisture = 0,
|
||
|
temperature = 30.
|
||
|
},
|
||
|
starting_area = "none",
|
||
|
autoplace_controls = {
|
||
|
["iron-ore"] = {
|
||
|
frequency = 0,
|
||
|
},
|
||
|
["copper-ore"] = {
|
||
|
frequency = 0,
|
||
|
},
|
||
|
["stone"] = {
|
||
|
frequency = 0,
|
||
|
},
|
||
|
["coal"] = {
|
||
|
frequency = 0,
|
||
|
},
|
||
|
["crude-oil"] = {
|
||
|
frequency = 10,
|
||
|
size = 1,
|
||
|
},
|
||
|
["trees"] = {
|
||
|
frequency = 4,
|
||
|
},
|
||
|
["enemy-base"] = {
|
||
|
frequency = 0,
|
||
|
}
|
||
|
},
|
||
|
}
|
||
|
}
|
||
|
|
||
|
global.this.entities_cache = nil
|
||
|
global.this.surface = nil
|
||
|
global.this.last_friend = nil
|
||
|
local function pick_map()
|
||
|
return global.this.maps[_common.rand_range(1, #global.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 function init_player_ship_bp(entity, player)
|
||
|
entity.force = player.force
|
||
|
if entity.name == "crash-site-chest-1" then
|
||
|
for _, stack in pairs(global.this._config.player_ship_loot) do
|
||
|
entity.insert(stack)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
if entity.name == "crash-site-generator" then
|
||
|
entity.electric_buffer_size = 2000
|
||
|
entity.power_production = 2000
|
||
|
end
|
||
|
end
|
||
|
|
||
|
global.this.events = {
|
||
|
merchant = {
|
||
|
alive = false,
|
||
|
moving = false,
|
||
|
spawn_tick = 0,
|
||
|
embark_tick = 0,
|
||
|
position = { x = 0, y = 0 },
|
||
|
offer = global.this._config.merchant_offer,
|
||
|
}
|
||
|
}
|
||
|
local function init_merchant_bp(entity, _)
|
||
|
entity.force = "merchant"
|
||
|
entity.rotatable = false
|
||
|
entity.minable = false
|
||
|
if entity.name ~= "market" then
|
||
|
entity.operable = false
|
||
|
else
|
||
|
for _, entry in pairs(global.this.events.merchant.offer) do
|
||
|
entity.add_market_item(entry)
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function noise_hostile_hook(ent)
|
||
|
ent.force = "enemy"
|
||
|
if ent.name == "character" then
|
||
|
ent.insert({name="pistol", count=1})
|
||
|
ent.insert({name="firearm-magazine", count=20})
|
||
|
else
|
||
|
ent.insert({name="firearm-magazine", count=200})
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function noise_set_neutral_hook(ent)
|
||
|
ent.force = "neutral"
|
||
|
end
|
||
|
|
||
|
global.this.bp = {
|
||
|
player_ship = require("planet_prison.bp.player_ship"),
|
||
|
merchant = require("planet_prison.bp.merchant")
|
||
|
}
|
||
|
local function init_game()
|
||
|
global.this.surface = game.create_surface("arena", pick_map())
|
||
|
global.this.surface.min_brightness = 0
|
||
|
global.this.surface.ticks_per_day = 25000 * 4
|
||
|
global.this.perks = {}
|
||
|
global.this.events.merchant.spawn_tick = game.tick + 5000
|
||
|
|
||
|
game.map_settings.pollution.enabled = false
|
||
|
game.map_settings.enemy_evolution.enabled = false
|
||
|
game.difficulty_settings.technology_price_multiplier = 0.1
|
||
|
game.difficulty_settings.research_queue_setting = "always"
|
||
|
|
||
|
_layers.init()
|
||
|
_layers.set_collision_mask({"water-tile"})
|
||
|
_layers.add_noise_layer("LuaTile", "concrete", {"concrete"}, 0.3, 0.2)
|
||
|
_layers.add_noise_layer("LuaTile", "stones", {"stone-path"}, 0.2, 0.4)
|
||
|
_layers.add_noise_layer("LuaTile", "shallows", {"water-shallow"}, 0.5, 0.005)
|
||
|
_layers.add_noise_layer("LuaEntity", "scrap", {"mineable-wreckage"}, 0.5, 0.1)
|
||
|
_layers.add_noise_layer("LuaEntity", "walls", {"stone-wall"}, 0.5, 0.09)
|
||
|
_layers.add_noise_layer("LuaEntity", "hostile", {"character",
|
||
|
"gun-turret"}, 0.92, 0.99)
|
||
|
_layers.add_noise_layer("LuaEntity", "structures", {"big-electric-pole",
|
||
|
"medium-electric-pole"}, 0.9, 0.9)
|
||
|
_layers.add_noise_layer_hook("structures", noise_set_neutral_hook)
|
||
|
_layers.add_noise_layer_hook("walls", noise_set_neutral_hook)
|
||
|
_layers.add_noise_layer_hook("hostile", noise_hostile_hook)
|
||
|
_bp.push_blueprint("player_ship", global.this.bp.player_ship)
|
||
|
_bp.set_blueprint_hook("player_ship", init_player_ship_bp)
|
||
|
_bp.push_blueprint("merchant", global.this.bp.merchant)
|
||
|
_bp.set_blueprint_hook("merchant", init_merchant_bp)
|
||
|
end
|
||
|
|
||
|
local function do_spawn_point(player)
|
||
|
local point = {
|
||
|
x = _common.get_axis(player.position, "x"),
|
||
|
y = _common.get_axis(player.position, "y") - 2
|
||
|
}
|
||
|
local instance = _bp.build(player.surface, "player_ship", point, player)
|
||
|
_layers.push_excluding_bounding_box(instance.bb)
|
||
|
end
|
||
|
|
||
|
local function get_non_obstructed_position(s, radius)
|
||
|
while true do
|
||
|
local chunk = s.get_random_chunk()
|
||
|
chunk.x = chunk.x * 32
|
||
|
chunk.y = chunk.y * 32
|
||
|
|
||
|
for x = 1, radius do
|
||
|
for y = 1, radius do
|
||
|
local tile = s.get_tile({chunk.x + x, chunk.y + y})
|
||
|
if not tile.collides_with("ground-tile") then
|
||
|
goto continue
|
||
|
end
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local search_info = {
|
||
|
position = chunk,
|
||
|
radius = radius,
|
||
|
force = {"neutral", "enemy"},
|
||
|
invert = true
|
||
|
}
|
||
|
local ents = s.find_entities_filtered(search_info)
|
||
|
if not ents then
|
||
|
return chunk
|
||
|
end
|
||
|
|
||
|
if #ents == 0 then
|
||
|
return chunk
|
||
|
end
|
||
|
|
||
|
if ents[1].name == "character" then
|
||
|
return chunk
|
||
|
end
|
||
|
|
||
|
::continue::
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function redraw_gui(p)
|
||
|
p.gui.left.clear()
|
||
|
|
||
|
local merchant = global.this.events.merchant
|
||
|
local perks = global.this.perks[p.tag]
|
||
|
local chat_type = "Global chat"
|
||
|
if not perks.chat_global then
|
||
|
chat_type = "Buddies chat"
|
||
|
end
|
||
|
|
||
|
local button = {
|
||
|
type = "button",
|
||
|
name = "manual_toggle",
|
||
|
caption = "Manual"
|
||
|
}
|
||
|
p.gui.left.add(button)
|
||
|
|
||
|
button = {
|
||
|
type = "button",
|
||
|
name = "chat_toggle",
|
||
|
caption = chat_type,
|
||
|
}
|
||
|
p.gui.left.add(button)
|
||
|
|
||
|
if merchant.alive and not perks.minimap then
|
||
|
button = {
|
||
|
type = "button",
|
||
|
name = "merchant_find",
|
||
|
caption = "Merchant",
|
||
|
}
|
||
|
p.gui.left.add(button)
|
||
|
end
|
||
|
|
||
|
if perks.flashlight then
|
||
|
button = {
|
||
|
type = "button",
|
||
|
name = "flashlight_toggle",
|
||
|
caption = "Toggle flashlight"
|
||
|
}
|
||
|
p.gui.left.add(button)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function print_merchant_position(player)
|
||
|
local position = global.this.events.merchant.position
|
||
|
local perks = global.this.perks[player.tag]
|
||
|
if not perks.minimap then
|
||
|
player.print(string.format(">> You were able to spot him %s from your location",
|
||
|
_common.get_readable_direction(player.position, position)))
|
||
|
else
|
||
|
player.print(string.format(">> You received a broadcast with [gps=%d,%d] coordinates", position.x, position.y))
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function on_gui_click(e)
|
||
|
local elem = e.element
|
||
|
local p = game.players[e.player_index]
|
||
|
local perks = global.this.perks[p.tag]
|
||
|
|
||
|
if elem.name == "chat_toggle" then
|
||
|
if perks.chat_global then
|
||
|
elem.caption = "Buddies chat"
|
||
|
perks.chat_global = false
|
||
|
else
|
||
|
elem.caption = "Global chat"
|
||
|
perks.chat_global = true
|
||
|
end
|
||
|
elseif elem.name == "flashlight_toggle" then
|
||
|
if perks.flashlight_enable then
|
||
|
perks.flashlight_enable = false
|
||
|
p.character.disable_flashlight()
|
||
|
else
|
||
|
perks.flashlight_enable = true
|
||
|
p.character.enable_flashlight()
|
||
|
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 = global.this._config.manual
|
||
|
}
|
||
|
text_box = p.gui.center.add(text_box)
|
||
|
text_box.style.minimal_width = 512
|
||
|
text_box.read_only = true
|
||
|
text_box.word_wrap = true
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function init_player(p)
|
||
|
p.teleport({0, 0}, "arena")
|
||
|
local s = p.surface
|
||
|
local position = get_non_obstructed_position(s, 10)
|
||
|
|
||
|
p.teleport(position, "arena")
|
||
|
p.name = "inmate"
|
||
|
p.tag = string.format("[%d]", _common.rand_range(1000, 9999))
|
||
|
p.force = game.create_force(p.tag)
|
||
|
p.force.set_friend("neutral", true)
|
||
|
global.this.perks[p.tag] = {
|
||
|
flashlight = false,
|
||
|
flashlight_enabled = false,
|
||
|
minimap = false,
|
||
|
chat_global = true,
|
||
|
}
|
||
|
|
||
|
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(global.this._config.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 on_player_joined_game(e)
|
||
|
local p = game.players[e.player_index]
|
||
|
init_player(p)
|
||
|
end
|
||
|
|
||
|
local function _build_merchant_bp(surf, position)
|
||
|
local instance = _bp.build(surf, "merchant", position, nil)
|
||
|
_layers.push_excluding_bounding_box(instance.bb)
|
||
|
end
|
||
|
|
||
|
local function _remove_merchant_bp(surf)
|
||
|
local refs = _bp.get_references("merchant")
|
||
|
local bb = _bp.reference_get_bounding_box(refs[1])
|
||
|
_layers.remove_excluding_bounding_box(bb)
|
||
|
_bp.destroy_references(surf, "merchant")
|
||
|
global.this.events.merchant.position = {
|
||
|
x = 0,
|
||
|
y = 0
|
||
|
}
|
||
|
end
|
||
|
|
||
|
local function spawn_merchant(s)
|
||
|
local merchant = global.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)
|
||
|
global.this.events.merchant.alive = false
|
||
|
global.this.events.merchant.moving = true
|
||
|
global.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 = global.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 cause_event(s)
|
||
|
merchant_event(s)
|
||
|
end
|
||
|
|
||
|
local function unlink_old_blueprints(name)
|
||
|
local query = {
|
||
|
timestamp = game.tick,
|
||
|
}
|
||
|
|
||
|
local refs = _bp.unlink_references_filtered(name, query)
|
||
|
for _, ref in pairs(refs) do
|
||
|
local bb = _bp.reference_get_bounding_box(ref)
|
||
|
_layers.remove_excluding_bounding_box(bb)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
-- global.this.profiler = nil
|
||
|
local function on_tick()
|
||
|
-- if not global.this.profiler then
|
||
|
-- global.this.profiler = game.create_profiler()
|
||
|
-- end
|
||
|
|
||
|
local s = global.this.surface
|
||
|
if not s then
|
||
|
log("on_tick: surface empty!")
|
||
|
return
|
||
|
end
|
||
|
|
||
|
if not s.is_chunk_generated then
|
||
|
log("on_tick: is_chunk_generated nil, map save?")
|
||
|
return
|
||
|
end
|
||
|
|
||
|
if not s.is_chunk_generated({0, 0}) then
|
||
|
return
|
||
|
end
|
||
|
|
||
|
local surf = global.this.surface
|
||
|
-- global.this.profiler.reset()
|
||
|
if game.tick % 4 == 0 then
|
||
|
_ai.do_job(surf, _ai.command.seek_and_destroy_player)
|
||
|
end
|
||
|
|
||
|
if game.tick % 10000 == 0 then
|
||
|
unlink_old_blueprints("player_ship")
|
||
|
end
|
||
|
|
||
|
_layers.do_job(surf, 64)
|
||
|
cause_event(s)
|
||
|
-- global.this.profiler.stop()
|
||
|
-- log(global.this.profiler)
|
||
|
end
|
||
|
|
||
|
local function make_ore_patch(e)
|
||
|
if _common.rand_range(1, 60) ~= 1 then
|
||
|
return
|
||
|
end
|
||
|
|
||
|
local surf = e.surface
|
||
|
local point = e.area.left_top
|
||
|
_map.draw_entity_circle(point, "stone", surf, 6, true, 1000000)
|
||
|
_map.draw_entity_circle(point, "coal", surf, 12, true, 1000000)
|
||
|
_map.draw_entity_circle(point, "copper-ore", surf, 18, true, 1000000)
|
||
|
_map.draw_entity_circle(point, "iron-ore", surf, 24, true, 1000000)
|
||
|
_map.draw_noise_tile_circle(point, "water", surf, 4)
|
||
|
end
|
||
|
|
||
|
local function on_chunk_generated(e)
|
||
|
make_ore_patch(e)
|
||
|
_layers.push_bounding_box(e.area)
|
||
|
end
|
||
|
|
||
|
local function on_player_mined_entity(e)
|
||
|
if e.entity.name ~= "mineable-wreckage" then
|
||
|
return
|
||
|
end
|
||
|
|
||
|
local candidates = {}
|
||
|
local chance = _common.rand_range(0, 1000)
|
||
|
for name, attrs in pairs(global.this._config.wreck_loot) do
|
||
|
local prob = attrs.rare * 100
|
||
|
if prob < chance then
|
||
|
local cand = {
|
||
|
name = name,
|
||
|
count = _common.rand_range(attrs.count[1], attrs.count[2]),
|
||
|
}
|
||
|
table.insert(candidates, cand)
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local count = #candidates
|
||
|
if count == 0 then
|
||
|
return
|
||
|
end
|
||
|
|
||
|
local cand = candidates[_common.rand_range(1, count)]
|
||
|
e.buffer.insert(cand)
|
||
|
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]
|
||
|
game.merge_forces(p.tag, "neutral")
|
||
|
global.this.perks[p.tag] = {
|
||
|
flashlight = false,
|
||
|
flashlight_enabled = false,
|
||
|
minimap = false,
|
||
|
chat_global = true,
|
||
|
}
|
||
|
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 global.this.last_friend then
|
||
|
global.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 = p.character.name,
|
||
|
position = ent.position,
|
||
|
limit = 1,
|
||
|
radius = 2,
|
||
|
})
|
||
|
if not ent_list or not #ent_list then
|
||
|
return
|
||
|
end
|
||
|
|
||
|
local peer = ent_list[1].player
|
||
|
if p.force.get_friend(peer.force) then
|
||
|
p.print(string.format("The %s %s is your buddy already", peer.name,
|
||
|
peer.tag))
|
||
|
return
|
||
|
end
|
||
|
|
||
|
if global.this.last_friend[peer.tag] == p.tag then
|
||
|
p.force.set_cease_fire(peer.force, true)
|
||
|
peer.force.set_cease_fire(p.force, true)
|
||
|
p.print(string.format("%s %s is now your buddy", peer.name, peer.tag))
|
||
|
peer.print(string.format("%s %s is now your buddy", p.name, p.tag))
|
||
|
global.this.last_friend[p.tag] = ""
|
||
|
return
|
||
|
end
|
||
|
|
||
|
global.this.last_friend[p.tag] = peer.tag
|
||
|
p.print(string.format("You want %s %s to be your buddy", peer.name, peer.tag))
|
||
|
peer.print(string.format("The %s %s wants to be your buddy", p.name, p.tag))
|
||
|
elseif ent.stack.name == "coal" then
|
||
|
local ent_list = p.surface.find_entities_filtered({
|
||
|
name = p.character.name,
|
||
|
position = ent.position,
|
||
|
limit = 1,
|
||
|
radius = 1,
|
||
|
})
|
||
|
if not ent_list or not #ent_list then
|
||
|
return
|
||
|
end
|
||
|
|
||
|
local peer = ent_list[1].player
|
||
|
if p.force.get_friend(peer.force) then
|
||
|
p.print(string.format("The %s %s is not your buddy", p.name, p.tag))
|
||
|
return
|
||
|
end
|
||
|
|
||
|
p.force.set_cease_fire(peer.force, false)
|
||
|
peer.force.set_cease_fire(p.force, false)
|
||
|
|
||
|
p.print(string.format("The %s %s is no longer your buddy", peer.name, peer.tag))
|
||
|
peer.print(string.format("The %s %s is no longer your buddy", p.name, p.tag))
|
||
|
end
|
||
|
end
|
||
|
|
||
|
local function on_chunk_charted(e)
|
||
|
local f_perks = global.this.perks[e.force.name]
|
||
|
|
||
|
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
|
||
|
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)
|
||
|
|
||
|
global.this.events.merchant.alive = false
|
||
|
global.this.events.merchant.moving = false
|
||
|
global.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 function hostile_death(e)
|
||
|
local ent = e.entity
|
||
|
local loot = e.loot
|
||
|
if ent.name ~= "character" then
|
||
|
return false
|
||
|
end
|
||
|
|
||
|
if ent.player then
|
||
|
loot.insert({name = "coin", count = 70})
|
||
|
else
|
||
|
loot.insert({name = "coin", count = 10})
|
||
|
end
|
||
|
|
||
|
return true
|
||
|
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)
|
||
|
end
|
||
|
|
||
|
|
||
|
local function merchant_exploit_check(e)
|
||
|
local ent = e.created_entity
|
||
|
if ent.type ~= "electric-pole" then
|
||
|
return
|
||
|
end
|
||
|
|
||
|
local refs = _bp.get_references("merchant")
|
||
|
if not refs or #refs <= 0 then
|
||
|
return
|
||
|
end
|
||
|
|
||
|
local bp_ent = _bp.reference_get_entities(refs[1])[1]
|
||
|
local surf = bp_ent.surface
|
||
|
|
||
|
local query = {
|
||
|
type = "electric-pole",
|
||
|
position = bp_ent.position,
|
||
|
radius = 15
|
||
|
}
|
||
|
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)
|
||
|
merchant_exploit_check(e)
|
||
|
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 = global.this.perks[p.tag]
|
||
|
|
||
|
if o.effect_description == "Construct a flashlight" then
|
||
|
perks.flashlight = true
|
||
|
perks.flashlight_enable = true
|
||
|
p.character.enable_flashlight()
|
||
|
redraw_gui(p)
|
||
|
elseif 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 = math.floor(r * 255)
|
||
|
end
|
||
|
|
||
|
if g <= 1 then
|
||
|
g = math.floor(g * 255)
|
||
|
end
|
||
|
|
||
|
if b <= 1 then
|
||
|
b = math.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 %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, p.tag)
|
||
|
local p_msg = string.format(msg_fmt, color, message)
|
||
|
|
||
|
if global.this.perks[p.tag].chat_global then
|
||
|
msg_fmt = "[color=red]global:[/color] %s %s"
|
||
|
else
|
||
|
msg_fmt = "[color=green]buddies:[/color] %s %s"
|
||
|
end
|
||
|
|
||
|
return string.format(msg_fmt, prefix, p_msg)
|
||
|
end
|
||
|
|
||
|
local function create_speech_bubble_message(p, message)
|
||
|
local msg_fmt = "[color=%s]%s[/color]"
|
||
|
local color = stringify_color(p.chat_color)
|
||
|
return string.format(msg_fmt, color, message)
|
||
|
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 global.this.perks[p.tag].chat_global then
|
||
|
local bubble = {
|
||
|
name = "compi-speech-bubble",
|
||
|
position = p.position,
|
||
|
target = p.character,
|
||
|
text = create_speech_bubble_message(p, e.message),
|
||
|
lifetime = 100,
|
||
|
}
|
||
|
|
||
|
p.surface.create_entity(bubble)
|
||
|
for _, peer in pairs(game.players) do
|
||
|
local perks = global.this.perks[peer.tag]
|
||
|
if peer.tag ~= p.tag then
|
||
|
if 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]
|
||
|
local perks = global.this.perks[peer.tag]
|
||
|
if peer.tag ~= p.tag then
|
||
|
if 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 = math.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 on_rocket_launched(e)
|
||
|
local surf = global.this.surface
|
||
|
local pid = e.player_index
|
||
|
surf.print(">> The rocket was launched")
|
||
|
if pid == nil then
|
||
|
surf.print(">> Nobody escaped by it")
|
||
|
else
|
||
|
local p = game.players[pid]
|
||
|
surf.print(string.format(">> The inmate %s was able to escape", p.tag))
|
||
|
on_player_died({player_index = pid})
|
||
|
p.character.die()
|
||
|
end
|
||
|
end
|
||
|
|
||
|
_evt.on_init(init_game)
|
||
|
_evt.add(defines.events.on_built_entity, on_built_entity)
|
||
|
_evt.add(defines.events.on_research_finished, on_research_finished)
|
||
|
_evt.add(defines.events.on_player_joined_game, on_player_joined_game)
|
||
|
_evt.add(defines.events.on_chunk_generated, on_chunk_generated)
|
||
|
_evt.add(defines.events.on_player_mined_entity, on_player_mined_entity)
|
||
|
_evt.add(defines.events.on_player_died, on_player_died)
|
||
|
_evt.add(defines.events.on_player_kicked, on_player_died)
|
||
|
_evt.add(defines.events.on_player_banned, on_player_died)
|
||
|
_evt.add(defines.events.on_player_respawned, on_player_respawned)
|
||
|
_evt.add(defines.events.on_player_dropped_item, on_player_dropped_item)
|
||
|
_evt.add(defines.events.on_pre_player_left_game, on_player_died)
|
||
|
_evt.add(defines.events.on_entity_damaged, on_entity_damaged)
|
||
|
_evt.add(defines.events.on_entity_died, on_entity_died)
|
||
|
_evt.add(defines.events.on_market_item_purchased, on_market_item_purchased)
|
||
|
_evt.add(defines.events.on_chunk_charted, on_chunk_charted)
|
||
|
_evt.add(defines.events.on_console_chat, on_console_chat)
|
||
|
_evt.add(defines.events.on_gui_click, on_gui_click)
|
||
|
_evt.add(defines.events.on_tick, on_tick)
|
||
|
_evt.add(defines.events.on_rocket_launched, on_rocket_launched)
|
||
|
|
||
|
_global.register_init({},
|
||
|
function(tbl)
|
||
|
tbl.this = global.this
|
||
|
end,
|
||
|
function(tbl)
|
||
|
global.this = tbl.this
|
||
|
end)
|