Первый фикс

Пачки некоторых позиций увеличены
This commit is contained in:
2024-03-01 20:53:32 +03:00
commit 7c9c708c92
23653 changed files with 767936 additions and 0 deletions

View File

@@ -0,0 +1,30 @@
local box = scripts.helpers
local _ = scripts.helpers.on
-- Helper functions for BoundingBox --
function box:boxoffset(arg1, arg2) -- accepts Position or x,y
local offx, offy = arg1, arg2
if arg2 == nil then offx, offy = arg1.x, arg1.y end
local x1, y1, x2, y2 = self.left_top.x, self.left_top.y, self.right_bottom.x, self.right_bottom.y
return _{left_top = {x = x1 + offx, y = y1 + offy}, right_bottom = {x = x2 + offx, y = y2 + offy}}
end
function box:expand(tilesx, tilesy) -- by number of tiles (y defaults to x)
tilesy = tilesy or tilesx
local x1, y1, x2, y2 = self.left_top.x, self.left_top.y, self.right_bottom.x, self.right_bottom.y
return _{left_top = {x = x1 - tilesx, y = y1 - tilesy}, right_bottom = {x = x2 + tilesx, y = y2 + tilesy}}
end
function box:boxwidth()
return self.right_bottom.x - self.left_top.x
end
function box:boxheight()
return self.right_bottom.y - self.left_top.y
end
function box:area()
return (self.right_bottom.x - self.left_top.x) * (self.right_bottom.y - self.left_top.y)
end

View File

@@ -0,0 +1,239 @@
local config = require("config")
local control = scripts.helpers
local _ = scripts.helpers.on
-- Helper functions for LuaControl --
function control:itemcount(...)
if self.is_player() then
return self:playeritemcount(...)
else
return self.get_item_count(...)
end
end
function control:requests(...)
if self.is_player() then
return _(self.character):entityrequests(...)
else
return self:entityrequests(...)
end
end
function control:request(...)
if self.is_player() then
return _(self.character):entityrequest(...)
else
return self:entityrequest(...)
end
end
function control:remainingRequest(item)
return self:request(item) - self.get_item_count(item)
end
function control:inventory(name)
if name == nil or name == "main" then -- get main inventory
return self.get_main_inventory() or
(self.type == "container" and self.get_inventory(defines.inventory.chest)) or
(self.type == "logistic-container" and self.get_inventory(defines.inventory.chest)) or
(self.type == "car" and self.get_inventory(defines.inventory.car_trunk)) or
(self.type == "spider-vehicle" and self.get_inventory(defines.inventory.car_trunk)) or
(self.type == "cargo-wagon" and self.get_inventory(defines.inventory.cargo_wagon)) or
(self.type == "rocket-silo" and self.get_inventory(defines.inventory.rocket_silo_rocket))
elseif name == "input" then
return (self.type == "furnace" and self.get_inventory(defines.inventory.furnace_source)) or
(self.type == "assembling-machine" and self.get_inventory(defines.inventory.assembling_machine_input)) or
(self.type == "lab" and self.get_inventory(defines.inventory.lab_input)) or
(self.type == "rocket-silo" and self.get_inventory(defines.inventory.assembling_machine_input))
elseif name == "output" then
return self.get_output_inventory()
elseif name == "modules" then
return self.get_module_inventory()
elseif name == "ammo" then
return (self.type == "ammo-turret" and self.get_inventory(defines.inventory.turret_ammo)) or
(self.type == "car" and self.get_inventory(defines.inventory.car_ammo)) or
(self.type == "spider-vehicle" and self.get_inventory(defines.inventory.car_ammo)) or
(self.type == "artillery-wagon" and self.get_inventory(defines.inventory.artillery_wagon_ammo)) or
(self.type == "artillery-turret" and self.get_inventory(defines.inventory.artillery_turret_ammo)) or
(self.type == "character" and self.get_inventory(defines.inventory.character_ammo)) or
(self.type == "character" and self.get_inventory(defines.inventory.editor_ammo))
elseif name == "fuel" then
return self.get_fuel_inventory()
elseif name == "burnt_result" then
return self.get_burnt_result_inventory()
end
-- get specific inventory
return self.get_inventory(defines.inventory[name])
end
function control:contents(name)
if name == nil and self.is_player() then
return self:playercontents()
end
local inv = self:inventory(name)
if _(inv):isnot("valid") then return {} end
return inv.get_contents()
end
local function insert(self, name, item, amount)
if amount <= 0 then return 0 end
local inv = self:inventory(name)
if inv then
-- inv.sort_and_merge()
local inserted = inv.insert{ name = item, count = amount }
if inserted < amount then -- retry for things like furnace ingredients (can be overfilled)
inserted = inserted + inv.insert{ name = item, count = amount - inserted }
end
return inserted
end
return 0
end
-- priority insert with fuel and ammo limits
function control:customInsert(player, item, amount, takenFromCar, takenFromTrash, replaceItems, useFuelLimit, useAmmoLimit, useRequestLimit, allowed)
if amount <= 0 then return 0 end
local inserted = 0
local prototype = _(game.item_prototypes[item])
-- allow/disallow insertion into specific inventories by passing table with true/false values (default is allow)
allowed = _({
fuel = true, -- set default values
ammo = true,
input = true,
output = true,
modules = true,
roboport = true,
main = true,
}):set(allowed or {}):toPlain()
if allowed.fuel and prototype:is("fuel") then
local inv = self:inventory("fuel")
if inv then
local limit = useFuelLimit and math.min(amount, math.max(0, player:itemLimit(prototype, config.fuelLimitProfiles) - inv.get_item_count(item))) or amount
local insertedHere = insert(self, "fuel", item, limit)
limit = limit - insertedHere
-- no space left --> replace inferior items
if replaceItems and limit > 0 then
for __,inferiorFuel in pairs(global.fuelList[prototype.fuel_category]) do
if inferiorFuel.name == prototype.name or limit <= 0 then break end
local returnToPlayer = 0
while limit > 0 do
local stack = inv.find_item_stack(inferiorFuel.name)
local returnCount = stack and stack.count or 0
if stack and stack.set_stack{ name = item, count = limit } then
limit = limit - stack.count
insertedHere = insertedHere + stack.count
returnToPlayer = returnToPlayer + returnCount
else
break
end
end
if returnToPlayer > 0 then
player:returnItems(inferiorFuel.name, returnToPlayer, takenFromCar, takenFromTrash)
end
end
end
inserted = inserted + insertedHere
amount = amount - insertedHere
end
end
if amount <= 0 then return inserted end
if allowed.ammo and prototype:is("ammo") then
local inv = self:inventory("ammo")
if inv then
local limit = useAmmoLimit and math.min(amount, math.max(0, player:itemLimit(prototype, config.ammoLimitProfiles) - inv.get_item_count(item))) or amount
local insertedHere = insert(self, "ammo", item, limit)
limit = limit - insertedHere
-- no space left --> replace inferior items
if replaceItems and limit > 0 then
for __,inferiorAmmo in pairs(global.ammoList[prototype.get_ammo_type().category]) do
if inferiorAmmo.name == prototype.name or limit <= 0 then break end
local returnToPlayer = 0
while limit > 0 do
local stack = inv.find_item_stack(inferiorAmmo.name)
local returnCount = stack and stack.count or 0
if stack and stack.set_stack{ name = item, count = limit } then
limit = limit - stack.count
insertedHere = insertedHere + stack.count
returnToPlayer = returnToPlayer + returnCount
else
break
end
end
if returnToPlayer > 0 then
player:returnItems(inferiorAmmo.name, returnToPlayer, takenFromCar, takenFromTrash)
end
end
end
inserted = inserted + insertedHere
amount = amount - insertedHere
end
end
if amount <= 0 then return inserted end
if allowed.input then
local insertedHere = insert(self, "input", item, amount)
inserted = inserted + insertedHere
amount = amount - insertedHere
if insertedHere > 0 then allowed.main = false end
end
if amount <= 0 then return inserted end
if allowed.output and self:recipe():hasProduct(item) then
local insertedHere = insert(self, "output", item, amount)
inserted = inserted + insertedHere
amount = amount - insertedHere
end
if amount <= 0 then return inserted end
if allowed.modules then
local insertedHere = insert(self, "modules", item, amount)
inserted = inserted + insertedHere
amount = amount - insertedHere
if insertedHere > 0 then allowed.main = false end
end
if allowed.roboport and self.type == "roboport" then
if amount <= 0 then return inserted end
local insertedHere = insert(self, "roboport_robot", item, amount)
inserted = inserted + insertedHere
amount = amount - insertedHere
if amount <= 0 then return inserted end
insertedHere = insert(self, "roboport_material", item, amount)
inserted = inserted + insertedHere
amount = amount - insertedHere
end
if amount <= 0 then return inserted end
if allowed.main then
local limit = useRequestLimit and math.min(amount, math.max(0, self:remainingRequest(item))) or amount
local insertedHere = insert(self, "main", item, limit)
inserted = inserted + insertedHere
amount = amount - insertedHere
end
return inserted
end

View File

@@ -0,0 +1,91 @@
local util = scripts.util
local config = require("config")
local entity = scripts.helpers
local _ = scripts.helpers.on
-- Helper functions for LuaEntity --
function entity:entityrequests() -- fetch all requests as table
local requests = {}
if self.request_slot_count > 0 then
for i = 1, self.request_slot_count do
local request = self.get_request_slot(i)
if request then
local item, amount = request.name, request.count
if amount > 0 then
requests[item] = math.max(requests[item] or 0, amount)
end
end
end
end
return requests
end
function entity:entityrequest(item) -- fetch specific item request
local count = 0
if self.request_slot_count > 0 then
for i = 1, self.request_slot_count do
local request = self.get_request_slot(i)
if request and request.name == item and request.count > count then
count = math.max(count, request.count)
end
end
end
return count
end
function entity:logisticSlots() -- fetch all requests as table
local logisticSlots = {}
if self.request_slot_count > 0 then
for i = 1, self.request_slot_count do
local slot = self.get_personal_logistic_slot(i)
if slot and slot.name then
logisticSlots[slot.name] = slot
end
end
end
return logisticSlots
end
function entity:isIgnored(player)
return not global.allowedEntities[self.name] or
global.settings[player.index].ignoredEntities[self.name] or
global.remoteIgnoredEntities[self.name]
end
function entity:recipe()
return _(self.get_recipe() or (self.type == "furnace" and self.previous_recipe))
end
-- for turrets
function entity:supportsAmmo(item)
local ammoType = item.get_ammo_type("turret") or item.get_ammo_type()
if ammoType then
local attackParameters = self.prototype.attack_parameters
if attackParameters then
return _(attackParameters.ammo_categories):contains(ammoType.category)
elseif self.type == "artillery-turret" or self.type == "artillery-wagon" then
return ammoType.category == "artillery-shell"
end
end
return false
end
-- for furnace
function entity:canSmelt(item)
return #game.get_filtered_recipe_prototypes({
unpack(_(self.prototype.crafting_categories):map(function(category)
return nil, {filter = "category", category = category, mode = "or"}
end):toPlain()),
{filter = "has-ingredient-item", elem_filters = {{filter = "name", name = item}}, mode = "and"},
}) > 0
end

View File

@@ -0,0 +1,124 @@
local this = {}
local config = require("config")
local prototype = scripts.helpers
local _ = scripts.helpers.on
function prototype:calculateDamage()
local type = self.get_ammo_type()
return type and type.action and this.damageFromActions(type.action) or 0
end
function prototype:calculateRadius()
local type = self.get_ammo_type()
return type and type.action and this.radiusFromActions(type.action) or 0
end
function this.damageFromActions(actions)
return _(actions)
:sum(function(__,action)
return this.damageFromAction(action) * action.repeat_count
end)
end
function this.damageFromAction(action)
if action.action_delivery then
local multiplier = action.radius and action.radius * action.radius * math.pi or 1
return _(action.action_delivery)
:sum(function(__,delivery)
return this.deliveryDamage(delivery) * multiplier
end)
end
return 0
end
function this.deliveryDamage(delivery)
if delivery.type == 'instant' and delivery.target_effects then
return _(delivery.target_effects)
:sum(function(__,effect)
return (effect.action and this.damageFromActions(effect.action) or 0) or
(effect.type == 'damage' and effect.damage.amount or 0) or
(effect.type == 'create-entity' and this.entityAttackDamage(effect.entity_name) or 0)
end)
elseif delivery.projectile then
return this.entityAttackDamage(delivery.projectile)
elseif delivery.stream then
return this.entityAttackDamage(delivery.stream)
end
return 0
end
function this.entityAttackDamage(name)
local entity = game.entity_prototypes[name]
local damage = 0
if entity then
if entity.attack_result then
damage = damage + this.damageFromActions(entity.attack_result)
end
if entity.final_attack_result then
damage = damage + this.damageFromActions(entity.final_attack_result)
end
end
return damage
end
function this.radiusFromActions(actions)
return _(actions)
:sum(function(__,action)
return this.radiusFromAction(action)
end)
end
function this.radiusFromAction(action)
if action.action_delivery then
return _(action.action_delivery)
:sum(function(__,delivery)
return this.radiusOfDelivery(delivery)
end)
+ (action.radius or 0)
end
return 0
end
function this.radiusOfDelivery(delivery)
if delivery.type == 'instant' and delivery.target_effects then
return _(delivery.target_effects)
:sum(function(__,effect)
if effect.action then
return this.radiusFromActions(effect.action) + (effects.action.radius or 0)
end
return 0
end)
elseif delivery.projectile then
return this.radiusFromEntity(delivery.projectile)
elseif delivery.stream then
return this.radiusFromEntity(delivery.stream)
end
end
function this.radiusFromEntity(name)
local entity = game.entity_prototypes[name]
local radius = 0
if entity then
if entity.attack_result then
radius = radius + this.radiusFromActions(entity.attack_result)
end
if entity.final_attack_result then
radius = radius + this.radiusFromActions(entity.final_attack_result)
end
end
return radius
end

View File

@@ -0,0 +1,171 @@
local config = require("config")
local player = scripts.helpers
local _ = scripts.helpers.on
-- Helper functions for LuaPlayer --
function player:setting(name)
if name == "enableDragDistribute" then
if settings.global["disable-distribute"].value then return false end
elseif name == "enableInventoryCleanupHotkey" then
if settings.global["disable-inventory-cleanup"].value then return false end
elseif name == "cleanupDropRange" then
return math.min(global.settings[self.index].cleanupDropRange, settings.global["global-max-inventory-cleanup-range"].value)
end
local setting = global.settings[self.index][name]
if setting == nil and self.mod_settings[name] then return self.mod_settings[name].value end
return setting
end
function player:changeSetting(name, newValue)
local setting = global.settings[self.index]
if setting[name] == nil and self.mod_settings[name] then
self.mod_settings[name] = { value = newValue }
else
setting[name] = newValue
end
end
function player:droprange()
return math.min(self.reach_distance * config.rangeMultiplier, self:setting("cleanupDropRange"))
end
function player:trashItems()
local cleanupRequestOverflow = self:setting("cleanupRequestOverflow")
local defaultTrash = global.defaultTrash
local trash = self:contents("character_trash")
local logisticSlots = self:has("valid", "character") and _(self.character):logisticSlots() or {}
for item,count in pairs(self:contents()) do
local targetAmount = count
local slot = logisticSlots[item]
if not slot then -- default if no logistic slot with this item
targetAmount = defaultTrash[item]
elseif cleanupRequestOverflow and slot.min > 0 then -- request overflow
targetAmount = slot.min
elseif slot.max < 4294967295 then -- max value set to infinity = no autotrash
targetAmount = slot.max
end
if targetAmount ~= nil then
local surplus = count - targetAmount
if surplus > 0 then trash[item] = (trash[item] or 0) + surplus end
end
end
return trash
end
function player:playeritemcount(item, includeInv, includeCar)
local count = 0
local cursor_stack = self.cursor_stack
if cursor_stack and cursor_stack.valid_for_read and cursor_stack.name == item then
count = count + cursor_stack.count
elseif not includeInv and not includeCar then
return global.cache[self.index].cursorStackCount or 0
end
if includeInv then
local mainInv = self:inventory();
if _(mainInv):is("valid") then count = count + mainInv.get_item_count(item) end
end
if includeCar and self.driving and self:has("valid", "vehicle") then
local vehicleInv = _(self.vehicle):inventory("car_trunk")
if _(vehicleInv):is("valid") then count = count + vehicleInv.get_item_count(item) end
end
return count
end
function player:playercontents()
local contents = self:contents("main")
local cursor_stack = self.cursor_stack
if cursor_stack and cursor_stack.valid_for_read then
local item = cursor_stack.name
contents[item] = (contents[item] or 0) + cursor_stack.count
end
return contents
end
function player:removeItems(item, amount, takeFromInv, takeFromCar, takeFromTrash)
local removed = 0
if takeFromTrash then
local trash = self:inventory("character_trash")
if _(trash):is("valid") then
removed = trash.remove{ name = item, count = amount }
if amount <= removed then return removed end
end
end
if takeFromInv then
local main = self:inventory()
if _(main):is("valid") then
removed = removed + main.remove{ name = item, count = amount - removed }
if amount <= removed then return removed end
end
end
local cursor_stack = self.cursor_stack
if cursor_stack and cursor_stack.valid_for_read and cursor_stack.name == item then
local result = math.min(cursor_stack.count, amount - removed)
removed = removed + result
cursor_stack.count = cursor_stack.count - result
if amount <= removed then return removed end
elseif not takeFromInv and not takeFromCar and not takeFromTrash then
local main = self:inventory()
if _(main):is("valid") then
return removed + main.remove{ name = item, count = amount - removed }
end
end
if takeFromCar and self.driving and self:has("valid", "vehicle") then
local vehicleInv = _(self.vehicle):inventory("car_trunk")
if _(vehicleInv):is("valid") then removed = removed + vehicleInv.remove{ name = item, count = amount - removed } end
end
return removed
end
function player:returnItems(item, amount, takenFromCar, takenFromTrash)
local remaining = amount - self.insert{ name = item, count = amount }
if remaining > 0 and takenFromCar and self.driving and self:has("valid", "vehicle") then
local vehicleInv = _(self.vehicle):inventory("car_trunk")
if _(vehicleInv):is("valid") then remaining = remaining - vehicleInv.insert{ name = item, count = remaining } end
end
if remaining > 0 and takenFromTrash then
local trash = self:inventory("character_trash")
if _(trash):is("valid") then remaining = remaining - trash.insert{ name = item, count = remaining } end
end
if remaining > 0 then
self.surface.spill_item_stack(self.position, { name = item, count = remaining }, false)
end
end
function player:itemLimit(prototype, profile)
if profile then
local limit = self:setting(profile.valueSetting)
local type = self:setting(profile.typeSetting)
if type == "items" then
return math.ceil(limit)
elseif type == "stacks" then
return math.ceil(limit * (prototype.stack_size or 1))
elseif type == "mj" then
return math.ceil((limit * 1000000) / (prototype.fuel_value or 1))
end
end
return math.huge
end

View File

@@ -0,0 +1,58 @@
local recipe = scripts.helpers
local _ = scripts.helpers.on
-- Helper functions for LuaRecipe --
function recipe:ingredientcount(item) -- get count of a specific item in recipe ingredients
if self:is("valid") then
for __,ingredient in pairs(self.ingredients) do
if ingredient.name == item then return ingredient.amount end
end
end
return 0
end
function recipe:productcount(item) -- get count of a specific item in recipe products
if self:is("valid") then
for __,product in pairs(self.products) do
if product.name == item then
return product.amount or product.amount_min or product.amount_max or product.probability or 1
end
end
end
return 0
end
function recipe:hasIngredient(item)
return self:ingredientcount(item) > 0
end
function recipe:hasProduct(item)
return self:productcount(item) > 0
end
function recipe:ingredientmap() -- ingredient table: item name --> amount
local ingredients = {}
if self:is("valid") then
for __,ingredient in pairs(self.ingredients) do
if ingredient.type == "item" then ingredients[ingredient.name] = ingredient.amount end
end
end
return ingredients
end
function recipe:productmap() -- product table: item name --> amount
local products = {}
if self:is("valid") then
for __,product in pairs(self.products) do
if product.type == "item" then products[product.name] = product.amount end
end
end
return products
end

View File

@@ -0,0 +1,24 @@
local pos = scripts.helpers
local _ = scripts.helpers.on
-- Helper functions for Position --
function pos:offset(...)
if self.left_top ~= nil then
return self:boxoffset(...)
else
return self:posoffset(...)
end
end
function pos:posoffset(arg1, arg2) -- accepts Position or x,y
local offx, offy = arg1, arg2
if arg2 == nil then offx, offy = arg1.x, arg1.y end
return _{x = self.x + offx, y = self.y + offy}
end
function pos:perimeter(radiusx, radiusy) -- with given radius (y radius defaults to x radius)
radiusy = radiusy or radiusx
return _{left_top = {x = self.x - radiusx, y = self.y - radiusy}, right_bottom = {x = self.x + radiusx, y = self.y + radiusy}}
end