This repository has been archived by the owner on Oct 25, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathdata-updates.lua
144 lines (114 loc) · 5.21 KB
/
data-updates.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
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()