myspace / CommonLua /GedGameObjectEditor.lua
sirnii's picture
Upload 1816 files
b6a38d7 verified
raw
history blame
7.86 kB
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