--factorio cave miner - mewmew made this - it is free to use, modify and enjoy
--set map setting: biter bases - high, very big
--do /market to spawn the market at map start

--[[ 
To do(maybe):
disable flashlight at join and after death
]]--

local simplex_noise = require 'map_gen.shared.simplex_noise'
local Event = require 'utils.event'

local function find_tile_placement_spot_around_target_position(tilename, position, mode, density)
	local x = position.x
	local y = position.y
	if not surface then surface = game.surfaces[1] end
	local scan_radius = 50
	if not tilename then return end
	if not mode then mode = "ball" end
	if not density then density = 1 end
	local cluster_tiles = {}
	local auto_correct = true
	
	local scanned_tile = surface.get_tile(x,y)
	if scanned_tile.name ~= tilename then
		table.insert(cluster_tiles, {name = tilename, position = {x,y}})
		surface.set_tiles(cluster_tiles,auto_correct)
		return true, x, y
	end
	
	local i = 2
	local r = 1		
	
	if mode == "ball" then
		if math.random(1,2) == 1 then 
			density = density * -1
		end
		r = math.random(1,4)
	end
	if mode == "line" then
		density = 1
		r = math.random(1,4)
	end
	if mode == "line_down" then
		density = density * -1
		r = math.random(1,4)
	end
	if mode == "line_up" then
		density = 1
		r = math.random(1,4)
	end
	if mode == "block" then
		r = 1
		density = 1
	end	
	
	if r == 1 then
		--start placing at -1,-1
		while i <= scan_radius do
			y = y - density						
			x = x - density				
			for a = 1, i, 1 do				
				local scanned_tile = surface.get_tile(x,y)				
				if scanned_tile.name ~= tilename then	
					table.insert(cluster_tiles, {name = tilename, position = {x,y}})
					surface.set_tiles(cluster_tiles,auto_correct)
					return true, x, y
				end
				x = x + density
			end		
			for a = 1, i, 1 do				
				local scanned_tile = surface.get_tile(x,y)
				if scanned_tile.name ~= tilename then	
					table.insert(cluster_tiles, {name = tilename, position = {x,y}})
					surface.set_tiles(cluster_tiles,auto_correct)
					return true, x, y
				end
				y = y + density
			end		
			for a = 1, i, 1 do				
				local scanned_tile = surface.get_tile(x,y)
				if scanned_tile.name ~= tilename then	
					table.insert(cluster_tiles, {name = tilename, position = {x,y}})
					surface.set_tiles(cluster_tiles,auto_correct)
					return true, x, y
				end
				x = x - density
			end		
			for a = 1, i, 1 do				
				local scanned_tile = surface.get_tile(x,y)
				if scanned_tile.name ~= tilename then	
					table.insert(cluster_tiles, {name = tilename, position = {x,y}})
					surface.set_tiles(cluster_tiles,auto_correct)
					return true, x, y
				end
				y = y - density
			end			
			i = i + 2
		end
	end
		
	if r == 2 then
		--start placing at 0,-1
		while i <= scan_radius do
			y = y - density						
			x = x - density
			for a = 1, i, 1 do
				x = x + density
				local scanned_tile = surface.get_tile(x,y)
				if scanned_tile.name ~= tilename then	
					table.insert(cluster_tiles, {name = tilename, position = {x,y}})
					surface.set_tiles(cluster_tiles,auto_correct)
					return true, x, y
				end
			end		
			for a = 1, i, 1 do
				y = y + density
				local scanned_tile = surface.get_tile(x,y)
				if scanned_tile.name ~= tilename then	
					table.insert(cluster_tiles, {name = tilename, position = {x,y}})
					surface.set_tiles(cluster_tiles,auto_correct)
					return true, x, y
				end
			end		
			for a = 1, i, 1 do
				x = x - density
				local scanned_tile = surface.get_tile(x,y)
				if scanned_tile.name ~= tilename then	
					table.insert(cluster_tiles, {name = tilename, position = {x,y}})
					surface.set_tiles(cluster_tiles,auto_correct)
					return true, x, y
				end
			end		
			for a = 1, i, 1 do
				y = y - density
				local scanned_tile = surface.get_tile(x,y)
				if scanned_tile.name ~= tilename then	
					table.insert(cluster_tiles, {name = tilename, position = {x,y}})
					surface.set_tiles(cluster_tiles,auto_correct)
					return true, x, y
				end
			end		
			i = i + 2
		end
	end
	
	if r == 3 then
		--start placing at 1,-1
		while i <= scan_radius do
			y = y - density						
			x = x + density								
			for a = 1, i, 1 do				
				local scanned_tile = surface.get_tile(x,y)
				if scanned_tile.name ~= tilename then	
					table.insert(cluster_tiles, {name = tilename, position = {x,y}})
					surface.set_tiles(cluster_tiles,auto_correct)
					return true, x, y
				end
				y = y + density
			end		
			for a = 1, i, 1 do				
				local scanned_tile = surface.get_tile(x,y)
				if scanned_tile.name ~= tilename then	
					table.insert(cluster_tiles, {name = tilename, position = {x,y}})
					surface.set_tiles(cluster_tiles,auto_correct)
					return true, x, y
				end
				x = x - density
			end		
			for a = 1, i, 1 do				
				local scanned_tile = surface.get_tile(x,y)
				if scanned_tile.name ~= tilename then	
					table.insert(cluster_tiles, {name = tilename, position = {x,y}})
					surface.set_tiles(cluster_tiles,auto_correct)
					return true, x, y
				end
				y = y - density
			end
			for a = 1, i, 1 do				
				local scanned_tile = surface.get_tile(x,y)
				if scanned_tile.name ~= tilename then	
					table.insert(cluster_tiles, {name = tilename, position = {x,y}})
					surface.set_tiles(cluster_tiles,auto_correct)
					return true, x, y
				end
				x = x + density
			end				
			i = i + 2
		end
	end
	
	if r == 4 then
		--start placing at 1,0
		while i <= scan_radius do
			y = y - density
			x = x + density				
			for a = 1, i, 1 do
				y = y + density
				local scanned_tile = surface.get_tile(x,y)
				if scanned_tile.name ~= tilename then	
					table.insert(cluster_tiles, {name = tilename, position = {x,y}})
					surface.set_tiles(cluster_tiles,auto_correct)
					return true, x, y
				end
			end		
			for a = 1, i, 1 do
				x = x - density
				local scanned_tile = surface.get_tile(x,y)
				if scanned_tile.name ~= tilename then	
					table.insert(cluster_tiles, {name = tilename, position = {x,y}})
					surface.set_tiles(cluster_tiles,auto_correct)
					return true, x, y
				end
			end		
			for a = 1, i, 1 do
				y = y - density
				local scanned_tile = surface.get_tile(x,y)
				if scanned_tile.name ~= tilename then	
					table.insert(cluster_tiles, {name = tilename, position = {x,y}})
					surface.set_tiles(cluster_tiles,auto_correct)
					return true, x, y
				end
			end
			for a = 1, i, 1 do
				x = x + density
				local scanned_tile = surface.get_tile(x,y)
				if scanned_tile.name ~= tilename then	
					table.insert(cluster_tiles, {name = tilename, position = {x,y}})
					surface.set_tiles(cluster_tiles,auto_correct)
					return true, x, y
				end
			end			
			i = i + 2
		end
	end	
	return false
end

local function create_tile_cluster(tilename,position,amount)
	local mode = "ball"
	local cluster_tiles = {}
	local surface = game.surfaces[1]
	local pos = position
	local x = pos.x
	local y = pos.y
	for i = 1, amount, 1 do
		local b,x,y = find_tile_placement_spot_around_target_position(tilename, pos, mode)
		if b == true then						
			if 1 == math.random(1,16) then
				pos.x = x
				pos.y = y
			end			
		end
		if b == false then return false,x,y end
		if i >= amount then return true,x,y end
	end		
end

local function on_chunk_generated(event)
	if not global.noise_seed then global.noise_seed = math.random(1,5000000) end
	if not global.spawn_dome_size then global.spawn_dome_size = 20000 end
	local surface = game.surfaces[1]	
	local noise = {}
	local tiles = {}	
	local enemy_buildings = {}
	local rock_positions = {}
	local extra_tree_positions = {}
	local tile_to_insert = false
	local entity_has_been_placed = false
	local pos_x = 0
	local pos_y = 0
	local tile_distance_to_center = 0			
	local entities = surface.find_entities(event.area)
	for _, e in pairs(entities) do
		if e.type == "resource" or e.type == "tree" then
			e.destroy()				
		else
			if e.name == "biter-spawner" or e.name == "spitter-spawner" then
				table.insert(enemy_buildings, e.position)					
			end
		end
	end	
	local noise_seed_add = 25000
	local current_noise_seed_add = noise_seed_add	
	local m1 = 0.12
	local m2 = 0.10
	local m3 = 0.07
	
	for x = 0, 31, 1 do
		for y = 0, 31, 1 do			
			pos_x = event.area.left_top.x + x
			pos_y = event.area.left_top.y + y
			tile_distance_to_center = pos_x^2 + pos_y^2
									
			noise[1] = simplex_noise.d2(pos_x/350, pos_y/350,global.noise_seed+current_noise_seed_add)
			current_noise_seed_add = current_noise_seed_add + noise_seed_add
			noise[2] = simplex_noise.d2(pos_x/200, pos_y/200,global.noise_seed+current_noise_seed_add)
			current_noise_seed_add = current_noise_seed_add + noise_seed_add
			noise[3] = simplex_noise.d2(pos_x/50, pos_y/50,global.noise_seed+current_noise_seed_add)
			current_noise_seed_add = current_noise_seed_add + noise_seed_add
			noise[4] = simplex_noise.d2(pos_x/20, pos_y/20,global.noise_seed+current_noise_seed_add)
			current_noise_seed_add = current_noise_seed_add + noise_seed_add			
			local cave_noise = noise[1] + noise[2]*0.3 + noise[3]*0.1 + noise[4]*0.02
			
			noise[1] = simplex_noise.d2(pos_x/120, pos_y/120,global.noise_seed+current_noise_seed_add)
			current_noise_seed_add = current_noise_seed_add + noise_seed_add
			noise[2] = simplex_noise.d2(pos_x/60, pos_y/60,global.noise_seed+current_noise_seed_add)
			current_noise_seed_add = current_noise_seed_add + noise_seed_add
			noise[3] = simplex_noise.d2(pos_x/40, pos_y/40,global.noise_seed+current_noise_seed_add)
			current_noise_seed_add = current_noise_seed_add + noise_seed_add
			noise[4] = simplex_noise.d2(pos_x/20, pos_y/20,global.noise_seed+current_noise_seed_add)
			current_noise_seed_add = current_noise_seed_add + noise_seed_add			
			local cave_noise_2 = noise[1] + noise[2]*0.4 + noise[3]*0.25 + noise[4]*0.1
			
			noise[1] = simplex_noise.d2(pos_x/50, pos_y/50,global.noise_seed+current_noise_seed_add)
			current_noise_seed_add = current_noise_seed_add + noise_seed_add
			noise[2] = simplex_noise.d2(pos_x/30, pos_y/30,global.noise_seed+current_noise_seed_add)
			current_noise_seed_add = current_noise_seed_add + noise_seed_add
			noise[3] = simplex_noise.d2(pos_x/20, pos_y/20,global.noise_seed+current_noise_seed_add)
			current_noise_seed_add = current_noise_seed_add + noise_seed_add
			noise[4] = simplex_noise.d2(pos_x/10, pos_y/10,global.noise_seed+current_noise_seed_add)
			current_noise_seed_add = current_noise_seed_add + noise_seed_add			
			local cave_noise_3 = noise[1] + noise[2]*0.5 + noise[3]*0.25 + noise[4]*0.1
			
			current_noise_seed_add = noise_seed_add	
			
			tile_to_insert = false	
			if tile_distance_to_center > global.spawn_dome_size then												
			
				if tile_distance_to_center > (global.spawn_dome_size + 5000) * (cave_noise_3 * 0.05 + 1.1) then
					if cave_noise > 1 then
						tile_to_insert = "deepwater"
					else
						if cave_noise > 0.98 then 
							tile_to_insert = "water"
						else
							if cave_noise > 0.82 then
								tile_to_insert = "grass-1"
								--tile_to_insert = "grass-4"
								--if cave_noise > 0.88 then tile_to_insert = "grass-2" end
								if cave_noise > 0.94 then
									table.insert(extra_tree_positions, {pos_x,pos_y})									
								end								
							else
								if cave_noise > 0.72 then
									tile_to_insert = "dirt-6"
									if cave_noise < 0.79 then table.insert(rock_positions, {pos_x,pos_y}) end
								end
							end
						end
					end
				end
				
				if tile_to_insert == false then
					if cave_noise < m1 and cave_noise > m1*-1 then
						tile_to_insert = "dirt-7"
						if math.random(1,1000) == 1 then
							local p = surface.find_non_colliding_position("crude-oil",{pos_x,pos_y}, 5,1)
							local e = surface.create_entity {name="crude-oil", position={pos_x,pos_y}, amount=math.random(50000,2000000)}
						end
					else
						if cave_noise_2 < m2 and cave_noise_2 > m2*-1 and cave_noise > (m2*-1) - 0.3 then
							tile_to_insert = "dirt-4"
						else
							if cave_noise_3 < m3 and cave_noise_3 > m3*-1 and cave_noise_2 < m2+0.3 and cave_noise_2 > (m2*-1)-0.3 then
								tile_to_insert = "dirt-2"
							end
						end
					end
				end
				
				if tile_distance_to_center < global.spawn_dome_size * (cave_noise_3 * 0.05 + 1.1)  then									
					tile_to_insert = "dirt-7"
				end
			else				
				tile_to_insert = "grass-1"
			end
			
			if tile_distance_to_center < global.spawn_dome_size and tile_distance_to_center > global.spawn_dome_size - 500 and tile_to_insert == "grass-1" then
				table.insert(rock_positions, {pos_x,pos_y})	
			end			
			if tile_to_insert == "dirt-7" or tile_to_insert == "dirt-4" or tile_to_insert == "dirt-2" then	
				 table.insert(rock_positions, {pos_x,pos_y})				
			end
			
			if tile_to_insert == false then
				table.insert(tiles, {name = "out-of-map", position = {pos_x,pos_y}}) 
			else
				table.insert(tiles, {name = tile_to_insert, position = {pos_x,pos_y}}) 
			end
		end							
	end
	surface.set_tiles(tiles,true)
	
	for _, p in pairs(extra_tree_positions) do	
		if math.random(1,20)==1 then 
			surface.create_entity {name="tree-02",position=p}
		end
	end
	
	for _, p in pairs(rock_positions) do	
		if math.random(1,5)==1 then 
			surface.create_entity {name="rock-huge",position=p}
		else
			if math.random(1,5)==1 then 
				surface.create_entity {name="rock-big",position=p}
			else
				if math.random(1,5)==1 then 
				surface.create_entity {name="sand-rock-big",position=p}
				end
			end
		end		
	end
	
	for _, p in pairs(enemy_buildings) do	
		local entities = surface.find_entities({{p.x-4, p.y-4}, {p.x+4, p.y+4}})			
		for _, e in pairs(entities) do			
			if e.name == "rock-huge" or e.name == "rock-big" or e.name == "sand-rock-big" then
				e.destroy()			
			end			
		end
		local entities = surface.find_entities({{p.x-5, p.y-3}, {p.x+5, p.y+3}})			
		for _, e in pairs(entities) do			
			if e.name == "rock-huge" or e.name == "rock-big" or e.name == "sand-rock-big" then
				e.destroy()			
			end			
		end
	end
	
	local decorative_names = {}
	for k,v in pairs(game.decorative_prototypes) do
		if v.autoplace_specification then
		  decorative_names[#decorative_names+1] = k
		end
	 end	 
	surface.regenerate_decorative(decorative_names, {{x=math.floor(event.area.left_top.x/32),y=math.floor(event.area.left_top.y/32)}})		
end

local function on_player_joined_game(event)
	local surface = game.surfaces[1]	
	local player = game.players[event.player_index]
	if not global.cave_miner_init_done then	
		surface.daytime = 0.5
		surface.freeze_daytime = 1
		game.forces["player"].technologies["landfill"].enabled = false
		game.forces["player"].technologies["night-vision-equipment"].enabled = false
		
		global.rock_inhabitants = {}
		global.rock_inhabitants[1] = {"small-biter"}
		global.rock_inhabitants[2] = {"small-biter","small-biter","small-biter","small-biter","small-biter","medium-biter"}
		global.rock_inhabitants[3] = {"small-biter","small-biter","small-biter","small-biter","medium-biter","medium-biter"}
		global.rock_inhabitants[4] = {"small-biter","small-biter","small-biter","medium-biter","medium-biter","small-spitter"}
		global.rock_inhabitants[5] = {"small-biter","small-biter","medium-biter","medium-biter","medium-biter","small-spitter"}
		global.rock_inhabitants[6] = {"small-biter","small-biter","medium-biter","medium-biter","big-biter","small-spitter"}
		global.rock_inhabitants[7] = {"small-biter","small-biter","medium-biter","medium-biter","big-biter","medium-spitter"}
		global.rock_inhabitants[8] = {"small-biter","medium-biter","medium-biter","medium-biter","big-biter","medium-spitter"}
		global.rock_inhabitants[9] = {"small-biter","medium-biter","medium-biter","big-biter","big-biter","medium-spitter"}
		global.rock_inhabitants[10] = {"medium-biter","medium-biter","medium-biter","big-biter","big-biter","big-spitter"}
		global.rock_inhabitants[11] = {"medium-biter","medium-biter","big-biter","big-biter","big-biter","big-spitter"}
		global.rock_inhabitants[12] = {"medium-biter","big-biter","big-biter","big-biter","big-biter","big-spitter"}
		global.rock_inhabitants[13] = {"big-biter","big-biter","big-biter","big-biter","big-biter","big-spitter"}
		global.rock_inhabitants[14] = {"big-biter","big-biter","big-biter","big-biter","behemoth-biter","big-spitter"}
		global.rock_inhabitants[15] = {"big-biter","big-biter","big-biter","behemoth-biter","behemoth-biter","big-spitter"}
		global.rock_inhabitants[16] = {"big-biter","big-biter","big-biter","behemoth-biter","behemoth-biter","behemoth-spitter"}
		global.rock_inhabitants[17] = {"big-biter","big-biter","behemoth-biter","behemoth-biter","behemoth-biter","behemoth-spitter"}
		global.rock_inhabitants[18] = {"big-biter","behemoth-biter","behemoth-biter","behemoth-biter","behemoth-biter","behemoth-spitter"}
		global.rock_inhabitants[19] = {"behemoth-biter","behemoth-biter","behemoth-biter","behemoth-biter","behemoth-biter","behemoth-spitter"}
		global.rock_inhabitants[20] = {"behemoth-biter","behemoth-biter","behemoth-biter","behemoth-biter","behemoth-spitter","behemoth-spitter"}	
				
		global.ore_spill_cap = 75
	
		global.rock_mining_chance_weights = {}
		global.rock_mining_chance_weights[1] = {"iron-ore",20}
		global.rock_mining_chance_weights[2] = {"copper-ore",18}
		global.rock_mining_chance_weights[3] = {"coal",15}
		global.rock_mining_chance_weights[4] = {"stone",8}
		global.rock_mining_chance_weights[5] = {"uranium-ore",3}
		global.rock_mining_raffle_table = {}				
		for _, t in pairs (global.rock_mining_chance_weights) do
			for x = 1, t[2], 1 do
				table.insert(global.rock_mining_raffle_table, t[1])
			end			
		end

		global.darkness_timer = {}
		global.darkness_messages = {
		"Something is lurking in the dark..."		
		}
						
		global.cave_miner_init_done = true						
	end
	global.darkness_timer[player.name] = game.tick
	player.insert {name = 'pistol', count = 1}
	player.insert {name = 'raw-fish', count = 3}
	player.insert {name = 'firearm-magazine', count = 16}			
	player.insert {name = 'iron-gear-wheel', count = 4}
	player.insert {name = 'iron-plate', count = 8}
end

local function spawn_rock_inhabitants(pos)	
	local tile_distance_to_center = math.sqrt(pos.x^2 + pos.y^2)			
	local rock_inhabitants_index = math.ceil((tile_distance_to_center-math.sqrt(global.spawn_dome_size))*0.02, 0)
	if rock_inhabitants_index < 1 then rock_inhabitants_index = 1 end
	if rock_inhabitants_index > 20 then rock_inhabitants_index = 20 end
	for x = 1, math.random(6,8), 1 do				
		local entity_name = global.rock_inhabitants[rock_inhabitants_index][math.random(1,#global.rock_inhabitants[rock_inhabitants_index])]
		local p = game.surfaces[1].find_non_colliding_position(entity_name , pos, 6, 1)			
		if p then game.surfaces[1].create_entity {name=entity_name, position=p} end
	end			
end

local function darkness_consume()
	for _, p in pairs (game.connected_players) do
		if game.tick - global.darkness_timer[p.name] >= 2700 then
			spawn_rock_inhabitants(p.position)
			local biters_found = game.surfaces[1].find_enemy_units(p.position, 10, "player")
			for _, biter in pairs(biters_found) do				
				biter.set_command({type=defines.command.attack, target=p.character, distraction=defines.distraction.none})					
			end
		else
			if game.tick - global.darkness_timer[p.name] >= 1800 then
				p.print(global.darkness_messages[math.random(1,#global.darkness_messages)],{ r=0.65, g=0.0, b=0.0})
				p.character.damage(1,"enemy")
			else
				if game.tick - global.darkness_timer[p.name] >= 900 then
					p.character.damage(1,"enemy") 
				end
			end
		end		
	end
end

local function darkness_check()
	for _, p in pairs (game.connected_players) do
		p.character.disable_flashlight()
		local tile_distance_to_center = math.sqrt(p.position.x^2 + p.position.y^2)
		if tile_distance_to_center < math.sqrt(global.spawn_dome_size) then
			global.darkness_timer[p.name] = game.tick
		else
			if p.character.driving == true then
				global.darkness_timer[p.name] = game.tick
			else
				local light_source_entities = game.surfaces[1].find_entities_filtered{area={{p.position.x-12,p.position.y-12},{p.position.x+12,p.position.y+12}}, name="small-lamp"}		
				for _, lamp in pairs (light_source_entities) do
					local circuit = lamp.get_or_create_control_behavior()
					if circuit then
						if lamp.energy > 60 and circuit.disabled == false then					
							global.darkness_timer[p.name] = game.tick
							break
						end
					else
						if lamp.energy > 60 then					
							global.darkness_timer[p.name] = game.tick
							break
						end
					end
				end
			end
		end
	end
end

local function on_tick(event)
		if game.tick % 900 == 0 then
			darkness_check()	
			darkness_consume()	
		end		
		
		if game.tick == 30 then
			local surface = game.surfaces[1]
			local pos = {}		
			pos.x=30 ; pos.y=0
			create_tile_cluster("water",pos,400)
			pos.x=-30 ; pos.y=0
			create_tile_cluster("water",pos,400)
			pos.x=0 ; pos.y=30
			create_tile_cluster("water",pos,400)
			pos.x=0 ; pos.y=-30
			create_tile_cluster("water",pos,400)			
			surface.regenerate_entity({"tree-01", "tree-02","tree-03","tree-04","tree-05","tree-06","tree-07","tree-08","tree-09","dead-dry-hairy-tree","dead-grey-trunk","dead-tree-desert","dry-hairy-tree","dry-tree","rock-big","rock-huge"})			
		end
end

local function on_marked_for_deconstruction(event)
	if event.entity.name == "rock-huge" or event.entity.name == "rock-big" or event.entity.name == "sand-rock-big" then
		event.entity.cancel_deconstruction(game.players[event.player_index].force.name)
	end
end

local function pre_player_mined_item(event)
	if math.random(1,8) == 1 then
		if event.entity.name == "rock-huge" or event.entity.name == "rock-big" or event.entity.name == "sand-rock-big" then
			spawn_rock_inhabitants(event.entity.position)
		end
	end
	if event.entity.name == "rock-huge" or event.entity.name == "rock-big" or event.entity.name == "sand-rock-big" then		
		local tile_distance_to_center = math.sqrt(event.entity.position.x^2 + event.entity.position.y^2)
		local player = game.players[event.player_index]
		local bonus_amount = math.ceil((tile_distance_to_center - math.sqrt(global.spawn_dome_size)) * 0.333, 0) 
		if bonus_amount < 1 then bonus_amount = 0 end		
		local amount = math.random(55,65) + bonus_amount		
		local mined_loot = global.rock_mining_raffle_table[math.random(1,#global.rock_mining_raffle_table)]
		if amount > global.ore_spill_cap then
			game.surfaces[1].spill_item_stack(event.entity.position,{name = mined_loot, count = global.ore_spill_cap},true)
			amount = amount - global.ore_spill_cap
			local i = player.insert {name = mined_loot, count = amount}
			amount = amount - i
			if amount > 0 then
				game.surfaces[1].spill_item_stack(event.entity.position,{name = mined_loot, count = amount},true)
			end
		else
			game.surfaces[1].spill_item_stack(event.entity.position,{name = global.rock_mining_raffle_table[math.random(1,#global.rock_mining_raffle_table)], count = amount},true)
		end
	end
end

local function on_player_mined_entity(event)
	if event.entity.name == "rock-huge" or event.entity.name == "rock-big" or event.entity.name == "sand-rock-big" then
		event.buffer.clear()
	end
end

local function on_entity_died(event)
	if math.random(1,6) == 1 then
		if event.entity.name == "rock-huge" or event.entity.name == "rock-big" or event.entity.name == "sand-rock-big" then			
			spawn_rock_inhabitants(event.entity.position)
		end
	end
end

local function on_player_respawned(event)
	local player = game.players[event.player_index]
	player.character.disable_flashlight()
end

function test()
	local x = 0
	if x == 1 then
		game.player.cheat_mode=true
		game.speed = 1
		game.player.force.research_all_technologies()
		game.forces["enemy"].evolution_factor = 0.2
		local chart = 300
		local surface = game.surfaces[1]	
		game.forces["player"].chart(surface, {lefttop = {x = chart*-1, y = chart*-1}, rightbottom = {x = chart, y = chart}})		
	end
end

Event.add(defines.events.on_player_respawned, on_player_respawned)
Event.add(defines.events.on_player_mined_entity, on_player_mined_entity)
Event.add(defines.events.on_entity_died, on_entity_died)
Event.add(defines.events.on_pre_player_mined_item, pre_player_mined_item)
Event.add(defines.events.on_marked_for_deconstruction, on_marked_for_deconstruction)
Event.add(defines.events.on_chunk_generated, on_chunk_generated)
Event.add(defines.events.on_tick, on_tick)	
Event.add(defines.events.on_player_joined_game, on_player_joined_game)