Download CommonLua/Classes/Light.lua from sirnii/myspace: direct link, hf CLI and curl.
- Browser
- Download file 20.3 kB
-
https://huggingface.co/spaces/sirnii/myspace/resolve/main/CommonLua/Classes/Light.lua
- Command line
-
hf download hf://spaces/sirnii/myspace/CommonLua/Classes/Light.lua
-
curl -L -o Light.lua https://huggingface.co/spaces/sirnii/myspace/resolve/main/CommonLua/Classes/Light.lua
20.3 kB
| DefineClass.ComponentLight = { | |
| __parents = { "CObject" }, | |
| flags = { cfLight = true, cofComponentLight = true, } | |
| } | |
| for name, func in pairs(ComponentLightFunctions) do | |
| ComponentLight[name] = func | |
| end | |
| local lightmodel_lights = {"A", "B", "C", "D"} | |
| DefineClass.Light = { | |
| __parents = { "Object", "InvisibleObject", "ComponentAttach", "ComponentLight" }, | |
| flags = { cfConstructible = false, gofRealTimeAnim = true, efShadow = false, efSunShadow = false, | |
| gofDetailClass0 = true, gofDetailClass1 = true, -- to match 'Eye Candy' default of DetailClass | |
| }, -- ATTN: cfEditorCallback added below when Platform.editor | |
| -- Properties, editable in the editor's property window (Ctrl+O) | |
| properties = { | |
| { id = "DetailClass", name = "Detail Class", editor = "dropdownlist", | |
| items = {"Default", "Essential", "Optional", "Eye Candy"}, default = "Eye Candy", | |
| }, | |
| { category = "Visuals", id = "Color", editor = "color", autoattach_prop = true, dont_save = function(obj) | |
| if not IsValid(obj) then return false end | |
| if obj:GetLightmodelColorIndexNumber() ~= 0 then return true end | |
| return false | |
| end, | |
| read_only = function(obj) | |
| if not IsValid(obj) then return false end | |
| if obj:GetLightmodelColorIndexNumber() ~= 0 then return true end | |
| return false | |
| end, | |
| }, | |
| { category = "Visuals", id = "LightmodelColorIndex", editor = "set", items = lightmodel_lights, max_items_in_set = 1, default = {}, autoattach_prop = true,}, | |
| { category = "Visuals", id = "OriginalColor", editor = "color", default = RGB(255, 255, 255), no_edit = true, dont_save = true }, | |
| { category = "Visuals", id = "Intensity", editor = "number", min = 0, max = 255, slider = true, autoattach_prop = true, }, | |
| { category = "Visuals", id = "Exterior", editor = "bool", autoattach_prop = true, }, | |
| { category = "Visuals", id = "Interior", editor = "bool", autoattach_prop = true, }, | |
| { category = "Visuals", id = "InteriorAndExteriorWhenHasShadowmap", editor = "bool", autoattach_prop = true, }, | |
| { category = "Visuals", id = "Volume", helper = "volume", editor = "object", default = false, base_class = "Volume" }, | |
| { category = "Visuals", id = "ConstantIntensity", editor = "number", default = 0, autoattach_prop = true, slider = true, max = 127, min = -128 }, | |
| { category = "Visuals", id = "AttenuationShape", editor = "number", default = 0, autoattach_prop = true, slider = true, max = 255, min = 0 }, | |
| { category = "Visuals", id = "CastShadows", editor = "bool", autoattach_prop = true }, | |
| { category = "Visuals", id = "DetailedShadows", editor = "bool", autoattach_prop = true }, | |
| { id = "ColorModifier", editor = false }, | |
| { id = "Occludes", editor = false }, | |
| { id = "Walkable", editor = false }, | |
| { id = "ApplyToGrids", editor = false }, | |
| { id = "Collision", editor = false }, | |
| { id = "Color1", editor = false }, | |
| { id = "ParentSIModulation", editor = "number", default = 100, min = 0, max = 255, slider = true, autoattach_prop = true, no_edit = function(o) | |
| return IsKindOf(o, "CObject") | |
| end, help = "To be used by the AutoAttach system."}, | |
| }, | |
| Color = RGB(255,255,255), | |
| Intensity = 100, | |
| Interior = true, | |
| Exterior = true, | |
| InteriorAndExteriorWhenHasShadowmap = true, | |
| CastShadows = false, | |
| DetailedShadows = false, | |
| Init = function(self) | |
| self:SetColor(self.Color) | |
| self:SetIntensity(self.Intensity) | |
| self:SetInterior(self.Interior) | |
| self:SetExterior(self.Exterior) | |
| self:SetInteriorAndExteriorWhenHasShadowmap(self.InteriorAndExteriorWhenHasShadowmap) | |
| self:SetConstantIntensity(0) | |
| self:SetAttenuationShape(0) | |
| self:SetLightmodelColorIndex(empty_table) | |
| self:SetCastShadows(self.CastShadows) | |
| self:SetDetailedShadows(self.DetailedShadows) | |
| end, | |
| GetCastShadows = function(self) return self:GetLightFlags(const.elfCastShadows) end, | |
| SetCastShadows = function(self, value) | |
| self.CastShadows = value | |
| if value then | |
| self:SetLightFlags(const.elfCastShadows) | |
| else | |
| self:ClearLightFlags(const.elfCastShadows) | |
| end | |
| end, | |
| GetDetailedShadows = function(self) return self:GetLightFlags(const.elfDetailedShadows) end, | |
| SetDetailedShadows = function(self, value) | |
| self.DetailedShadows = value | |
| if value then | |
| self:SetLightFlags(const.elfDetailedShadows) | |
| else | |
| self:ClearLightFlags(const.elfDetailedShadows) | |
| end | |
| end, | |
| GetColor = function(self) | |
| local index = self:GetLightmodelColorIndexNumber() | |
| if index ~= 0 then return GetSceneParamColor("LightColor" .. index) end | |
| return self:GetColor0() | |
| end, | |
| SetColor = function(self, rgb) self:SetColor0(rgb) self:SetColor1(rgb) end, | |
| GetColor0 = function(self) return self:GetColorAtIndex(0) end, | |
| GetColor1 = function(self) return self:GetColorAtIndex(1) end, | |
| SetColor0 = function(self, rgb) self:SetColorAtIndex(0, rgb) self:SetColorModifier(rgb or 0) end, | |
| SetColor1 = function(self, rgb) self:SetColorAtIndex(1, rgb) end, | |
| GetExterior = function(self) | |
| return self:GetLightFlags(const.elfExterior) | |
| end, | |
| SetExterior = function(self, value) | |
| self.Exterior = value | |
| if value then | |
| self:SetLightFlags(const.elfExterior) | |
| else | |
| self:ClearLightFlags(const.elfExterior) | |
| end | |
| end, | |
| GetInterior = function(self) | |
| return self:GetLightFlags(const.elfInterior) | |
| end, | |
| SetInterior = function(self, value) | |
| self.Interior = value | |
| if value then | |
| self:SetLightFlags(const.elfInterior) | |
| else | |
| self:ClearLightFlags(const.elfInterior) | |
| end | |
| end, | |
| GetInteriorAndExteriorWhenHasShadowmap = function(self) | |
| return self:GetLightFlags(const.elfInteriorAndExteriorWhenHasShadowmap) | |
| end, | |
| SetInteriorAndExteriorWhenHasShadowmap = function(self, value) | |
| self.InteriorAndExteriorWhenHasShadowmap = value | |
| if value then | |
| self:SetLightFlags(const.elfInteriorAndExteriorWhenHasShadowmap) | |
| else | |
| self:ClearLightFlags(const.elfInteriorAndExteriorWhenHasShadowmap) | |
| end | |
| end, | |
| SetLightmodelColorIndex = function(self, val) | |
| local index = 0 | |
| local activated_key = false | |
| for key, value in pairs(val or empty_table) do | |
| if value then activated_key = key end | |
| end | |
| if activated_key then | |
| index = table.find(lightmodel_lights, activated_key) | |
| end | |
| assert(index >= 0 and index <= 4) | |
| -- maskset(old, const.elfColorIndexMask, index << const.elfColorIndexShift) | |
| self:ClearLightFlags(const.elfColorIndexMask) | |
| self:SetLightFlags(index << const.elfColorIndexShift) | |
| end, | |
| GetLightmodelColorIndex = function(self) | |
| local index = self:GetLightmodelColorIndexNumber() | |
| if index == 0 then return {} end | |
| return { [lightmodel_lights[index]] = true } | |
| end, | |
| SetIntensity = function(self, value) self:SetIntensityAtIndex(0, value) self:SetIntensityAtIndex(1, value) end, | |
| SetIntensity0 = function(self, value) self:SetIntensityAtIndex(0, value) end, | |
| SetIntensity1 = function(self, value) self:SetIntensityAtIndex(1, value) end, | |
| GetIntensity0 = function(self, value) return self:GetIntensityAtIndex(0) end, | |
| GetIntensity1 = function(self, value) return self:GetIntensityAtIndex(1) end, | |
| GetIntensity = function(self, value) return self:GetIntensityAtIndex(0), self:GetIntensityAtIndex(1) end, | |
| GetAlwaysRenderable = function(self) return self:GetGameFlags(const.gofAlwaysRenderable) end, | |
| SetAlwaysRenderable = function(self, value) | |
| if value == true then | |
| self:SetGameFlags(const.gofAlwaysRenderable) | |
| else | |
| self:ClearGameFlags(const.gofAlwaysRenderable) | |
| end | |
| end, | |
| SetBehavior = function(self, b) | |
| if b == "flicker" then | |
| self:SetLightFlags(const.elfFlicker) | |
| else | |
| self:ClearLightFlags(const.elfFlicker) | |
| end | |
| end, | |
| CurrTime = function(self) | |
| if self:GetGameFlags( const.gofRealTimeAnim ) > 0 then | |
| return RealTime() | |
| end | |
| return GameTime() | |
| end, | |
| Fade = function(self, color, intensity, time) | |
| self:SetBehavior("fade") | |
| self:SetTimes(self:CurrTime(), self:CurrTime() + time) | |
| self:SetColor0(self:GetColor1()) | |
| self:SetColor1(color) | |
| self:SetIntensity0(self:GetIntensity1()) | |
| self:SetIntensity1(intensity) | |
| end, | |
| Flicker = function(self, color, intensity, period, phase) | |
| self:SetBehavior("flicker") | |
| phase = self:CurrTime() - (phase or AsyncRand(period)) | |
| self:SetTimes(phase, phase + period * 300) | |
| self:SetColor(color) | |
| self:SetIntensity0(0) | |
| self:SetIntensity1(intensity) | |
| end, | |
| Steady = function(self, color, intensity) | |
| self:SetColor(color) | |
| self:SetBehavior("fade") | |
| self:SetTimes(-1,-1) | |
| self:SetIntensity(intensity) | |
| end, | |
| SetParentSIModulation = function(self, value) | |
| local parent = self:GetParent() | |
| if parent then | |
| parent:SetSIModulation(value) | |
| end | |
| end, | |
| GetParentSIModulation = function(self) | |
| local parent = self:GetParent() | |
| if parent then | |
| return parent:GetSIModulation() | |
| end | |
| return 100 | |
| end, | |
| SetVolume = function(self, volume_obj) | |
| self:SetTargetVolumeId(volume_obj and volume_obj.handle or 0) | |
| end, | |
| GetVolume = function(self) | |
| local handle = self:GetTargetVolumeId() | |
| if not handle or handle == 0 then return false end | |
| return HandleToObject[handle] | |
| end, | |
| SetContourOuterID = empty_func, | |
| } | |
| function Light:OnEditorSetProperty(prop_id) | |
| if prop_id == "DetailClass" then | |
| self:DestroyRenderObj() | |
| end | |
| end | |
| const.ShadowDirsComboItems = { | |
| [LastSetBit(const.eLightDirX) + 1] = { name = "+X" }, | |
| [LastSetBit(const.eLightDirNegX) + 1] = { name = "-X" }, | |
| [LastSetBit(const.eLightDirY) + 1] = { name = "+Y" }, | |
| [LastSetBit(const.eLightDirNegY) + 1] = { name = "-Y" }, | |
| [LastSetBit(const.eLightDirZ) + 1] = { name = "+Z" }, | |
| [LastSetBit(const.eLightDirNegZ) + 1] = { name = "-Z" }, | |
| } | |
| local shadowDirsDefault = 0 | |
| DefineClass.PointLight = { | |
| __parents = { "Light" }, | |
| entity = "PointLight", -- needed by the editor | |
| properties = { | |
| { category = "Visuals", id = "SourceRadius", name = "Source Radius (cm)", editor = "number", min = guic, max=20*guim, default = 10*guic, scale = guic, slider = true, | |
| helper = "sradius", color = RGB(200, 200, 0), autoattach_prop = true, }, | |
| { category = "Visuals", id = "AttenuationRadius", name = "Attenuation Radius", editor = "number", min = 0*guim, max=500*guim, default = 10*guim, scale = "m", slider = true, | |
| helper = "sradius", color = RGB(255, 0, 0), autoattach_prop = true, }, | |
| { category = "Visuals", id = "ShadowDirs", name = "Shadow Dirs (To disable)", editor = "flags", items = const.ShadowDirsComboItems, default = shadowDirsDefault, size = 6, | |
| autoattach_prop = true, }, | |
| }, | |
| ShadowDirsDefault = shadowDirsDefault, | |
| SourceRadius = 1*guic, | |
| AttenuationRadius = 10*guim, | |
| Init = function(self) | |
| self:SetSourceRadius(self.SourceRadius) | |
| self:SetAttenuationRadius(self.AttenuationRadius) | |
| self:SetLightType(const.eLightTypePoint) | |
| self:SetShadowDirs(shadowDirsDefault) | |
| end, | |
| } | |
| DefineClass.LightFlicker = { | |
| __parents = {"InitDone"}, | |
| entity = "PointLight", -- needed by the editor | |
| properties = { | |
| { id = "Color", editor = false }, | |
| { id = "Intensity", editor = false }, | |
| { category = "Visuals", id = "Color0", editor = "color", default = RGB(255,255,255), autoattach_prop = true, }, | |
| { category = "Visuals", id = "Intensity0", editor = "number", default = 0, min = 0, max = 255, slider = true, autoattach_prop = true, }, | |
| { category = "Visuals", id = "Color1", editor = "color", default = RGB(255,255,255), autoattach_prop = true, }, | |
| { category = "Visuals", id = "Intensity1", editor = "number", default = 100, min = 0, max = 255, slider = true, autoattach_prop = true, }, | |
| { category = "Visuals", id = "Period", editor = "number", default = 500, min = 0, max = 100000, scale = 1000, slider = true, autoattach_prop = true, }, | |
| }, | |
| -- defaults | |
| Period = 40000, | |
| } | |
| function LightFlicker:Init() | |
| self:SetBehavior("flicker") | |
| self:SetColor(self.Color) | |
| self:SetIntensity0(0) | |
| self:SetIntensity1(self.Intensity) | |
| self:SetPeriod(self.Period) | |
| end | |
| function LightFlicker:GetPeriod() | |
| local t0,t1 = self:GetTimes() | |
| return t1 - t0 | |
| end | |
| function LightFlicker:SetPeriod(period) | |
| period = Max(period, 1) | |
| local phase = AsyncRand(period) | |
| local time = self:CurrTime() | |
| if self:CurrTime() < phase then | |
| self:SetTimes(0, period) | |
| else | |
| self:SetTimes(time - phase, time - phase + period) | |
| end | |
| end | |
| DefineClass.PointLightFlicker = { | |
| __parents = { "PointLight", "LightFlicker" }, | |
| } | |
| DefineClass.SpotLightFlicker = { | |
| __parents = { "SpotLight", "LightFlicker" }, | |
| } | |
| DefineClass.MaskedLight = { | |
| __parents = { "Light" }, | |
| properties = { | |
| { category = "Visuals", id = "Mask", editor = "browse", folder = "Textures/Misc/LightMasks", help = "Specifies the texture that is going to be applied to modify the light appearance" }, | |
| { category = "Visuals", id = "AnimX", editor = "number", min = 1, max = 16, help = "How many cuts on the X axis are specified in the mask texture. The animation is traversed left to right." }, | |
| { category = "Visuals", id = "AnimY", editor = "number", min = 1, max = 16, help = "How many cuts on the Y axis are specified in the mask texture. The animation is traversed top to bottom." }, | |
| { category = "Visuals", id = "AnimPeriod", editor = "number", min = 0, max = 256, scale = 10, help = "The period of the animation. If zero is specified, the animation is not applied." }, | |
| { category = "Visuals", id = "ScaleMask", editor = "bool", default = false, }, | |
| }, | |
| -- defaults | |
| Mask = "Textures/Misc/LightMasks/angle-attn.tga", | |
| ScaleMask = false, | |
| AnimX = 1, | |
| AnimY = 1, | |
| AnimPeriod = 256, | |
| Init = function(self) | |
| self:SetMask(self.Mask) | |
| self:SetScaleMask(self.ScaleMask) | |
| self:SetAnimX(self.AnimX) | |
| self:SetAnimY(self.AnimY) | |
| self:SetAnimPeriod(self.AnimPeriod) | |
| end, | |
| GetScaleMask = function(self) return self:GetLightFlags(const.elfScaleMask) end, | |
| SetScaleMask = function(self, scale) | |
| if scale then | |
| self:SetLightFlags(const.elfScaleMask) | |
| else | |
| self:ClearLightFlags(const.elfScaleMask) | |
| end | |
| end, | |
| GetAnim = function(self, nshift) | |
| local flags = self:GetAnimParams() | |
| local anim_size = band(shift(flags, -nshift), const.elAnimMask) + 1 | |
| return anim_size | |
| end, | |
| SetAnim = function(self, nshift, num) | |
| local flags = self:GetAnimParams() | |
| local new_data = maskset(flags, shift(const.elAnimMask, nshift), shift(num-1, nshift)) | |
| self:SetAnimParams(new_data) | |
| end, | |
| GetAnimX = function(self) return self:GetAnim(const.elAnimXShift) end, | |
| SetAnimX = function(self, num) self:SetAnim(const.elAnimXShift, num) end, | |
| GetAnimY = function(self) return self:GetAnim(const.elAnimYShift) end, | |
| SetAnimY = function(self, num) self:SetAnim(const.elAnimYShift, num) end, | |
| GetMask = _GetCustomString, | |
| SetMask = _SetCustomString, | |
| GetAnimPeriod = function(self) | |
| return shift(band(self:GetAnimParams(), const.elAnimPeriodMask), -const.elAnimPeriodShift) | |
| end, | |
| SetAnimPeriod = function(self, period) | |
| local params = self:GetAnimParams() | |
| local new_params = maskset(params, const.elAnimPeriodMask, shift(period, const.elAnimPeriodShift)) | |
| self:SetAnimParams(new_params ) | |
| end, | |
| } | |
| DefineClass.BoxLight = { | |
| __parents = { "MaskedLight" }, | |
| entity = "PointLight", -- needed by the editor | |
| properties = { | |
| { category = "Visuals", id = "BoxWidth", editor = "number", min = guim/10, max = 50*guim, slider = true, helper = "box3" }, | |
| { category = "Visuals", id = "BoxHeight", editor = "number", min = guim/10, max = 50*guim, slider = true, helper = "box3" }, | |
| { category = "Visuals", id = "BoxDepth", editor = "number", min = guim/10, max = 50*guim, slider = true, helper = "box3" }, | |
| }, | |
| -- defaults | |
| BoxWidth = 5 * guim, | |
| BoxHeight = 5 * guim, | |
| BoxDepth = 5 * guim, | |
| Init = function(self) | |
| self:SetBoxWidth(self.BoxWidth) | |
| self:SetBoxHeight(self.BoxHeight) | |
| self:SetBoxDepth(self.BoxDepth) | |
| self:SetLightType(const.eLightTypeBox) | |
| end, | |
| } | |
| DefineClass.SpotLight = { | |
| __parents = { "PointLight", "MaskedLight" }, | |
| entity = "PointLight", -- needed by the editor | |
| properties = { | |
| { category = "Visuals", id = "ConeInnerAngle", editor = "number", min = 5, max = (180 - 5), default = 45, slider = true, helper = "spotlighthelper", autoattach_prop = true, }, | |
| { category = "Visuals", id = "ConeOuterAngle", editor = "number", min = 5, max = (180 - 5), default = 90, slider = true, helper = "spotlighthelper", autoattach_prop = true, }, | |
| }, | |
| -- defaults | |
| ConeInnerAngle = 45, | |
| ConeOuterAngle = 90, | |
| target_helper = false, | |
| Init = function(self) | |
| self:SetConeInnerAngle(self.ConeInnerAngle) | |
| self:SetConeOuterAngle(self.ConeOuterAngle) | |
| self:SetLightType(const.eLightTypeSpot) | |
| end, | |
| GetConeInnerAngle = function(self) return self:GetInnerAngle() end, | |
| GetConeOuterAngle = function(self) return self:GetOuterAngle() end, | |
| } | |
| if Platform.developer then | |
| function SpotLight:SetConeInnerAngle(v) | |
| self:SetInnerAngle(v) | |
| if (v > self:GetOuterAngle()) then | |
| self:SetOuterAngle(v) | |
| end | |
| end | |
| function SpotLight:SetConeOuterAngle(v) | |
| self:SetOuterAngle(v) | |
| if (v < self:GetInnerAngle()) then | |
| self:SetInnerAngle(v) | |
| end | |
| end | |
| else | |
| function SpotLight:SetConeInnerAngle(v) self:SetInnerAngle(v) end | |
| function SpotLight:SetConeOuterAngle(v) self:SetOuterAngle(v) end | |
| end | |
| function SpotLight:OnEditorSetProperty(...) | |
| Light.OnEditorSetProperty(self, ...) | |
| PropertyHelpers_UpdateAllHelpers(self) | |
| end | |
| function SpotLight:ConfigureTargetHelper() | |
| if not self.target_helper or not IsValid(self.target_helper) then | |
| self.target_helper = PlaceObject("SpotHelper") | |
| self.target_helper.obj = self | |
| end | |
| local axis = self:GetOrientation() | |
| local pos = self:GetVisualPos() | |
| local o, closest, normal = IntersectSegmentWithClosestObj(pos, pos - axis * guim) | |
| if closest and normal and o ~= self.target_helper then | |
| self.target_helper:SetPos(closest) | |
| else | |
| local newPos = terrain.IntersectRay(pos, pos + axis) | |
| if newPos then | |
| self.target_helper:SetPos(newPos:SetZ(const.InvalidZ)) | |
| end | |
| end | |
| end | |
| function OnMsg.EditorSelectionChanged(objs) | |
| local isSpotLight = false | |
| for _, obj in ipairs(objs) do | |
| if obj.class == "SpotLight" then | |
| isSpotLight = true | |
| obj:ConfigureTargetHelper() | |
| elseif obj.class == "SpotHelper" then | |
| isSpotLight = true | |
| end | |
| end | |
| if not isSpotLight then | |
| MapForEach(true, "SpotHelper", function(spot_helper) | |
| DoneObject(spot_helper) | |
| end) | |
| end | |
| end | |
| function OnMsg.EditorCallback(id, objects, ...) | |
| if id == "EditorCallbackMove" or id == "EditorCallbackRotate" or id == "EditorCallbackPlace" then | |
| for _, obj in ipairs(objects) do | |
| if obj.class == "SpotLight" then | |
| obj:ConfigureTargetHelper() | |
| end | |
| end | |
| if id == "EditorCallbackMove" then | |
| for _, obj in ipairs(objects) do | |
| if obj.class == "SpotHelper" and obj.obj.class == "SpotLight" then | |
| obj.obj:SetOrientation(Normalize(obj.obj:GetVisualPos() - obj:GetVisualPos()), 0) | |
| end | |
| end | |
| end | |
| elseif id == "EditorCallbackDelete" then | |
| for _, obj in ipairs(objects) do | |
| if obj.class == "SpotLight" then | |
| DoneObject(obj.target_helper) | |
| obj.target_helper = false | |
| end | |
| end | |
| end | |
| end | |
| if Platform.developer and false then | |
| function OnMsg.NewMapLoaded() | |
| -- check if used lightmaps are available | |
| local masks = {} | |
| MapForEach("map", "Light", function(light) if light:HasMember("GetMask") then masks[light:GetMask()] = true end end) | |
| for mask, _ in pairs(masks) do | |
| local id = ResourceManager.GetResourceID(mask) | |
| if id == const.InvalidResourceID then | |
| printf("once", "Light mask texture '%s' is not present", mask) | |
| end | |
| end | |
| end | |
| end | |
| function PointLight:ConfigureInvisibleObjectHelper(helper) | |
| if not helper then return end | |
| local important = self:GetDetailClass() == "Essential" | |
| helper:SetScale(important and 100 or 60) | |
| if important then | |
| helper:SetColorModifier(self:GetCastShadows() and RGB(100, 10, 10) or RGB(20, 80, 100)) | |
| else | |
| helper:SetColorModifier(self:GetCastShadows() and RGB(100, 30, 30) or RGB(40, 80, 100)) | |
| end | |
| end | |
| DefineClass.AttachLightPropertyObject = { | |
| __parents = {"PropertyObject"}, | |
| properties = { | |
| {category = "Lights", id = "AttachLight", name = "Attach Light", editor = "bool", default = true}, | |
| }, | |
| } | |
| local detail_class_weight = {["Essential"] = 1, ["Optional"] = 2, ["Eye Candy"] = 3} | |
| function GetLights(filter) | |
| if GetMap() == "" then return end | |
| local lights = MapGet("map", "Light", const.efVisible, filter) or empty_table | |
| table.sort(lights, function(light1, light2) | |
| local weight1 = detail_class_weight[light1:GetDetailClass()] or 4 | |
| local weight2 = detail_class_weight[light2:GetDetailClass()] or 4 | |
| if weight1 == weight2 then | |
| return light1.handle < light2.handle | |
| else | |
| return weight1 < weight2 | |
| end | |
| end) | |
| return lights | |
| end | |