1481 lines
		
	
	
		
			48 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
			
		
		
	
	
			1481 lines
		
	
	
		
			48 KiB
		
	
	
	
		
			Lua
		
	
	
	
	
	
-------------------------------------------------------------------------------
 | 
						|
---Description of the module.
 | 
						|
---@class Player
 | 
						|
local Player = {
 | 
						|
  ---single-line comment
 | 
						|
  classname = "HMPlayer"
 | 
						|
}
 | 
						|
 | 
						|
local Lua_player = nil
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Print message
 | 
						|
function Player.print(...)
 | 
						|
  if Lua_player ~= nil then
 | 
						|
    Lua_player.print(table.concat({...}," "))
 | 
						|
  end
 | 
						|
end
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Load factorio player
 | 
						|
---@param event LuaEvent
 | 
						|
---@return Player
 | 
						|
function Player.load(event)
 | 
						|
  Lua_player = game.players[event.player_index]
 | 
						|
  return Player
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Load factorio player by name or first
 | 
						|
---@param player_name string
 | 
						|
---@return Player
 | 
						|
function Player.try_load_by_name(player_name)
 | 
						|
  for _, player in pairs(game.players) do
 | 
						|
    if Lua_player == nil then
 | 
						|
      Lua_player = player
 | 
						|
    end
 | 
						|
    if player.name == player_name then
 | 
						|
      Lua_player = player
 | 
						|
      break
 | 
						|
    end
 | 
						|
  end
 | 
						|
  return Player
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Set factorio player
 | 
						|
---@param player LuaPlayer
 | 
						|
---@return Player
 | 
						|
function Player.set(player)
 | 
						|
  Lua_player = player
 | 
						|
  return Player
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Get game day
 | 
						|
---@return number, number, number, number
 | 
						|
function Player.getGameDay()
 | 
						|
  local surface = game.surfaces[1]
 | 
						|
  local day = surface.ticks_per_day
 | 
						|
  local dusk = surface.evening-surface.dusk
 | 
						|
  local night = surface.morning-surface.evening
 | 
						|
  local dawn = surface.dawn-surface.morning
 | 
						|
  return day, day*dusk, day*night, day*dawn
 | 
						|
end
 | 
						|
 | 
						|
------------------------------------------------------------------------------
 | 
						|
---Get display sizes
 | 
						|
---@return number, number, number
 | 
						|
function Player.getDisplaySizes()
 | 
						|
  if Lua_player == nil or not Lua_player.valid then return 800,600,1 end
 | 
						|
  local display_resolution = Lua_player.display_resolution
 | 
						|
  local display_scale = Lua_player.display_scale
 | 
						|
  return display_resolution.width, display_resolution.height, display_scale
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Set pipette
 | 
						|
---@param entity any
 | 
						|
---@return any
 | 
						|
function Player.setPipette(entity)
 | 
						|
  if Lua_player == nil then return nil end
 | 
						|
  return Lua_player.pipette_entity(entity)
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Get character crafting speed
 | 
						|
---@return number
 | 
						|
function Player.getCraftingSpeed()
 | 
						|
  if Lua_player == nil then return 0 end
 | 
						|
  return 1 + Lua_player.character_crafting_speed_modifier
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Get main inventory
 | 
						|
---@return any
 | 
						|
function Player.getMainInventory()
 | 
						|
  if Lua_player == nil then return nil end
 | 
						|
  return Lua_player.get_main_inventory()
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Begin Crafting
 | 
						|
---@param item string
 | 
						|
---@param count number
 | 
						|
function Player.beginCrafting(item, count)
 | 
						|
  if Lua_player == nil then return nil end
 | 
						|
  local filters = {{filter = "has-product-item", elem_filters = {{filter = "name", name = item}}}}
 | 
						|
  local recipes = game.get_filtered_recipe_prototypes(filters)
 | 
						|
  if recipes ~= nil and table.size(recipes) > 0 then
 | 
						|
    local first_recipe = Model.firstRecipe(recipes)
 | 
						|
    local craft = {count=math.ceil(count),recipe=first_recipe.name,silent=false}
 | 
						|
    Lua_player.begin_crafting(craft)
 | 
						|
  else
 | 
						|
    Player.print("No recipe found for this craft!")
 | 
						|
  end
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Get smart tool
 | 
						|
---@return LuaItemStack
 | 
						|
function Player.getSmartTool(entities)
 | 
						|
  if Lua_player == nil then
 | 
						|
    return nil
 | 
						|
  end
 | 
						|
  local script_inventory = game.create_inventory(1)
 | 
						|
  local tool_stack = script_inventory[1]
 | 
						|
  tool_stack.set_stack({name="blueprint"})
 | 
						|
  tool_stack.set_blueprint_entities(entities)
 | 
						|
  tool_stack.label = "Helmod Smart Tool"
 | 
						|
 | 
						|
  Lua_player.add_to_clipboard(tool_stack)
 | 
						|
  Lua_player.activate_paste()
 | 
						|
  script_inventory.destroy()
 | 
						|
  return tool_stack
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Set smart tool
 | 
						|
---@param recipe table
 | 
						|
---@param type string
 | 
						|
---@param index number
 | 
						|
---@return any
 | 
						|
function Player.setSmartTool(recipe, type, index)  
 | 
						|
    if Lua_player == nil or recipe == nil then
 | 
						|
      return nil
 | 
						|
    end
 | 
						|
    local factory = recipe[type]
 | 
						|
    if index ~= nil then
 | 
						|
      factory = factory[index]
 | 
						|
    end
 | 
						|
    local modules = {}
 | 
						|
    for name,value in pairs(factory.modules or {}) do
 | 
						|
      modules[name] = value
 | 
						|
    end
 | 
						|
    local entity = {
 | 
						|
      entity_number = 1,
 | 
						|
      name = factory.name,
 | 
						|
      position = {0, 0},
 | 
						|
      items = modules
 | 
						|
    }
 | 
						|
    if type == "factory" then
 | 
						|
      entity.recipe = recipe.name
 | 
						|
    end
 | 
						|
 | 
						|
    Player.getSmartTool({entity})
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Is valid sprite path
 | 
						|
---@param sprite_path string
 | 
						|
---@return boolean
 | 
						|
function Player.is_valid_sprite_path(sprite_path)
 | 
						|
  if Lua_player == nil then return false end
 | 
						|
  return Lua_player.gui.is_valid_sprite_path(sprite_path)
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return factorio player
 | 
						|
---@return LuaPlayer
 | 
						|
function Player.native()
 | 
						|
  return Lua_player
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return admin player
 | 
						|
---@return boolean
 | 
						|
function Player.isAdmin()
 | 
						|
  return Lua_player.admin
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Get gui
 | 
						|
---@param location string
 | 
						|
---@return LuaGuiElement
 | 
						|
function Player.getGui(location)
 | 
						|
  return Lua_player.gui[location]
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return force's player
 | 
						|
---@return LuaForce
 | 
						|
function Player.getForce()
 | 
						|
  return Lua_player.force
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Sets the toggle state of the shotcut tool/icon
 | 
						|
---@param state boolean
 | 
						|
function Player.setShortcutState(state)
 | 
						|
  if Lua_player ~= nil then
 | 
						|
    Lua_player.set_shortcut_toggled("helmod-shortcut", state)
 | 
						|
  end
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return item type
 | 
						|
---@param element LuaPrototype
 | 
						|
---@return string
 | 
						|
function Player.getItemIconType(element)
 | 
						|
  local item = Player.getItemPrototype(element.name)
 | 
						|
  if item ~= nil then
 | 
						|
    return "item"
 | 
						|
  end
 | 
						|
  local fluid = Player.getFluidPrototype(element.name)
 | 
						|
  if fluid ~= nil then
 | 
						|
    return "fluid"
 | 
						|
  else
 | 
						|
    return "item"
 | 
						|
  end
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return localised name
 | 
						|
---@param element LuaPrototype
 | 
						|
---@return string|table
 | 
						|
function Player.getLocalisedName(element)
 | 
						|
  local localisedName = element.name
 | 
						|
  if element.type ~= nil then
 | 
						|
    if element.type == "recipe" or element.type == "recipe-burnt" then
 | 
						|
      local recipe = Player.getPlayerRecipe(element.name)
 | 
						|
      if recipe ~= nil then
 | 
						|
        localisedName = recipe.localised_name
 | 
						|
      end
 | 
						|
    elseif element.type == "technology" then
 | 
						|
      local technology = Player.getPlayerTechnology(element.name)
 | 
						|
      if technology ~= nil then
 | 
						|
        localisedName = technology.localised_name
 | 
						|
      end
 | 
						|
    elseif element.type == "entity" or element.type == "resource" then
 | 
						|
      local item = Player.getEntityPrototype(element.name)
 | 
						|
      if item ~= nil then
 | 
						|
        localisedName = item.localised_name
 | 
						|
      end
 | 
						|
    elseif element.type == 0 or element.type == "item" then
 | 
						|
      local item = Player.getItemPrototype(element.name)
 | 
						|
      if item ~= nil then
 | 
						|
        localisedName = item.localised_name
 | 
						|
      end
 | 
						|
    elseif element.type == 1 or element.type == "fluid" then
 | 
						|
      local item = Player.getFluidPrototype(element.name)
 | 
						|
      if item ~= nil then
 | 
						|
        if element.temperature then
 | 
						|
          localisedName = {"helmod_common.fluid-temperature", item.localised_name, element.temperature}
 | 
						|
        elseif (element.minimum_temperature and (element.minimum_temperature >= -1e300)) and (element.maximum_temperature and (element.maximum_temperature <= 1e300)) then
 | 
						|
          localisedName = {"helmod_common.fluid-temperature-range", item.localised_name, element.minimum_temperature, element.maximum_temperature}
 | 
						|
        elseif (element.minimum_temperature and (element.minimum_temperature >= -1e300)) then
 | 
						|
          localisedName = {"helmod_common.fluid-temperature-min", item.localised_name, element.minimum_temperature}
 | 
						|
        elseif (element.maximum_temperature and (element.maximum_temperature <= 1e300)) then
 | 
						|
          localisedName = {"helmod_common.fluid-temperature-max", item.localised_name, element.maximum_temperature}
 | 
						|
        else
 | 
						|
          localisedName = item.localised_name
 | 
						|
        end
 | 
						|
      end
 | 
						|
    elseif element.type == "energy" then
 | 
						|
      localisedName = {string.format("helmod_common.%s", element.name)}
 | 
						|
    end
 | 
						|
  end
 | 
						|
  return localisedName
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return localised name
 | 
						|
---@param prototype LuaPrototype
 | 
						|
---@return string|table
 | 
						|
function Player.getRecipeLocalisedName(prototype)
 | 
						|
  local element = Player.getPlayerRecipe(prototype.name)
 | 
						|
  if element ~= nil then
 | 
						|
    return element.localised_name
 | 
						|
  end
 | 
						|
  return prototype.name
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return localised name
 | 
						|
---@param prototype LuaPrototype
 | 
						|
---@return string|table
 | 
						|
function Player.getTechnologyLocalisedName(prototype)
 | 
						|
  local element = Player.getPlayerTechnology(prototype.name)
 | 
						|
  if element ~= nil then
 | 
						|
    return element.localised_name
 | 
						|
  end
 | 
						|
  return element.name
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return recipes
 | 
						|
---@return table
 | 
						|
function Player.getPlayerRecipes()
 | 
						|
  if Lua_player ~= nil then
 | 
						|
    return Player.getForce().recipes
 | 
						|
  end
 | 
						|
  return {}
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return recipe prototypes
 | 
						|
---@return table
 | 
						|
function Player.getRecipes()
 | 
						|
  return game.recipe_prototypes
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return technologie prototypes
 | 
						|
---@param filters table
 | 
						|
---@return table
 | 
						|
function Player.getTechnologies(filters)
 | 
						|
  if filters ~= nil then
 | 
						|
    return game.get_filtered_technology_prototypes(filters)
 | 
						|
  end
 | 
						|
  return game.technology_prototypes
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return technology prototype
 | 
						|
---@param name string
 | 
						|
---@return LuaTechnologyPrototype
 | 
						|
function Player.getTechnology(name)
 | 
						|
  return game.technology_prototypes[name]
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return technologies
 | 
						|
---@return table
 | 
						|
function Player.getPlayerTechnologies()
 | 
						|
  if Lua_player ~= nil then
 | 
						|
    local technologies = {}
 | 
						|
    for _,technology in pairs(Player.getForce().technologies) do
 | 
						|
      technologies[technology.name] = technology
 | 
						|
    end
 | 
						|
    return technologies
 | 
						|
  end
 | 
						|
  return {}
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return technology
 | 
						|
---@param name string
 | 
						|
---@return LuaTechnology
 | 
						|
function Player.getPlayerTechnology(name)
 | 
						|
  if Lua_player ~= nil then
 | 
						|
    local technology = Player.getForce().technologies[name]
 | 
						|
    return technology
 | 
						|
  end
 | 
						|
  return nil
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return rule
 | 
						|
---@param rule_name string
 | 
						|
---@return table, table --rules_included, rules_excluded
 | 
						|
function Player.getRules(rule_name)
 | 
						|
  local rules_included = {}
 | 
						|
  local rules_excluded = {}
 | 
						|
  for rule_id, rule in spairs(Model.getRules(), function(t,a,b) return t[b].index > t[a].index end) do
 | 
						|
    if game.active_mods[rule.mod] and rule.name == rule_name then
 | 
						|
      if rule.excluded then
 | 
						|
        if rules_excluded[rule.category] == nil then rules_excluded[rule.category] = {} end
 | 
						|
        if rules_excluded[rule.category][rule.type] == nil then rules_excluded[rule.category][rule.type] = {} end
 | 
						|
        rules_excluded[rule.category][rule.type][rule.value] = true
 | 
						|
      else
 | 
						|
        if rules_included[rule.category] == nil then rules_included[rule.category] = {} end
 | 
						|
        if rules_included[rule.category][rule.type] == nil then rules_included[rule.category][rule.type] = {} end
 | 
						|
        rules_included[rule.category][rule.type][rule.value] = true
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
  return rules_included, rules_excluded
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return rule
 | 
						|
---@param check boolean
 | 
						|
---@param rules table
 | 
						|
---@param category string
 | 
						|
---@param lua_entity table
 | 
						|
---@param included boolean
 | 
						|
---@return boolean
 | 
						|
function Player.checkRules(check, rules, category, lua_entity, included)
 | 
						|
  if rules[category] then
 | 
						|
    if rules[category]["entity-name"] and (rules[category]["entity-name"]["all"] or rules[category]["entity-name"][lua_entity.name]) then
 | 
						|
      check = included
 | 
						|
    elseif rules[category]["entity-type"] and (rules[category]["entity-type"]["all"] or rules[category]["entity-type"][lua_entity.type]) then
 | 
						|
      check = included
 | 
						|
    elseif rules[category]["entity-group"] and (rules[category]["entity-group"]["all"] or rules[category]["entity-group"][lua_entity.group.name]) then
 | 
						|
      check = included
 | 
						|
    elseif rules[category]["entity-subgroup"] and (rules[category]["entity-subgroup"]["all"] or rules[category]["entity-subgroup"][lua_entity.subgroup.name]) then
 | 
						|
      check = included
 | 
						|
    end
 | 
						|
  end
 | 
						|
  return check
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Check factory limitation module
 | 
						|
---@param module table
 | 
						|
---@param lua_recipe RecipeData
 | 
						|
---@return boolean
 | 
						|
function Player.checkFactoryLimitationModule(module, lua_recipe)
 | 
						|
  local factory = lua_recipe.factory
 | 
						|
  if factory.module_slots ==  0 then
 | 
						|
    return false
 | 
						|
  end
 | 
						|
 | 
						|
  local rules_included, rules_excluded = Player.getRules("module-limitation")
 | 
						|
  local model_filter_factory_module = User.getModGlobalSetting("model_filter_factory_module")
 | 
						|
  local allowed = true
 | 
						|
  local check_not_bypass = true
 | 
						|
  local prototype = RecipePrototype(lua_recipe)
 | 
						|
  local category = prototype:getCategory()
 | 
						|
  if prototype:getType() == "rocket" then
 | 
						|
    local rocket_part_recipe = Player.getRocketPartRecipe(lua_recipe.factory)
 | 
						|
    if rocket_part_recipe and category == rocket_part_recipe.category and lua_recipe.name ~= rocket_part_recipe.name then
 | 
						|
      local rocket_recipe = RecipePrototype(rocket_part_recipe.name)
 | 
						|
      if rocket_recipe.lua_prototype ~= nil then
 | 
						|
        rocket_recipe.name = rocket_part_recipe.name
 | 
						|
        rocket_recipe.factory = lua_recipe.factory
 | 
						|
        allowed = Player.checkFactoryLimitationModule(module, rocket_recipe)
 | 
						|
        return allowed
 | 
						|
      end
 | 
						|
      return true
 | 
						|
    end
 | 
						|
  end
 | 
						|
  if rules_excluded[category] == nil then
 | 
						|
    category = "standard"
 | 
						|
  end
 | 
						|
  check_not_bypass = Player.checkRules(check_not_bypass, rules_excluded, category, EntityPrototype(factory.name):native(), false)
 | 
						|
  if table.size(module.limitations) > 0 and check_not_bypass and model_filter_factory_module == true then
 | 
						|
    allowed = false
 | 
						|
    for _, recipe_name in pairs(module.limitations) do
 | 
						|
      if lua_recipe.name == recipe_name then
 | 
						|
        allowed = true
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  local allowed_effects = EntityPrototype(factory):getAllowedEffects()
 | 
						|
  if allowed_effects ~= nil and model_filter_factory_module == true then
 | 
						|
    for _, effect in pairs({"speed", "productivity", "consumption", "pollution"}) do
 | 
						|
      if (Player.getModuleBonus(module.name, effect) ~= 0) and (not allowed_effects[effect]) then
 | 
						|
        allowed = false
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  return allowed
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Check beacon limitation module
 | 
						|
---@param beacon FactoryData
 | 
						|
---@param recipe RecipeData
 | 
						|
---@param module LuaItemPrototype
 | 
						|
---@return boolean
 | 
						|
function Player.checkBeaconLimitationModule(beacon, recipe, module)
 | 
						|
  local allowed = true
 | 
						|
  local model_filter_beacon_module = User.getModGlobalSetting("model_filter_beacon_module")
 | 
						|
 | 
						|
  if table.size(module.limitations) > 0 and model_filter_beacon_module == true and recipe.type ~= "resource" then
 | 
						|
    allowed = false
 | 
						|
    for _, module_recipe_name in pairs(module.limitations) do
 | 
						|
      if module_recipe_name == recipe.name then
 | 
						|
        allowed = true
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  local allowed_effects = EntityPrototype(beacon):getAllowedEffects()
 | 
						|
  if allowed_effects ~= nil and model_filter_beacon_module == true then
 | 
						|
    for _, effect in pairs({"speed", "productivity", "consumption", "pollution"}) do
 | 
						|
      if (Player.getModuleBonus(module.name, effect) ~= 0) and (not allowed_effects[effect]) then
 | 
						|
        allowed = false
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  if beacon.module_slots ==  0 then
 | 
						|
    allowed = false
 | 
						|
  end
 | 
						|
  return allowed
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return list of productions
 | 
						|
---@param category string
 | 
						|
---@param lua_recipe table
 | 
						|
---@return table
 | 
						|
function Player.getProductionsCrafting(category, lua_recipe)
 | 
						|
  local productions = {}
 | 
						|
  local rules_included, rules_excluded = Player.getRules("production-crafting")
 | 
						|
  if category == "crafting-handonly" then
 | 
						|
    productions["character"] = game.entity_prototypes["character"]
 | 
						|
  elseif lua_recipe.name ~= nil and category == "fluid" then
 | 
						|
    for key, lua_entity in pairs(Player.getOffshorePumps(lua_recipe.name)) do
 | 
						|
      productions[lua_entity.name] = lua_entity
 | 
						|
    end
 | 
						|
  else
 | 
						|
    for key, lua_entity in pairs(Player.getProductionMachines()) do
 | 
						|
      local check = false
 | 
						|
      if category ~= nil then
 | 
						|
        if not(rules_included[category]) then
 | 
						|
          ---standard recipe
 | 
						|
          if lua_entity.crafting_categories ~= nil and lua_entity.crafting_categories[category] then
 | 
						|
            local recipe_ingredient_count = RecipePrototype(lua_recipe, "recipe"):getIngredientCount()
 | 
						|
            local factory_ingredient_count = EntityPrototype(lua_entity):getIngredientCount()
 | 
						|
            --- check ingredient limitation
 | 
						|
            if factory_ingredient_count >= recipe_ingredient_count then
 | 
						|
              check = true
 | 
						|
            end
 | 
						|
            ---resolve rule excluded
 | 
						|
            check = Player.checkRules(check, rules_excluded, "standard", lua_entity, false)
 | 
						|
          end
 | 
						|
        else
 | 
						|
          ---resolve rule included
 | 
						|
          check = Player.checkRules(check, rules_included, category, lua_entity, true)
 | 
						|
          ---resolve rule excluded
 | 
						|
          check = Player.checkRules(check, rules_excluded, category, lua_entity, false)
 | 
						|
        end
 | 
						|
      else
 | 
						|
        --- take all production if category is nil
 | 
						|
        if lua_entity.group ~= nil and lua_entity.group.name == "production" then
 | 
						|
          check = true
 | 
						|
        end
 | 
						|
      end
 | 
						|
      ---resource filter
 | 
						|
      if check then
 | 
						|
        if lua_recipe.name ~= nil then
 | 
						|
          local lua_entity_filter = Player.getEntityPrototype(lua_recipe.name)
 | 
						|
          if lua_entity_filter ~= nil then
 | 
						|
            if lua_entity.resource_categories ~= nil and not(lua_entity.resource_categories[lua_entity_filter.resource_category]) then
 | 
						|
              check = false
 | 
						|
            elseif lua_entity_filter.mineable_properties and lua_entity_filter.mineable_properties.required_fluid then
 | 
						|
              local fluidboxes = EntityPrototype(lua_entity):getFluidboxPrototypes()
 | 
						|
              if #fluidboxes == 0 then
 | 
						|
                check = false
 | 
						|
              end
 | 
						|
            end
 | 
						|
          end
 | 
						|
        end
 | 
						|
      end
 | 
						|
      ---ok to add entity
 | 
						|
      if check then
 | 
						|
        productions[lua_entity.name] = lua_entity
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
  return productions
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Excludes entities that are placed only by a hidden item
 | 
						|
---@param entities table
 | 
						|
---@return table
 | 
						|
function Player.ExcludePlacedByHidden(entities)
 | 
						|
  local results = {}
 | 
						|
 | 
						|
  for entity_name, entity in pairs(entities) do
 | 
						|
    local item_filters = {}
 | 
						|
 | 
						|
    for _, item in pairs(entity.items_to_place_this or {}) do
 | 
						|
      if type(item) == "string" then
 | 
						|
        table.insert(item_filters, {filter="name", name=item, mode="or"})
 | 
						|
      elseif item.name then
 | 
						|
        table.insert(item_filters, {filter="name", name=item.name, mode="or"})
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    local show = false
 | 
						|
 | 
						|
    if #item_filters == 0 then
 | 
						|
      -- Has no items to place it. Probably placed by script.
 | 
						|
      -- e.g. Numal reef from Py
 | 
						|
      show = true
 | 
						|
    else
 | 
						|
      local items = game.get_filtered_item_prototypes(item_filters)
 | 
						|
      for _, item in pairs(items) do
 | 
						|
        if not item.has_flag("hidden") then
 | 
						|
          show = true
 | 
						|
          break
 | 
						|
        end
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    if show == true then
 | 
						|
      results[entity_name] = entity
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  return results
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return list of modules
 | 
						|
---@return table
 | 
						|
function Player.getModules()
 | 
						|
  local items = {}
 | 
						|
  local filters = {}
 | 
						|
  table.insert(filters,{filter="type",type="module",mode="or"})
 | 
						|
  table.insert(filters,{filter="flag",flag="hidden",mode="and", invert=true})
 | 
						|
 | 
						|
  for _,item in pairs(game.get_filtered_item_prototypes(filters)) do
 | 
						|
    table.insert(items,item)
 | 
						|
  end
 | 
						|
  return items
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return list of production machines
 | 
						|
---@return table
 | 
						|
function Player.getProductionMachines()
 | 
						|
  local cache_machines = Cache.getData(Player.classname, "list_machines")
 | 
						|
  if cache_machines ~= nil then
 | 
						|
    return cache_machines
 | 
						|
  end
 | 
						|
 | 
						|
  local filters = {}
 | 
						|
  table.insert(filters, {filter="crafting-machine", mode="or"})
 | 
						|
  table.insert(filters, {filter="hidden", mode="and", invert=true})
 | 
						|
  table.insert(filters, {filter="type", type="lab", mode="or"})
 | 
						|
  table.insert(filters, {filter="hidden", mode="and", invert=true})
 | 
						|
  table.insert(filters, {filter="type", type="mining-drill", mode="or"})
 | 
						|
  table.insert(filters, {filter="hidden", mode="and", invert=true})
 | 
						|
  table.insert(filters, {filter="type", type="rocket-silo", mode="or"})
 | 
						|
  table.insert(filters, {filter="hidden", mode="and", invert=true})
 | 
						|
  local prototypes = game.get_filtered_entity_prototypes(filters)
 | 
						|
  prototypes = Player.ExcludePlacedByHidden(prototypes)
 | 
						|
  
 | 
						|
  local list_machines = {}
 | 
						|
  for prototype_name, lua_prototype in pairs(prototypes) do
 | 
						|
    local machine = {name=lua_prototype.name, group=(lua_prototype.group or {}).name, subgroup=(lua_prototype.subgroup or {}).name, type=lua_prototype.type, order=lua_prototype.order, crafting_categories=lua_prototype.crafting_categories, resource_categories=lua_prototype.resource_categories}
 | 
						|
    table.insert(list_machines, machine)
 | 
						|
  end
 | 
						|
 | 
						|
  Cache.setData(Player.classname, "list_machines", list_machines)
 | 
						|
  return list_machines
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return list of energy machines
 | 
						|
---@return table
 | 
						|
function Player.getEnergyMachines()
 | 
						|
  local machines = {}
 | 
						|
 | 
						|
  local filters = {}
 | 
						|
  for _, type in pairs({"generator", "solar-panel", "accumulator", "reactor", "burner-generator", "electric-energy-interface"}) do
 | 
						|
    table.insert(filters, {filter="type", mode="or", invert=false, type=type})
 | 
						|
    table.insert(filters, {filter="hidden", mode="and", invert=true})
 | 
						|
    table.insert(filters, {filter="type", mode="or", invert=false, type=type})
 | 
						|
    table.insert(filters, {filter="flag", flag="player-creation", mode="and"})
 | 
						|
  end
 | 
						|
  for entity_name, entity in pairs(game.get_filtered_entity_prototypes(filters)) do
 | 
						|
    machines[entity_name] = entity
 | 
						|
  end
 | 
						|
 | 
						|
  machines = Player.ExcludePlacedByHidden(machines)
 | 
						|
  return machines
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return list of boilers
 | 
						|
---@param fluid_name string
 | 
						|
---@return table
 | 
						|
function Player.getBoilers(fluid_name)
 | 
						|
  local filters = {}
 | 
						|
  table.insert(filters, {filter="type", type="boiler", mode="or"})
 | 
						|
  table.insert(filters, {filter="hidden", mode="and", invert=true})
 | 
						|
  table.insert(filters, {filter="type", type="boiler", mode="or"})
 | 
						|
  table.insert(filters, {filter="flag", flag="player-creation", mode="and"})
 | 
						|
  local prototypes = game.get_filtered_entity_prototypes(filters)
 | 
						|
 | 
						|
  prototypes = Player.ExcludePlacedByHidden(prototypes)
 | 
						|
 | 
						|
  if fluid_name == nil then
 | 
						|
    return prototypes
 | 
						|
  else
 | 
						|
    local boilers = {}
 | 
						|
    for boiler_name, boiler in pairs(prototypes) do
 | 
						|
      for _, fluidbox in pairs(boiler.fluidbox_prototypes) do
 | 
						|
        if (fluidbox.production_type == "output") and fluidbox.filter and (fluidbox.filter.name == fluid_name) then
 | 
						|
          boilers[boiler_name] = boiler
 | 
						|
          break
 | 
						|
        end
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    return boilers
 | 
						|
  end
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return table of boiler recipes
 | 
						|
---@return table
 | 
						|
function Player.getBoilersForRecipe(recipe_prototype)
 | 
						|
  local boilers = {}
 | 
						|
 | 
						|
  for boiler_name, boiler in pairs(Player.getBoilers()) do
 | 
						|
    ---Check temperature
 | 
						|
    if boiler.target_temperature ~= recipe_prototype.output_fluid_temperature then
 | 
						|
      goto continue
 | 
						|
    end
 | 
						|
 | 
						|
    ---Check input fluid
 | 
						|
    local input_fluid
 | 
						|
    local fluidbox = boiler.fluidbox_prototypes[1]
 | 
						|
    if fluidbox.filter then
 | 
						|
      input_fluid = fluidbox.filter.name
 | 
						|
    end
 | 
						|
    if input_fluid ~= recipe_prototype.input_fluid_name then
 | 
						|
      goto continue
 | 
						|
    end
 | 
						|
 | 
						|
    ---Check output fluid
 | 
						|
    local output_fluid
 | 
						|
    for _, fluidbox in pairs(boiler.fluidbox_prototypes) do
 | 
						|
      if fluidbox.filter and fluidbox.production_type == "output" then
 | 
						|
        output_fluid = fluidbox.filter.name
 | 
						|
      end
 | 
						|
    end
 | 
						|
    if output_fluid ~= recipe_prototype.output_fluid_name then
 | 
						|
      goto continue
 | 
						|
    end
 | 
						|
    
 | 
						|
    boilers[boiler_name] = boiler
 | 
						|
 | 
						|
    ::continue::
 | 
						|
  end
 | 
						|
 | 
						|
  return boilers
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return list of Offshore-Pump
 | 
						|
---@param fluid_name string
 | 
						|
---@return table
 | 
						|
function Player.getOffshorePumps(fluid_name)
 | 
						|
  local filters = {}
 | 
						|
  table.insert(filters, {filter="type", type="offshore-pump", mode="or"})
 | 
						|
  local entities = game.get_filtered_entity_prototypes(filters)
 | 
						|
  local offshore_pump = {}
 | 
						|
  for key, entity in pairs(entities) do
 | 
						|
    if entity.fluid.name == fluid_name then
 | 
						|
      for _, fluidbox in pairs(entity.fluidbox_prototypes) do
 | 
						|
        if #fluidbox.pipe_connections > 0 then
 | 
						|
          offshore_pump[key] = entity
 | 
						|
          break
 | 
						|
        end
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
  return offshore_pump
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return module bonus (default return: bonus = 0 )
 | 
						|
---@param module string
 | 
						|
---@param effect string
 | 
						|
---@return number
 | 
						|
function Player.getModuleBonus(module, effect)
 | 
						|
  if module == nil then return 0 end
 | 
						|
  local bonus = 0
 | 
						|
  ---search module
 | 
						|
  local module = Player.getItemPrototype(module)
 | 
						|
  if module ~= nil and module.module_effects ~= nil and module.module_effects[effect] ~= nil then
 | 
						|
    bonus = module.module_effects[effect].bonus
 | 
						|
  end
 | 
						|
  return bonus
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return recipe prototype
 | 
						|
---@param name string
 | 
						|
---@return LuaRecipe
 | 
						|
function Player.getRecipe(name)
 | 
						|
  if name == nil then return nil end
 | 
						|
  return game.recipe_prototypes[name]
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return recipe
 | 
						|
---@param name string
 | 
						|
---@return LuaRecipe
 | 
						|
function Player.getPlayerRecipe(name)
 | 
						|
  if Lua_player ~= nil then
 | 
						|
    return Player.getForce().recipes[name]
 | 
						|
  end
 | 
						|
  return nil
 | 
						|
end
 | 
						|
 | 
						|
function Player.buildResourceRecipe(entity_prototype)
 | 
						|
  local prototype = entity_prototype:native()
 | 
						|
  if prototype == nil then return nil end
 | 
						|
  local ingredients = {}
 | 
						|
  if entity_prototype:getMineableMiningFluidRequired() then
 | 
						|
    local fluid_ingredient = {name=entity_prototype:getMineableMiningFluidRequired(), type="fluid", amount=entity_prototype:getMineableMiningFluidAmount()}
 | 
						|
    table.insert(ingredients, fluid_ingredient)
 | 
						|
  end
 | 
						|
  local recipe = {}
 | 
						|
  recipe.category = "extraction-machine"
 | 
						|
  recipe.enabled = true
 | 
						|
  recipe.energy = 1
 | 
						|
  recipe.force = {}
 | 
						|
  recipe.group = {name="helmod", order="zzzz"}
 | 
						|
  recipe.subgroup = {name="helmod-resource", order="aaaa"}
 | 
						|
  recipe.hidden = false
 | 
						|
  if prototype then
 | 
						|
    if prototype.flags ~= nil then
 | 
						|
      recipe.hidden = prototype.flags["hidden"] or false
 | 
						|
    end
 | 
						|
    recipe.localised_description = prototype.localised_description
 | 
						|
    recipe.localised_name = prototype.localised_name
 | 
						|
    recipe.name = prototype.name
 | 
						|
  end
 | 
						|
  recipe.ingredients = ingredients
 | 
						|
  recipe.products = entity_prototype:getMineableMiningProducts()
 | 
						|
  recipe.prototype = {}
 | 
						|
  recipe.valid = true
 | 
						|
 | 
						|
  return recipe
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return resource recipes
 | 
						|
---@return table
 | 
						|
function Player.getResourceRecipes()
 | 
						|
  local recipes = {}
 | 
						|
 | 
						|
  for key, prototype in pairs(game.entity_prototypes) do
 | 
						|
    if prototype.name ~= nil and prototype.resource_category ~= nil then
 | 
						|
      local recipe = Player.buildResourceRecipe(EntityPrototype(prototype))
 | 
						|
      if recipe ~= nil then
 | 
						|
        recipes[recipe.name] = recipe
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  return recipes
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return resource recipe
 | 
						|
---@param name string
 | 
						|
---@return table
 | 
						|
function Player.getResourceRecipe(name)
 | 
						|
  local entity_prototype = EntityPrototype(name)
 | 
						|
  local recipe = Player.buildResourceRecipe(entity_prototype)
 | 
						|
 | 
						|
  return recipe
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return energy recipe
 | 
						|
---@param name string
 | 
						|
---@return table
 | 
						|
function Player.getEnergyRecipe(name)
 | 
						|
  local entity_prototype = EntityPrototype(name)
 | 
						|
  local prototype = entity_prototype:native()
 | 
						|
  local recipe = {}
 | 
						|
  recipe.category = "energy"
 | 
						|
  recipe.enabled = true
 | 
						|
  recipe.energy = 1
 | 
						|
  recipe.force = {}
 | 
						|
  recipe.group = {name="helmod", order="zzzz"}
 | 
						|
  recipe.subgroup = {name="helmod-energy", order="dddd"}
 | 
						|
  recipe.hidden = false
 | 
						|
  if prototype ~= nil and prototype.flags ~= nil then
 | 
						|
    recipe.hidden = prototype.flags["hidden"] or false
 | 
						|
  end
 | 
						|
  recipe.ingredients = {}
 | 
						|
  recipe.products = {}
 | 
						|
  recipe.localised_description = prototype.localised_description
 | 
						|
  recipe.localised_name = prototype.localised_name
 | 
						|
  recipe.name = prototype.name
 | 
						|
  recipe.prototype = {}
 | 
						|
  recipe.valid = true
 | 
						|
 | 
						|
  return recipe
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return table of fluid recipes
 | 
						|
---@return table
 | 
						|
function Player.getFluidRecipes()
 | 
						|
  local recipes = {}
 | 
						|
 | 
						|
  ---Offshore pumps
 | 
						|
  local filters = {}
 | 
						|
  table.insert(filters, {filter="type", type="offshore-pump", mode="or"})
 | 
						|
  local entities = game.get_filtered_entity_prototypes(filters)
 | 
						|
  for key, entity in pairs(entities) do
 | 
						|
    for _, fluidbox in pairs(entity.fluidbox_prototypes) do
 | 
						|
      if #fluidbox.pipe_connections > 0 then
 | 
						|
        local recipe = Player.buildFluidRecipe(entity.fluid.name, {}, nil)
 | 
						|
        recipe.subgroup = {name="helmod-fluid", order="bbbb"}
 | 
						|
        if not recipes[entity.fluid.name] then
 | 
						|
          recipes[entity.fluid.name] = recipe
 | 
						|
        end
 | 
						|
        if entity.has_flag("hidden") then
 | 
						|
          recipes[entity.fluid.name].hidden = true
 | 
						|
        end
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  return recipes
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return recipe
 | 
						|
---@param name string
 | 
						|
---@return table
 | 
						|
function Player.getFluidRecipe(name)
 | 
						|
  local recipes = Player.getFluidRecipes()
 | 
						|
  return recipes[name]
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return table of boiler recipes
 | 
						|
---@return table
 | 
						|
function Player.getBoilerRecipes()
 | 
						|
  local recipes = {}
 | 
						|
 | 
						|
  ---Boilers
 | 
						|
  local boilers = Player.getBoilers()
 | 
						|
 | 
						|
  for boiler_name, boiler in pairs(boilers) do
 | 
						|
    local input_fluid
 | 
						|
    local output_fluid
 | 
						|
 | 
						|
    local fluidbox = boiler.fluidbox_prototypes[1]
 | 
						|
    if fluidbox.filter then
 | 
						|
      input_fluid = fluidbox.filter.name
 | 
						|
    end
 | 
						|
 | 
						|
    for _, fluidbox in pairs(boiler.fluidbox_prototypes) do
 | 
						|
      if fluidbox.filter and fluidbox.production_type == "output" then
 | 
						|
        output_fluid = fluidbox.filter.name
 | 
						|
      end
 | 
						|
    end
 | 
						|
 | 
						|
    if input_fluid ~= nil and output_fluid ~= nil then
 | 
						|
      local ingredients = {{name=input_fluid, type="fluid", amount=1}}
 | 
						|
      local fluid_prototype = FluidPrototype(output_fluid)
 | 
						|
      local recipe = Player.buildFluidRecipe(fluid_prototype, ingredients, boiler.target_temperature)
 | 
						|
      recipe.subgroup = {name="helmod-boiler", order="cccc"}
 | 
						|
      recipe.input_fluid_name = input_fluid
 | 
						|
      recipe.output_fluid_name = output_fluid
 | 
						|
      recipe.output_fluid_temperature = boiler.target_temperature
 | 
						|
 | 
						|
      if not recipes[recipe.name] then
 | 
						|
        recipes[recipe.name] = recipe
 | 
						|
      end
 | 
						|
      if boiler.has_flag("hidden") then
 | 
						|
        recipes[recipe.name].hidden = true
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  return recipes
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return recipe
 | 
						|
---@param name string
 | 
						|
---@return table
 | 
						|
function Player.getBoilerRecipe(name)
 | 
						|
  local recipes = Player.getBoilerRecipes()
 | 
						|
  return recipes[name]
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return recipe
 | 
						|
---@param ingredients table
 | 
						|
---@param fluid string|table
 | 
						|
---@param temperature number
 | 
						|
---@return table
 | 
						|
function Player.buildFluidRecipe(fluid, ingredients, temperature)
 | 
						|
  local fluid_prototype
 | 
						|
  if type(fluid) == "string" then
 | 
						|
    fluid_prototype = FluidPrototype(fluid)
 | 
						|
  else
 | 
						|
    fluid_prototype = fluid
 | 
						|
  end
 | 
						|
 | 
						|
  local prototype = fluid_prototype:native()
 | 
						|
  local products = {{name=prototype.name, type="fluid", amount=1, temperature=temperature}}
 | 
						|
  local recipe = {}
 | 
						|
  recipe.enabled = true
 | 
						|
  recipe.energy = 1
 | 
						|
  recipe.force = {}
 | 
						|
  recipe.group = {name="helmod", order="zzzz"}
 | 
						|
  recipe.subgroup = {}
 | 
						|
  recipe.hidden = false
 | 
						|
  recipe.ingredients = ingredients
 | 
						|
  recipe.products = products
 | 
						|
  recipe.localised_description = prototype.localised_description
 | 
						|
  recipe.localised_name = prototype.localised_name
 | 
						|
  if temperature ~= nil then
 | 
						|
    recipe.name = string.format("%s#%s", prototype.name, temperature)
 | 
						|
  else
 | 
						|
    recipe.name = prototype.name
 | 
						|
  end
 | 
						|
  if #ingredients > 0 then
 | 
						|
    recipe.name = string.format("%s->%s", ingredients[1].name, recipe.name)
 | 
						|
  end
 | 
						|
  recipe.category = recipe.name
 | 
						|
  recipe.prototype = {}
 | 
						|
  recipe.valid = true
 | 
						|
 | 
						|
  return recipe
 | 
						|
end
 | 
						|
 | 
						|
function Player.getRocketPartRecipe(factory)
 | 
						|
  -- Get rocket silos
 | 
						|
  local silos = {}
 | 
						|
  if factory and factory.name then
 | 
						|
    silos = {game.entity_prototypes[factory.name]}
 | 
						|
  else
 | 
						|
    local entity_filters = {
 | 
						|
      {filter = "type", invert = false, mode = "and", type = "rocket-silo"},
 | 
						|
      {filter = "hidden", invert = true, mode = "and"},
 | 
						|
    }
 | 
						|
    silos = game.get_filtered_entity_prototypes(entity_filters)
 | 
						|
  end
 | 
						|
 | 
						|
  -- Get rocket silo fixed recipes
 | 
						|
  local rocket_part_recipes = {}
 | 
						|
  for _, silo_prototype in pairs(silos) do
 | 
						|
    if silo_prototype.fixed_recipe then
 | 
						|
      table.insert(rocket_part_recipes, game.recipe_prototypes[silo_prototype.fixed_recipe])
 | 
						|
    end
 | 
						|
  end
 | 
						|
  
 | 
						|
  if #rocket_part_recipes == 0 then
 | 
						|
    return nil
 | 
						|
  else
 | 
						|
    return rocket_part_recipes[1]
 | 
						|
  end
 | 
						|
end
 | 
						|
 | 
						|
function Player.buildRocketRecipe(prototype)
 | 
						|
  if prototype == nil then return nil end
 | 
						|
  local products = prototype.rocket_launch_products
 | 
						|
  local ingredients = {}
 | 
						|
  local item_prototype = ItemPrototype(prototype.name)
 | 
						|
  local stack_size = item_prototype:stackSize()
 | 
						|
  table.insert(ingredients, {name=prototype.name, type="item", amount=1, constant=true})
 | 
						|
  local recipe = {}
 | 
						|
  recipe.category = Player.getRocketPartRecipe().category
 | 
						|
  recipe.enabled = true
 | 
						|
  recipe.energy = 1
 | 
						|
  recipe.force = {}
 | 
						|
  recipe.group = {name="helmod", order="zzzz"}
 | 
						|
  recipe.subgroup = {name="helmod-rocket", order="eeee"}
 | 
						|
  recipe.hidden = false
 | 
						|
  recipe.ingredients = ingredients
 | 
						|
  for key, product in pairs(products) do
 | 
						|
    local product_prototype = ItemPrototype(product.name)
 | 
						|
    local i=0
 | 
						|
  end
 | 
						|
  recipe.products = products
 | 
						|
  recipe.localised_description = prototype.localised_description
 | 
						|
  recipe.localised_name = prototype.localised_name
 | 
						|
  recipe.name = prototype.name
 | 
						|
  recipe.prototype = {}
 | 
						|
  recipe.valid = true
 | 
						|
 | 
						|
  return recipe
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return table of recipe
 | 
						|
---@return table
 | 
						|
function Player.getRocketRecipes()
 | 
						|
  local recipes = {}
 | 
						|
  
 | 
						|
  if Player.getRocketPartRecipe() ~= nil then
 | 
						|
    for key, item_prototype in pairs(Player.getItemPrototypes()) do
 | 
						|
      if item_prototype.rocket_launch_products ~= nil and table.size(item_prototype.rocket_launch_products) > 0 then
 | 
						|
        local recipe = Player.buildRocketRecipe(item_prototype)
 | 
						|
        recipes[recipe.name] = recipe
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
  return recipes
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return recipe
 | 
						|
---@param name string
 | 
						|
---@return table
 | 
						|
function Player.getRocketRecipe(name)
 | 
						|
  local item_prototype = ItemPrototype(name)
 | 
						|
  local prototype = item_prototype:native()
 | 
						|
  local recipe = Player.buildRocketRecipe(prototype)
 | 
						|
 | 
						|
  return recipe
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return recipe
 | 
						|
---@param name string
 | 
						|
---@return table
 | 
						|
function Player.getBurntRecipe(name)
 | 
						|
  local recipe_prototype = Player.getRecipe(name)
 | 
						|
  local recipe = {}
 | 
						|
  recipe.category = recipe_prototype.category
 | 
						|
  recipe.enabled = true
 | 
						|
  recipe.energy = recipe_prototype.energy
 | 
						|
  recipe.force = {}
 | 
						|
  recipe.group = {name="helmod", order="zzzz"}
 | 
						|
  recipe.subgroup = {name="helmod-recipe-burnt", order="ffff"}
 | 
						|
  recipe.hidden = false
 | 
						|
  recipe.ingredients = recipe_prototype.ingredients
 | 
						|
  recipe.products = recipe_prototype.products
 | 
						|
  recipe.localised_description = recipe_prototype.localised_description
 | 
						|
  recipe.localised_name = recipe_prototype.localised_name
 | 
						|
  recipe.name = recipe_prototype.name
 | 
						|
  recipe.prototype = {}
 | 
						|
  recipe.valid = true
 | 
						|
  recipe.hidden_from_player_crafting = recipe_prototype.hidden_from_player_crafting
 | 
						|
 | 
						|
  return recipe
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return list of recipes
 | 
						|
---@param element_name string
 | 
						|
---@param by_ingredient boolean
 | 
						|
---@return table
 | 
						|
function Player.searchRecipe(element_name, by_ingredient)
 | 
						|
  local recipes = {}
 | 
						|
  ---recherche dans les produits des recipes
 | 
						|
  for key, recipe in pairs(Player.getPlayerRecipes()) do
 | 
						|
    local elements = recipe.products or {}
 | 
						|
    if by_ingredient == true then
 | 
						|
      elements = recipe.ingredients or {}
 | 
						|
    end
 | 
						|
    for k, element in pairs(elements) do
 | 
						|
      if element.name == element_name then
 | 
						|
        table.insert(recipes,{name=recipe.name, type="recipe"})
 | 
						|
        break
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
  ---recherche dans les resource
 | 
						|
  for key, resource in pairs(Player.getResources()) do
 | 
						|
    local elements = EntityPrototype(resource):getMineableMiningProducts()
 | 
						|
    for key, element in pairs(elements) do
 | 
						|
      if element.name == element_name then
 | 
						|
        table.insert(recipes,{name=resource.name, type="resource"})
 | 
						|
        break
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
  ---recherche dans les fluids
 | 
						|
  for key, recipe in pairs(Player.getFluidRecipes()) do
 | 
						|
    if recipe.name == element_name then
 | 
						|
      table.insert(recipes, {name=recipe.name, type="fluid"})
 | 
						|
    end
 | 
						|
  end
 | 
						|
  for key, recipe in pairs(Player.getBoilerRecipes()) do
 | 
						|
    if recipe.name == element_name then
 | 
						|
      table.insert(recipes, {name=recipe.name, type="boiler"})
 | 
						|
    end
 | 
						|
  end
 | 
						|
  return recipes
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return entity prototypes
 | 
						|
---@param filters table --{{filter="type", mode="or", invert=false type="transport-belt"}}
 | 
						|
---@return table
 | 
						|
function Player.getEntityPrototypes(filters)
 | 
						|
  if filters ~= nil then
 | 
						|
    return game.get_filtered_entity_prototypes(filters)
 | 
						|
  end
 | 
						|
  return game.entity_prototypes
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return entity prototype types
 | 
						|
---@return table
 | 
						|
function Player.getEntityPrototypeTypes()
 | 
						|
  local types = {}
 | 
						|
  for _,entity in pairs(game.entity_prototypes) do
 | 
						|
    local type = entity.type
 | 
						|
    types[type] = true
 | 
						|
  end
 | 
						|
  return types
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return entity prototype
 | 
						|
---@param name string
 | 
						|
---@return LuaEntityPrototype
 | 
						|
function Player.getEntityPrototype(name)
 | 
						|
  if name == nil then return nil end
 | 
						|
  return game.entity_prototypes[name]
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return beacon production
 | 
						|
---@return table
 | 
						|
function Player.getProductionsBeacon()
 | 
						|
  local items = {}
 | 
						|
  local filters = {}
 | 
						|
  table.insert(filters,{filter="type",type="beacon",mode="or"})
 | 
						|
  table.insert(filters,{filter="hidden",invert=true,mode="and"})
 | 
						|
 | 
						|
  for _,item in pairs(game.get_filtered_entity_prototypes(filters)) do
 | 
						|
    table.insert(items,item)
 | 
						|
  end
 | 
						|
  return items
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return resources list
 | 
						|
---@return table
 | 
						|
function Player.getResources()
 | 
						|
  local cache_resources = Cache.getData(Player.classname, "resources")
 | 
						|
  if cache_resources ~= nil then return cache_resources end
 | 
						|
  local items = {}
 | 
						|
  for _,item in pairs(game.entity_prototypes) do
 | 
						|
    if item.name ~= nil and item.resource_category ~= nil then
 | 
						|
      table.insert(items,item)
 | 
						|
    end
 | 
						|
  end
 | 
						|
  Cache.setData(Player.classname, "resources", items)
 | 
						|
  return items
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return item prototypes
 | 
						|
---@param filters table --{{filter="fuel-category", mode="or", invert=false,["fuel-category"]="chemical"}}
 | 
						|
---@return table
 | 
						|
function Player.getItemPrototypes(filters)
 | 
						|
  if filters ~= nil then
 | 
						|
    return game.get_filtered_item_prototypes(filters)
 | 
						|
  end
 | 
						|
  return game.item_prototypes
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return item prototype types
 | 
						|
---@return table
 | 
						|
function Player.getItemPrototypeTypes()
 | 
						|
  local types = {}
 | 
						|
  for _,entity in pairs(game.item_prototypes) do
 | 
						|
    local type = entity.type
 | 
						|
    types[type] = true
 | 
						|
  end
 | 
						|
  return types
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return item prototype
 | 
						|
---@param name string
 | 
						|
---@return LuaItemPrototype
 | 
						|
function Player.getItemPrototype(name)
 | 
						|
  if name == nil then return nil end
 | 
						|
  return game.item_prototypes[name]
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return fluid prototypes
 | 
						|
---@param filters table --{{filter="type", mode="or", invert=false type="transport-belt"}}
 | 
						|
---@return table
 | 
						|
function Player.getFluidPrototypes(filters)
 | 
						|
  if filters ~= nil then
 | 
						|
    return game.get_filtered_fluid_prototypes(filters)
 | 
						|
  end
 | 
						|
  return game.fluid_prototypes
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return fluid prototype types
 | 
						|
---@return table
 | 
						|
function Player.getFluidPrototypeTypes()
 | 
						|
  local types = {}
 | 
						|
  for _,entity in pairs(game.fluid_prototypes) do
 | 
						|
    local type = entity.type
 | 
						|
    types[type] = true
 | 
						|
  end
 | 
						|
  return types
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return fluid prototype subgroups
 | 
						|
---@return table
 | 
						|
function Player.getFluidPrototypeSubgroups()
 | 
						|
  local types = {}
 | 
						|
  for _,entity in pairs(game.fluid_prototypes) do
 | 
						|
    local type = entity.subgroup.name
 | 
						|
    types[type] = true
 | 
						|
  end
 | 
						|
  return types
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return fluid prototype
 | 
						|
---@param name string
 | 
						|
---@return LuaFluidPrototype
 | 
						|
function Player.getFluidPrototype(name)
 | 
						|
  if name == nil then return nil end
 | 
						|
  return game.fluid_prototypes[name]
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return fluid fuel prototype
 | 
						|
---@return table
 | 
						|
function Player.getFluidFuelPrototypes()
 | 
						|
  local filters = {}
 | 
						|
  table.insert(filters, {filter = "hidden", invert = true, mode = "and"})
 | 
						|
  table.insert(filters, {filter = "fuel-value", mode= "and", invert = false, comparison = ">", value = 0})
 | 
						|
 | 
						|
  local items = {}
 | 
						|
  
 | 
						|
  for _, fluid in spairs(Player.getFluidPrototypes(filters), function(t,a,b) return t[b].fuel_value > t[a].fuel_value end) do
 | 
						|
    table.insert(items, FluidPrototype(fluid))
 | 
						|
  end
 | 
						|
  return items
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return items logistic
 | 
						|
---@param type string --belt, container or transport
 | 
						|
---@return table
 | 
						|
function Player.getItemsLogistic(type)
 | 
						|
  local filters = {}
 | 
						|
  if type == "inserter" then
 | 
						|
    filters = {{filter="type", mode="or", invert=false, type="inserter"}}
 | 
						|
  elseif type == "belt" then
 | 
						|
    filters = {{filter="type", mode="or", invert=false, type="transport-belt"}}
 | 
						|
  elseif type == "container" then
 | 
						|
    filters = {{filter="type", mode="or", invert=false, type="container"}, {filter="minable", mode="and", invert=false}, {filter="type", mode="or", invert=false, type="logistic-container"}, {filter="minable", mode="and", invert=false}}
 | 
						|
  elseif type == "transport" then
 | 
						|
    filters = {{filter="type", mode="or", invert=false, type="cargo-wagon"}, {filter="type", mode="or", invert=false, type="logistic-robot"}, {filter="type", mode="or", invert=false, type="car"}}
 | 
						|
  end
 | 
						|
  return Player.getEntityPrototypes(filters)
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return default item logistic
 | 
						|
---@param type string --belt, container or transport
 | 
						|
---@return table
 | 
						|
function Player.getDefaultItemLogistic(type)
 | 
						|
  local default = User.getParameter(string.format("items_logistic_%s", type))
 | 
						|
  if default == nil then 
 | 
						|
    local logistics = Player.getItemsLogistic(type)
 | 
						|
    if logistics ~= nil then
 | 
						|
      default = first(logistics).name
 | 
						|
      User.setParameter(string.format("items_logistic_%s", type), default)
 | 
						|
    end
 | 
						|
  end
 | 
						|
  return default
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return fluids logistic
 | 
						|
---@param type string --pipe, container or transport
 | 
						|
---@return table
 | 
						|
function Player.getFluidsLogistic(type)
 | 
						|
  local filters = {}
 | 
						|
  if type == "pipe" then
 | 
						|
    filters = {{filter="type", mode="or", invert=false, type="pipe"}}
 | 
						|
  elseif type == "container" then
 | 
						|
    filters = {{filter="type", mode="or", invert=false, type="storage-tank"}, {filter="minable", mode="and", invert=false}}
 | 
						|
  elseif type == "transport" then
 | 
						|
    filters = {{filter="type", mode="or", invert=false, type="fluid-wagon"}}
 | 
						|
  end
 | 
						|
  return Player.getEntityPrototypes(filters)
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return default fluid logistic
 | 
						|
---@param type string --pipe, container or transport
 | 
						|
---@return table
 | 
						|
function Player.getDefaultFluidLogistic(type)
 | 
						|
  local default = User.getParameter(string.format("fluids_logistic_%s", type))
 | 
						|
  if default == nil then 
 | 
						|
    local logistics = Player.getFluidsLogistic(type)
 | 
						|
    if logistics ~= nil then
 | 
						|
      default = first(logistics).name
 | 
						|
      User.setParameter(string.format("fluids_logistic_%s", type), default)
 | 
						|
    end
 | 
						|
  end
 | 
						|
  return default
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return number
 | 
						|
---@param number string
 | 
						|
---@return number
 | 
						|
function Player.parseNumber(number)
 | 
						|
  if number == nil then return 0 end
 | 
						|
  local value = string.match(number,"[0-9.]*",1)
 | 
						|
  local power = string.match(number,"[0-9.]*([a-zA-Z]*)",1)
 | 
						|
  if power == nil then
 | 
						|
    return tonumber(value)
 | 
						|
  elseif string.lower(power) == "kw" then
 | 
						|
    return tonumber(value)*1000
 | 
						|
  elseif string.lower(power) == "mw" then
 | 
						|
    return tonumber(value)*1000*1000
 | 
						|
  elseif string.lower(power) == "gw" then
 | 
						|
    return tonumber(value)*1000*1000*1000
 | 
						|
  elseif string.lower(power) == "kj" then
 | 
						|
    return tonumber(value)*1000
 | 
						|
  elseif string.lower(power) == "mj" then
 | 
						|
    return tonumber(value)*1000*1000
 | 
						|
  elseif string.lower(power) == "gj" then
 | 
						|
    return tonumber(value)*1000*1000*1000
 | 
						|
  end
 | 
						|
end
 | 
						|
 | 
						|
-------------------------------------------------------------------------------
 | 
						|
---Return fluid prototypes with temperature
 | 
						|
---@param fluid LuaFluidPrototype
 | 
						|
---@return table
 | 
						|
function Player.getFluidTemperaturePrototypes(fluid)
 | 
						|
 | 
						|
  -- Find all ways of making this fluid
 | 
						|
 | 
						|
  local temperatures = {}
 | 
						|
 | 
						|
  -- Recipes
 | 
						|
  local filters = {}
 | 
						|
  ---Hidden fluids do need to be included unfortunately. Only real alternative would be to add a setting.
 | 
						|
  ---table.insert(filters, {filter = "hidden", invert = true, mode = "and"})
 | 
						|
  table.insert(filters, {filter = "has-product-fluid", elem_filters = {{filter = "name", name = fluid.name}}, mode = "and"})
 | 
						|
  local prototypes = game.get_filtered_recipe_prototypes(filters)
 | 
						|
 | 
						|
  for recipe_name, recipe in pairs(prototypes) do
 | 
						|
    for product_name, product in pairs(recipe.products) do
 | 
						|
      if product.name == fluid.name and product.temperature then
 | 
						|
        temperatures[product.temperature] = true
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  -- Boilers
 | 
						|
  local boilers = Player.getBoilers()
 | 
						|
 | 
						|
  for boiler_name, boiler in pairs(boilers) do
 | 
						|
    for _, fluidbox in pairs(boiler.fluidbox_prototypes) do
 | 
						|
      if (fluidbox.production_type == "output") and fluidbox.filter and (fluidbox.filter.name == fluid.name) then
 | 
						|
        temperatures[boiler.target_temperature] = true
 | 
						|
      end
 | 
						|
    end
 | 
						|
  end
 | 
						|
 | 
						|
  -- Build result table of FluidPrototype
 | 
						|
  local items = {}
 | 
						|
  local item
 | 
						|
  for temperature, _ in spairs(temperatures, function(t,a,b) return b > a end) do
 | 
						|
    item = FluidPrototype(fluid)
 | 
						|
    item:setTemperature(temperature)
 | 
						|
    table.insert(items, item)
 | 
						|
  end
 | 
						|
 | 
						|
  return items
 | 
						|
end
 | 
						|
 | 
						|
return Player |