File size: 3,490 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
local function FindHighestRoof(obj)
	local pos = obj:GetVisualPos()
	local highest_room, highest_z, highest_pt_dir = false, 0, 0
	MapForEach(pos, roomQueryRadius, "Room", function(room, pos)
		if not IsPointInVolume2D(room, pos) then return end
		
		local z, dir = room:GetRoofZAndDir(pos)
		if not IsKindOf(obj, "Decal") then
			local thickness = room:GetRoofThickness()
			z = z + thickness
		end
		
		if z < highest_z then return end
		
		highest_z = z 
		highest_room = room
		highest_pt_dir = dir
	end, pos)
	
	return highest_room, highest_z, highest_pt_dir
end

function editor.ToggleDontHideWithRoom()
	local sel = editor:GetSel()
	if #sel < 1 then
		return
	end
	
	XEditorUndo:BeginOp{ objects = sel, "Set hide with room" }
	local set = 0
	local cleared = 0
	for i = 1, #sel do
		local obj = sel[i]
		if obj:GetGameFlags(const.gofDontHideWithRoom) == 0 then
			obj:SetDontHideWithRoom(true)
			set = set + 1
		else
			obj:SetDontHideWithRoom(false)
			cleared = cleared + 1
		end
	end
	
	print("Set flag to " .. tostring(set) .. " objects.")
	print("Cleared flag from " .. tostring(cleared) .. " objects.")
	XEditorUndo:EndOp(sel)
end

function editor.ClearRoofFlags()
	local sel = editor:GetSel()
	if #sel < 1 then
		return
	end

	XEditorUndo:BeginOp{ objects = sel, name = "Set roof OFF" }
	
	for i = 1, #sel do
		local obj = sel[i]
		
		obj:ClearHierarchyGameFlags(const.gofOnRoof)
	end
	print("CLEARED objects' roof flags")
	XEditorUndo:EndOp(sel)
end

function editor.SnapToRoof()
	local sel = editor:GetSel()
	if #sel < 1 then
		return
	end

	XEditorUndo:BeginOp{ objects = sel, name = "Set roof ON" }
	local counter = 0
	
	for i = 1, #sel do
		local obj = sel[i]
		
		if obj:GetGameFlags(const.gofOnRoof) == 0 then
			counter = counter + 1
			obj:SetHierarchyGameFlags(const.gofOnRoof)
		end
	end
	
	if counter > 0 then
		print(tostring(counter) .. " objects MARKED as OnRoof objects out of " .. tostring(#sel))
		XEditorUndo:EndOp(sel)
		return
	end
	
	SuspendPassEditsForEditOp()
	local new_position = { }
	local new_up = { }
	
	for i = 1, #sel do
		local obj = sel[i]
		
		local highest_roof = FindHighestRoof(obj)
		if highest_roof then
			local target_pos, target_up = highest_roof:SnapObject(obj)
			new_position[obj] = target_pos
			new_up[obj] = target_up
			counter = counter + 1
		end
	end
	print(tostring(counter) .. " objects SNAPPED to roof out of " .. tostring(#sel))
	--editor callbacks
	local objects = {}
	local cfEditorCallback = const.cfEditorCallback
	for i = 1, #sel do
		if sel[i]:GetClassFlags(cfEditorCallback) ~= 0 then
			objects[#objects + 1] = sel[i]
		end
	end
	if #objects > 0 then
		Msg("EditorCallback", "EditorCallbackMove", objects)
	end
	
	XEditorUndo:EndOp(sel)
	ResumePassEditsForEditOp()
	
	for i = 1, #sel do
		local obj = sel[i]
		
		local pos = obj:GetPos()
		local wrong_pos = new_position[obj] and new_position[obj] ~= pos
		
		local wrong_angle
		local up = RotateAxis(point(0, 0, 4096), obj:GetAxis(), obj:GetAngle())
		if new_up[obj] then
			local axis, angle = GetAxisAngle(new_up[obj], up)
			wrong_angle = (angle > 0)
		end
		
		local obj_name = IsKindOf(obj, "CObject") and obj:GetEntity() or obj.class
		local aligned_obj = IsKindOf(obj, "AlignedObj")
		
		if wrong_pos then
			local err = "not snapped to the roof Z"
			if aligned_obj then
				err = err .. " (AlignedObj)"
			end
			print(obj_name, err)
		end
		
		if wrong_angle then
			local err = "not aligned with the roof slope"
			print(obj_name, err)
		end
	end
end