public Combatant GetTargetInfo( OverlayType type) { if (!this.IsAvailable || this.readCombatantMethodInfo == null) { return(null); } dynamic data = this.readCombatantMethodInfo?.Invoke( this.overlayData, new object[] { type }); if (data == null) { return(null); } uint id = data.id; Combatant combatant = null; lock (this.combatantListLock) { if (this.combatantDictionary != null && this.combatantDictionary.ContainsKey(id)) { combatant = this.combatantDictionary[id]; combatant.Player = this.combatantList.FirstOrDefault(); } } this.SetSkillName(combatant); return(combatant); }
public double GetHorizontalDistance(Combatant target) => Math.Round( (double)Math.Sqrt( Math.Pow(this.PosX - target.PosX, 2) + Math.Pow(this.PosY - target.PosY, 2)), 1, MidpointRounding.AwayFromZero);
public Combatant GetBossInfo( double bossHPThreshold) { if (!this.IsAvailable) { return(null); } var party = this.GetPartyList(); var combatants = this.GetCombatantList(); if (party == null || combatants == null || party.Count < 1 || combatants.Count < 1) { return(null); } // パーティのHP平均値を算出する var players = party.Where(x => x.type == ObjectType.PC); if (!players.Any()) { return(null); } var avg = players.Average(x => x.MaxHP); // BOSSを検出する var boss = ( from x in combatants where x.MaxHP >= (avg * bossHPThreshold) && x.type == ObjectType.Monster && x.CurrentHP > 0 orderby x.Level descending, (x.MaxHP != x.CurrentHP ? 0 : 1)ascending, x.MaxHP descending, x.ID descending select x).FirstOrDefault(); if (boss != null) { boss.Player = combatants.FirstOrDefault(); } this.SetSkillName(boss); #region Logger if (boss != null) { if (this.previousBoss == null || this.previousBoss.ID != boss.ID) { var ratio = avg != 0 ? boss.MaxHP / avg : boss.MaxHP; var player = combatants.FirstOrDefault(); var message = $"BOSS " + $"name={boss.Name}, " + $"maxhp={boss.MaxHP}, " + $"ptavg={avg.ToString("F0")}, " + $"ratio={ratio.ToString("F1")}, " + $"BOSS_pos={boss.PosX},{boss.PosY},{boss.PosZ}, " + $"player_pos={player.PosX},{player.PosY},{player.PosZ}"; AppLogger.Info(message); } } this.previousBoss = boss; #endregion Logger return(boss); }
private void RefreshCombatantListFromFFXIVPlugin() { dynamic list = this.pluginScancombat.GetCombatantList(); var count = (int)list.Count; var newList = new List <Combatant>(count); var newDictionary = new Dictionary <uint, Combatant>(count); var player = default(Combatant); var pcCount = 0; foreach (dynamic item in list.ToArray()) { if (item == null) { continue; } var combatant = new Combatant(); combatant.ID = (uint)item.ID; combatant.OwnerID = (uint)item.OwnerID; combatant.Job = (byte)item.Job; combatant.type = (ObjectType)((byte)item.type); combatant.Level = (byte)item.Level; combatant.CurrentHP = (int)item.CurrentHP; combatant.MaxHP = (int)item.MaxHP; combatant.CurrentMP = (int)item.CurrentMP; combatant.MaxMP = (int)item.MaxMP; combatant.CurrentTP = (short)item.CurrentTP; combatant.IsCasting = (bool)item.IsCasting; combatant.CastBuffID = (int)item.CastBuffID; combatant.CastDurationCurrent = (float)item.CastDurationCurrent; combatant.CastDurationMax = (float)item.CastDurationMax; // 扱うプレイヤー数の最大数を超えたらカットする if (combatant.type == ObjectType.PC) { pcCount++; if (pcCount >= MaxPCCount) { continue; } } this.SetSkillName(combatant); combatant.PosX = (float)item.PosX; combatant.PosY = (float)item.PosY; combatant.PosZ = (float)item.PosZ; var name = (string)item.Name; // 名前を登録する // TYPEによって分岐するため先にTYPEを設定しておくこと combatant.SetName(name); if (player == null) { player = combatant; } combatant.Player = player; newList.Add(combatant); newDictionary.Add(combatant.ID, combatant); } lock (this.combatantListLock) { var addedCombatants = this.combatantList == null? newList.ToArray() : newList .Where(x => !this.combatantList.Any(y => y.ID == x.ID)) .ToArray(); this.combatantList = newList; this.combatantDictionary = newDictionary; if (addedCombatants.Any()) { Task.Run(() => this.OnAddedCombatants(new AddedCombatantsEventArgs(addedCombatants))); } } lock (this.playerLocker) { this.player = player; } }
private unsafe List <EnmityEntry> GetEnmityEntryList() { short num = 0; uint topEnmity = 0; List <EnmityEntry> result = new List <EnmityEntry>(); List <Combatant> combatantList = Combatants; Combatant mychar = GetSelfCombatant(); /// 一度に全部読む byte[] buffer = GetByteArray(enmityAddress, 0x900 + 2); fixed(byte *p = buffer) num = (short)p[2296]; if (num <= 0) { return(result); } if (num > 31) { num = 31; // changed??? 32->31 } for (short i = 0; i < num; i++) { int p = i * 72; uint _id; uint _enmity; fixed(byte *bp = buffer) { _id = *(uint *)&bp[p + 56]; _enmity = *(uint *)&bp[p + 60]; } var entry = new EnmityEntry() { ID = _id, Enmity = _enmity, isMe = false, Name = "Unknown", Job = 0x00 }; if (entry.ID > 0) { Combatant c = combatantList.Find(x => x.ID == entry.ID); if (c != null) { entry.Name = c.Name; entry.Job = c.Job; entry.OwnerID = c.OwnerID; } if (entry.ID == mychar.ID) { entry.isMe = true; } if (topEnmity <= entry.Enmity) { topEnmity = entry.Enmity; } entry.HateRate = (int)(((double)entry.Enmity / (double)topEnmity) * 100); result.Add(entry); } } return(result); }
private void RefreshCombatantListFromFFXIVReader() { var query = FFXIVReader.Instance.GetCombatantsV1() .Select(x => new Combatant(x)); var player = default(Combatant); var pcCount = 0; var list = new List <Combatant>(query.Count()); foreach (var combatant in query) { // 扱うプレイヤー数の最大数を超えたらカットする if (combatant.type == ObjectType.PC) { pcCount++; if (pcCount >= MaxPCCount) { continue; } } this.SetSkillName(combatant); combatant.SetName(combatant.Name); if (player == null) { player = combatant; } combatant.Player = player; list.Add(combatant); } lock (this.combatantListLock) { var addedCombatants = this.combatantList == null? list.ToArray() : list .Where(x => !this.combatantList.Any(y => y.ID == x.ID)) .ToArray(); this.combatantList = list; this.combatantDictionary = list.ToDictionary(x => x.ID); // TargetOfTargetを設定する if (player != null && player.TargetID != 0) { if (this.combatantDictionary.ContainsKey(player.TargetID)) { var target = this.combatantDictionary[player.TargetID]; player.TargetOfTargetID = target.TargetID; } } if (addedCombatants.Any()) { Task.Run(() => this.OnAddedCombatants(new AddedCombatantsEventArgs(addedCombatants))); } } lock (this.playerLocker) { this.player = player; } }