You've already forked ComfyFactorio
							
							
				mirror of
				https://github.com/ComfyFactory/ComfyFactorio.git
				synced 2025-10-30 23:47:41 +02:00 
			
		
		
		
	Push new map
Infestation island - mini arena per island game where you fight bugs and progress through levels
This commit is contained in:
		| @@ -202,6 +202,9 @@ require 'utils.remote_chunks' | ||||
| --![[Prebuilt buildings on the map that can not be removed, you will hate this map]]-- | ||||
| --require 'maps.spaghettorio' | ||||
|  | ||||
| --![[Infestation Islands]]-- | ||||
| require 'maps.infestation_islands.main' | ||||
|  | ||||
| --![[Misc / WIP]]-- | ||||
| --require 'maps.rainbow_road' | ||||
| --require 'maps.cratewood_forest' | ||||
|   | ||||
| @@ -150,13 +150,13 @@ map_info_main_caption=T E R R I T O R I A L    C O N T R O L | ||||
| map_info_sub_caption=    ..alone in the darkness.. | ||||
| map_info_text=Citizen Log #468-2A-3287, Freelancer Trent. \n\nTo whoever is reading this message, \nAny natural resources are rare and the ones worth while are too hard for me to reach.	\nLuckily, the wrecks yield all kinds of useful scraps, but also various dangers. \nAlmost lost half a leg some days ago while digging out some scrap. \nThe wildlife is extremely aggressive, especially at the time of night.	\nMost of these insect appearing like creatures seem to live underground. \nStay near your light sources, if you want to have a chance of surviving here! \n\n###Log End### | ||||
|  | ||||
| [wip] | ||||
| map_info_main_caption=S T A R S H I P  T R O O P E R S | ||||
| map_info_sub_caption=    ~~ shooty shooty bug bug ~~ | ||||
| map_info_text=Some useful map info here. | ||||
| [infestation_islands] | ||||
| map_info_main_caption=I N F E S T A T I O N  I S L E S | ||||
| map_info_sub_caption=    ~~ clear the swarm, claim the land ~~ | ||||
| map_info_text=You start on a small island infested with biters.\nYour mission is simple: clear the island of all bugs.\n\nOnce secure, head to the market to unlock the next island.\nEach new island will be more dangerous — more bugs, more nests, more chaos.\n\nKill the biters. Unlock the next island. Rinse and repeat.\nOnly when the swarm is wiped out will true victory be achieved.\n\nGood luck, trooper. | ||||
|  | ||||
|  | ||||
| [minesweeper] | ||||
| map_info_main_caption=Minesweeper | ||||
| map_info_sub_caption='' | ||||
| map_info_text=Mechanical lifeforms once dominated this world.\nThey have left long ago, leaving an inhabitable wasteland.\nIt also seems riddled with buried explosives.\n\nMark mines with your stone furnace.\nMarked mines are save to walk on.\nWhen enough mines in an area are marked,\nthey will disarm and yield rewards!\nFaulty marking may trigger surrounding mines!!\n\nAs you move away from spawn,\nmine density and radius required to disarm will increase.\nCrates will contain more loot and ore will have higher yield.\n\nThe paint for the numerics does not work very well with the dirt.\nLaying some stone bricks or better may help.\n | ||||
|  | ||||
|   | ||||
							
								
								
									
										441
									
								
								maps/infestation_islands/buried_biters.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										441
									
								
								maps/infestation_islands/buried_biters.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,441 @@ | ||||
| local Event = require 'utils.event' | ||||
| local Public = require 'maps.infestation_islands.table' | ||||
| local Global = require 'utils.global' | ||||
| local BiterHealthBooster = require 'modules.biter_health_booster_v2' | ||||
| local Server = require 'utils.server' | ||||
|  | ||||
| local this = {} | ||||
|  | ||||
| Global.register( | ||||
| 	this, | ||||
| 	function (t) | ||||
| 		this = t | ||||
| 	end | ||||
| ) | ||||
|  | ||||
| local scale_units_by_health = | ||||
| { | ||||
| 	['small-biter'] = 1, | ||||
| 	['medium-biter'] = 0.75, | ||||
| 	['big-biter'] = 0.5, | ||||
| 	['behemoth-biter'] = 0.25, | ||||
| 	['small-spitter'] = 1, | ||||
| 	['medium-spitter'] = 0.75, | ||||
| 	['big-spitter'] = 0.5, | ||||
| 	['behemoth-spitter'] = 0.25 | ||||
| } | ||||
|  | ||||
| local scale_worms_by_health = | ||||
| { | ||||
| 	['land-mine'] = 0.5, -- not active as of now | ||||
| 	['gun-turret'] = 0.5, -- not active as of now | ||||
| 	['flamethrower-turret'] = 0.4, -- not active as of now | ||||
| 	['artillery-turret'] = 0.25, -- not active as of now | ||||
| 	['small-worm-turret'] = 0.8, | ||||
| 	['medium-worm-turret'] = 0.6, | ||||
| 	['big-worm-turret'] = 0.3, | ||||
| 	['behemoth-worm-turret'] = 0.3 | ||||
| } | ||||
|  | ||||
| local round = math.round | ||||
| local floor = math.floor | ||||
| local random = math.random | ||||
|  | ||||
| local spawn_amount_rolls = {} | ||||
| for a = 48, 1, -1 do | ||||
| 	spawn_amount_rolls[#spawn_amount_rolls + 1] = floor(a ^ 5) | ||||
| end | ||||
|  | ||||
| local random_particles = | ||||
| { | ||||
| 	'dirt-2-stone-particle-medium', | ||||
| 	'dirt-4-dust-particle', | ||||
| 	'coal-particle' | ||||
| } | ||||
|  | ||||
| local s_random_particles = #random_particles | ||||
|  | ||||
| local function create_particles(data) | ||||
| 	local surface = data.surface | ||||
| 	local position = data.position | ||||
| 	local amount = data.amount | ||||
|  | ||||
| 	if not surface or not surface.valid then | ||||
| 		return | ||||
| 	end | ||||
| 	for _ = 1, amount, 1 do | ||||
| 		local m = random(6, 12) | ||||
| 		local m2 = m * 0.005 | ||||
|  | ||||
| 		surface.create_particle( | ||||
| 			{ | ||||
| 				name = random_particles[random(1, s_random_particles)], | ||||
| 				position = position, | ||||
| 				frame_speed = 0.1, | ||||
| 				vertical_speed = 0.1, | ||||
| 				height = 0.1, | ||||
| 				movement = { m2 - (random(0, m) * 0.01), m2 - (random(0, m) * 0.01) } | ||||
| 			} | ||||
| 		) | ||||
| 	end | ||||
| end | ||||
|  | ||||
| local function roll_biter(level) | ||||
| 	if not level or level <= 3 then | ||||
| 		return 'small-biter' | ||||
| 	elseif level <= 6 then | ||||
| 		local choices = { 'small-biter', 'medium-biter' } | ||||
| 		return choices[random(1, #choices)] | ||||
| 	elseif level <= 10 then | ||||
| 		local choices = { 'small-biter', 'medium-biter', 'big-biter' } | ||||
| 		return choices[random(1, #choices)] | ||||
| 	else | ||||
| 		local choices = { 'medium-biter', 'big-biter', 'behemoth-biter' } | ||||
| 		return choices[random(1, #choices)] | ||||
| 	end | ||||
| end | ||||
|  | ||||
| local function roll_worm(level) | ||||
| 	if not level or level <= 3 then | ||||
| 		return 'small-worm-turret' | ||||
| 	elseif level <= 6 then | ||||
| 		local choices = { 'small-worm-turret', 'medium-worm-turret' } | ||||
| 		return choices[random(1, #choices)] | ||||
| 	elseif level <= 10 then | ||||
| 		local choices = { 'small-worm-turret', 'medium-worm-turret', 'big-worm-turret' } | ||||
| 		return choices[random(1, #choices)] | ||||
| 	else | ||||
| 		local choices = { 'medium-worm-turret', 'big-worm-turret', 'behemoth-worm-turret' } | ||||
| 		return choices[random(1, #choices)] | ||||
| 	end | ||||
| end | ||||
|  | ||||
| local function roll_health_boost(level) | ||||
| 	if not level or level <= 3 then | ||||
| 		return 1 | ||||
| 	elseif level <= 6 then | ||||
| 		return 1.5 | ||||
| 	elseif level <= 10 then | ||||
| 		return 2 | ||||
| 	end | ||||
| end | ||||
|  | ||||
| local function spawn_biters(data) | ||||
| 	local alive_enemies = Public.get('alive_enemies') | ||||
| 	local max_biters_per_island = Public.get('max_biters_per_island') | ||||
| 	if alive_enemies >= max_biters_per_island then | ||||
| 		return false | ||||
| 	end | ||||
|  | ||||
| 	local surface = data.surface | ||||
| 	if not (surface and surface.valid) then | ||||
| 		return false | ||||
| 	end | ||||
| 	local current_level = Public.get('current_level') | ||||
|  | ||||
| 	local position = surface.find_non_colliding_position('small-biter', data.position, 10, 1) | ||||
| 	if not position then | ||||
| 		position = data.position | ||||
| 	end | ||||
|  | ||||
| 	local unit_to_create = roll_biter(current_level) | ||||
|  | ||||
| 	if not unit_to_create then | ||||
| 		Server.output_script_data('buried_enemies - unit_to_create was nil?') | ||||
| 		return | ||||
| 	end | ||||
|  | ||||
|  | ||||
| 	local unit = surface.create_entity({ name = unit_to_create, position = position, force = data.force or 'enemy' }) | ||||
| 	if not unit or not unit.valid then | ||||
| 		return | ||||
| 	end | ||||
|  | ||||
| 	Public.set('alive_enemies', alive_enemies + 1) | ||||
|  | ||||
| 	local health_boost = roll_health_boost(current_level) | ||||
|  | ||||
| 	if random(1, 30) == 1 then | ||||
| 		BiterHealthBooster.add_boss_unit(unit, health_boost, 0.38) | ||||
| 	else | ||||
| 		local final_health = round(health_boost * scale_units_by_health[unit.name], 3) | ||||
| 		if final_health < 1 then | ||||
| 			final_health = 1 | ||||
| 		end | ||||
| 		BiterHealthBooster.add_unit(unit, final_health) | ||||
| 	end | ||||
| 	return true | ||||
| end | ||||
|  | ||||
| local function spawn_tech(data) | ||||
| 	local alive_enemies = Public.get('alive_enemies') | ||||
| 	local max_biters_per_island = Public.get('max_biters_per_island') | ||||
| 	if alive_enemies >= max_biters_per_island then | ||||
| 		return false | ||||
| 	end | ||||
|  | ||||
| 	local surface = data.surface | ||||
| 	if not (surface and surface.valid) then | ||||
| 		return false | ||||
| 	end | ||||
| 	local position = surface.find_non_colliding_position('small-biter', data.position, 10, 1) | ||||
| 	if not position then | ||||
| 		position = data.position | ||||
| 	end | ||||
|  | ||||
| 	local current_level = Public.get('current_level') | ||||
|  | ||||
| 	local rand_tech = | ||||
| 	{ | ||||
| 		'defender', | ||||
| 		'destroyer', | ||||
| 		'distractor' | ||||
| 	} | ||||
|  | ||||
| 	local unit_to_create | ||||
|  | ||||
| 	if random(1, 3) == 1 then | ||||
| 		unit_to_create = rand_tech[random(1, #rand_tech)] | ||||
| 	else | ||||
| 		unit_to_create = rand_tech[random(1, #rand_tech)] | ||||
| 	end | ||||
|  | ||||
| 	if not unit_to_create then | ||||
| 		Server.output_script_data('spawn_tech - unit_to_create was nil?') | ||||
| 		return | ||||
| 	end | ||||
|  | ||||
| 	local health_boost = roll_health_boost(current_level) | ||||
|  | ||||
|  | ||||
| 	local unit = surface.create_entity({ name = unit_to_create, position = position, force = data.force or 'enemy' }) | ||||
| 	if not unit or not unit.valid then | ||||
| 		return | ||||
| 	end | ||||
|  | ||||
| 	if random(1, 30) == 1 then | ||||
| 		BiterHealthBooster.add_boss_unit(unit, health_boost, 0.38) | ||||
| 	else | ||||
| 		local final_health = round(health_boost * 0.5, 3) | ||||
| 		if final_health < 1 then | ||||
| 			final_health = 1 | ||||
| 		end | ||||
| 		BiterHealthBooster.add_unit(unit, final_health) | ||||
| 	end | ||||
| 	return true | ||||
| end | ||||
|  | ||||
| local function spawn_worms(data) | ||||
| 	local alive_enemies = Public.get('alive_enemies') | ||||
| 	local max_biters_per_island = Public.get('max_biters_per_island') | ||||
| 	if alive_enemies >= max_biters_per_island then | ||||
| 		return false | ||||
| 	end | ||||
|  | ||||
| 	local current_level = Public.get('current_level') | ||||
| 	local unit_to_create = roll_worm(current_level) | ||||
|  | ||||
| 	if not unit_to_create then | ||||
| 		return false | ||||
| 	end | ||||
|  | ||||
| 	local surface = data.surface | ||||
| 	if not (surface and surface.valid) then | ||||
| 		return false | ||||
| 	end | ||||
| 	local position = surface.find_non_colliding_position('small-worm-turret', data.position, 10, 1) | ||||
| 	if not position then | ||||
| 		position = data.position | ||||
| 	end | ||||
|  | ||||
| 	local unit = surface.create_entity({ name = unit_to_create, position = position }) | ||||
| 	if not unit or not unit.valid then | ||||
| 		return | ||||
| 	end | ||||
|  | ||||
| 	Public.set('alive_enemies', alive_enemies + 1) | ||||
|  | ||||
| 	local health_boost = roll_health_boost(current_level) | ||||
|  | ||||
| 	if random(1, 30) == 1 then | ||||
| 		BiterHealthBooster.add_boss_unit(unit, health_boost, 0.38) | ||||
| 	else | ||||
| 		local final_health = round(health_boost * scale_worms_by_health[unit.name], 3) | ||||
| 		if final_health < 1 then | ||||
| 			final_health = 1 | ||||
| 		end | ||||
|  | ||||
| 		BiterHealthBooster.add_unit(unit, final_health) | ||||
| 	end | ||||
| end | ||||
|  | ||||
| function Public.buried_biter(surface, position, count, force) | ||||
| 	if not (surface and surface.valid) then | ||||
| 		return | ||||
| 	end | ||||
| 	if not position then | ||||
| 		return | ||||
| 	end | ||||
| 	if not position.x then | ||||
| 		return | ||||
| 	end | ||||
| 	if not position.y then | ||||
| 		return | ||||
| 	end | ||||
|  | ||||
| 	if not count then | ||||
| 		count = 1 | ||||
| 	end | ||||
|  | ||||
| 	for t = 1, 60, 1 do | ||||
| 		if not this[game.tick + t] then | ||||
| 			this[game.tick + t] = {} | ||||
| 		end | ||||
|  | ||||
| 		this[game.tick + t][#this[game.tick + t] + 1] = | ||||
| 		{ | ||||
| 			callback = 'create_particles', | ||||
| 			data = { surface = surface, position = { x = position.x, y = position.y }, amount = math.ceil(t * 0.05) } | ||||
| 		} | ||||
|  | ||||
| 		if t == 60 then | ||||
| 			if count == 1 then | ||||
| 				this[game.tick + t][#this[game.tick + t] + 1] = | ||||
| 				{ | ||||
| 					callback = 'spawn_biters', | ||||
| 					data = { surface = surface, position = { x = position.x, y = position.y }, count = count or 1, force = force or 'enemy' } | ||||
| 				} | ||||
| 			else | ||||
| 				local tick = 2 | ||||
| 				for _ = 1, count do | ||||
| 					this[game.tick + t][#this[game.tick + t] + 1 + tick] = | ||||
| 					{ | ||||
| 						callback = 'spawn_biters', | ||||
| 						data = { surface = surface, position = { x = position.x, y = position.y }, count = count or 1, force = force or 'enemy' } | ||||
| 					} | ||||
| 					tick = tick + 2 | ||||
| 				end | ||||
| 			end | ||||
| 		end | ||||
| 	end | ||||
| end | ||||
|  | ||||
| function Public.buried_tech(surface, position, count, force) | ||||
| 	if not (surface and surface.valid) then | ||||
| 		return | ||||
| 	end | ||||
| 	if not position then | ||||
| 		return | ||||
| 	end | ||||
| 	if not position.x then | ||||
| 		return | ||||
| 	end | ||||
| 	if not position.y then | ||||
| 		return | ||||
| 	end | ||||
|  | ||||
| 	if not count then | ||||
| 		count = 1 | ||||
| 	end | ||||
|  | ||||
| 	for t = 1, 60, 1 do | ||||
| 		if not this[game.tick + t] then | ||||
| 			this[game.tick + t] = {} | ||||
| 		end | ||||
|  | ||||
| 		this[game.tick + t][#this[game.tick + t] + 1] = | ||||
| 		{ | ||||
| 			callback = 'create_particles', | ||||
| 			data = { surface = surface, position = { x = position.x, y = position.y }, amount = math.ceil(t * 0.05) } | ||||
| 		} | ||||
|  | ||||
| 		if t == 60 then | ||||
| 			if count == 1 then | ||||
| 				this[game.tick + t][#this[game.tick + t] + 1] = | ||||
| 				{ | ||||
| 					callback = 'spawn_tech', | ||||
| 					data = { surface = surface, position = { x = position.x, y = position.y }, count = count or 1, force = force or 'enemy' } | ||||
| 				} | ||||
| 			else | ||||
| 				local tick = 2 | ||||
| 				for _ = 1, count do | ||||
| 					this[game.tick + t][#this[game.tick + t] + 1 + tick] = | ||||
| 					{ | ||||
| 						callback = 'spawn_tech', | ||||
| 						data = { surface = surface, position = { x = position.x, y = position.y }, count = count or 1, force = force or 'enemy' } | ||||
| 					} | ||||
| 					tick = tick + 2 | ||||
| 				end | ||||
| 			end | ||||
| 		end | ||||
| 	end | ||||
| end | ||||
|  | ||||
| function Public.buried_worm(surface, position) | ||||
| 	if not (surface and surface.valid) then | ||||
| 		return | ||||
| 	end | ||||
| 	if not position then | ||||
| 		return | ||||
| 	end | ||||
| 	if not position.x then | ||||
| 		return | ||||
| 	end | ||||
| 	if not position.y then | ||||
| 		return | ||||
| 	end | ||||
|  | ||||
| 	for t = 1, 60, 1 do | ||||
| 		if not this[game.tick + t] then | ||||
| 			this[game.tick + t] = {} | ||||
| 		end | ||||
|  | ||||
| 		this[game.tick + t][#this[game.tick + t] + 1] = | ||||
| 		{ | ||||
| 			callback = 'create_particles', | ||||
| 			data = { surface = surface, position = { x = position.x, y = position.y }, amount = math.ceil(t * 0.05) } | ||||
| 		} | ||||
|  | ||||
| 		if t == 60 then | ||||
| 			this[game.tick + t][#this[game.tick + t] + 1] = | ||||
| 			{ | ||||
| 				callback = 'spawn_worms', | ||||
| 				data = { surface = surface, position = { x = position.x, y = position.y } } | ||||
| 			} | ||||
| 		end | ||||
| 	end | ||||
| end | ||||
|  | ||||
| local callbacks = | ||||
| { | ||||
| 	['create_particles'] = create_particles, | ||||
| 	['spawn_biters'] = spawn_biters, | ||||
| 	['spawn_worms'] = spawn_worms, | ||||
| 	['spawn_tech'] = spawn_tech | ||||
| } | ||||
|  | ||||
| local function on_tick() | ||||
| 	local t = game.tick | ||||
| 	if not this[t] then | ||||
| 		return | ||||
| 	end | ||||
| 	for _, token in pairs(this[t]) do | ||||
| 		local callback = token.callback | ||||
| 		local data = token.data | ||||
| 		local cbl = callbacks[callback] | ||||
| 		if callbacks[callback] then | ||||
| 			cbl(data) | ||||
| 		end | ||||
| 	end | ||||
| 	this[t] = nil | ||||
| end | ||||
|  | ||||
| function Public.reset_buried_biters() | ||||
| 	for k, _ in pairs(this) do | ||||
| 		this[k] = nil | ||||
| 	end | ||||
| end | ||||
|  | ||||
| Event.add(defines.events.on_tick, on_tick) | ||||
|  | ||||
| return Public | ||||
							
								
								
									
										1250
									
								
								maps/infestation_islands/func.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1250
									
								
								maps/infestation_islands/func.lua
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										340
									
								
								maps/infestation_islands/main.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										340
									
								
								maps/infestation_islands/main.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,340 @@ | ||||
| --created by Gerkiz | ||||
| local Public = require 'maps.infestation_islands.table' | ||||
| local Event = require 'utils.event' | ||||
| local Func = require 'maps.infestation_islands.func' | ||||
| local Map = require 'modules.map_info' | ||||
| local Task = require 'utils.task_token' | ||||
| local Scheduler = require 'utils.scheduler' | ||||
|  | ||||
| local set_gamestate_token = | ||||
|     Task.register( | ||||
|         function () | ||||
|             local this = Public.get() | ||||
|             this.gamestate = 1 | ||||
|         end | ||||
|     ) | ||||
|  | ||||
| local reset_players_token = | ||||
|     Task.register( | ||||
|         function () | ||||
|             local surface = game.get_surface(1) | ||||
|  | ||||
|             for _, f in pairs(game.forces) do | ||||
|                 f.reset() | ||||
|                 f.clear_chart(surface) | ||||
|                 f.reset_evolution() | ||||
|             end | ||||
|             for _, tech in pairs(game.forces.player.technologies) do | ||||
|                 tech.researched = false | ||||
|                 tech.saved_progress = 0 | ||||
|             end | ||||
|  | ||||
|             local players = game.connected_players | ||||
|             for i = 1, #players do | ||||
|                 local player = players[i] | ||||
|                 player.set_controller { type = defines.controllers.god } | ||||
|                 player.create_character() | ||||
|                 player.insert({ name = 'raw-fish', count = 3 }) | ||||
|                 player.insert({ name = 'grenade', count = 1 }) | ||||
|                 player.insert({ name = 'iron-plate', count = 16 }) | ||||
|                 player.insert({ name = 'iron-gear-wheel', count = 8 }) | ||||
|                 player.insert({ name = 'stone', count = 5 }) | ||||
|                 player.insert({ name = 'pistol', count = 1 }) | ||||
|                 player.insert({ name = 'firearm-magazine', count = 16 }) | ||||
|  | ||||
|                 local p = surface.find_non_colliding_position('character', { 0, 2 }, 8, 0.5) | ||||
|                 if not p then | ||||
|                     player.teleport({ 0, 2 }, surface) | ||||
|                 else | ||||
|                     player.teleport(p, surface) | ||||
|                 end | ||||
|             end | ||||
|         end | ||||
|     ) | ||||
|  | ||||
| local function create_stage_gui(player) | ||||
|     if player.gui.top.stage_gui then | ||||
|         return | ||||
|     end | ||||
|     local element = player.gui.top.add({ type = 'frame', name = 'stage_gui', caption = ' ' }) | ||||
|     local style = element.style | ||||
|     style.minimal_height = 54 | ||||
|     style.maximal_height = 54 | ||||
|     style.minimal_width = 140 | ||||
|     style.maximal_width = 420 | ||||
|     style.top_padding = 12 | ||||
|     style.left_padding = 4 | ||||
|     style.right_padding = 4 | ||||
|     style.bottom_padding = 2 | ||||
|     style.font_color = { r = 155, g = 85, b = 25 } | ||||
|     style.font = 'default-large-bold' | ||||
| end | ||||
|  | ||||
| local function update_stage_gui(caption_override) | ||||
|     local this = Public.get() | ||||
|     if not this.stages then | ||||
|         return | ||||
|     end | ||||
|     local caption = 'Level: ' .. this.current_level | ||||
|     caption = caption .. '  |  Stage: ' | ||||
|     local stage = this.current_stage | ||||
|     if stage > #this.stages - 1 then | ||||
|         stage = #this.stages - 1 | ||||
|     end | ||||
|     caption = caption .. stage | ||||
|     caption = caption .. '/' | ||||
|     caption = caption .. #this.stages - 1 | ||||
|     caption = caption .. '  |  Bugs remaining: ' | ||||
|     caption = caption .. this.alive_enemies | ||||
|  | ||||
|  | ||||
|     for _, player in pairs(game.connected_players) do | ||||
|         if player.gui.top.stage_gui then | ||||
|             player.gui.top.stage_gui.caption = caption_override or caption | ||||
|             player.gui.top.stage_gui.tooltip = 'Max biter count: ' .. this.max_biters_per_island | ||||
|         end | ||||
|     end | ||||
| end | ||||
|  | ||||
| local function bring_players() | ||||
|     local surface = game.surfaces[1] | ||||
|     for _, player in pairs(game.connected_players) do | ||||
|         if player.position.y < -1 then | ||||
|             if player.character then | ||||
|                 if player.character.valid then | ||||
|                     local p = surface.find_non_colliding_position('character', { 0, 2 }, 8, 0.5) | ||||
|                     if not p then | ||||
|                         player.teleport({ 0, 2 }, surface) | ||||
|                     else | ||||
|                         player.teleport(p, surface) | ||||
|                     end | ||||
|                 end | ||||
|             end | ||||
|         end | ||||
|     end | ||||
|     local this = Public.get() | ||||
|     this.gamestate = 2 | ||||
| end | ||||
|  | ||||
| local function drift_corpses_toward_beach() | ||||
|     local surface = game.surfaces[1] | ||||
|     for _, corpse in pairs(surface.find_entities_filtered({ name = 'character-corpse' })) do | ||||
|         if corpse.position.y < 0 then | ||||
|             if surface.get_tile(corpse.position.x, corpse.position.y).collides_with('resource') then | ||||
|                 corpse.clone | ||||
|                 { | ||||
|                     position = { corpse.position.x, corpse.position.y + (math.random(50, 250) * 0.01) }, | ||||
|                     surface = surface, | ||||
|                     force = corpse.force.name | ||||
|                 } | ||||
|                 corpse.destroy() | ||||
|             end | ||||
|         end | ||||
|     end | ||||
| end | ||||
|  | ||||
| local function clear_surface() | ||||
|     local surface = game.get_surface(1) | ||||
|     surface.clear() | ||||
| end | ||||
|  | ||||
| local function on_player_joined_game(event) | ||||
|     local player = game.players[event.player_index] | ||||
|     create_stage_gui(player) | ||||
|  | ||||
|     update_stage_gui() | ||||
|  | ||||
|     if player.online_time == 0 then | ||||
|         player.insert({ name = 'raw-fish', count = 3 }) | ||||
|         player.insert({ name = 'grenade', count = 1 }) | ||||
|         player.insert({ name = 'iron-plate', count = 16 }) | ||||
|         player.insert({ name = 'iron-gear-wheel', count = 8 }) | ||||
|         player.insert({ name = 'stone', count = 5 }) | ||||
|         player.insert({ name = 'pistol', count = 1 }) | ||||
|         player.insert({ name = 'firearm-magazine', count = 16 }) | ||||
|         return | ||||
|     end | ||||
| end | ||||
|  | ||||
| local function on_init() | ||||
|     local storage = Public.get() | ||||
|     for index, _ in pairs(storage) do | ||||
|         storage[index] = nil | ||||
|     end | ||||
|     local T = Map.Pop_info() | ||||
|     T.localised_category = 'infestation_islands' | ||||
|     T.main_caption_color = { r = 150, g = 150, b = 0 } | ||||
|     T.sub_caption_color = { r = 0, g = 150, b = 0 } | ||||
|  | ||||
|     Scheduler.can_run_scheduler(true) | ||||
|  | ||||
|     local this = Public.get() | ||||
|  | ||||
|     this.game_lost = false | ||||
|  | ||||
|     local surface = game.surfaces[1] | ||||
|     surface.request_to_generate_chunks({ x = 0, y = 0 }, 6) | ||||
|  | ||||
|     local mgs = game.surfaces[1].map_gen_settings | ||||
|     mgs.water = 9.9 | ||||
|     mgs.property_expression_names = | ||||
|     { | ||||
|         ['control-setting:aux:bias'] = '0.500000', | ||||
|         ['control-setting:aux:frequency:multiplier'] = '6.000000', | ||||
|         ['control-setting:moisture:bias'] = '-0.050000', | ||||
|         ['control-setting:moisture:frequency:multiplier'] = '6.000000', | ||||
|     } | ||||
|     game.surfaces[1].map_gen_settings = mgs | ||||
|  | ||||
|     local blacklist = | ||||
|     { | ||||
|         ['dark-mud-decal'] = true, | ||||
|         ['sand-dune-decal'] = true, | ||||
|         ['light-mud-decal'] = true, | ||||
|         ['puberty-decal'] = true, | ||||
|         ['sand-decal'] = true, | ||||
|         ['red-desert-decal'] = true | ||||
|     } | ||||
|     this.decorative_names = {} | ||||
|     for k, v in pairs(prototypes.decorative) do | ||||
|         if not blacklist[k] then | ||||
|             if v.autoplace_specification then | ||||
|                 this.decorative_names[#this.decorative_names + 1] = k | ||||
|             end | ||||
|         end | ||||
|     end | ||||
|  | ||||
|     local tree_raffle = {} | ||||
|     for _, e in pairs(prototypes.entity) do | ||||
|         if e.type == 'tree' then | ||||
|             table.insert(tree_raffle, e.name) | ||||
|         end | ||||
|     end | ||||
|  | ||||
|     this.tree_raffle = tree_raffle | ||||
|  | ||||
|     local corpses_raffle = {} | ||||
|     for _, e in pairs(prototypes.entity) do | ||||
|         if e.type == 'corpse' then | ||||
|             table.insert(corpses_raffle, e.name) | ||||
|         end | ||||
|     end | ||||
|  | ||||
|     this.corpses_raffle = corpses_raffle | ||||
|  | ||||
|     this.stages = {} | ||||
|     local island_level = 12 | ||||
|     for _ = 1, 30 do | ||||
|         this.stages[#this.stages + 1] = | ||||
|         { | ||||
|             size = 16 + (32 + island_level) * 1.5 | ||||
|         } | ||||
|         island_level = island_level + 5 | ||||
|     end | ||||
|  | ||||
|     this.stages[#this.stages].final = true | ||||
|  | ||||
|     this.level_vectors = {} | ||||
|     this.alive_boss_enemy_entities = {} | ||||
|     this.current_level = 0 | ||||
|     this.gamestate = 0 | ||||
|     Task.set_timeout_in_ticks(30, set_gamestate_token) | ||||
|  | ||||
|     game.forces.player.set_spawn_position({ 0, 2 }, surface) | ||||
|  | ||||
|     this.alive_enemies = 0 | ||||
|     this.alive_boss_enemy_count = 0 | ||||
|  | ||||
|     this.current_level = this.current_level + 1 | ||||
|     this.current_stage = 1 | ||||
|  | ||||
|     this.completed_levels = {} | ||||
|  | ||||
|     this.market_positions = {} | ||||
|  | ||||
|     this.centered_points = {} | ||||
|  | ||||
|     this.tiles = {} | ||||
|  | ||||
|     this.spawned_markets = {} | ||||
|  | ||||
|     this.path_tiles = nil | ||||
|  | ||||
|     this.max_biters_per_island = 150 | ||||
|  | ||||
|     this.seeds = nil | ||||
|  | ||||
|     this.nomed_marked = nil | ||||
|  | ||||
|     Func.reset_buried_biters() | ||||
|  | ||||
|     Func.generate_decoratives() | ||||
|  | ||||
|     game.forces['player'].technologies['landfill'].enabled = false | ||||
|     game.forces['player'].technologies['night-vision-equipment'].enabled = false | ||||
|     game.forces['player'].technologies['artillery-shell-range-1'].enabled = false | ||||
|     game.forces['player'].technologies['artillery-shell-speed-1'].enabled = false | ||||
|     game.forces['player'].technologies['artillery'].enabled = false | ||||
|     game.forces['player'].technologies['atomic-bomb'].enabled = false | ||||
| end | ||||
|  | ||||
| local gamestate_functions = | ||||
| { | ||||
|     [1] = bring_players, | ||||
|     [2] = Func.draw_main_island, | ||||
| } | ||||
|  | ||||
| local function on_tick() | ||||
|     local this = Public.get() | ||||
|     if game.tick % 25 == 0 and gamestate_functions[this.gamestate] then | ||||
|         gamestate_functions[this.gamestate]() | ||||
|     end | ||||
|     if game.tick % 25 == 0 then | ||||
|         if this.alive_enemies < 0 then this.alive_enemies = 0 end | ||||
|         if this.game_lost then | ||||
|             local message = this.nomed_marked and 'The bugs had a feast on the marked at level ' .. this.nomed_marked .. '!' or 'The bugs had a feast on the marked!' | ||||
|             update_stage_gui(message) | ||||
|         else | ||||
|             update_stage_gui() | ||||
|         end | ||||
|     end | ||||
|     if game.tick % 150 == 0 then | ||||
|         drift_corpses_toward_beach() | ||||
|         if this.infini_chest and this.infini_chest.valid then | ||||
|             if this.current_level > 0 and this.current_level <= 10 then | ||||
|                 this.infini_chest.insert({ name = 'firearm-magazine', count = 1 }) | ||||
|             elseif this.current_level > 10 then | ||||
|                 this.infini_chest.insert({ name = 'piercing-rounds-magazine', count = 1 }) | ||||
|             end | ||||
|         end | ||||
|     end | ||||
|  | ||||
|     if game.tick % 200 == 0 then | ||||
|         if this.game_lost then return end | ||||
|         if this.completed_levels[this.current_level] then | ||||
|             return | ||||
|         end | ||||
|  | ||||
|         Func.do_buried_biters() | ||||
|     end | ||||
|  | ||||
|  | ||||
|     if this.game_lost and this.game_reset_tick then | ||||
|         this.game_reset_tick = this.game_reset_tick - 1 | ||||
|         if this.game_reset_tick % 600 == 0 then | ||||
|             game.print('Game will reset in ' .. this.game_reset_tick / 60 .. ' seconds!', { color = { r = 0.22, g = 0.88, b = 0.22 } }) | ||||
|         end | ||||
|         if this.game_reset_tick <= 0 then | ||||
|             this.game_reset_tick = nil | ||||
|             this.game_lost = false | ||||
|             Scheduler.can_run_scheduler(false) | ||||
|             clear_surface() | ||||
|             on_init() | ||||
|             Task.set_timeout_in_ticks(500, reset_players_token) | ||||
|         end | ||||
|     end | ||||
| end | ||||
|  | ||||
| Event.on_init(on_init) | ||||
| Event.add(defines.events.on_tick, on_tick) | ||||
| Event.add(defines.events.on_player_joined_game, on_player_joined_game) | ||||
							
								
								
									
										58
									
								
								maps/infestation_islands/table.lua
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								maps/infestation_islands/table.lua
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,58 @@ | ||||
| -- one table to rule them all! | ||||
| local Global = require 'utils.global' | ||||
| local Event = require 'utils.event' | ||||
|  | ||||
| local this = | ||||
| { | ||||
| } | ||||
|  | ||||
| local Public = {} | ||||
|  | ||||
| Global.register( | ||||
|     this, | ||||
|     function (tbl) | ||||
|         this = tbl | ||||
|     end | ||||
| ) | ||||
|  | ||||
| function Public.reset_main_table() | ||||
| end | ||||
|  | ||||
| function Public.get(key) | ||||
|     if key then | ||||
|         return this[key] | ||||
|     else | ||||
|         return this | ||||
|     end | ||||
| end | ||||
|  | ||||
| function Public.is_game_lost() | ||||
|     return this.storage.game_lost or false | ||||
| end | ||||
|  | ||||
| function Public.set(key, value) | ||||
|     if key and (value or value == false) then | ||||
|         this[key] = value | ||||
|         return this[key] | ||||
|     elseif key then | ||||
|         return this[key] | ||||
|     else | ||||
|         return this | ||||
|     end | ||||
| end | ||||
|  | ||||
| function Public.remove(key, sub_key) | ||||
|     if key and sub_key then | ||||
|         if this[key] and this[key][sub_key] then | ||||
|             this[key][sub_key] = nil | ||||
|         end | ||||
|     elseif key then | ||||
|         if this[key] then | ||||
|             this[key] = nil | ||||
|         end | ||||
|     end | ||||
| end | ||||
|  | ||||
| Event.on_init(Public.reset_main_table) | ||||
|  | ||||
| return Public | ||||
		Reference in New Issue
	
	Block a user