public int GetNextDamageSeeded(int min, int max, int data)
        {
            float dmgMod = ItemDesc.GetStat(data, ItemData.Damage, ItemDesc.DamageMultiplier);
            int   minDmg = min + (int)(min * dmgMod);
            int   maxDmg = max + (int)(max * dmgMod);

            return((int)Client.Random.NextIntRange((uint)minDmg, (uint)maxDmg));
        }
        public int GetNextDamage(int min, int max, int data)
        {
            float dmgMod = ItemDesc.GetStat(data, ItemData.Damage, ItemDesc.DamageMultiplier);
            int   minDmg = min + (int)(min * dmgMod);
            int   maxDmg = max + (int)(max * dmgMod);

            return(MathUtils.NextInt(minDmg, maxDmg));
        }
Beispiel #3
0
        public void RecalculateEquipBonuses()
        {
            for (int i = 0; i < 8; i++)
            {
                Boosts[i] = 0;
            }

            for (int i = 0; i < 4; i++)
            {
                if (Inventory[i] == -1)
                {
                    continue;
                }

                ItemDesc item = Resources.Type2Item[(ushort)Inventory[i]];
                foreach (KeyValuePair <int, int> s in item.StatBoosts)
                {
                    Boosts[s.Key] += s.Value;
                }

                int data = ItemDatas[i];
                if (data == -1)
                {
                    continue;
                }

                Boosts[0] += (int)(ItemDesc.GetStat(data, ItemData.MaxHP, 5));
                Boosts[1] += (int)(ItemDesc.GetStat(data, ItemData.MaxMP, 5));
                Boosts[2] += (int)(ItemDesc.GetStat(data, ItemData.Attack, 1));
                Boosts[3] += (int)(ItemDesc.GetStat(data, ItemData.Defense, 1));
                Boosts[4] += (int)(ItemDesc.GetStat(data, ItemData.Speed, 1));
                Boosts[5] += (int)(ItemDesc.GetStat(data, ItemData.Dexterity, 1));
                Boosts[6] += (int)(ItemDesc.GetStat(data, ItemData.Vitality, 1));
                Boosts[7] += (int)(ItemDesc.GetStat(data, ItemData.Wisdom, 1));
            }

            UpdateStats();
        }
        public void TryShoot(int time, Position pos, float attackAngle, bool ability, int numShots)
        {
            if (!ValidTime(time))
            {
#if DEBUG
                Program.Print(PrintType.Error, "Invalid time for player shoot");
#endif
                Client.Disconnect();
                return;
            }

            if (AwaitingGoto.Count > 0)
            {
                Client.Random.Drop(numShots);
                return;
            }

            if (!ValidMove(time, pos))
            {
#if DEBUG
                Program.Print(PrintType.Error, "Invalid move for player shoot");
#endif
                Client.Disconnect();
                return;
            }

            int startId = NextProjectileId;
            NextProjectileId -= numShots;

            ItemDesc desc = ability ? GetItem(1) : GetItem(0);
            if (desc == null)
            {
#if DEBUG
                Program.Print(PrintType.Error, "Undefined item descriptor");
#endif
                Client.Random.Drop(numShots);
                return;
            }


            if (numShots != desc.NumProjectiles)
            {
#if DEBUG
                Program.Print(PrintType.Error, "Manipulated num shots");
#endif
                Client.Random.Drop(numShots);
                return;
            }

            if (HasConditionEffect(ConditionEffectIndex.Stunned))
            {
#if DEBUG
                Program.Print(PrintType.Error, "Stunned...");
#endif
                Client.Random.Drop(numShots);
                return;
            }

            if (ability)
            {
                if (ShootAEs.TryDequeue(out ushort aeItemType))
                {
                    if (aeItemType != desc.Type)
                    {
                        Client.Random.Drop(numShots);
                        return;
                    }

                    float arcGap   = (desc.ArcGap * MathUtils.ToRadians);
                    float totalArc = arcGap * (numShots - 1);
                    float angle    = attackAngle - (totalArc / 2f);
                    for (int i = 0; i < numShots; i++)
                    {
                        int        damage     = (int)(GetNextDamageSeeded(desc.Projectile.MinDamage, desc.Projectile.MaxDamage, ItemDatas[1]) * GetAttackMultiplier());
                        Projectile projectile = new Projectile(this, desc.Projectile, startId - i, time, angle + (arcGap * i), pos, damage);
                        ShotProjectiles.Add(projectile.Id, projectile);
                    }

                    byte[] packet = GameServer.AllyShoot(Id, desc.Type, attackAngle);
                    foreach (Entity en in Parent.PlayerChunks.HitTest(Position, SightRadius))
                    {
                        if (en is Player player && player.Client.Account.AllyShots && !player.Equals(this))
                        {
                            player.Client.Send(packet);
                        }
                    }

                    FameStats.Shots += numShots;
                }
                else
                {
#if DEBUG
                    Program.Print(PrintType.Error, "Invalid ShootAE");
#endif
                    Client.Random.Drop(numShots);
                }
            }
            else
            {
                if (time > ShotTime + ShotDuration)
                {
                    float arcGap   = (desc.ArcGap * MathUtils.ToRadians);
                    float totalArc = arcGap * (numShots - 1);
                    float angle    = attackAngle - (totalArc / 2f);
                    for (int i = 0; i < numShots; i++)
                    {
                        int        damage     = (int)(GetNextDamageSeeded(desc.Projectile.MinDamage, desc.Projectile.MaxDamage, ItemDatas[0]) * GetAttackMultiplier());
                        Projectile projectile = new Projectile(this, desc.Projectile, startId - i, time, angle + (arcGap * i), pos, damage);
                        ShotProjectiles.Add(projectile.Id, projectile);
                    }

                    byte[] packet = GameServer.AllyShoot(Id, desc.Type, attackAngle);
                    foreach (Entity en in Parent.PlayerChunks.HitTest(Position, SightRadius))
                    {
                        if (en is Player player && player.Client.Account.AllyShots && !player.Equals(this))
                        {
                            player.Client.Send(packet);
                        }
                    }

                    FameStats.Shots += numShots;
                    float rateOfFireMod = ItemDesc.GetStat(ItemDatas[0], ItemData.RateOfFire, ItemDesc.RateOfFireMultiplier);
                    float rateOfFire    = desc.RateOfFire;
                    rateOfFire  *= 1 + rateOfFireMod;
                    ShotDuration = (int)((1f / GetAttackFrequency() * (1f / rateOfFire)) * (1f / RateOfFireThreshold));
                    ShotTime     = time;
                }

                else
                {
#if DEBUG
                    Program.Print(PrintType.Error, "Shot too early, ignored");
#endif
                    Client.Random.Drop(numShots);
                }
            }
        }