diff --git a/MareAPI b/MareAPI index 8a7640c..d16afc7 160000 --- a/MareAPI +++ b/MareAPI @@ -1 +1 @@ -Subproject commit 8a7640c1a13bcfc32977a4e0818754f7d080ef4e +Subproject commit d16afc76ec1cd0d01d74bcdd94145abb82ff387a diff --git a/MareSynchronos/PlayerData/Pairs/Pair.cs b/MareSynchronos/PlayerData/Pairs/Pair.cs index 268d5e3..2ce719c 100644 --- a/MareSynchronos/PlayerData/Pairs/Pair.cs +++ b/MareSynchronos/PlayerData/Pairs/Pair.cs @@ -1,5 +1,6 @@ using Dalamud.ContextMenu; using Dalamud.Utility; +using Lumina.Excel.GeneratedSheets; using MareSynchronos.API.Data; using MareSynchronos.API.Data.Comparer; using MareSynchronos.API.Data.Extensions; @@ -190,14 +191,17 @@ public class Pair } bool disableIndividualAnimations = UserPair != null && (UserPair.OtherPermissions.IsDisableAnimations() || UserPair.OwnPermissions.IsDisableAnimations()); + bool disableIndividualVFX = UserPair != null && (UserPair.OtherPermissions.IsDisableVFX() || UserPair.OwnPermissions.IsDisableVFX()); bool disableGroupAnimations = GroupPair.All(pair => pair.Value.GroupUserPermissions.IsDisableAnimations() || pair.Key.GroupPermissions.IsDisableAnimations() || pair.Key.GroupUserPermissions.IsDisableAnimations()); bool disableAnimations = (UserPair != null && disableIndividualAnimations) || (UserPair == null && disableGroupAnimations); bool disableIndividualSounds = UserPair != null && (UserPair.OtherPermissions.IsDisableSounds() || UserPair.OwnPermissions.IsDisableSounds()); bool disableGroupSounds = GroupPair.All(pair => pair.Value.GroupUserPermissions.IsDisableSounds() || pair.Key.GroupPermissions.IsDisableSounds() || pair.Key.GroupUserPermissions.IsDisableSounds()); + bool disableGroupVFX = GroupPair.All(pair => pair.Value.GroupUserPermissions.IsDisableVFX() || pair.Key.GroupPermissions.IsDisableVFX() || pair.Key.GroupUserPermissions.IsDisableVFX()); bool disableSounds = (UserPair != null && disableIndividualSounds) || (UserPair == null && disableGroupSounds); + bool disableVFX = (UserPair != null && disableIndividualVFX) || (UserPair == null && disableGroupVFX); _logger.LogTrace("Individual Sounds: {disableIndividualSounds}, Individual Anims: {disableIndividualAnims}; " + "Group Sounds: {disableGroupSounds}, Group Anims: {disableGroupAnims} => Disable Sounds: {disableSounds}, Disable Anims: {disableAnims}", @@ -205,7 +209,7 @@ public class Pair if (disableAnimations || disableSounds) { - _logger.LogTrace("Data cleaned up: Animations disabled: {disableAnimations}, Sounds disabled: {disableSounds}", disableAnimations, disableSounds); + _logger.LogTrace("Data cleaned up: Animations disabled: {disableAnimations}, Sounds disabled: {disableSounds}, VFX disabled: {disableVFX}", disableAnimations, disableSounds, disableVFX); foreach (var objectKind in data.FileReplacements.Select(k => k.Key)) { if (disableSounds) @@ -216,6 +220,10 @@ public class Pair data.FileReplacements[objectKind] = data.FileReplacements[objectKind] .Where(f => !f.GamePaths.Any(p => p.EndsWith("tmb", StringComparison.OrdinalIgnoreCase) || p.EndsWith("pap", StringComparison.OrdinalIgnoreCase))) .ToList(); + if(disableVFX) + data.FileReplacements[objectKind] = data.FileReplacements[objectKind] + .Where(f => !f.GamePaths.Any(p => p.EndsWith("atex", StringComparison.OrdinalIgnoreCase) || p.EndsWith("avfx", StringComparison.OrdinalIgnoreCase))) + .ToList(); } } diff --git a/MareSynchronos/PlayerData/Pairs/PairManager.cs b/MareSynchronos/PlayerData/Pairs/PairManager.cs index 5a943de..c5bb439 100644 --- a/MareSynchronos/PlayerData/Pairs/PairManager.cs +++ b/MareSynchronos/PlayerData/Pairs/PairManager.cs @@ -237,8 +237,9 @@ public sealed class PairManager : DisposableMediatorSubscriberBase pair.UserPair.OtherPermissions = dto.Permissions; - Logger.LogTrace("Paired: {synced}, Paused: {paused}, Anims: {anims}, Sounds: {sounds}", - pair.UserPair.OwnPermissions.IsPaired(), pair.UserPair.OwnPermissions.IsPaused(), pair.UserPair.OwnPermissions.IsDisableAnimations(), pair.UserPair.OwnPermissions.IsDisableSounds()); + Logger.LogTrace("Paired: {synced}, Paused: {paused}, Anims: {anims}, Sounds: {sounds}, VFX: {vfx}", + pair.UserPair.OwnPermissions.IsPaired(), pair.UserPair.OwnPermissions.IsPaused(), pair.UserPair.OwnPermissions.IsDisableAnimations(), pair.UserPair.OwnPermissions.IsDisableSounds(), + pair.UserPair.OwnPermissions.IsDisableVFX()); pair.ApplyLastReceivedData(); } @@ -259,8 +260,9 @@ public sealed class PairManager : DisposableMediatorSubscriberBase pair.UserPair.OwnPermissions = dto.Permissions; - Logger.LogTrace("Paired: {synced}, Paused: {paused}, Anims: {anims}, Sounds: {sounds}", - pair.UserPair.OwnPermissions.IsPaired(), pair.UserPair.OwnPermissions.IsPaused(), pair.UserPair.OwnPermissions.IsDisableAnimations(), pair.UserPair.OwnPermissions.IsDisableSounds()); + Logger.LogTrace("Paired: {synced}, Paused: {paused}, Anims: {anims}, Sounds: {sounds}, VFX: {vfx}", + pair.UserPair.OwnPermissions.IsPaired(), pair.UserPair.OwnPermissions.IsPaused(), pair.UserPair.OwnPermissions.IsDisableAnimations(), pair.UserPair.OwnPermissions.IsDisableSounds(), + pair.UserPair.OwnPermissions.IsDisableVFX()); pair.ApplyLastReceivedData(); } @@ -286,7 +288,8 @@ public sealed class PairManager : DisposableMediatorSubscriberBase var prevPermissions = _allClientPairs[dto.User].GroupPair[group].GroupUserPermissions; _allClientPairs[dto.User].GroupPair[group].GroupUserPermissions = dto.GroupPairPermissions; if (prevPermissions.IsDisableAnimations() != dto.GroupPairPermissions.IsDisableAnimations() - || prevPermissions.IsDisableSounds() != dto.GroupPairPermissions.IsDisableSounds()) + || prevPermissions.IsDisableSounds() != dto.GroupPairPermissions.IsDisableSounds() + || prevPermissions.IsDisableVFX() != dto.GroupPairPermissions.IsDisableVFX()) { _allClientPairs[dto.User].ApplyLastReceivedData(); } @@ -298,7 +301,8 @@ public sealed class PairManager : DisposableMediatorSubscriberBase var prevPermissions = _allGroups[dto.Group].GroupPermissions; _allGroups[dto.Group].GroupPermissions = dto.Permissions; if (prevPermissions.IsDisableAnimations() != dto.Permissions.IsDisableAnimations() - || prevPermissions.IsDisableSounds() != dto.Permissions.IsDisableSounds()) + || prevPermissions.IsDisableSounds() != dto.Permissions.IsDisableSounds() + || prevPermissions.IsDisableVFX() != dto.Permissions.IsDisableVFX()) { RecreateLazy(); var group = _allGroups[dto.Group]; @@ -317,7 +321,8 @@ public sealed class PairManager : DisposableMediatorSubscriberBase var prevPermissions = _allGroups[dto.Group].GroupUserPermissions; _allGroups[dto.Group].GroupUserPermissions = dto.GroupPairPermissions; if (prevPermissions.IsDisableAnimations() != dto.GroupPairPermissions.IsDisableAnimations() - || prevPermissions.IsDisableSounds() != dto.GroupPairPermissions.IsDisableSounds()) + || prevPermissions.IsDisableSounds() != dto.GroupPairPermissions.IsDisableSounds() + || prevPermissions.IsDisableVFX() != dto.GroupPairPermissions.IsDisableVFX()) { RecreateLazy(); var group = _allGroups[dto.Group]; diff --git a/MareSynchronos/UI/Components/DrawGroupPair.cs b/MareSynchronos/UI/Components/DrawGroupPair.cs index afbfbbd..f0c0be8 100644 --- a/MareSynchronos/UI/Components/DrawGroupPair.cs +++ b/MareSynchronos/UI/Components/DrawGroupPair.cs @@ -108,16 +108,18 @@ public class DrawGroupPair : DrawPairBase var soundsDisabled = _fullInfoDto.GroupUserPermissions.IsDisableSounds(); var animDisabled = _fullInfoDto.GroupUserPermissions.IsDisableAnimations(); + var vfxDisabled = _fullInfoDto.GroupUserPermissions.IsDisableVFX(); var individualSoundsDisabled = (_pair.UserPair?.OwnPermissions.IsDisableSounds() ?? false) || (_pair.UserPair?.OtherPermissions.IsDisableSounds() ?? false); var individualAnimDisabled = (_pair.UserPair?.OwnPermissions.IsDisableAnimations() ?? false) || (_pair.UserPair?.OtherPermissions.IsDisableAnimations() ?? false); + var individualVFXDisabled = (_pair.UserPair?.OwnPermissions.IsDisableVFX() ?? false) || (_pair.UserPair?.OtherPermissions.IsDisableVFX() ?? false); bool showInfo = (individualAnimDisabled || individualSoundsDisabled || animDisabled || soundsDisabled); bool showPlus = _pair.UserPair == null; bool showBars = (userIsOwner || (userIsModerator && !entryIsMod && !entryIsOwner)) || !_pair.IsPaused; var spacing = ImGui.GetStyle().ItemSpacing.X; - var permIcon = (individualAnimDisabled || individualSoundsDisabled) ? FontAwesomeIcon.ExclamationTriangle - : ((soundsDisabled || animDisabled) ? FontAwesomeIcon.InfoCircle : FontAwesomeIcon.None); + var permIcon = (individualAnimDisabled || individualSoundsDisabled || individualVFXDisabled) ? FontAwesomeIcon.ExclamationTriangle + : ((soundsDisabled || animDisabled || vfxDisabled) ? FontAwesomeIcon.InfoCircle : FontAwesomeIcon.None); var infoIconWidth = UiSharedService.GetIconSize(permIcon).X; var plusButtonWidth = UiSharedService.GetIconButtonSize(FontAwesomeIcon.Plus).X; var barButtonWidth = UiSharedService.GetIconButtonSize(FontAwesomeIcon.Bars).X; @@ -162,6 +164,17 @@ public class DrawGroupPair : DrawPairBase ImGui.Text("You: " + (_pair.UserPair!.OwnPermissions.IsDisableAnimations() ? "Disabled" : "Enabled") + ", They: " + (_pair.UserPair!.OtherPermissions.IsDisableAnimations() ? "Disabled" : "Enabled")); } + if (individualVFXDisabled) + { + var userVFXText = "VFX sync disabled with " + _pair.UserData.AliasOrUID; + UiSharedService.FontText(FontAwesomeIcon.Circle.ToIconString(), UiBuilder.IconFont); + ImGui.SameLine(40 * ImGuiHelpers.GlobalScale); + ImGui.Text(userVFXText); + ImGui.NewLine(); + ImGui.SameLine(40 * ImGuiHelpers.GlobalScale); + ImGui.Text("You: " + (_pair.UserPair!.OwnPermissions.IsDisableVFX() ? "Disabled" : "Enabled") + ", They: " + (_pair.UserPair!.OtherPermissions.IsDisableVFX() ? "Disabled" : "Enabled")); + } + ImGui.EndTooltip(); } ImGui.SameLine(); @@ -192,6 +205,14 @@ public class DrawGroupPair : DrawPairBase ImGui.Text(userAnimText); } + if (vfxDisabled) + { + var userVFXText = "VFX sync disabled by " + _pair.UserData.AliasOrUID; + UiSharedService.FontText(FontAwesomeIcon.Circle.ToIconString(), UiBuilder.IconFont); + ImGui.SameLine(40 * ImGuiHelpers.GlobalScale); + ImGui.Text(userVFXText); + } + ImGui.EndTooltip(); } ImGui.SameLine(); diff --git a/MareSynchronos/UI/Components/DrawUserPair.cs b/MareSynchronos/UI/Components/DrawUserPair.cs index e795a7f..ba534eb 100644 --- a/MareSynchronos/UI/Components/DrawUserPair.cs +++ b/MareSynchronos/UI/Components/DrawUserPair.cs @@ -80,8 +80,9 @@ public class DrawUserPair : DrawPairBase { var individualSoundsDisabled = (_pair.UserPair?.OwnPermissions.IsDisableSounds() ?? false) || (_pair.UserPair?.OtherPermissions.IsDisableSounds() ?? false); var individualAnimDisabled = (_pair.UserPair?.OwnPermissions.IsDisableAnimations() ?? false) || (_pair.UserPair?.OtherPermissions.IsDisableAnimations() ?? false); + var individualVFXDisabled = (_pair.UserPair?.OwnPermissions.IsDisableVFX() ?? false) || (_pair.UserPair?.OtherPermissions.IsDisableVFX() ?? false); - if (individualAnimDisabled || individualSoundsDisabled) + if (individualAnimDisabled || individualSoundsDisabled || individualVFXDisabled) { var infoIconPosDist = windowEndX - barButtonSize.X - spacingX - pauseIconSize.X - spacingX; var icon = FontAwesomeIcon.ExclamationTriangle; @@ -121,6 +122,17 @@ public class DrawUserPair : DrawPairBase ImGui.Text("You: " + (_pair.UserPair!.OwnPermissions.IsDisableAnimations() ? "Disabled" : "Enabled") + ", They: " + (_pair.UserPair!.OtherPermissions.IsDisableAnimations() ? "Disabled" : "Enabled")); } + if (individualVFXDisabled) + { + var userVFXText = "VFX sync disabled with " + _pair.UserData.AliasOrUID; + UiSharedService.FontText(FontAwesomeIcon.Circle.ToIconString(), UiBuilder.IconFont); + ImGui.SameLine(40 * ImGuiHelpers.GlobalScale); + ImGui.Text(userVFXText); + ImGui.NewLine(); + ImGui.SameLine(40 * ImGuiHelpers.GlobalScale); + ImGui.Text("You: " + (_pair.UserPair!.OwnPermissions.IsDisableVFX() ? "Disabled" : "Enabled") + ", They: " + (_pair.UserPair!.OtherPermissions.IsDisableVFX() ? "Disabled" : "Enabled")); + } + ImGui.EndTooltip(); } } @@ -216,6 +228,16 @@ public class DrawUserPair : DrawPairBase _ = _apiController.UserSetPairPermissions(new UserPermissionsDto(entry.UserData, permissions)); } + var isDisableVFX = entry.UserPair!.OwnPermissions.IsDisableVFX(); + string disableVFXText = isDisableAnims ? "Enable VFX sync" : "Disable VFX sync"; + var disableVFXIcon = isDisableAnims ? FontAwesomeIcon.Sun : FontAwesomeIcon.Circle; + if (UiSharedService.IconTextButton(disableVFXIcon, disableVFXText)) + { + var permissions = entry.UserPair.OwnPermissions; + permissions.SetDisableVFX(!isDisableVFX); + _ = _apiController.UserSetPairPermissions(new UserPermissionsDto(entry.UserData, permissions)); + } + if (UiSharedService.IconTextButton(FontAwesomeIcon.Trash, "Unpair Permanently") && UiSharedService.CtrlPressed()) { _ = _apiController.UserRemovePair(new(entry.UserData)); diff --git a/MareSynchronos/UI/Components/GroupPanel.cs b/MareSynchronos/UI/Components/GroupPanel.cs index c980fcd..9187f48 100644 --- a/MareSynchronos/UI/Components/GroupPanel.cs +++ b/MareSynchronos/UI/Components/GroupPanel.cs @@ -465,17 +465,21 @@ internal sealed class GroupPanel bool invitesEnabled = !groupDto.GroupPermissions.IsDisableInvites(); var soundsDisabled = groupDto.GroupPermissions.IsDisableSounds(); var animDisabled = groupDto.GroupPermissions.IsDisableAnimations(); + var vfxDisabled = groupDto.GroupPermissions.IsDisableVFX(); var userSoundsDisabled = groupDto.GroupUserPermissions.IsDisableSounds(); var userAnimDisabled = groupDto.GroupUserPermissions.IsDisableAnimations(); + var userVFXDisabled = groupDto.GroupUserPermissions.IsDisableVFX(); - bool showInfoIcon = !invitesEnabled || soundsDisabled || animDisabled || userSoundsDisabled || userAnimDisabled; + bool showInfoIcon = !invitesEnabled || soundsDisabled || animDisabled || vfxDisabled || userSoundsDisabled || userAnimDisabled || userVFXDisabled; var lockedIcon = invitesEnabled ? FontAwesomeIcon.LockOpen : FontAwesomeIcon.Lock; var animIcon = animDisabled ? FontAwesomeIcon.Stop : FontAwesomeIcon.Running; var soundsIcon = soundsDisabled ? FontAwesomeIcon.VolumeOff : FontAwesomeIcon.VolumeUp; + var vfxIcon = vfxDisabled ? FontAwesomeIcon.Circle : FontAwesomeIcon.Sun; var userAnimIcon = userAnimDisabled ? FontAwesomeIcon.Stop : FontAwesomeIcon.Running; var userSoundsIcon = userSoundsDisabled ? FontAwesomeIcon.VolumeOff : FontAwesomeIcon.VolumeUp; + var userVFXIcon = userVFXDisabled ? FontAwesomeIcon.Circle : FontAwesomeIcon.Sun; var iconSize = UiSharedService.GetIconSize(infoIcon); var diffLockUnlockIcons = showInfoIcon ? (UiSharedService.GetIconSize(infoIcon).X - iconSize.X) / 2 : 0; @@ -489,7 +493,7 @@ internal sealed class GroupPanel if (ImGui.IsItemHovered()) { ImGui.BeginTooltip(); - if (!invitesEnabled || soundsDisabled || animDisabled) + if (!invitesEnabled || soundsDisabled || animDisabled || vfxDisabled) { ImGui.Text("Syncshell permissions"); @@ -516,11 +520,19 @@ internal sealed class GroupPanel ImGui.SameLine(40 * ImGuiHelpers.GlobalScale); ImGui.Text(animText); } + + if (vfxDisabled) + { + var vfxText = "VFX sync disabled through owner"; + UiSharedService.FontText(vfxIcon.ToIconString(), UiBuilder.IconFont); + ImGui.SameLine(40 * ImGuiHelpers.GlobalScale); + ImGui.Text(vfxText); + } } - if (userSoundsDisabled || userAnimDisabled) + if (userSoundsDisabled || userAnimDisabled || userVFXDisabled) { - if (!invitesEnabled || soundsDisabled || animDisabled) + if (!invitesEnabled || soundsDisabled || animDisabled || vfxDisabled) ImGui.Separator(); ImGui.Text("Your permissions"); @@ -541,7 +553,15 @@ internal sealed class GroupPanel ImGui.Text(userAnimText); } - if (!invitesEnabled || soundsDisabled || animDisabled) + if (userVFXDisabled) + { + var userVFXText = "VFX sync disabled through you"; + UiSharedService.FontText(userVFXIcon.ToIconString(), UiBuilder.IconFont); + ImGui.SameLine(40 * ImGuiHelpers.GlobalScale); + ImGui.Text(userVFXText); + } + + if (!invitesEnabled || soundsDisabled || animDisabled || vfxDisabled) UiSharedService.TextWrapped("Note that syncshell permissions for disabling take precedence over your own set permissions"); } ImGui.EndTooltip(); @@ -605,6 +625,20 @@ internal sealed class GroupPanel + Environment.NewLine + "Note: this setting can be forcefully overridden to 'disabled' through the syncshell owner." + Environment.NewLine + "Note: this setting does not apply to individual pairs that are also in the syncshell."); + var vfxText = userVFXDisabled ? "Enable VFX sync" : "Disable VFX sync"; + if (UiSharedService.IconTextButton(userAnimIcon, vfxText)) + { + ImGui.CloseCurrentPopup(); + var perm = groupDto.GroupUserPermissions; + perm.SetDisableVFX(!perm.IsDisableVFX()); + _ = ApiController.GroupChangeIndividualPermissionState(new(groupDto.Group, new UserData(ApiController.UID), perm)); + } + UiSharedService.AttachToolTip("Sets your allowance for VFX synchronization for users of this syncshell." + + Environment.NewLine + "Disabling the synchronization will stop applying VFX modifications for users of this syncshell." + + Environment.NewLine + "Note: this setting might also affect animation synchronization to some degree" + + Environment.NewLine + "Note: this setting can be forcefully overridden to 'disabled' through the syncshell owner." + + Environment.NewLine + "Note: this setting does not apply to individual pairs that are also in the syncshell."); + if (isOwner || groupDto.GroupUserInfo.IsModerator()) { ImGui.Separator(); @@ -662,6 +696,18 @@ internal sealed class GroupPanel + "Note: users that are individually paired with others in the syncshell will ignore this setting." + Environment.NewLine + "Note: if the synchronization is enabled, users can individually override this setting to disabled."); + var groupVFXText = vfxDisabled ? "Enable syncshell VFX sync" : "Disable syncshell VFX sync"; + if (UiSharedService.IconTextButton(vfxIcon, groupVFXText)) + { + ImGui.CloseCurrentPopup(); + var perm = groupDto.GroupPermissions; + perm.SetDisableVFX(!perm.IsDisableVFX()); + _ = ApiController.GroupChangeGroupPermissionState(new(groupDto.Group, perm)); + } + UiSharedService.AttachToolTip("Sets syncshell-wide allowance for VFX synchronization for all users." + Environment.NewLine + + "Note: users that are individually paired with others in the syncshell will ignore this setting." + Environment.NewLine + + "Note: if the synchronization is enabled, users can individually override this setting to disabled."); + if (UiSharedService.IconTextButton(FontAwesomeIcon.Envelope, "Single one-time invite")) { ImGui.CloseCurrentPopup();