145 lines
5.1 KiB
Lua
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()
|