Follow transformed battle characters in FaceCam
This commit is contained in:
1 parent
3fbb70a30c
commit
448ea61a68
1 file changed
+37
-8
+37
-8
@@ -74,10 +74,10 @@ local function current_facecam_target()
|
||||
local field = typeof(CS.RPG.Client.GamePhaseManager):GetField('_CurrentPhase', flags)
|
||||
local phase = manager and field and field:GetValue(manager)
|
||||
if not phase then return nil, nil, nil, false end
|
||||
local entity
|
||||
local entity, mode
|
||||
if typeof(CS.RPG.Client.BattleGamePhase):IsInstanceOfType(phase) then
|
||||
local instance = phase.BattleInstanceRef
|
||||
local mode = instance and instance.TurnBasedGameModeRef
|
||||
mode = instance and instance.TurnBasedGameModeRef
|
||||
entity = mode and mode.CurrentTurnOwnerEntity
|
||||
-- Inserted attacks can act outside the turn owner's turn. Prefer the
|
||||
-- most recently attacking entity while the Client reports one.
|
||||
@@ -91,15 +91,35 @@ local function current_facecam_target()
|
||||
return nil, nil, nil, false
|
||||
end
|
||||
if not entity then return nil, nil, nil, true end
|
||||
if _G.__FC_FACE_ENTITY == entity.RuntimeID and _G.__FC_FACE_HEAD and _G.__FC_FACE_ROOT then
|
||||
local function model_for(candidate)
|
||||
local ok, result = pcall(function()
|
||||
local component = candidate and candidate:GetComponent(typeof(CS.RPG.GameCore.CharacterModelComponent))
|
||||
return component and component:GetModelGO()
|
||||
end)
|
||||
if ok then return result end
|
||||
return nil
|
||||
end
|
||||
local model = model_for(entity)
|
||||
-- In a transformed turn the Client can report a model-less turn owner;
|
||||
-- the live battle's MVP entity points to the visible transformed actor.
|
||||
if not model and mode then
|
||||
local fallback = mode.CurrentMVPEntity
|
||||
local fallbackModel = model_for(fallback)
|
||||
if fallbackModel then entity, model = fallback, fallbackModel end
|
||||
end
|
||||
if not model then return nil, nil, nil, true end
|
||||
local cachedAlive, cachedActive = pcall(function()
|
||||
return _G.__FC_FACE_HEAD and _G.__FC_FACE_ROOT
|
||||
and _G.__FC_FACE_HEAD.gameObject.activeInHierarchy and _G.__FC_FACE_ROOT.gameObject.activeInHierarchy
|
||||
end)
|
||||
if _G.__FC_FACE_ENTITY == entity.RuntimeID and cachedAlive and cachedActive then
|
||||
return _G.__FC_FACE_HEAD, _G.__FC_FACE_ROOT, entity.RuntimeID, true
|
||||
end
|
||||
local component = entity:GetComponent(typeof(CS.RPG.GameCore.CharacterModelComponent))
|
||||
local model = component and component:GetModelGO()
|
||||
if not model then return nil, nil, nil, true end
|
||||
local nodes = model:GetComponentsInChildren(typeof(CS.UnityEngine.Transform), true)
|
||||
for i = 0, nodes.Length - 1 do
|
||||
if nodes[i].name == 'Head_M' then return nodes[i], model.transform, entity.RuntimeID, true end
|
||||
if nodes[i].name == 'Head_M' and nodes[i].gameObject.activeInHierarchy then
|
||||
return nodes[i], model.transform, entity.RuntimeID, true
|
||||
end
|
||||
end
|
||||
return nil, nil, nil, true
|
||||
end
|
||||
@@ -137,7 +157,14 @@ local function update_facecam(cam, settings)
|
||||
end
|
||||
end
|
||||
local head, root = _G.__FC_FACE_HEAD, _G.__FC_FACE_ROOT
|
||||
if not head or not root or not head.gameObject.activeInHierarchy then return false end
|
||||
local alive, active = pcall(function() return head and root and head.gameObject.activeInHierarchy end)
|
||||
if not alive or not active then
|
||||
-- Character transformations can briefly unload a model while keeping
|
||||
-- the same entity ID. Give the replacement time to become available.
|
||||
_G.__FC_FACE_MISSING_SINCE = _G.__FC_FACE_MISSING_SINCE or now
|
||||
return now - _G.__FC_FACE_MISSING_SINCE < 2
|
||||
end
|
||||
_G.__FC_FACE_MISSING_SINCE = nil
|
||||
local distance = _G.__FC_FACE_DISTANCE or tonumber(settings.distance) or 2
|
||||
local scroll = Input.mouseScrollDelta.y
|
||||
if scroll ~= 0 then distance = distance - scroll * 0.2 end
|
||||
@@ -331,6 +358,7 @@ function _G.__FREECAM_TICK()
|
||||
_G.__FC_FACE_HEAD, _G.__FC_FACE_ROOT = nil, nil
|
||||
_G.__FC_FACE_ENTITY = nil
|
||||
_G.__FC_FACE_DISTANCE, _G.__FC_FACE_LOCAL_FORWARD = nil, nil
|
||||
_G.__FC_FACE_MISSING_SINCE = nil
|
||||
if _G.__FC_FACE_ANCHOR then CS.UnityEngine.Object.Destroy(_G.__FC_FACE_ANCHOR); _G.__FC_FACE_ANCHOR = nil end
|
||||
local label = settings.mode == 'facecam' and 'FaceCam' or 'FreeCam'
|
||||
show_ui('<color=#00FF88><b>[' .. label .. ': OFF]</b></color>')
|
||||
@@ -362,6 +390,7 @@ function _G.__FREECAM_TICK()
|
||||
_G.__FC_FACE_HEAD, _G.__FC_FACE_ROOT = nil, nil
|
||||
_G.__FC_FACE_ENTITY = nil
|
||||
_G.__FC_FACE_DISTANCE, _G.__FC_FACE_LOCAL_FORWARD = nil, nil
|
||||
_G.__FC_FACE_MISSING_SINCE = nil
|
||||
if _G.__FC_FACE_ANCHOR then CS.UnityEngine.Object.Destroy(_G.__FC_FACE_ANCHOR); _G.__FC_FACE_ANCHOR = nil end
|
||||
show_ui("<color=#FFAA44>FaceCam: character unavailable</color>")
|
||||
end
|
||||
|
||||
Reference in new issue
Block a user