393 lines
14 KiB
Lua
393 lines
14 KiB
Lua
require("util")
|
|
require("utils")
|
|
require("particles")
|
|
local ticks_1_s = 60
|
|
|
|
-- CUSTOM EVENT HANDLING --
|
|
-- if your mod creates the stage 1 construction site via script, you should add the "raise_built=true" to your create_entity, so here
|
|
-- it will fire the script_raised_built event
|
|
-- A custom event is raised upon each finished construction stage, named "on_silo_stage_finished"
|
|
--(remote interface is lower in the file, there I describe how to subscribe to my event)
|
|
local on_silo_stage_finished = script.generate_event_name() --uint returns event.created_entity
|
|
|
|
|
|
|
|
function ModSetup()
|
|
ReadRunTimeSettings(event)
|
|
if global.rsc_silo_under_construction==nil then global.rsc_silo_under_construction={} end
|
|
global.automated_forces = global.automated_forces or {}
|
|
global.st_insert_material_work = settings.startup["rsc-st-work-for-insert-material"].value
|
|
global.st_remove_stone_work = settings.startup["rsc-st-work-for-remove-stone"].value
|
|
global.st_not_removable_silo = settings.startup["rsc-st-not-removable-silo"].value
|
|
global.st_not_removable_site = settings.startup["rsc-st-not-removable-site"].value
|
|
global.st_dont_place_tiles = settings.startup["rsc-st-dont-place-tiles"].value
|
|
global.st_enable_se_cargo = false
|
|
global.st_enable_se_probe = false
|
|
if settings.startup["rsc-st-enable-se-cargo-silo"] then global.st_enable_se_cargo =settings.startup["rsc-st-enable-se-cargo-silo"].value end
|
|
if settings.startup["rsc-st-enable-se-probe-silo"] then global.st_enable_se_probe =settings.startup["rsc-st-enable-se-probe-silo"].value end
|
|
|
|
|
|
for f=1, #game.forces do
|
|
local force = game.forces[f]
|
|
if force and force.technologies then
|
|
if force.technologies['rocket-silo'] and force.technologies['rocket-silo'].researched then
|
|
force.recipes['rsc-excavation-site'].enabled = true
|
|
end
|
|
if force.technologies['se-rocket-launch-pad'] and force.technologies['se-rocket-launch-pad'].researched then
|
|
if global.st_enable_se_cargo then force.recipes['rsc-serlp-excavation-site'].enabled=true end
|
|
force.recipes['se-rocket-launch-pad'].enabled = not global.st_enable_se_cargo
|
|
end
|
|
if force.technologies['se-space-probe'] and force.technologies['se-space-probe'].researched then
|
|
if global.st_enable_se_probe then force.recipes['rsc-sesprs-excavation-site'].enabled=true end
|
|
force.recipes['se-space-probe-rocket-silo'].enabled = not global.st_enable_se_probe
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
function ReadRunTimeSettings(event)
|
|
global.st_only_in_alt_mode = settings.global["rsc-only-in-alt-mode"].value
|
|
end
|
|
script.on_event(defines.events.on_runtime_mod_setting_changed, ReadRunTimeSettings)
|
|
|
|
function On_Init()
|
|
ModSetup()
|
|
end
|
|
|
|
function on_configuration_changed(data)
|
|
ModSetup()
|
|
end
|
|
script.on_configuration_changed(on_configuration_changed)
|
|
script.on_init(On_Init)
|
|
|
|
|
|
|
|
local function FillWith(surface,position,area,withwhat)
|
|
if (not global.st_dont_place_tiles) and (not remote.interfaces["warptorio2"]) then
|
|
if remote.interfaces["space-exploration"] then
|
|
local Zone = remote.call("space-exploration", "get_zone_from_name", {zone_name = surface.name})
|
|
if Zone then
|
|
local zone_index = Zone.index
|
|
local is_space = remote.call("space-exploration", "get_zone_is_space", {zone_index = zone_index})
|
|
if is_space then return end
|
|
end
|
|
end
|
|
|
|
local solo = {}
|
|
|
|
local X = position.x
|
|
local Y = position.y
|
|
|
|
local x1,x2 = X-area , X+area
|
|
local y1,y2 = Y-area , Y+area
|
|
for y=y1,y2 do
|
|
for x=x1,x2 do
|
|
table.insert(solo, {name=withwhat, position={x=x, y=y}})
|
|
end
|
|
end
|
|
|
|
if #solo>0 then
|
|
surface.set_tiles(solo)
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
local function CallFrenzyAttack(target)
|
|
if (target and target.valid) then
|
|
if target.surface.map_gen_settings and target.surface.map_gen_settings.autoplace_controls and
|
|
target.surface.map_gen_settings.autoplace_controls["enemy-base"] and target.surface.map_gen_settings.autoplace_controls["enemy-base"].size>0 then
|
|
local Min = 30
|
|
local Max = 50
|
|
local Dist = 400
|
|
local aliens = math.random(Min,Max)
|
|
local spawn = target.surface.find_entities_filtered({type = "unit-spawner",limit=1,position=target.position, radius=Dist})
|
|
if #spawn>0 then
|
|
local force = spawn[1].force
|
|
local sent = target.surface.set_multi_command({
|
|
command = {type=defines.command.attack_area, destination=target.position, radius=50, distraction = defines.distraction.by_anything },
|
|
unit_count = aliens,
|
|
force = force,
|
|
unit_search_distance = Dist,
|
|
})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
|
|
function upgrade_construction_site(silo_data)
|
|
|
|
local silo=silo_data.silo
|
|
if silo and silo.valid then
|
|
|
|
local name=silo.name
|
|
local upgrade_to
|
|
local last_user = silo.last_user
|
|
local final_building = 'rocket-silo' -- default
|
|
|
|
if silo_data.final_building ~= nil then final_building=silo_data.final_building end
|
|
|
|
local work = global.st_insert_material_work
|
|
local position=silo.position
|
|
local surface=silo.surface
|
|
local force=silo.force
|
|
|
|
if name=='rsc-silo-stage1' then upgrade_to='rsc-silo-stage2'
|
|
elseif name=='rsc-silo-stage2' then upgrade_to='rsc-silo-stage3' work = global.st_remove_stone_work
|
|
elseif name=='rsc-silo-stage3' then upgrade_to='rsc-silo-stage4' FillWith(surface,position,5,'concrete')
|
|
elseif name=='rsc-silo-stage4' then upgrade_to='rsc-silo-stage5'
|
|
elseif name=='rsc-silo-stage5' then upgrade_to='rsc-silo-stage6' FillWith(surface,position,6,'concrete') FillWith(surface,position,5,'refined-hazard-concrete-left')
|
|
elseif name=='rsc-silo-stage6' then upgrade_to=final_building
|
|
|
|
elseif name=='rsc-silo-stage1-serlp' then upgrade_to='rsc-silo-stage2-serlp'
|
|
elseif name=='rsc-silo-stage2-serlp' then upgrade_to='rsc-silo-stage3-serlp' work = global.st_remove_stone_work
|
|
elseif name=='rsc-silo-stage3-serlp' then upgrade_to='rsc-silo-stage4-serlp' FillWith(surface,position,6,'concrete')
|
|
elseif name=='rsc-silo-stage4-serlp' then upgrade_to='rsc-silo-stage5-serlp'
|
|
elseif name=='rsc-silo-stage5-serlp' then upgrade_to='rsc-silo-stage6-serlp' FillWith(surface,position,7,'concrete') FillWith(surface,position,6,'refined-hazard-concrete-left')
|
|
elseif name=='rsc-silo-stage6-serlp' then upgrade_to=final_building
|
|
|
|
elseif name=='rsc-silo-stage1-sesprs' then upgrade_to='rsc-silo-stage2-sesprs'
|
|
elseif name=='rsc-silo-stage2-sesprs' then upgrade_to='rsc-silo-stage3-sesprs' work = global.st_remove_stone_work
|
|
elseif name=='rsc-silo-stage3-sesprs' then upgrade_to='rsc-silo-stage4-sesprs'
|
|
elseif name=='rsc-silo-stage4-sesprs' then upgrade_to='rsc-silo-stage5-sesprs'
|
|
elseif name=='rsc-silo-stage5-sesprs' then upgrade_to='rsc-silo-stage6-sesprs'
|
|
elseif name=='rsc-silo-stage6-sesprs' then upgrade_to=final_building end
|
|
|
|
|
|
silo.destroy()
|
|
local new_stage = surface.create_entity{name = upgrade_to, position = position, force=force, raise_built=true}
|
|
if math.random(0,1)==0 then CallFrenzyAttack(new_stage) end
|
|
|
|
if last_user then new_stage.last_user = last_user end
|
|
|
|
if upgrade_to~=final_building then
|
|
local silo_data = {silo=new_stage,bar_back=nil,progress_bar=nil,work_value=work,final_building=final_building}
|
|
table.insert (global.rsc_silo_under_construction,silo_data)
|
|
check_construction_site(silo_data)
|
|
if global.st_not_removable_site then new_stage.minable=false end
|
|
else
|
|
if global.st_not_removable_silo then new_stage.minable=false end
|
|
end
|
|
|
|
|
|
script.raise_event(on_silo_stage_finished, {created_entity = new_stage})
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
function check_construction_site(silo_data)
|
|
local entity=silo_data.silo
|
|
local progress=entity.products_finished
|
|
local max_progress=silo_data.work_value
|
|
|
|
if progress>=max_progress then
|
|
entity.active = false
|
|
if entity.get_output_inventory().get_item_count()<1 or in_list(global.automated_forces,entity.force.name) then
|
|
upgrade_construction_site(silo_data)
|
|
return
|
|
end
|
|
|
|
end
|
|
|
|
local visible_to
|
|
if not in_list(global.automated_forces,entity.force.name) then visible_to = {entity.force} end
|
|
|
|
|
|
local background = silo_data.bar_back
|
|
if not background then
|
|
background = rendering.draw_line
|
|
{
|
|
color = {r = 1, b = 1, g = 1},
|
|
width = 10,
|
|
from = entity,
|
|
from_offset = {-33/32, 1},
|
|
to = entity,
|
|
to_offset = {33/32, 1},
|
|
surface = entity.surface,
|
|
forces = visible_to,
|
|
only_in_alt_mode = global.st_only_in_alt_mode
|
|
}
|
|
silo_data.bar_back = background
|
|
end
|
|
|
|
local progress_bar = silo_data.progress_bar
|
|
if not progress_bar then
|
|
progress_bar = rendering.draw_line
|
|
{
|
|
color = {r = 0, g = 1, b = 0},
|
|
width = 8,
|
|
from = entity,
|
|
from_offset = {-1, 1},
|
|
to = entity,
|
|
to_offset = {1, 1},
|
|
surface = entity.surface,
|
|
forces = visible_to,
|
|
only_in_alt_mode = global.st_only_in_alt_mode
|
|
}
|
|
silo_data.progress_bar = progress_bar
|
|
end
|
|
rendering.set_to(silo_data.progress_bar, entity, {(2 * (progress / max_progress)) - 1, 1})
|
|
|
|
if (entity.is_crafting() and entity.crafting_progress>0 and entity.crafting_progress<1) or (not visible_to) then
|
|
if (entity.energy>0 or (not visible_to)) then
|
|
if (string.find(entity.name, 'stage1') or string.find(entity.name, 'stage3')) then
|
|
if math.random(5)==1 then create_remnants_particles(entity.surface, 8 + math.random(20), get_random_pos_near(entity.position,3),2)
|
|
elseif math.random(3)==1 then create_stone_particles(entity.surface, 8 + math.random(30), get_random_pos_near(entity.position,3),2) end
|
|
end
|
|
for x=1,2 do
|
|
local p = get_random_pos_near(entity.position,2)
|
|
entity.surface.create_trivial_smoke{name='fire-smoke-on-adding-fuel', position=p}
|
|
entity.surface.create_trivial_smoke{name='turbine-smoke', position=p}
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
script.on_nth_tick(ticks_1_s, function (event)
|
|
|
|
for k, silo_data in pairs (global.rsc_silo_under_construction) do
|
|
local silo = silo_data.silo
|
|
if silo and silo.valid then
|
|
check_construction_site(silo_data)
|
|
else
|
|
table.remove (global.rsc_silo_under_construction,k)
|
|
end
|
|
end
|
|
end)
|
|
|
|
|
|
function On_Built(event)
|
|
local ent = event.created_entity
|
|
if not ent then ent = event.entity end
|
|
local sufix = ''
|
|
if ent and ent.valid then
|
|
if string.sub(ent.name,1,15) == 'rsc-silo-stage1' then
|
|
local surface = ent.surface
|
|
local final_building = 'rocket-silo'
|
|
local work_value=global.st_remove_stone_work
|
|
if ent.name == 'rsc-silo-stage1-serlp' then final_building = 'se-rocket-launch-pad' sufix='-serlp'
|
|
elseif ent.name == 'rsc-silo-stage1-sesprs' then final_building = 'se-space-probe-rocket-silo' sufix='-sesprs'
|
|
end
|
|
|
|
-- if space explorarion mod present - if in orbit, then construction starts in stage 4 - no excavation required
|
|
if remote.interfaces["space-exploration"] then
|
|
local Zone = remote.call("space-exploration", "get_zone_from_name", {zone_name = surface.name})
|
|
if Zone then
|
|
local zone_index = Zone.index
|
|
local is_space = remote.call("space-exploration", "get_zone_is_space", {zone_index = zone_index})
|
|
if is_space then
|
|
local position = ent.position
|
|
local force=ent.force
|
|
local player_index=event.player_index
|
|
ent.destroy()
|
|
local stage4 = 'rsc-silo-stage4' .. sufix
|
|
ent=surface.create_entity{name=stage4, force=force, position = position, raise_built=true}
|
|
if player_index then ent.last_user = game.players[player_index] end
|
|
work_value=global.st_insert_material_work
|
|
end
|
|
end
|
|
end
|
|
|
|
local silo_data =
|
|
{
|
|
silo=ent,
|
|
bar_back=nil,
|
|
progress_bar=nil,
|
|
work_value=work_value,
|
|
final_building=final_building
|
|
}
|
|
table.insert (global.rsc_silo_under_construction,silo_data)
|
|
check_construction_site(silo_data)
|
|
if global.st_not_removable_site then ent.minable=false end
|
|
end
|
|
end
|
|
end
|
|
--local build_events = {defines.events.on_built_entity, defines.events.on_robot_built_entity, defines.events.script_raised_built}
|
|
local filters = {{filter = "name", name = "rsc-silo-stage1"}, {filter = "name", name = "rsc-silo-stage1-serlp"}, {filter = "name", name = "rsc-silo-stage1-sesprs"}}
|
|
script.on_event(defines.events.on_built_entity, On_Built, filters)
|
|
script.on_event(defines.events.on_robot_built_entity, On_Built, filters)
|
|
script.on_event(defines.events.script_raised_built, On_Built,filters)
|
|
script.on_event(defines.events.script_raised_revive, On_Built,filters)
|
|
|
|
|
|
|
|
|
|
|
|
function on_entity_cloned(event)
|
|
local destination = event.destination
|
|
local list = {}
|
|
|
|
if string.sub(destination.name,1,14)=='rsc-silo-stage' then
|
|
for k,silo_data in pairs (global.rsc_silo_under_construction) do
|
|
if silo_data.silo == event.source then
|
|
global.rsc_silo_under_construction[k].silo = destination
|
|
global.rsc_silo_under_construction[k].bar_back=nil
|
|
global.rsc_silo_under_construction[k].progress_bar=nil
|
|
break
|
|
end
|
|
end
|
|
end
|
|
end
|
|
script.on_event(defines.events.on_entity_cloned, on_entity_cloned)
|
|
|
|
|
|
|
|
|
|
local function upgrade_silos_now(force_name)
|
|
local tabcopy = table.deepcopy(global.rsc_silo_under_construction)
|
|
local force
|
|
if force_name then force = game.forces[force_name] end
|
|
|
|
for k, silo_data in pairs (tabcopy) do
|
|
if (not force_name) or (force and silo_data.silo.force == force) then
|
|
upgrade_construction_site(silo_data)
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
|
|
|
|
-- INTERFACE --
|
|
--------------------------------------------------------------------------------------
|
|
local interface = {}
|
|
|
|
-- /c remote.call("RocketSiloCon","UpgradeConstruction")
|
|
function interface.UpgradeConstruction()
|
|
upgrade_silos_now()
|
|
end
|
|
-- /c remote.call("RocketSiloCon","UpgradeForceConstruction","player")
|
|
function interface.UpgradeForceConstruction(force_name)
|
|
upgrade_silos_now(force_name)
|
|
end
|
|
|
|
function interface.add_automated_force(force_name)
|
|
add_list(global.automated_forces, force_name)
|
|
end
|
|
|
|
|
|
|
|
--[[ HOW TO subscribe to my custom event:
|
|
script.on_event(remote.call("RocketSiloCon", "get_on_silo_stage_finished"), function(event)
|
|
--do your stuff
|
|
end)
|
|
WARNING: this has to be done within on_init and on_load, otherwise the game will error about the remote.call
|
|
returns {created_entity = new_stage}
|
|
|
|
if your dependency on my mod is optional, remember to check if the remote interface exists before calling it:
|
|
if remote.interfaces["RocketSiloCon"] then
|
|
--interface exists
|
|
end]]
|
|
|
|
function interface.get_on_silo_stage_finished()
|
|
return on_silo_stage_finished
|
|
end
|
|
-- Returns :
|
|
-- event.created_entity = The new entity created (next stage building)
|
|
|
|
remote.add_interface("RocketSiloCon", interface ) |