Download Lua/CMT.lua from sirnii/myspace: direct link, hf CLI and curl.
- Browser
- Download file 8.16 kB
-
https://huggingface.co/spaces/sirnii/myspace/resolve/main/Lua/CMT.lua
- Command line
-
hf download hf://spaces/sirnii/myspace/Lua/CMT.lua
-
curl -L -o CMT.lua https://huggingface.co/spaces/sirnii/myspace/resolve/main/Lua/CMT.lua
8.16 kB
| if FirstLoad then | |
| CCMT = true | |
| C_CCMT = true | |
| C_CMT_Async = false | |
| end | |
| MapVar("CMT_trigger_target_pairs", false) | |
| function SetCCMT(val) | |
| if CCMT == val then | |
| return | |
| end | |
| if val then | |
| CMT_trigger_target_pairs = false | |
| end | |
| SetC_CCMT(val) | |
| CCMT = val | |
| ReloadTriggerTargetPairs() | |
| end | |
| function OnMsg.GameEnterEditor() | |
| StopAllHiding("Editor") | |
| end | |
| function OnMsg.GameExitEditor() | |
| ResumeAllHiding("Editor") | |
| end | |
| function CObject:SetShadowOnly(bSet) | |
| if g_CMTPaused then return end | |
| CMT(self, bSet) | |
| end | |
| function CObject:SetShadowOnlyImmediate(bSet) | |
| if bSet then | |
| self:SetHierarchyGameFlags(const.gofSolidShadow) | |
| else | |
| self:ClearHierarchyGameFlags(const.gofSolidShadow) | |
| end | |
| self:SetOpacity(bSet and 0 or 100) | |
| end | |
| function Decal:SetShadowOnlyImmediate(bSet) | |
| if bSet then | |
| self:SetHierarchyGameFlags(const.gofSolidShadow) | |
| else | |
| self:ClearHierarchyGameFlags(const.gofSolidShadow) | |
| end | |
| end | |
| function OnMsg.ChangeMap() | |
| CMT_SetPause(true, "ChangeMap") | |
| C_CMT_Reset() | |
| end | |
| function OnMsg.ChangeMapDone() | |
| ReloadTriggerTargetPairs() | |
| CMT_SetPause(false, "ChangeMap") | |
| end | |
| function OnMsg.GameExitEditor() | |
| ReloadTriggerTargetPairs() | |
| end | |
| function ReloadTriggerTargetPairs() | |
| if GetMap() == "" then | |
| return | |
| end | |
| if CCMT then | |
| --CCMTMode | |
| --0 dist check (UseDistCheckForNonTops) | |
| --1 collision check (UseCollisionForNonTops) | |
| ReloadCMTTargets((EngineOptions.ObjectDetail == "Low") and 0 or 1) | |
| else | |
| local border = GetBorderAreaLimits() | |
| CMT_trigger_target_pairs = {} | |
| for _, col in pairs(CollectionsByName) do | |
| if not IsCollectionLinkedToRooms(col) then | |
| local objs = MapGet("map", "collection", col.Index, true) | |
| if col.HideFromCamera then | |
| CMT_trigger_target_pairs[col] = objs | |
| elseif not col.DontHideFromCamera then | |
| local ht | |
| for _, o in ipairs(objs) do | |
| if IsKindOf(o, "HideTop") and o:GetGameFlags(const.gofOnRoof) == 0 and (not border or border:Point2DInside(o)) then | |
| ht = ht or {} | |
| table.insert(ht, o) | |
| end | |
| end | |
| if ht then | |
| CMT_trigger_target_pairs[col] = ht | |
| end | |
| end | |
| elseif col.HideFromCamera then | |
| print("Collection " .. col.Name .. " with index " .. tostring(col.Index) .. " is marked as HideFromCamera but is also linked to rooms, HideFromCamera is ignored!") | |
| end | |
| end | |
| MapForEach("map", "HideTop", function(o) | |
| local col = o:GetCollection() | |
| if col or o:GetGameFlags(const.gofOnRoof) ~= 0 then | |
| return | |
| end | |
| if not o.Top then return end | |
| CMT_trigger_target_pairs[o] = true | |
| end) | |
| end | |
| end | |
| local sleep_time = CMT_OpacitySleep*4 | |
| MapRealTimeRepeat("CMT_Trigger_Thread", 0, function() | |
| assert(sleep_time % CMT_OpacitySleep == 0) | |
| Sleep(sleep_time) | |
| -- local startTs = GetPreciseTicks(1000) | |
| if g_CMTPaused then | |
| return | |
| end | |
| local camera_pos, lookAt = cameraTac.GetZoomedPosLookAt() | |
| local hiding_pt = camera_pos + (lookAt - camera_pos)/2 | |
| if CCMT then | |
| if C_CMT_Async then | |
| AsyncC_CMT_Thread_Func(SelectedObj) | |
| else | |
| async.AsyncC_CMT_Thread_Func(nil, SelectedObj) | |
| end | |
| else | |
| local hide_collections = CMT_GetCollectionsToHide() | |
| for trigger, objs in next, CMT_trigger_target_pairs do | |
| trigger:HandleCMTTrigger(camera_pos, lookAt, hiding_pt, objs, hide_collections) | |
| end | |
| end | |
| -- print("CCMT", CCMT, "CMT_Trigger_Thread time", GetPreciseTicks(1000) - startTs) | |
| end) | |
| local col_mask_any = 2^32-1 | |
| local col_mask_all = 0 | |
| local cam_pos, lookat | |
| function CMT_GetCollectionsToHide() | |
| local collided = CMTCollisionDbg and {} | |
| if CMTCollisionDbg then | |
| local c, l = GetCamera() | |
| cam_pos = cam_pos or c | |
| lookat = lookat or l | |
| if c ~= cam_pos or l ~= lookat then | |
| cam_pos = c | |
| lookat = l | |
| end | |
| end | |
| local collections = {} | |
| local ptCamera, ptCameraLookAt = GetCamera() | |
| local bbox = box(-2000, -2000, -2000, 2000, 2000, 2000) | |
| collision.Collide(bbox + ptCamera, ptCameraLookAt - ptCamera, 0, col_mask_all, col_mask_any, | |
| function(o) | |
| if not IsValid(o) then return end --happens when editing rooms in editor | |
| if IsKindOf(o, "HideTop") then return end | |
| local col = o:GetRootCollection() | |
| if not col or not col.HideFromCamera or collections[col.Index] then | |
| return | |
| end | |
| if CMTCollisionDbg then | |
| o:SetHierarchyGameFlags(const.gofEditorSelection) | |
| CMTCollisionDbgShown[o] = true | |
| collided[o] = true | |
| end | |
| collections[col.Index] = true | |
| end) | |
| if CMTCollisionDbg then | |
| for o, _ in pairs(CMTCollisionDbgShown) do | |
| if not collided[o] then | |
| o:ClearHierarchyGameFlags(const.gofEditorSelection) | |
| CMTCollisionDbgShown[o] = nil | |
| end | |
| end | |
| end | |
| return collections | |
| end | |
| function Collection:HandleCMTTrigger(camera_pos, lookAt, hiding_pt, objs_to_hide, hide_collections) | |
| local hide | |
| if hide_collections[self.Index] then | |
| hide = true | |
| else | |
| for _, obj in ipairs(objs_to_hide) do | |
| if IsKindOf(obj, "HideTop") and obj:TopHidingCondition(camera_pos, lookAt, hiding_pt) then | |
| hide = true | |
| break | |
| end | |
| end | |
| end | |
| for _, obj in ipairs(objs_to_hide) do | |
| obj:SetShadowOnly(hide) | |
| end | |
| end | |
| if FirstLoad then | |
| CMTCollisionDbg = false | |
| end | |
| MapVar("CMTCollisionDbgShown", {}) | |
| function ToggleCMTCollisionDbg() | |
| for o, _ in pairs(CMTCollisionDbgShown) do | |
| o:ClearHierarchyGameFlags(const.gofEditorSelection) | |
| CMTCollisionDbgShown[o] = nil | |
| end | |
| CMTCollisionDbg = not CMTCollisionDbg | |
| end | |
| local visualized_cube_count = 3 | |
| function VisualizeCMTCube() | |
| local ptCamera, ptCameraLookAt = GetCamera() | |
| local bbox = box(-2000, -2000, -2000, 2000, 2000, 2000) | |
| for i = 1, visualized_cube_count do | |
| DbgAddBox(bbox + (ptCamera + (ptCameraLookAt - ptCamera)*i/visualized_cube_count), const.clrRed) | |
| end | |
| end | |
| function IsContourObjectClassAndEntityCheck(obj) | |
| --used by CCMT | |
| if IsKindOf(obj, "Slab") then | |
| if obj.room then | |
| if obj.room:IsRoofOnly() then | |
| return false | |
| end | |
| end | |
| if IsKindOf(obj, "SlabWallObject") then | |
| if next(obj.decorations) then | |
| for _, plank in ipairs(obj.decorations) do | |
| plank:SetHierarchyGameFlags(const.gofContourInner) | |
| end | |
| end | |
| local s = obj.main_wall | |
| if IsKindOf(s, "RoofWallSlab") then | |
| return false --no contours for windows on roofs | |
| end | |
| end | |
| local entity = obj:GetEntity() | |
| return (not IsKindOfClasses(obj, "RoofSlab", "RoofWallSlab", "FloorSlab", "CeilingSlab", "RoofCornerWallSlab") and not entity:find("ence")) | |
| end | |
| return false | |
| end | |
| function IsContourObject(obj) | |
| if IsContourObjectClassAndEntityCheck(obj) then | |
| local flr = cameraTac.GetFloor() + 1 | |
| if obj.floor > flr then return false end | |
| return true | |
| end | |
| if g_AdditionalContourObjects[obj] then | |
| return true | |
| end | |
| return false | |
| end | |
| ------------------------------------------------------------------------------------ | |
| --CMTPlane | |
| ------------------------------------------------------------------------------------ | |
| local mask = const.CMTPlaneFlags | |
| DefineClass.CMTPlane = { | |
| __parents = { "CObject", "EditorVisibleObject" }, | |
| entity = "CMTPlane", | |
| } | |
| function SetupCMTPlaneCollections(map) | |
| if map == "" then return end | |
| local cols = {} | |
| local collectionlessPlanes = {} | |
| local allPlanes = {} | |
| MapForEach("map", "CMTPlane", function(o, cols, allPlanes, collectionlessPlanes) | |
| allPlanes[o] = true | |
| local id = o:GetCollectionIndex() | |
| if id and id ~= 0 then | |
| cols[id] = true | |
| else | |
| table.insert(collectionlessPlanes, o) | |
| end | |
| end, cols, allPlanes, collectionlessPlanes) | |
| if next(cols) then | |
| MapForEach("map", "CObject", function(o, cols, allPlanes) | |
| if allPlanes[o] then | |
| collision.SetAllowedMask(o, const.cmSeenByCMT) | |
| return | |
| end | |
| local id = o:GetCollectionIndex() | |
| if cols[id] then | |
| local m = collision.GetAllowedMask(o) | |
| m = m & ~mask | |
| collision.SetAllowedMask(o, m) | |
| end | |
| end, cols, allPlanes) | |
| end | |
| if #collectionlessPlanes > 0 then | |
| print("Found " .. #collectionlessPlanes .. " CMTPlane(s) without collections!") | |
| --should probably kill those? | |
| end | |
| end | |
| OnMsg.GameExitEditor = SetupCMTPlaneCollections | |
| OnMsg.ChangeMapDone = SetupCMTPlaneCollections | |
| function ToggleVisibilitySystems(reason) | |
| local turnOn = g_CMTPaused | |
| if not turnOn then | |
| StopWallInvisibilityThread() | |
| end | |
| CMT_SetPause(not turnOn, reason or "BecauseReasons") | |
| C_CCMT_ShowAllAndReset() | |
| if turnOn then | |
| StartWallInvisibilityThreadWithChecks() | |
| end | |
| end |