File size: 7,864 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 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 |
if FirstLoad then
GedObjectEditor = false
end
function GedInvokedMapEditorUndo() XEditorUndo:UndoRedo("undo") end
function GedInvokedMapEditorRedo() XEditorUndo:UndoRedo("redo") end
local last_selection_idx = 1
function GedOpViewGameObject(socket, obj)
local is_obj_starting_table = type(obj) == "table" and IsValid(obj[1])
if IsKindOf(obj, "GedMultiSelectAdapter") or is_obj_starting_table then
local objs = is_obj_starting_table and obj or obj.__objects
if #objs == 0 then return end
if #objs < last_selection_idx then
last_selection_idx = 1
end
ViewObject(objs[last_selection_idx])
last_selection_idx = last_selection_idx + 1
else
ViewObject(obj)
end
end
local function GetSelectionTable(socket, obj, allow_root)
if (type(obj) == "table" and obj[1] and IsValid(obj[1])) then
return obj
elseif IsKindOf(obj, "GedMultiSelectAdapter") then
return obj.__objects
elseif obj == socket:ResolveObj("root") then
return allow_root and obj or {}
else
return {obj}
end
end
function GedOpConvertToTemplate(socket, obj)
local objs = GetSelectionTable(socket, obj)
if #objs > 0 then
Template.TurnObjectsIntoTemplates(objs)
end
end
function GedOpConvertToObject(socket, obj)
local objs = GetSelectionTable(socket, obj)
if #objs > 0 then
Template.TurnTemplatesIntoObjects(objs)
end
end
local shown_spots = {}
function GedOpToggleSpotVisiblity(socket, obj)
local objs = GetSelectionTable(socket, obj)
if #objs == 0 then return nil end
return ToggleSpotVisibility(objs)
end
function ToggleSpotVisibility(objs)
if not shown_spots[objs[1]] then
for _, obj in ipairs(objs) do
if IsValid(obj) then
obj:ShowSpots()
shown_spots[obj] = true
end
end
else
for _, obj in ipairs(objs) do
if IsValid(obj) then
obj:HideSpots()
shown_spots[obj] = nil
end
end
end
end
function ToggleSurfaceVisibility(objs)
if not ObjToShownSurfaces[objs[1]] then
for _, obj in ipairs(objs) do
if IsValid(obj) then
obj:ShowSurfaces()
end
end
else
for _, obj in ipairs(objs) do
if IsValid(obj) then
obj:HideSurfaces()
end
end
end
end
function GedOpSetSingleSel(socket, obj)
if IsEditorActive() then
editor.SetSel{ obj }
else
SelectObj(obj)
end
end
function GedOpDisplaySpotsWithFilter(socket, obj)
if not obj then return end
-- List spots by name & autoattach
local spots = {}
if obj["HasEntity"] and obj:HasEntity() then
local start_id, end_id = obj:GetAllSpots(obj:GetState())
for i = start_id, end_id do
local spot_name = GetSpotNameByType(obj:GetSpotsType(i))
local annotation = obj:GetSpotAnnotation(i) or ""
local attach_class = annotation:match(".*,(.*),.*")
spots[spot_name .. (attach_class and ":"..attach_class or "")] = true
end
end
-- Construct combo box items
local items = table.keys(spots)
if #items > 0 then
table.sort(items)
local spot_name = socket:WaitUserInput("Select Spots to Show", items[1], items)
obj:HideSpots()
if spot_name then
obj:ShowSpots(unpack_params(spot_name:split(":")))
shown_spots[obj] = true
end
else
socket:ShowMessage("Information", "No spots to show for this object.")
end
end
function GedOpRemoveDuplicated(socket, obj)
local obj_list = GetSelectionTable(socket, obj, "allow_root")
local selection = editor.GetSel()
editor.ClearSel()
DeleteDuplicates(obj_list)
table.validate(selection)
editor.AddToSel(selection)
end
function GedOpDeleteObject(socket, obj)
local selection = editor.GetSel()
editor.ClearSel()
DoneObjects(GetSelectionTable(socket, obj))
table.validate(selection)
editor.AddToSel(selection)
end
function GedOpOpenEntityEditor(socket, obj)
local objs = GetSelectionTable(socket, obj, "allow_root")
if #objs > 0 then
CreateEntityViewer(objs[1])
end
end
function GedOpenAutoattachEditorButton(root, obj, prop_id, ged)
if not root or not obj then return end
OpenAutoattachEditor(root, true)
end
function GedOpRemoveUnselected(socket, obj)
local objs = GetSelectionTable(socket, obj)
editor.ClearSel()
editor.AddToSel(objs)
end
local function UpdateAnimationTimeFlags(oldsel, newsel)
if IsEditorActive() then
if oldsel then
for _, o in ipairs(oldsel) do
if IsValid(o) then
if IsKindOf(o, "ParSystem") then
if o:ShouldBeGameTime() then
ObjectAnimToGameTime(o)
end
elseif GetClassGameFlags(o.class, const.gofRealTimeAnim) == 0 then
ObjectAnimToGameTime(o)
end
end
end
end
if newsel then
for _, o in ipairs(newsel) do
o:SetRealtimeAnim(true)
end
end
end
end
local function UpdateForcedLODs(oldsel, newsel)
if IsEditorActive() then
if oldsel then
for _, o in ipairs(oldsel) do
if IsValid(o) then
o:RestoreForcedLODState()
ObjModified(o)
end
end
end
if newsel then
for _, o in ipairs(newsel) do
o:CacheForcedLODState()
if o:GetForcedLODMin() then
o:SetForcedLOD(Max(o:GetLODsCount(), 1) - 1)
end
ObjModified(o)
end
end
end
end
local function EditorFilterObjList(objects)
if not EditorSettings:GetLimitObjectEditorItems() then
return objects
end
-- show no more than 500 objects in the Object Editor (otherwise the performance is abysmal)
local i, n, ret = 1, 1, {}
while i <= #objects and n <= 500 do
local obj = objects[i]
if IsValid(obj) and not IsKindOf(obj, "PropertyHelper") then
ret[n] = obj
n = n + 1
end
i = i + 1
end
return ret
end
local obj_modified_list = {}
local obj_modified_thread = false
local obj_rebind_thread = false
local function mark_modified(obj)
obj_modified_list[obj] = true
for _, attach in ipairs(obj:GetAttaches() or empty_table) do
mark_modified(attach)
end
end
function OnMsg.EditorObjectOperation(op_finished, obj_list)
if GedObjectEditor and op_finished then
for _, obj in ipairs(obj_list) do
mark_modified(obj)
end
obj_modified_thread = obj_modified_thread or CreateRealTimeThread(function()
Sleep(250)
obj_modified_thread = false
for obj in pairs(obj_modified_list) do
ObjModified(obj)
end
obj_modified_list = {}
end)
end
end
function OnMsg.EditorSelectionChanged(objects)
if GedObjectEditor and not GedObjectEditor.objects_locked then
-- no need to call ObjModified if we will rebind everything
DeleteThread(obj_modified_thread)
obj_modified_thread = false
obj_modified_list = {}
-- add 100 ms delay, restart everything if selection is changed again (as in the drag to select case)
DeleteThread(obj_rebind_thread)
obj_rebind_thread = CreateRealTimeThread(function()
Sleep(100)
if GedObjectEditor then
local root = GedObjectEditor:ResolveObj("root")
if objects and #objects == 1 and IsKindOf(objects[1], "PropertyHelper") then
objects = root -- keep all objects, but filter invalids
end
objects = EditorFilterObjList(objects)
UpdateAnimationTimeFlags(root, objects)
UpdateForcedLODs(root, objects)
GedObjectEditor:UnbindObjs("root")
GedObjectEditor:BindObj("root", objects)
GedObjectEditor:SelectAll("root")
end
end)
end
end
function OpenGedGameObjectEditor(objects, locked_objs)
CreateRealTimeThread(function(objects)
if not GedObjectEditor then
objects = EditorFilterObjList(objects)
UpdateAnimationTimeFlags(nil, objects)
UpdateForcedLODs(nil, objects)
GedObjectEditor = OpenGedApp("GedObjectEditor", objects, { WarningsUpdateRoot = "root" }) or false
GedObjectEditor:SelectAll("root")
else
GedObjectEditor:Call("rfnApp", "Activate")
end
rawset(GedObjectEditor, "objects_locked", locked_objs or false)
end, objects)
end
function OnMsg.GedClosing(ged_id)
if GedObjectEditor and GedObjectEditor.ged_id == ged_id then
local objects = GedObjectEditor:ResolveObj("root")
table.validate(objects)
UpdateAnimationTimeFlags(objects, nil)
UpdateForcedLODs(objects, nil)
GedObjectEditor = false
end
end
|