1
0
mirror of https://github.com/ComfyFactory/ComfyFactorio.git synced 2025-05-13 21:56:29 +02:00

planet_prison: add timer to player spawn

These generators from ships are way to op as you can easily place
radars around it. We'll explode the ships after 10 minutes, so they
don't clutter the map and don't give exploits.
This commit is contained in:
cogito 2020-01-13 20:32:08 +01:00
parent bdcdc9ae96
commit 198b5fd17a
5 changed files with 233 additions and 16 deletions

View File

@ -2,6 +2,7 @@ global.this = {}
local _global = require("utils.global")
local _evt = require("utils.event")
local _map = require("tools.map_functions")
local _timers = require("planet_prison.mod.timers")
local _common = require("planet_prison.mod.common")
local _layers = require("planet_prison.mod.layers")
local _ai = require("planet_prison.mod.ai")
@ -233,6 +234,7 @@ local function init_game()
game.difficulty_settings.technology_price_multiplier = 0.1
game.difficulty_settings.research_queue_setting = "always"
_timers.init()
_layers.init()
_layers.set_collision_mask({"water-tile"})
@ -255,6 +257,41 @@ local function init_game()
_bp.set_blueprint_hook("merchant", init_merchant_bp)
end
local function explode_ship(deps)
local bp = deps.modules.bp
local layers = deps.modules.layers
for _, ent in pairs(bp.reference_get_entities(deps.ship)) do
if not ent.valid then
goto continue
end
local explosion = {
name = "massive-explosion",
position = ent.position
}
deps.surf.create_entity(explosion)
::continue::
end
local bb = bp.reference_get_bounding_box(deps.ship)
layers.remove_excluding_bounding_box(bb)
bp.destroy_reference(deps.surf, deps.ship)
rendering.destroy(deps.id)
end
local function explode_ship_update(left, deps)
local common = deps.modules.common
for _, ent in pairs(deps.ship.entities) do
if not ent.valid then
return false
end
end
rendering.set_text(deps.id, common.get_time(left))
return true
end
local function do_spawn_point(player)
local point = {
x = _common.get_axis(player.position, "x"),
@ -262,6 +299,38 @@ local function do_spawn_point(player)
}
local instance = _bp.build(player.surface, "player_ship", point, player)
_layers.push_excluding_bounding_box(instance.bb)
local left = global.this._config.self_explode
local object = {
text = _common.get_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 entry = {
id = rendering.draw_text(object),
ship = instance,
modules = {
bp = _bp,
layers = _layers,
common = _common,
timers = _timers,
},
surf = player.surface,
}
local timer = _timers.set_timer(left, explode_ship)
_timers.set_timer_on_update(timer, explode_ship_update)
_timers.set_timer_dependency(timer, entry)
_timers.set_timer_start(timer)
end
local function get_non_obstructed_position(s, radius)
@ -520,18 +589,6 @@ 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
local function kill_player(p)
p.character.die()
end
@ -548,16 +605,16 @@ local function on_tick()
_ai.do_job(surf, _ai.command.seek_and_destroy_player)
end
if (game.tick + 1) % 500 == 0 then
unlink_old_blueprints("player_ship")
end
_layers.do_job(surf)
cause_event(s)
if (game.tick + 1) % 100 == 0 then
_afk.on_inactive_players(90, kill_player)
end
if (game.tick + 1) % 60 == 0 then
_timers.do_job()
end
end
local function make_ore_patch(e)

View File

@ -31,6 +31,8 @@ public.player_ship_loot = {
}
}
public.self_explode = 60 * 60 * 10
public.wreck_loot = {
["iron-plate"] = {
rare = 0.1,

View File

@ -196,6 +196,45 @@ public.destroy_references = function(surf, name)
public.destroy_references_filtered(surf, name, {})
end
local function _destroy_reference(surf, ref)
for _, ent in pairs(ref.entities) do
if ent.valid then
ent.destroy()
end
end
local tiles = {}
for _, tile in pairs(ref.tiles) do
if tile.valid then
goto continue
end
tile.name = "concrete"
table.insert(tiles, tile)
::continue::
end
surf.set_tiles(tiles)
end
--[[
destroy_reference - Destroys reference of a blueprint at given surface.
@param surf - Surface on which blueprints are placed.
@param reference - Any valid reference.
--]]
public.destroy_reference = function(surf, reference)
for _, meta in pairs(this._bps) do
for i = 1, #meta.refs do
local ref = meta.refs[i]
if reference.id == ref.id then
_destroy_reference(surf, ref)
table.remove(meta.refs, i)
return
end
end
end
end
local function _build_tiles(surf, point, tiles)
local _tiles = {}

View File

@ -265,4 +265,25 @@ public.merge_bounding_boxes = function(bbs)
return box
end
--[[
get_time - Return strigified time of a tick.
@param ticks - Just a ticks.
--]]
public.get_time = function(ticks)
local seconds = math.floor((ticks / 60) % 60)
local minutes = math.floor((ticks / 60 / 60) % 60)
local hours = math.floor(ticks / 60 / 60 / 60)
local time
if hours > 0 then
time = string.format("%02d:%01d:%02d", hours, minutes, seconds)
elseif minutes > 0 then
time = string.format("%02d:%02d", minutes, seconds)
else
time = string.format("00:%02d", seconds)
end
return time
end
return public

View File

@ -0,0 +1,98 @@
local public = {}
local _global = require("utils.global")
public.init = function()
if global.this == nil then
global.this = {}
end
global.this.timers = {}
end
--[[
set_timer - Sets a timer.
@param left - Time left on the timer in ticks.
@param hook - Action executed after timer is elapsed.
--]]
public.set_timer = function(left, hook)
local id = game.tick
local entry = {
left = left,
hook_finish = hook,
hook_update = nil,
deps = nil,
running = false,
last_update = 0,
}
global.this.timers[id] = entry
return id
end
--[[
set_timer_on_update - Adds a hook that is executed everytime a
timers is updated.
@param id - Id of the timer.
@param hook - Hook that will be executed per update.
--]]
public.set_timer_on_update = function(id, hook)
global.this.timers[id].hook_update = hook
end
--[[
set_timer_dependency - Adds dependency into user callback.
@param id - Id of the timer,
@param deps - Dependency of timer to add.
--]]
public.set_timer_dependency = function(id, deps)
global.this.timers[id].deps = deps
end
--[[
set_timer_start - Sets the timer to run.
@param id - Id of a timer.
--]]
public.set_timer_start = function(id)
global.this.timers[id].running = true
global.this.timers[id].last_update = game.tick
end
--[[
kill_timer - Effectivly kills the timer.
@param id - Timer id.
--]]
public.kill_timer = function(id)
global.this.timers[id] = nil
end
--[[
do_job - Execute timer logic within a tick.
--]]
public.do_job = function()
for id, entry in pairs(global.this.timers) do
if entry.running == false then
goto continue
end
entry.left = entry.left - (game.tick - entry.last_update)
if entry.left > 0 then
entry.last_update = game.tick
if entry.hook_update ~= nil then
if not entry.hook_update(entry.left, entry.deps) then
goto premature_finish
end
end
goto continue
end
::premature_finish::
entry.hook_finish(entry.deps)
global.this.timers[id] = nil
::continue::
end
end
return public