Download CommonLua/Classes/AttachViaProp.lua from sirnii/myspace: direct link, hf CLI and curl.
- Browser
- Download file 7.65 kB
-
https://huggingface.co/spaces/sirnii/myspace/resolve/main/CommonLua/Classes/AttachViaProp.lua
- Command line
-
hf download hf://spaces/sirnii/myspace/CommonLua/Classes/AttachViaProp.lua
-
curl -L -o AttachViaProp.lua https://huggingface.co/spaces/sirnii/myspace/resolve/main/CommonLua/Classes/AttachViaProp.lua
7.65 kB
| local EDITOR = Platform.editor | |
| local function SpotEntry(obj, idx) | |
| local name = idx >= 0 and obj:GetSpotName(idx) or "" | |
| if name == "" then | |
| return false | |
| end | |
| local offset = idx - obj:GetSpotBeginIndex(name) | |
| return offset == 0 and name or {name, offset} | |
| end | |
| DefineClass.AttachViaProp = { | |
| __parents = { "ComponentAttach" }, | |
| properties = { | |
| { category = "Attach-Via-Prop", id = "AttachList", name = "Attach List", editor = "prop_table", default = "", no_edit = true }, | |
| { category = "Attach-Via-Prop", id = "AttachCounter", name = "Attach Counter", editor = "number", default = 0, dont_save = true, read_only = true }, | |
| }, | |
| } | |
| function AttachViaProp:SetAttachList(value) | |
| self.AttachList = value | |
| self:UpdatePropAttaches() | |
| end | |
| function AttachViaProp:ResolveSpotIdx(entry) | |
| local spot = entry.spot | |
| local offset | |
| if type(spot) == "table" then | |
| spot, offset = unpack_params(spot) | |
| assert(type(spot) == "string") | |
| assert(type(offset) == "number") | |
| end | |
| if type(spot) == "number" then | |
| -- support for older version | |
| entry.spot = SpotEntry(self, spot) | |
| elseif type(spot) == "string" then | |
| spot = self:HasSpot(spot) and self:GetSpotBeginIndex(spot) | |
| end | |
| return (spot or -1) + (offset or 0) | |
| end | |
| function AttachViaProp:UpdatePropAttaches() | |
| if self.AttachCounter > 0 then | |
| self:ForEachAttach(function(obj) | |
| if rawget(obj, "attach_via_prop") then | |
| DoneObject(obj) | |
| end | |
| end) | |
| self.AttachCounter = nil | |
| end | |
| local list = self.AttachList | |
| for i=#list,1,-1 do | |
| local entry = list[i] | |
| local spot = self:ResolveSpotIdx(entry) | |
| if not spot then | |
| table.remove(list, i) | |
| else | |
| local class = entry.class or "" | |
| local particles = entry.particles or "" | |
| local obj, err | |
| if particles ~= "" then | |
| obj = PlaceParticles(particles) | |
| else | |
| obj = PlaceObject(class) | |
| end | |
| if obj then | |
| rawset(obj, "attach_via_prop", true) | |
| if entry.offset then | |
| obj:SetAttachOffset(entry.offset) | |
| end | |
| if entry.axis then | |
| obj:SetAttachAxis(entry.axis) | |
| end | |
| if entry.angle then | |
| obj:SetAttachAngle(entry.angle) | |
| end | |
| err = self:Attach(obj, spot) | |
| end | |
| if not IsValid(obj) or obj:GetAttachSpot() ~= spot or err then | |
| StoreErrorSource(self, "Failed to attach via props!") | |
| DoneObject(obj) | |
| else | |
| self.AttachCounter = self.AttachCounter + 1 | |
| end | |
| end | |
| end | |
| if not EDITOR then | |
| self.AttachList = nil | |
| end | |
| end | |
| ---- | |
| if EDITOR then | |
| local function SpotName(obj, idx) | |
| local name = obj:GetSpotName(idx) | |
| local anot = obj:GetSpotAnnotation(idx) | |
| return name .. (anot and (" (" .. anot .. ")") or "") | |
| end | |
| local function SpotNamesCombo(obj) | |
| local start_idx, end_idx = obj:GetAllSpots( obj:GetState() ) | |
| local items = {} | |
| local names = {} | |
| for idx = start_idx, end_idx do | |
| items[#items + 1] = {value = SpotEntry(obj, idx), text = SpotName(obj, idx)} | |
| end | |
| table.sortby_field(items, "text") | |
| table.insert(items, 1, {value = false, text = ""}) | |
| return items | |
| end | |
| if FirstLoad then | |
| l_used_entries = false | |
| end | |
| local function SmartAttachCombo() | |
| local items = {} | |
| local classes = ClassDescendantsList("ComponentAttach") | |
| local tbl = {"", " - Object"} | |
| for i = 1, #classes do | |
| local class = classes[i] | |
| tbl[1] = class | |
| local text = table.concat(tbl) | |
| items[#items + 1] = {value = { class, 1, text }, text = text} | |
| end | |
| local particles = ParticlesComboItems() | |
| local tbl = {"", " - Particle"} | |
| for i = 1, #particles do | |
| local particle = particles[i] | |
| tbl[1] = particle | |
| local text = table.concat(tbl) | |
| items[#items + 1] = {value = { particle, 2, text }, text = text} | |
| end | |
| table.sortby_field(items, "text") | |
| if l_used_entries then | |
| local idx = 1 | |
| local tbl = {"> ", ""} | |
| for text, entry in sorted_pairs(l_used_entries) do | |
| tbl[2] = text | |
| table.insert(items, idx, {value = entry, text = table.concat(tbl)}) | |
| idx = idx + 1 | |
| end | |
| table.insert(items, idx, {value = "", text = ""}) | |
| end | |
| table.insert(items, 1, {value = false, text = ""}) | |
| return items | |
| end | |
| table.iappend(AttachViaProp.properties, { | |
| { category = "Attach-Via-Prop", id = "AttachPreview", name = "Attach List", editor = "text", lines = 5, default = "", dont_save = true, read_only = true, min = 10 }, | |
| { category = "Attach-Via-Prop", id = "AttachToSpot", name = "Attach At", editor = "combo", default = false, dont_save = true, items = SpotNamesCombo, min = 0, buttons = {{name = "Add", func = "ButtonAddAttach"}, {name = "Rem", func = "ButtonRemAttach"}, {name = "Rem All", func = "ButtonRemAllAttaches"}}}, | |
| { category = "Attach-Via-Prop", id = "AttachObject", name = "Attach Object", editor = "combo", default = false, dont_save = true, items = SmartAttachCombo }, | |
| { category = "Attach-Via-Prop", id = "AttachWithOffset", name = "Attach Offset ", editor = "point", default = point30, dont_save = true, scale = "m" }, | |
| { category = "Attach-Via-Prop", id = "AttachWithAxis", name = "Attach Axis ", editor = "point", default = axis_z, dont_save = true }, | |
| { category = "Attach-Via-Prop", id = "AttachWithAngle", name = "Attach Angle ", editor = "number", default = 0, dont_save = true, scale = "deg" }, | |
| }) | |
| function AttachViaProp:GetAttachListCombo() | |
| local items = {} | |
| local list = self.AttachList | |
| for i=#list,1,-1 do | |
| local entry = list[i] | |
| local spot = self:ResolveSpotIdx(entry) | |
| if not spot then | |
| table.remove(list, i) | |
| else | |
| local str = SpotName(self, spot) .. " -- " .. (entry.particles or entry.class or "?") | |
| if entry.offset then | |
| str = str .. " o" .. tostring(entry.offset) | |
| end | |
| if entry.axis then | |
| str = str .. " x" .. tostring(entry.axis) | |
| end | |
| if entry.angle then | |
| str = str .. " a" .. tostring(entry.angle) | |
| end | |
| items[#items + 1] = str | |
| end | |
| end | |
| table.sort(items) | |
| return items | |
| end | |
| function AttachViaProp:GetAttachPreview() | |
| local list = self:GetAttachListCombo() | |
| return table.concat(list, "\n") | |
| end | |
| function ButtonAddAttach(main_obj, object, prop_id) | |
| if type(object.AttachObject) ~= "table" then | |
| return | |
| end | |
| local oname, otype, otext = unpack_params(object.AttachObject) | |
| local class = otype == 1 and oname or "" | |
| local particles = otype == 2 and oname or "" | |
| if class == "" and particles == "" then | |
| return | |
| end | |
| l_used_entries = l_used_entries or {} | |
| l_used_entries[otext] = object.AttachObject | |
| local spot = object.AttachToSpot or nil | |
| local list = object.AttachList | |
| if #list == 0 then | |
| list = {} | |
| object.AttachList = list | |
| end | |
| local offset = object.AttachWithOffset | |
| if offset == point30 then | |
| offset = nil | |
| end | |
| local axis = object.AttachWithAxis | |
| if axis == axis_z then | |
| axis = nil | |
| end | |
| local angle = object.AttachWithAngle | |
| if angle == 0 then | |
| angle = nil | |
| end | |
| if class ~= "" then | |
| list[#list + 1] = {spot = spot, offset = offset, axis = axis, angle = angle, class = class, } | |
| end | |
| if particles ~= "" then | |
| list[#list + 1] = {spot = spot, offset = offset, axis = axis, angle = angle, particles = particles, } | |
| end | |
| object:UpdatePropAttaches() | |
| end | |
| function ButtonRemAllAttaches(main_obj, object, prop_id) | |
| if not object then | |
| return | |
| end | |
| object.AttachList = nil | |
| object:UpdatePropAttaches() | |
| end | |
| function ButtonRemAttach(main_obj, object, prop_id) | |
| if not object then | |
| return | |
| end | |
| local list = object:GetAttachListCombo() | |
| if #list == 0 then | |
| return | |
| end | |
| local entry, err = PropEditorWaitUserInput(main_obj, list[#list], "Select attach to remove", list) | |
| if not entry then | |
| assert(false, err) | |
| return | |
| end | |
| local idx = table.find(list, entry) | |
| if not idx then | |
| return | |
| end | |
| table.remove(object.AttachList, idx) | |
| if #object.AttachList == 0 then | |
| object.AttachList = nil | |
| end | |
| object:UpdatePropAttaches() | |
| end | |
| end -- EDITOR | |
| ---- |