protected virtual void RefreshStatusView( CombatantEx targetInfo) { if (this.MyHPView == null && this.MyMPView == null) { return; } var model = MyStatusModel.Instance; model.UpdateAvailablityMPView(targetInfo); if (!this.MyHPView.ViewModel.OverlayVisible && !this.MyMPView.ViewModel.OverlayVisible) { return; } model.Update(targetInfo); }
public void Update( CombatantEx me) { if (Settings.Instance.MyHP.IsDesignMode || Settings.Instance.MyMP.IsDesignMode) { this.UpdateDesignData(); return; } var isHPChanged = false; var isMPChanged = false; if (this.MaxHP != me.MaxHP || this.CurrentHP != me.CurrentHP) { this.MaxHP = me.MaxHP; this.CurrentHP = me.CurrentHP; isHPChanged = true; } if (this.IsAvailableMPView) { if (this.CurrentMP != me.CurrentMP) { this.CurrentMP = me.CurrentMP; isMPChanged = true; } } if (isHPChanged) { this.RaisePropertyChanged(nameof(this.CurrentHP)); } if (isMPChanged) { this.RaisePropertyChanged(nameof(this.CurrentMP)); } }
protected override void RefreshEnmityView(CombatantEx targetInfo) { if (this.EnmityView == null) { return; } if (!this.EnmityView.ViewModel.OverlayVisible) { return; } var now = DateTime.Now; if ((now - this.enmityTimestamp).TotalMilliseconds <= 100d) { return; } this.enmityTimestamp = now; EnmityModel.CreateBrushes(); if (targetInfo == null) { this.Model.RefreshEnmityList(null); return; } lock (this.CurrentEnmityModelList) { this.Model.RefreshEnmityList( this.CurrentEnmityModelList, this.currentTankEPS, this.currentNearThreshold); } }
protected virtual void RefreshTacticalRadarView( CombatantEx targetInfo) { if (this.TacticalRadarView == null) { return; } if (!this.TacticalRadarView.ViewModel.OverlayVisible) { return; } var model = this.Model as TacticalRadarModel; var actors = default(IEnumerable <CombatantEx>); lock (this.TargetInfoLock) { actors = model.TargetActors.ToArray(); } this.TacticalRadarVM.UpdateTargets(actors); }
private void RefreshCurrentEnmityModelList( IEnumerable <EnmityEntry> enmityEntryList) { lock (this.CurrentEnmityModelList) { this.CurrentEnmityModelList.Clear(); if (enmityEntryList == null) { return; } var config = Settings.Instance.Enmity; var pcNameStyle = ConfigBridge.Instance.PCNameStyle; var count = 0; foreach (var entry in enmityEntryList) { if (entry.ID == 0) { continue; } count++; if (count > config.MaxCountOfDisplay) { break; } var name = entry.Name; if (string.IsNullOrEmpty(name)) { name = CombatantEx.UnknownName; } else { name = config.IsSelfDisplayYou && entry.IsMe ? "YOU" : CombatantEx.NameToInitial(entry.Name, pcNameStyle); } var model = new EnmityModel(); model.Index = count; model.ID = entry.ID; model.Name = name; model.JobID = (JobIDs)entry.Job; model.Enmity = (double)entry.Enmity; model.HateRate = entry.HateRate / 100f; model.IsMe = entry.IsMe; model.IsPet = entry.IsPet; model.IsTop = count <= 1; this.CurrentEnmityModelList.Add(model); Thread.Yield(); } // EPSを更新する var isRefreshed = this.RefreshEPS(); // ログを出力する if (isRefreshed) { this.WriteEnmityLog(enmityEntryList); } } }
private void RefreshCombatants() { var player = default(CombatantEx); var party = default(IEnumerable <CombatantEx>); lock (SimulationLocker) { if (this.InSimulation && this.SimulationPlayer != null && this.SimulationParty.Any()) { player = this.SimulationPlayer; party = this.SimulationParty; } else { player = CombatantsManager.Instance.Player; party = CombatantsManager.Instance.GetPartyList(); } } if (player != null) { this.player = player; } if (party != null) { var newList = new List <CombatantEx>(party); if (newList.Count < 1 && !string.IsNullOrEmpty(this.player?.Name)) { newList.Add(this.player); } // パーティリストを入れ替える this.partyList.Clear(); this.partyList.AddRange(newList); // 読み仮名リストをメンテナンスする var newPhonetics = from x in newList select new PCPhonetic() { ID = x.ID, NameFI = x.NameFI, NameIF = x.NameIF, NameII = x.NameII, Name = x.Name, JobID = x.JobID, }; WPFHelper.BeginInvoke(() => { var phonetics = TTSDictionary.Instance.Phonetics; var toAdd = newPhonetics.Where(x => !phonetics.Any(y => y.Name == x.Name)); phonetics.AddRange(toAdd); var toRemove = phonetics.Where(x => !newPhonetics.Any(y => y.Name == x.Name)).ToArray(); foreach (var item in toRemove) { phonetics.Remove(item); } }); } }
protected override void RefreshModel( CombatantEx targetInfo) { base.RefreshModel(targetInfo); this.RefreshTacticalRadarView(targetInfo); }
protected virtual void RefreshEnmityView(CombatantEx targetInfo) { }
protected virtual void GetCombatantHoverOff(ref CombatantEx targetInfo) => targetInfo = XIVPluginHelper.Instance.GetTargetInfo(OverlayType.Target);
protected override void RefreshModel( CombatantEx targetInfo) { base.RefreshModel(targetInfo); this.RefreshEnemyListView(); }
protected override void GetCombatant() { lock (this.TargetInfoLock) { var now = DateTime.Now; if ((now - this.combatantsTimestamp).TotalMilliseconds < Settings.Instance.MobList.RefreshRateMin) { return; } this.combatantsTimestamp = now; } #region Test Mode // テストモード? if (Settings.Instance.MobList.TestMode) { var dummyTargets = new List <MobInfo>(); dummyTargets.Add(new MobInfo() { Name = "TEST:シルバーの吉田直樹", Rank = "EX", Combatant = new CombatantEx() { ID = 1, Name = "TEST:シルバーの吉田直樹", Type = (byte)Actor.Type.Monster, MaxHP = 1, PosX = 0, PosY = 10, PosZ = 10, }, }); dummyTargets.Add(new MobInfo() { Name = "TEST:イクシオン", Rank = "EX", Combatant = new CombatantEx() { ID = 2, Name = "TEST:イクシオン", Type = (byte)Actor.Type.Monster, MaxHP = 1, PosX = 100, PosY = 100, PosZ = -10, }, }); dummyTargets.Add(new MobInfo() { Name = "TEST:イクシオン", Rank = "EX", Combatant = new CombatantEx() { ID = 21, Name = "TEST:イクシオン", Type = (byte)Actor.Type.Monster, MaxHP = 1, PosX = 100, PosY = 100, PosZ = -10, }, }); dummyTargets.Add(new MobInfo() { Name = "TEST:ソルト・アンド・ライト", Rank = "S", Combatant = new CombatantEx() { ID = 3, Name = "TEST:ソルト・アンド・ライト", Type = (byte)Actor.Type.Monster, MaxHP = 1, PosX = 10, PosY = 0, PosZ = 0, }, }); dummyTargets.Add(new MobInfo() { Name = "TEST:オルクス", Rank = "A", Combatant = new CombatantEx() { ID = 4, Name = "TEST:オルクス", Type = (byte)Actor.Type.Monster, MaxHP = 1, PosX = 100, PosY = -100, PosZ = 0, }, }); dummyTargets.Add(new MobInfo() { Name = "TEST:宵闇のヤミニ", Rank = "B", Combatant = new CombatantEx() { ID = 5, Name = "TEST:宵闇のヤミニ", Type = (byte)Actor.Type.Monster, MaxHP = 1, PosX = 0, PosY = -100, PosZ = 0, }, }); dummyTargets.Add(new MobInfo() { Name = CombatantEx.NameToInitial("TEST:Hime Hana", ConfigBridge.Instance.PCNameStyle), Rank = "DEAD", Combatant = new CombatantEx() { ID = 7, Name = CombatantEx.NameToInitial("TEST:Hime Hana", ConfigBridge.Instance.PCNameStyle), Type = (byte)Actor.Type.Monster, Job = (byte)JobIDs.BLM, MaxHP = 43462, PosX = -100, PosY = -100, PosZ = 0, }, }); lock (this.TargetInfoLock) { this.TargetInfo = dummyTargets.First().Combatant; this.targetMobList = dummyTargets; } return; } #endregion Test Mode if ((CombatantsManager.Instance.CombatantsMainCount + CombatantsManager.Instance.CombatantsOtherCount) <= 0) { return; } var targets = default(IEnumerable <MobInfo>); var combatants = CombatantsManager.Instance.GetCombatants(); // モブを検出する IEnumerable <MobInfo> GetTargetMobs() { foreach (var x in combatants) { if (string.IsNullOrEmpty(x?.Name)) { continue; } if (x.ActorType == Actor.Type.PC || x.ActorType == Actor.Type.Monster) { if (x.MaxHP <= 0 || (x.MaxHP > 0 && x.CurrentHP <= 0)) { continue; } } var targetInfo = Settings.Instance.MobList.GetTargetMobInfo(x.Name); if (string.IsNullOrEmpty(targetInfo.Name)) { continue; } yield return(new MobInfo() { Name = x.Name, Combatant = x, Rank = targetInfo.Rank, MaxDistance = targetInfo.MaxDistance, TTSEnabled = targetInfo.TTSEnabled, }); } } targets = GetTargetMobs(); // 戦闘不能者を検出する? var deadmenInfo = Settings.Instance.MobList.GetDetectDeadmenInfo; if (!string.IsNullOrEmpty(deadmenInfo.Name)) { var party = CombatantsManager.Instance.GetPartyList(); var deadmen = from x in party where x != null && !x.IsPlayer && x.ActorType == Actor.Type.PC && x.MaxHP > 0 && x.CurrentHP <= 0 select new MobInfo() { Name = x.NameForDisplay, Combatant = x, Rank = deadmenInfo.Rank, MaxDistance = deadmenInfo.MaxDistance, TTSEnabled = deadmenInfo.TTSEnabled, }; targets = targets.Concat(deadmen); } // クエリを実行する targets = targets.ToArray(); lock (this.TargetInfoLock) { this.targetMobList = targets .Where(x => x.Distance <= x.MaxDistance) .ToList(); this.TargetInfo = this.targetMobList.FirstOrDefault()?.Combatant; if (this.TargetInfo == null) { var model = this.Model as MobListModel; if (model != null && model.MobList.Any()) { WPFHelper.BeginInvoke(model.ClearMobList); } } } if (combatants != null) { CombatantsViewModel.RefreshCombatants(combatants.ToArray()); } }
protected virtual void RefreshMobListView( CombatantEx targetInfo) { if (this.MobListView == null) { return; } if (!this.MobListView.ViewModel.OverlayVisible) { return; } var model = this.Model as MobListModel; if (model == null) { return; } // プレイヤー情報を更新する var player = CombatantsManager.Instance.Player; model.MeX = player?.PosX ?? 0; model.MeY = player?.PosY ?? 0; model.MeZ = player?.PosZ ?? 0; // モブリストを取り出す var moblist = default(IReadOnlyList <MobInfo>); lock (this.TargetInfoLock) { moblist = this.targetMobList; if (Settings.Instance.MobList.UngroupSameNameMobs) { moblist = moblist.OrderBy(y => y.Distance).ToList(); } else { moblist = ( from x in moblist group x by x.Name into g select g.OrderBy(x => x.Distance).First().Clone((clone => { clone.DuplicateCount = g.Count(); }))).ToList(); } } // 表示件数によるフィルタをかけるメソッド void SortAndFilterMobList() { // ソートして表示を設定する var i = 0; var sorted = from x in model.MobList orderby x.RankSortKey, x.Distance select new { Index = ++i, MobInfo = x, }; foreach (var item in sorted) { Thread.Yield(); item.MobInfo.Visible = item.Index <= Settings.Instance.MobList.DisplayCount; item.MobInfo.Index = item.MobInfo.Visible ? item.Index : 9999; } } lock (model.MobList) { try { // テストモード? if (Settings.Instance.MobList.TestMode) { if (!model.MobList.Any(x => x.Name.Contains("TEST"))) { model.MobList.Clear(); foreach (var mob in moblist) { model.MobList.Add(mob); } // ソートと件数のフィルタを行う SortAndFilterMobList(); } return; } // この先は本番モード var isChanged = false; var targets = moblist.Where(x => !x.Name.Contains("TEST")); foreach (var mob in targets) { Thread.Yield(); var item = model.MobList.FirstOrDefault(x => x.Combatant?.UniqueObjectID == mob.Combatant?.UniqueObjectID); // 存在しないものは追加する if (item == null) { model.MobList.Add(mob); // TTSで通知する mob.NotifyByTTS(); isChanged = true; continue; } var distance = item.Distance; var rankSortKey = item.RankSortKey; // 更新する item.Name = mob.Name; item.Rank = mob.Rank; item.Combatant = mob.Combatant; item.DuplicateCount = mob.DuplicateCount; item.RefreshDistance(); if (distance != item.Distance || rankSortKey != item.RankSortKey) { isChanged = true; } } // 不要になったモブを抽出する var itemsForRemove = model.MobList .Where(x => !targets.Any(y => y.Combatant?.UniqueObjectID == x.Combatant?.UniqueObjectID)) .ToArray(); // 除去する foreach (var item in itemsForRemove) { Thread.Yield(); model.MobList.Remove(item); isChanged = true; } // ソートと件数のフィルタを行う if (isChanged) { SortAndFilterMobList(); } } finally { model.MobListCount = model.MobList.Count; } } }
public static bool PredicateFilters( this IFilterizableTrigger trigger, CombatantEx player, IEnumerable <CombatantEx> partyList, int?currentZoneID) { // パーティリストからプレイヤーを除外する var combatants = partyList?.Where(x => x.ID != (player?.ID ?? 0)); var enabledByJob = false; var enabledByPartyJob = false; var enabledByZone = false; var enabledByPartyComposition = false; // ジョブフィルタをかける if (string.IsNullOrEmpty(trigger.JobFilter)) { enabledByJob = true; } else { var jobs = trigger.JobFilter.Split(','); if (jobs.Any(x => x == player.Job.ToString())) { enabledByJob = true; } } // filter by specific jobs in party if (string.IsNullOrEmpty(trigger.PartyJobFilter)) { enabledByPartyJob = true; } else { if (combatants != null) { var jobs = trigger.PartyJobFilter.Split(','); foreach (var combatant in combatants) { if (jobs.Contains(combatant.Job.ToString())) { enabledByPartyJob = true; } } } } // ゾーンフィルタをかける if (string.IsNullOrEmpty(trigger.ZoneFilter)) { enabledByZone = true; } else { if (currentZoneID.HasValue) { var zoneIDs = trigger.ZoneFilter.Split(','); if (zoneIDs.Any(x => x == currentZoneID.ToString())) { enabledByZone = true; } } } // パーティ構成によるフィルタをかける if (string.IsNullOrEmpty(trigger.PartyCompositionFilter)) { enabledByPartyComposition = true; } else { var currentPartyComposition = CombatantsManager.Instance.PartyComposition.ToString(); var filters = trigger.PartyCompositionFilter.Split(','); if (filters.Any(x => string.Equals( x, currentPartyComposition, StringComparison.OrdinalIgnoreCase))) { enabledByPartyComposition = true; } } return(enabledByJob && enabledByZone && enabledByPartyJob && enabledByPartyComposition); }