예제 #1
0
        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);
        }
예제 #2
0
 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);
예제 #3
0
        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);
        }
예제 #4
0
        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);
        }
예제 #6
0
        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;
            }
        }