Aleksei-bird 7c9c708c92 Первый фикс
Пачки некоторых позиций увеличены
2024-03-01 20:54:33 +03:00

145 lines
5.1 KiB
Lua

require "config"
-- Prototype names and types to not alter.
local excluded_prototype_names = {}
local excluded_prototype_types = {}
-- Helper functions to check if a prototype name or type is excluded.
local function prototype_name_excluded(name)
return excluded_prototype_names[name]
end
local function prototype_type_excluded(type)
return excluded_prototype_types[type]
end
-- Returns true when an exclusion should be applied or false otherwise.
local function exclusion_applies(exclusion)
-- Exclusions always apply if no apply_when_object_exists is specified.
if not exclusion.apply_when_object_exists then
return true
else
-- Exclusions apply when the apply_when_object_exists object actually exists.
if data.raw[exclusion.apply_when_object_exists.type][exclusion.apply_when_object_exists.name] then
return true
end
end
-- The apply_when_object_exists object didn't exist (the mod which the exclusion was for is not active).
return false
end
-- Update the exclusion arrays by parsing an exclusion (from config.lua).
local function apply_exclusion(exclusion)
if exclusion.excluded_prototype_names then
for _,n in pairs(exclusion.excluded_prototype_names) do
excluded_prototype_names[n] = true
end
end
if exclusion.excluded_prototype_types then
for _,t in pairs(exclusion.excluded_prototype_types) do
excluded_prototype_types[t] = true
end
end
end
-- Parse the exclusions defined in config.lua only applying those which are applicable.
local function apply_exclusions()
for _,e in pairs(exclusions) do
if exclusion_applies(e) then
apply_exclusion(e)
end
end
end
-- Returns a coordinate reduced where required to form the specified gap between it and the tile boundary.
local function adjust_coordinate_to_form_gap(coordinate, required_gap)
-- Treat all coordinates as positive to simplify calculations.
local is_negative_coordinate = (coordinate < 0)
if is_negative_coordinate then
coordinate = coordinate * -1
end
local tile_width = 0.5
-- Calculate the existing gap (how much space there is to the next tile edge or 0 when the coordinate lies on a tile edge).
local distance_past_last_tile_edge = coordinate % tile_width -- This is how far the collision box extends over any tile edge, and should be 0 for a perfect fit.
local existing_gap = 0
if distance_past_last_tile_edge > 0 then
existing_gap = (tile_width - distance_past_last_tile_edge)
end
-- Reduce the coordinate to make the gap large enough if it is not already.
if existing_gap < required_gap then
coordinate = coordinate + existing_gap - required_gap
if coordinate < 0 then
coordinate = 0
end
end
-- Make the coordinate negative again if it was originally negative.
if is_negative_coordinate then
coordinate = coordinate * -1
end
return coordinate
end
-- Checks all existing prototypes listed in prototype_type_gap_requirements and reduces their collision box to make a gap large enough to walk though if it is not already.
local function adjust_collision_boxes()
for prototype_type, required_gap in pairs(prototype_type_gap_requirements) do
-- Don't shrink prototypes of this type if they've been excluded.
if not prototype_type_excluded(prototype_type) then
for prototype_name, prototype in pairs(data.raw[prototype_type]) do
-- If the prototype is not excluded and has a collision box, and if it does not opt out, then resize it.
local exclude_entity = false
local compat_mode = settings.startup["squeakthrough-mod-compatibility"].value
-- If compat_mode == "force", don't bother changing exclude_entity
if compat_mode == "opt-out" then
if data.raw[prototype_type][prototype_name].squeak_behaviour == false then -- not the same as "not data.raw..." because we don't want this to happen if there's no set value
exclude_entity = true
end
elseif compat_mode == "opt-in" then
if data.raw[prototype_type][prototype_name].squeak_behaviour ~= true then -- again, can't use "not", this time because we DO want this to happen if there is no set value
exclude_entity = true
end
end
if (not exclude_entity) and (not prototype_name_excluded(prototype_name)) and prototype["collision_box"] then
if prototype.collision_box.lefttop then
prototype.collision_box.lefttop[1] = adjust_coordinate_to_form_gap(prototype.collision_box.lefttop[1], required_gap)
prototype.collision_box.rightbottom[1] = adjust_coordinate_to_form_gap(prototype.collision_box.rightbottom[1], required_gap)
prototype.collision_box.lefttop[2] = adjust_coordinate_to_form_gap(prototype.collision_box.lefttop[2], required_gap)
prototype.collision_box.rightbottom[2] = adjust_coordinate_to_form_gap(prototype.collision_box.rightbottom[2], required_gap)
else
for y=1,2 do
for x=1,2 do
prototype.collision_box[x][y] = adjust_coordinate_to_form_gap(prototype.collision_box[x][y], required_gap)
end
end
end
end
end
end
end
end
-- Exclude prototypes from alteration for mods that have compatibility issues with modified collision boxes.
apply_exclusions()
-- Make the adjustments.
adjust_collision_boxes()