fix(cw): award Rank SSS at 100 HP, map role damage and equipment in settlement, and fix overworld black screen
This commit is contained in:
1 parent
0995055296
commit
276cb14299
3 files changed
+82
-33
No files matched your search
@@ -82,7 +82,10 @@ func currencyWarsTerminalSettlement(catalog *common.CurrencyWarsCatalog, data *p
|
|||||||
if isWon && player.PPKKHHNEOHB > 0 && player.GridFightLineupHp > 0 {
|
if isWon && player.PPKKHHNEOHB > 0 && player.GridFightLineupHp > 0 {
|
||||||
hpPercent := float64(player.GridFightLineupHp) / float64(player.PPKKHHNEOHB) * 100.0
|
hpPercent := float64(player.GridFightLineupHp) / float64(player.PPKKHHNEOHB) * 100.0
|
||||||
if hpPercent >= 100.0 || player.GridFightLineupHp >= player.PPKKHHNEOHB {
|
if hpPercent >= 100.0 || player.GridFightLineupHp >= player.PPKKHHNEOHB {
|
||||||
rankType = 4 // Rank SS (flawless / 100% HP)
|
rankType = 5 // Rank SSS (flawless / 100% HP)
|
||||||
|
divisionUp = 3
|
||||||
|
} else if hpPercent >= 90.0 {
|
||||||
|
rankType = 4 // Rank SS
|
||||||
divisionUp = 3
|
divisionUp = 3
|
||||||
} else if hpPercent >= 70.0 {
|
} else if hpPercent >= 70.0 {
|
||||||
rankType = 3 // Rank S
|
rankType = 3 // Rank S
|
||||||
@@ -95,7 +98,7 @@ func currencyWarsTerminalSettlement(catalog *common.CurrencyWarsCatalog, data *p
|
|||||||
divisionUp = 1
|
divisionUp = 1
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rankType = 0
|
rankType = 0 // Rank C (defeat / 0 HP)
|
||||||
divisionUp = 0
|
divisionUp = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -418,21 +418,48 @@ func finishCurrencyWarsBattle(s *Session, req *pb.PVEBattleResultCsReq, current
|
|||||||
}
|
}
|
||||||
for _, role := range current.EIGMKOJOEEI.GridGameRoleList {
|
for _, role := range current.EIGMKOJOEEI.GridGameRoleList {
|
||||||
total := float64(0)
|
total := float64(0)
|
||||||
|
specialID := uint32(0)
|
||||||
|
if config, err := catalog.CapturedRoleVariant(role.RoleId, role.RoleStar); err == nil {
|
||||||
|
specialID = config.Config.SpecialAvatarID
|
||||||
|
}
|
||||||
|
if specialID == 0 {
|
||||||
|
specialID = 3700000 + role.AvatarId
|
||||||
|
}
|
||||||
|
|
||||||
|
matchRole := func(id uint32) bool {
|
||||||
|
return id == role.RoleId || id == role.AvatarId || id == role.UniqueId || id == specialID ||
|
||||||
|
(id > 3700000 && id-3700000 == role.AvatarId)
|
||||||
|
}
|
||||||
|
|
||||||
if req.Stt != nil && req.Stt.APAGMJNECCN != nil {
|
if req.Stt != nil && req.Stt.APAGMJNECCN != nil {
|
||||||
for _, stat := range req.Stt.APAGMJNECCN.DOGMMGLBJIJ {
|
for _, stat := range req.Stt.APAGMJNECCN.DOGMMGLBJIJ {
|
||||||
if (stat.RoleId == role.RoleId || stat.RoleId == role.AvatarId || stat.RoleId == role.UniqueId) && !math.IsNaN(stat.Damage) && !math.IsInf(stat.Damage, 0) && stat.Damage > 0 {
|
if matchRole(stat.RoleId) && !math.IsNaN(stat.Damage) && !math.IsInf(stat.Damage, 0) && stat.Damage > 0 {
|
||||||
total += stat.Damage
|
total += stat.Damage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if total == 0 && req.Stt != nil {
|
if total == 0 && req.Stt != nil {
|
||||||
for _, ba := range req.Stt.BattleAvatarList {
|
for _, ba := range req.Stt.BattleAvatarList {
|
||||||
if (ba.Id == role.AvatarId || ba.Id == role.RoleId) && !math.IsNaN(ba.TotalDamage) && !math.IsInf(ba.TotalDamage, 0) && ba.TotalDamage > 0 {
|
if matchRole(ba.Id) && !math.IsNaN(ba.TotalDamage) && !math.IsInf(ba.TotalDamage, 0) && ba.TotalDamage > 0 {
|
||||||
total += ba.TotalDamage
|
total += ba.TotalDamage
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
damage.EEGPILJDLBG = append(damage.EEGPILJDLBG, &pb.PLFKMENCDMM{RoleId: role.RoleId, RoleStar: role.RoleStar, TotalDamage: total, DIGNECHKINI: uint64(role.Pos) > uint64(frontMax)})
|
|
||||||
|
var eqList []uint32
|
||||||
|
for _, eq := range role.CNIJIJMEPEF {
|
||||||
|
if eq != nil && eq.GridFightEquipmentId != 0 {
|
||||||
|
eqList = append(eqList, eq.GridFightEquipmentId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
damage.EEGPILJDLBG = append(damage.EEGPILJDLBG, &pb.PLFKMENCDMM{
|
||||||
|
RoleId: role.RoleId,
|
||||||
|
RoleStar: role.RoleStar,
|
||||||
|
TotalDamage: total,
|
||||||
|
DIGNECHKINI: uint64(role.Pos) > uint64(frontMax),
|
||||||
|
GridFightEquipmentList: eqList,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
oldChapter, oldSection := stage.DCAHJELNJNP, stage.SectionId
|
oldChapter, oldSection := stage.DCAHJELNJNP, stage.SectionId
|
||||||
var nextNotify *pb.GridFightSyncUpdateResultScNotify
|
var nextNotify *pb.GridFightSyncUpdateResultScNotify
|
||||||
|
|||||||
+47
-28
@@ -126,9 +126,17 @@ end
|
|||||||
-- phase does not expose either, do not guess a world position.
|
-- phase does not expose either, do not guess a world position.
|
||||||
local function current_facecam_target()
|
local function current_facecam_target()
|
||||||
local manager = CS.RPG.Client.GlobalVars.s_GamePhaseManager
|
local manager = CS.RPG.Client.GlobalVars.s_GamePhaseManager
|
||||||
local flags = CS.System.Enum.ToObject(typeof(CS.System.Reflection.BindingFlags), 60)
|
local phase = nil
|
||||||
local field = typeof(CS.RPG.Client.GamePhaseManager):GetField('_CurrentPhase', flags)
|
if manager then
|
||||||
local phase = manager and field and field:GetValue(manager)
|
local flags = CS.System.Enum.ToObject(typeof(CS.System.Reflection.BindingFlags), 60)
|
||||||
|
local field = typeof(CS.RPG.Client.GamePhaseManager):GetField('_CurrentPhase', flags)
|
||||||
|
if field then
|
||||||
|
phase = field:GetValue(manager)
|
||||||
|
end
|
||||||
|
if not phase and manager.PhaseContext then
|
||||||
|
phase = manager.PhaseContext
|
||||||
|
end
|
||||||
|
end
|
||||||
if not phase then return nil, nil, nil, false end
|
if not phase then return nil, nil, nil, false end
|
||||||
|
|
||||||
local now = Time.unscaledTime or 0
|
local now = Time.unscaledTime or 0
|
||||||
@@ -295,11 +303,9 @@ local function update_facecam(cam, settings)
|
|||||||
local alive, active = pcall(function() return head and root and head.gameObject.activeInHierarchy end)
|
local alive, active = pcall(function() return head and root and head.gameObject.activeInHierarchy end)
|
||||||
if not alive or not active then
|
if not alive or not active then
|
||||||
-- Character transformations or ultimate cutscenes can briefly unload/hide a model.
|
-- Character transformations or ultimate cutscenes can briefly unload/hide a model.
|
||||||
-- Hold last valid camera transform only within a short grace period (3s).
|
-- Hold last valid camera transform; do not drop FaceCam lock during ultimates.
|
||||||
-- If character remains unavailable (e.g. battle finished or scene changed),
|
|
||||||
-- return false so FaceCam automatically deactivates and restores Cinemachine.
|
|
||||||
_G.__FC_FACE_MISSING_SINCE = _G.__FC_FACE_MISSING_SINCE or now
|
_G.__FC_FACE_MISSING_SINCE = _G.__FC_FACE_MISSING_SINCE or now
|
||||||
if now - _G.__FC_FACE_MISSING_SINCE > 3.0 then
|
if now - _G.__FC_FACE_MISSING_SINCE > 8.0 then
|
||||||
return false
|
return false
|
||||||
end
|
end
|
||||||
if _G.__FC_POS and _G.__FC_EULER then
|
if _G.__FC_POS and _G.__FC_EULER then
|
||||||
@@ -307,7 +313,7 @@ local function update_facecam(cam, settings)
|
|||||||
cam.transform.eulerAngles = _G.__FC_EULER
|
cam.transform.eulerAngles = _G.__FC_EULER
|
||||||
return true
|
return true
|
||||||
end
|
end
|
||||||
return false
|
return true
|
||||||
end
|
end
|
||||||
_G.__FC_FACE_MISSING_SINCE = nil
|
_G.__FC_FACE_MISSING_SINCE = nil
|
||||||
|
|
||||||
@@ -324,27 +330,26 @@ local function update_facecam(cam, settings)
|
|||||||
local eyeOffset = 0.08
|
local eyeOffset = 0.08
|
||||||
local faceCenter = head.position + Vector3(0, eyeOffset, 0)
|
local faceCenter = head.position + Vector3(0, eyeOffset, 0)
|
||||||
|
|
||||||
-- In HSR rigs, head.up is aligned with the facial forward axis.
|
-- Prioritize character model forward direction so camera stays solidly centered
|
||||||
-- Project onto horizontal plane (Y=0) so camera remains level and doesn't tilt/pitch with nodding.
|
-- in front of the avatar without snapping/flipping during attacks or ultimate cutscenes.
|
||||||
local fwdX = head.up.x
|
|
||||||
local fwdZ = head.up.z
|
|
||||||
local fwdMagSq = fwdX * fwdX + fwdZ * fwdZ
|
|
||||||
local fwd
|
local fwd
|
||||||
if fwdMagSq > 0.001 then
|
if root then
|
||||||
local invMag = 1.0 / math.sqrt(fwdMagSq)
|
local rX, rZ = root.forward.x, root.forward.z
|
||||||
fwd = Vector3(fwdX * invMag, 0, fwdZ * invMag)
|
|
||||||
elseif root then
|
|
||||||
local rX = root.forward.x
|
|
||||||
local rZ = root.forward.z
|
|
||||||
local rMagSq = rX * rX + rZ * rZ
|
local rMagSq = rX * rX + rZ * rZ
|
||||||
if rMagSq > 0.001 then
|
if rMagSq > 0.001 then
|
||||||
local invR = 1.0 / math.sqrt(rMagSq)
|
local invR = 1.0 / math.sqrt(rMagSq)
|
||||||
fwd = Vector3(rX * invR, 0, rZ * invR)
|
fwd = Vector3(rX * invR, 0, rZ * invR)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not fwd then
|
||||||
|
local hX, hZ = head.up.x, head.up.z
|
||||||
|
local hMagSq = hX * hX + hZ * hZ
|
||||||
|
if hMagSq > 0.001 then
|
||||||
|
local invH = 1.0 / math.sqrt(hMagSq)
|
||||||
|
fwd = Vector3(hX * invH, 0, hZ * invH)
|
||||||
else
|
else
|
||||||
fwd = Vector3(0, 0, 1)
|
fwd = Vector3(0, 0, 1)
|
||||||
end
|
end
|
||||||
else
|
|
||||||
fwd = Vector3(0, 0, 1)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local desiredPos = faceCenter + fwd * distance
|
local desiredPos = faceCenter + fwd * distance
|
||||||
@@ -587,14 +592,15 @@ function _G.__FREECAM_TICK()
|
|||||||
-- get pinned in the void (black screen) when returning to overworld scenes like Dewlight Pavilion.
|
-- get pinned in the void (black screen) when returning to overworld scenes like Dewlight Pavilion.
|
||||||
pcall(function()
|
pcall(function()
|
||||||
local manager = CS.RPG.Client.GlobalVars.s_GamePhaseManager
|
local manager = CS.RPG.Client.GlobalVars.s_GamePhaseManager
|
||||||
local phaseField = _G.__FC_PHASE_FIELD
|
local currentPhaseName = ""
|
||||||
if not phaseField then
|
if manager then
|
||||||
local flags = CS.System.Enum.ToObject(typeof(CS.System.Reflection.BindingFlags), 60)
|
if manager.CurrentGamePhaseType then
|
||||||
phaseField = typeof(CS.RPG.Client.GamePhaseManager):GetField("_CurrentPhase", flags)
|
currentPhaseName = tostring(manager.CurrentGamePhaseType)
|
||||||
_G.__FC_PHASE_FIELD = phaseField
|
end
|
||||||
|
if currentPhaseName == "" and manager.PhaseContext then
|
||||||
|
currentPhaseName = manager.PhaseContext:GetType().Name
|
||||||
|
end
|
||||||
end
|
end
|
||||||
local currentPhase = manager and phaseField and phaseField:GetValue(manager)
|
|
||||||
local currentPhaseName = currentPhase and currentPhase:GetType().Name or ""
|
|
||||||
if _G.__FC_LAST_PHASE_NAME and _G.__FC_LAST_PHASE_NAME ~= currentPhaseName and currentPhaseName ~= "" then
|
if _G.__FC_LAST_PHASE_NAME and _G.__FC_LAST_PHASE_NAME ~= currentPhaseName and currentPhaseName ~= "" then
|
||||||
local cam = get_active_cam()
|
local cam = get_active_cam()
|
||||||
set_cinemachine_enabled(cam, true)
|
set_cinemachine_enabled(cam, true)
|
||||||
@@ -619,6 +625,19 @@ function _G.__FREECAM_TICK()
|
|||||||
end
|
end
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
-- Ensure Cinemachine is always active when Freecam is off to prevent black screens
|
||||||
|
if not _G.__FREECAM_ENABLED then
|
||||||
|
pcall(function()
|
||||||
|
local mainCam = CS.UnityEngine.Camera.main
|
||||||
|
if mainCam then
|
||||||
|
local brain = mainCam:GetComponent(typeof(CS.Cinemachine.CinemachineBrain))
|
||||||
|
if brain and not brain.enabled then
|
||||||
|
brain.enabled = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
if _G.__FREECAM_ENABLED then
|
if _G.__FREECAM_ENABLED then
|
||||||
local cam = get_active_cam()
|
local cam = get_active_cam()
|
||||||
if cam then
|
if cam then
|
||||||
|
|||||||
Reference in new issue
Block a user