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