Example #1
0
        private void BulletNova(RealmTime time, Item item, Position target)
        {
            Projectile[]   prjs    = new Projectile[20];
            ProjectileDesc prjDesc = item.Projectiles[0];
            var            batch   = new Message[21];

            for (var i = 0; i < 20; i++)
            {
                Projectile proj = CreateProjectile(prjDesc, item.ObjectType,
                                                   Random.Next(prjDesc.MinDamage, prjDesc.MaxDamage),
                                                   time.TotalElapsedMs, target, (float)(i * (Math.PI * 2) / 20));
                Owner?.EnterWorld(proj);
                FameCounter.Shoot(proj);
                batch[i] = new SERVERPLAYERSHOOT()
                {
                    BulletId      = proj.ProjectileId,
                    OwnerId       = Id,
                    ContainerType = item.ObjectType,
                    StartingPos   = target,
                    Angle         = proj.Angle,
                    Damage        = (short)proj.Damage
                };
                prjs[i] = proj;
            }

            batch[20] = new SHOWEFFECT()
            {
                EffectType = EffectType.Line,
                PosA       = target,
                TargetId   = Id,
                Color      = new ARGB(0xFFFF00AA)
            };

            foreach (Player plr in Owner?.Players.Values.Where(p => p?.DistSqr(this) < RadiusSqr))
            {
                plr?.Client.SendMessage(batch);
            }
        }
        protected override void TickCore(Entity host, RealmTime time, ref object state)
        {
            var player    = host.GetPlayerOwner();
            var pet       = player.Pet;
            var hatchling = player.HatchlingPet;

            if (hatchling)
            {
                return;
            }

            if (player.Owner == null || pet == null || host == null)
            {
                pet.Owner.LeaveWorld(host);
                return;
            }

            if (host.Owner.SafePlace || !player.EnablePetAttack)
            {
                return;
            }

            var cool = (int?)state ?? -1;

            Status = CycleStatus.NotStarted;

            if (cool <= 0)
            {
                if (player.HasConditionEffect(ConditionEffectIndex.Sick) || player.HasConditionEffect(ConditionEffectIndex.PetDisable))
                {
                    return;
                }

                var stars = player.Stars;

                if (pet.GetNearestEntity(12, false, enemy => enemy is Enemy && pet.Dist(enemy) <= 12) is Enemy target && target.ObjectDesc.Enemy)
                {
                    var desc = pet.ObjectDesc.Projectiles[projectileIndex];
                    var a    = fixedAngle ?? (target == null ? defaultAngle.Value : Math.Atan2(target.Y - pet.Y, target.X - pet.X));
                    a += angleOffset;

                    var variance = 0;

                    if (stars == 70)
                    {
                        variance = 7000;
                    }
                    else
                    {
                        variance = player.Stars * 100;
                    }

                    cool = special ? cool = coolDown.Next(Random) : (7750 - variance); // max 750ms cooldown if not special

                    var rnd     = new Random();
                    var min     = 0;
                    var max     = 100;
                    var success = stars + 30;
                    var rng     = rnd.Next(min, max);

                    if (rng > success)
                    {
                        var _outgoing     = new List <Message>();
                        var _effect       = new SHOWEFFECT();
                        var _position     = new Position();
                        var _notification = new NOTIFICATION();

                        _position.X = .25f;
                        _position.Y = 2 / _position.X;

                        _effect.Color      = new ARGB(0xFF0000);
                        _effect.EffectType = EffectType.Flash;
                        _effect.PosA       = _position;
                        _effect.TargetId   = pet.Id;

                        _outgoing.Add(_effect);

                        _notification.Color    = new ARGB(0xFFFFFF);
                        _notification.ObjectId = pet.Id;
                        _notification.Text     = "{\"key\":\"blank\",\"tokens\":{\"data\":\"Miss!\"}}";

                        _outgoing.Add(_notification);

                        pet.Owner.BroadcastMessage(_outgoing, null);

                        state = cool;
                        return;
                    }

                    var dmg        = rnd.Next(desc.MinDamage, desc.MaxDamage);
                    var startAngle = a - shootAngle * (count - 1) / 2;
                    var prjPos     = new Position()
                    {
                        X = pet.X, Y = pet.Y
                    };
                    var prj = player.CreateProjectile(desc, pet.ObjectType, dmg, time.TotalElapsedMs, prjPos, (float)startAngle);

                    player.Owner.Projectiles.TryAdd(prj, null);

                    player.Owner.EnterWorld(prj);

                    var _outgoingMessages = new List <Message>();
                    var _shoot            = new ENEMYSHOOT
                    {
                        BulletId   = 0,
                        OwnerId    = pet.Id,
                        Position   = prjPos,
                        Angle      = prj.Angle,
                        Damage     = 0,
                        BulletType = 0,
                        AngleInc   = (float)shootAngle,
                        NumShots   = 0
                    };
                    var _shoot2 = new SERVERPLAYERSHOOT
                    {
                        BulletId      = prj.ProjectileId,
                        OwnerId       = player.Id,
                        ContainerType = pet.ObjectType,
                        StartingPos   = prj.BeginPos,
                        Angle         = prj.Angle,
                        Damage        = (short)prj.Damage
                    };

                    _outgoingMessages.Add(_shoot); // visual, display no animation only activate pet set alt index
                    _outgoingMessages.Add(_shoot2);

                    player.Owner.BroadcastMessage(_outgoingMessages, null);

                    player.FameCounter.Shoot(prj);

                    Status = CycleStatus.Completed;
                }
                else
                {
                    return;
                }
            }