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 ) |