File size: 6,081 Bytes
b6a38d7 |
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 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 |
local cardinal_dirs = {"east", "west", "north", "south"}
local dir_angle = { ["east"] = 90 * 60, ["west"] = 270 * 60, ["south"] = 180 * 60, ["north"] = 0 }
local function GetPlaneDir(plane)
for _, dir in ipairs(cardinal_dirs) do
if string.match(plane:lower(), dir) then
return dir
end
end
end
MapVar("s_BorderBuildingAutoAttachesRequired", 0)
MapVar("s_BorderBuildingAutoAttachesCreated", 0)
DefineClass.BorderBuilding = {
__parents = {"AutoAttachObject", "EditorCallbackObject", "EditorSelectedObject"},
properties = {
{category = "Windows Auto Attaches", id = "east", name = "East", editor = "bool", default = true, help = "Uncheck to remove window auto attaches from this side"},
{category = "Windows Auto Attaches", id = "west", name = "West", editor = "bool", default = true, help = "Uncheck to remove window auto attaches from this side"},
{category = "Windows Auto Attaches", id = "north", name = "North", editor = "bool", default = true, help = "Uncheck to remove window auto attaches from this side"},
{category = "Windows Auto Attaches", id = "south", name = "South", editor = "bool", default = true, help = "Uncheck to remove window auto attaches from this side"},
{category = "Windows Auto Attaches", id = "Recalc", editor = "buttons", default = false,
buttons = {
{ name = "Recalc Visible Sides", func = function(self)
self:CalcVisibleSides()
end},
{ name = "Turn All Sides ON", func = function(self)
self:TurnAllSides(true)
end},
{ name = "Turn All Sides OFF", func = function(self)
self:TurnAllSides(false)
end},
},
},
},
texts = false,
}
function BorderBuilding:ShouldAttach(attach)
s_BorderBuildingAutoAttachesRequired = s_BorderBuildingAutoAttachesRequired + 1
local spot_ann = self:GetSpotAnnotation(attach.spot_idx)
if not spot_ann then return true end
local dir = GetPlaneDir(spot_ann)
if not dir then return true end
return self[dir]
end
function BorderBuilding:OnAttachCreated(attach, spot)
s_BorderBuildingAutoAttachesCreated = s_BorderBuildingAutoAttachesCreated + 1
if IsKindOfClasses(attach, "WindowTunnelObject", "Door") then
attach.AttachLight = false
end
end
function BorderBuilding:UpdateAutoAttaches()
self:SetAutoAttachMode(self:GetAutoAttachMode())
end
function BorderBuilding:GatherWallWindows()
local spots_used = {}
local spots = table.imap(AutoAttachPresets[self.class], function(attach)
spots_used[attach.name] = true
end)
local spots = table.keys(spots_used)
local planes = {}
local sides = {}
for _, spot_name in ipairs(spots) do
local first, last = self:GetSpotRange(spot_name)
for spot_idx = first, last do
local spot_pos = self:GetSpotPos(spot_idx)
local spot_ann = self:GetSpotAnnotation(spot_idx)
if spot_ann then
local dir = GetPlaneDir(spot_ann)
if dir then
local spot = {pos = spot_pos, name = spot_name, idx = spot_idx}
planes[spot_ann] = planes[spot_ann] or {dir = dir}
table.insert(planes[spot_ann], spot)
sides[dir] = sides[dir] or {}
table.insert(sides[dir], spot)
end
end
end
end
return planes, sides
end
function BorderBuilding:CalcVisibleSides()
local center = GetMapBox():Center()
local planes, sides = self:GatherWallWindows()
local side_count = {}
for plane_name, plane in pairs(planes) do
local dir = GetPlaneDir(plane_name)
local angle = self:GetAngle() + dir_angle[dir]
local plane_norm = Rotate(point(4096, 0), angle)
local plane_data = side_count[dir] or {total = 0, visible = 0}
side_count[dir] = plane_data
plane_data.total = plane_data.total + #plane
if Dot(center - plane[1].pos, plane_norm) > 0 then
plane_data.visible = plane_data.visible + #plane
end
end
for dir, side in pairs(side_count) do
self:SetProperty(dir, side.visible > side.total / 2)
end
ObjModified(self)
self:UpdateAutoAttaches()
end
function BorderBuilding:TurnAllSides(state)
for _, dir in pairs(cardinal_dirs) do
self:SetProperty(dir, state)
end
ObjModified(self)
self:UpdateAutoAttaches()
end
function BorderBuilding:OnEditorSetProperty(prop_id)
if table.find(cardinal_dirs, prop_id) then
self:UpdateAutoAttaches()
end
end
function BorderBuilding:DelayedRecalcAutoAttaches()
DelayedCall(500, function(self)
self:CalcVisibleSides()
self:UpdateAutoAttaches()
end, self)
end
BorderBuilding.EditorCallbackMove = BorderBuilding.DelayedRecalcAutoAttaches
BorderBuilding.EditorCallbackRotate = BorderBuilding.DelayedRecalcAutoAttaches
BorderBuilding.EditorCallbackPlace = BorderBuilding.DelayedRecalcAutoAttaches
function BorderBuilding:EditorSelect(selected)
if selected then
local center = self:GetPos()
local high_z = self:GetObjectBBox():sizez() + guim
local _, sides = self:GatherWallWindows()
for dir, spots in pairs(sides) do
local pos = point30
for _, spot in pairs(spots) do
pos = pos + spot.pos - center
end
pos = (pos / #spots):SetZ(high_z)
local text = PlaceText(dir:upper(), pos, const.clrGreen)
self:Attach(text)
text:SetAttachOffset(pos)
self.texts = self.texts or {}
table.insert(self.texts, text)
end
elseif self.texts then
for _, text in ipairs(self.texts) do
if IsValid(text) then
text:Detach()
DoneObject(text)
end
end
self.texts = false
end
end
function BorderBuildingsRecalcVisibleSides()
s_BorderBuildingAutoAttachesRequired = 0
s_BorderBuildingAutoAttachesCreated = 0
local buildings = 0
MapForEach("map", "BorderBuilding", function(bld)
buildings = buildings + 1
bld:CalcVisibleSides()
bld:UpdateAutoAttaches()
end)
printf("BorderBuilding(s): %d, Auto Attaches Created/Required: %d/%d(%d%%)", buildings,
s_BorderBuildingAutoAttachesCreated, s_BorderBuildingAutoAttachesRequired,
100 * s_BorderBuildingAutoAttachesCreated / s_BorderBuildingAutoAttachesRequired)
end
function SelectionBorderBuildingToggleWall(dir)
for _, obj in ipairs(editor.GetSel() or empty_table) do
if IsKindOf(obj, "BorderBuilding") then
obj:SetProperty(dir, not obj:GetProperty(dir))
obj:UpdateAutoAttaches()
end
end
end
|