local format_time = util.formattime function format_time_from_tick(ThatTick) if game.tick > ThatTick then return format_time(game.tick-ThatTick) else return format_time(ThatTick - game.tick) end end -- Get a random 1 or -1 function RandomNegPos() if (math.random(0,1) == 1) then return 1 else return -1 end end -- Create a random direction vector to look in function GetRandomVector() local randVec = {x=0,y=0} while ((randVec.x == 0) and (randVec.y == 0)) do randVec.x = math.random(-3,3) randVec.y = math.random(-3,3) end return randVec end -- Find random coordinates within a given distance away -- maxTries is the recursion limit basically. function FindUngeneratedCoordinates(minDistChunks, maxDistChunks, surface) local position = {x=0,y=0} local chunkPos = {x=0,y=0} local maxTries = 100 local tryCounter = 0 local minDistSqr = minDistChunks^2 local maxDistSqr = maxDistChunks^2 while(true) do chunkPos.x = math.random(0,maxDistChunks) * RandomNegPos() chunkPos.y = math.random(0,maxDistChunks) * RandomNegPos() local distSqrd = chunkPos.x^2 + chunkPos.y^2 -- Enforce a max number of tries tryCounter = tryCounter + 1 if (tryCounter > maxTries) then DebugPrint("FindUngeneratedCoordinates - Max Tries Hit!") break -- Check that the distance is within the min,max specified elseif ((distSqrd < minDistSqr) or (distSqrd > maxDistSqr)) then -- Keep searching! -- Check there are no generated chunks in a 10x10 area. elseif IsChunkAreaUngenerated(chunkPos, 5, surface) then position.x = (chunkPos.x*32) + (32/2) position.y = (chunkPos.y*32) + (32/2) break -- SUCCESS end end return position end function make_composite_icon_rb(icon1, tint1, icon2, tint2) return { {icon=icon1,icon_size = 64, icon_mipmaps = 4, tint=tint1}, {icon=icon2,icon_size = 64, icon_mipmaps = 4, tint=tint2,priority="medium",shift={8,8},scale=0.3}} end function safe_player_teleport(player,surface,position) local pos = surface.find_non_colliding_position("character", position, 0, 2) player.teleport(pos, surface) end function get_localized_name(name) local lname = '' if game.item_prototypes[name] then lname = game.item_prototypes[name].localised_name elseif game.equipment_prototypes[name] then lname = game.equipment_prototypes[name].localised_name elseif game.entity_prototypes[name] then lname = game.entity_prototypes[name].localised_name end return lname end function check_container_for_items(container,items) local has_all =true for k=1,#items do if container.get_item_count(items[k].name)0 then inv_a.remove({name=item_type, count=qt}) end end end end return tqt end function transfer_fluid (entity_a, entity_b) local fluids = entity_a.get_fluid_contents() local name,amt,name_b for n,a in pairs (fluids) do name=n amt=a break end local fluids_b = entity_b.get_fluid_contents() for n,a in pairs (fluids_b) do name_b=n break end local transfered=0 if name and amt and ((not name_b) or name==name_b) then entity_b.remove_fluid{name=name,amount=transfered} transfered = entity_b.insert_fluid({name=name,amount=amt}) entity_a.remove_fluid{name=name,amount=transfered} end return name, transfered end function get_gps_tag(position,surface) local r = '[gps='..math.floor(position.x)..','..math.floor(position.y) if surface then r=r..','..surface.name end r=r..']' return r end function Log(what) game.write_file("big_monster.log", serpent.block(what), true) end function dLog(what) log(serpent.block(what)) end function to_table(pos_arr) if #pos_arr == 2 then return { x = pos_arr[1], y = pos_arr[2] } end return pos_arr end function distance_squared(pos1, pos2) pos1 = to_table(pos1) pos2 = to_table(pos2) local axbx = pos1.x - pos2.x local ayby = pos1.y - pos2.y return axbx * axbx + ayby * ayby end -------------------------------------------------------------------------------------- function square_area( origin, radius ) return { {x=origin.x - radius, y=origin.y - radius}, {x=origin.x + radius, y=origin.y + radius} } end function get_area_center(area) local x1 = area.left_top.x local y1 = area.left_top.y local x2 = area.right_bottom.x local y2 = area.right_bottom.y return {x= math.floor(x1 + x2) /2,y= math.floor(y1 + y2) /2} end -- Get an area given a position and distance. -- Square length = 2x distance function GetAreaAroundPos(pos, dist) return {left_top= {x=pos.x-dist, y=pos.y-dist}, right_bottom= {x=pos.x+dist, y=pos.y+dist}} end function create_retangle_area(pos,hight,width,adjust_w,adjust_h) local h = math.ceil(hight/2) local w = math.ceil(width/2) adjust_w = adjust_w or 0 adjust_h = adjust_h or 0 return {left_top= {x=pos.x-w + adjust_w, y=pos.y-h + adjust_h}, right_bottom= {x=pos.x+w, y=pos.y+h}} end function get_random_pos_near(pos,dist) return {x=pos.x+math.random(-dist,dist),y=pos.y+math.random(-dist,dist)} end -------------------------------------------------------------------------------------- function distance( pos1, pos2 ) local dx = pos2.x - pos1.x local dy = pos2.y - pos1.y return( math.sqrt(dx*dx+dy*dy) ) end -------------------------------------------------------------------------------------- function distance_square( pos1, pos2 ) return( math.max(math.abs(pos2.x - pos1.x),math.abs(pos2.y - pos1.y)) ) end -------------------------------------------------------------------------------------- function pos_offset( pos, offset ) return { x=pos.x + offset.x, y=pos.y + offset.y } end -------------------------------------------------------------------------------------- function surface_area(surf) local x1, y1, x2, y2 = 0,0,0,0 for chunk in surf.get_chunks() do if chunk.x < x1 then x1 = chunk.x elseif chunk.x > x2 then x2 = chunk.x end if chunk.y < y1 then y1 = chunk.y elseif chunk.y > y2 then y2 = chunk.y end end return( {{x1*32-8,y1*32-8},{x2*32+40,y2*32+40}} ) end -------------------------------------------------------------------------------------- function iif( cond, val1, val2 ) if cond then return val1 else return val2 end end --for k,v in Sort_a_Table(your_table, function(t,a,b) return t[b] > t[a] end) do function Sort_a_Table(t, order) -- collect the keys local keys = {} for k in pairs(t) do keys[#keys+1] = k end -- if order function given, sort by it by passing the table and keys a, b, -- otherwise just sort the keys if order then table.sort(keys, function(a,b) return order(t, a, b) end) else table.sort(keys) end -- return the iterator function local i = 0 return function() i = i + 1 if keys[i] then return keys[i], t[keys[i]] end end end -------------------------------------------------------------------------------------- function add_list(list, obj) -- to avoid duplicates... for i, obj2 in pairs(list) do if obj2 == obj then return(false) end end table.insert(list,obj) return(true) end -------------------------------------------------------------------------------------- function del_list(list, obj) for i, obj2 in pairs(list) do if obj2 == obj then table.remove( list, i ) return(true) end end return(false) end -------------------------------------------------------------------------------------- function in_list(list, obj) for k, obj2 in pairs(list) do if obj2 == obj then return(k) end end return(nil) end -------------------------------------------------------------------------------------- function size_list(list) local n = 0 for i in pairs(list) do n = n + 1 end return(n) end -------------------------------------------------------------------------------------- function concat_lists(list1, list2) -- add list2 into list1 , do not avoid duplicates... for i, obj in pairs(list2) do table.insert(list1,obj) end end function concat_lists_no_dup(list1, list2) -- add list2 into list1 , Avoiding duplicates... for i, obj in pairs(list2) do add_list(list1,obj) end end function add_technology_prerequisite(technology, prerequisite) if not data.raw.technology[technology].prerequisites then data.raw.technology[technology].prerequisites={} end if not in_list(data.raw.technology[technology].prerequisites, prerequisite) then table.insert(data.raw.technology[technology].prerequisites,prerequisite) end end function add_recipe_unlock(technology, recipe) if data.raw.technology[technology] and data.raw.recipe[recipe] then local addit = true if not data.raw.technology[technology].effects then data.raw.technology[technology].effects = {} end for i, effect in pairs(data.raw.technology[technology].effects) do if effect.type == "unlock-recipe" and effect.recipe == recipe then addit = false end end if addit then table.insert(data.raw.technology[technology].effects,{type = "unlock-recipe", recipe = recipe}) end else if not data.raw.technology[technology] then log("Technology " .. technology .. " does not exist.") end if not data.raw.recipe[recipe] then log("Recipe " .. recipe .. " does not exist.") end end end function update_science_pack_amount(technology, amount) if data.raw.technology[technology] then local new ={} for i, ingredient in pairs(data.raw.technology[technology].unit.ingredients) do table.insert (new,{ingredient[1], ingredient[2] + amount}) end data.raw.technology[technology].unit.ingredients = new end end function add_new_science_pack(technology, pack, amount) if data.raw.technology[technology] and data.raw.tool[pack] then local addit = true for i, ingredient in pairs(data.raw.technology[technology].unit.ingredients) do if ingredient[1] == pack or ingredient.name == pack then addit = false end end if addit then table.insert(data.raw.technology[technology].unit.ingredients,{pack, amount}) end else if not data.raw.technology[technology] then log("Technology " .. technology .. " does not exist.") end if not data.raw.tool[pack] then log("Science pack " .. new .. " does not exist.") end end end function FindUnchartedChunk(surface, MinDist,MaxDist) local X1=0 local X2=0 local Y1=0 local Y2=0 for chunk in surface.get_chunks() do local X,Y = chunk.x, chunk.y if game.forces["player"].is_chunk_charted(surface,({X,Y})) then if XX2 then X2=X end if YY2 then Y2=Y end end end local dX1 = MinDist*-1 local dX2 = MinDist local dY1 = MinDist*-1 local dY2 = MinDist if X1*-1>=MinDist then dX1 = X1 -1 end if X2>=MinDist then dX2 = 1 + X2 end if Y1*-1>=MinDist then dY1 = Y1-1 end if Y2>=MinDist then dY2 = 1 + Y2 end local Max = MaxDist local t local novoX local novoY for a=1,100 do t = math.random(1,4) if t==1 then if Max10) or (string.find(name, "explosive") and temp<40) then add=false end end if string.find(name, "kr-") or string.find(name, "RTPrimer") then add=false end -- krastorio fake worms if not (string.find(name, "worm")) then add=false end if add then table.insert(worms,name) end end end end local strong_worms = {} if extra_evo then local filter = {{filter = "type",type = "turret"},{filter = "build-base-evolution-requirement", comparison = "≤", value = evolution+extra_evo, mode = "and"}, {filter = "build-base-evolution-requirement", comparison = "≥", value = evolution, mode = "and"}} local worms_p = game.get_filtered_entity_prototypes(filter) for name,proto in pairs (worms_p) do if not string.find(name, "boss") then if proto.build_base_evolution_requirement ~= nil then local add = true if temp then if (string.find(name, "cold") and temp>10) or (string.find(name, "explosive") and temp<40) then add=false end end if string.find(name, "kr-") or string.find(name, "RTPrimer") then add=false end -- krastorio and RenaiTransportation fake worms if not (string.find(name, "worm")) then add=false end if add then table.insert(strong_worms,name) end end end end end return worms,strong_worms end function create_tatoo_for_unit(unit, color) if unit and unit.valid then if not color then color=colors.red end local tatoo = rendering.draw_circle { color = color, radius = 0.18, filled = true, target = unit, surface = unit.surface, } end end function get_units_for_evolution(evolution,extra_evo) if not evolution then evolution = game.forces.enemy.evolution_factor end local filter = {{filter = "type", type = "unit-spawner"}} local spawners = game.get_filtered_entity_prototypes(filter) local unit_names = {} local strong_units = {} -- for extra strong ones for name,proto in pairs (spawners) do if not (string.find(name, "protomolecule") or string.find(name, "boss") or string.find(name, "entity-proxy") ) then for Y,RU in pairs (proto.result_units) do local uname = RU.unit local SP = RU['spawn_points'] if not in_list(unit_names,uname) and game.entity_prototypes[uname] and game.entity_prototypes[uname].type=='unit' then local emin = SP[1]['evolution_factor'] local emax = SP[#SP]['evolution_factor'] if SP[#SP]['weight']>0 then emax=2 end if evolution>=emin and evolution=emin and evolution+extra_evo