Esempio n. 1
0
        public void LaserAttack(ref int lapCount, Ammuninition ammo)
        {
            lock (_laserLock) {
                #region {[ CHECKING ]}
                if (PlayerController.Locked == null ||
                    PlayerController.Locked.MovementAssembly.ActualPosition()
                    .DistanceTo(PlayerController.MovementAssembly.ActualPosition()) > 600 ||
                    !_attackRunning)
                {
                    return;
                }

                bool stopLoop   = true;
                bool stopAttack = false;
                if (PlayerController.Locked.ZoneAssembly.IsInDMZ)
                {
                    PlayerController.Send(PacketBuilder.Messages.PeaceArea());
                    stopAttack = true;
                }

                if (!PlayerController.Account.CurrentHangar.LaserEquipped)
                {
                    PlayerController.Send(PacketBuilder.Messages.NoLasersOnBoard());
                    stopAttack = true;
                }

                if (!stopAttack && !CheckLaserCount(ammo, false, out int currentCount))
                {
                    PlayerController.Send(PacketBuilder.Messages.NoLaserAmmo());
                    stopAttack = true;
                }

                if (!stopAttack && !LaserCooldown(ref lapCount, ammo))
                {
                    stopAttack = true;
                    stopLoop   = false;
                }

                if (stopAttack)
                {
                    if (stopLoop)
                    {
                        Stop();
                    }

                    return;
                }
                #endregion

                CheckLaserCount(ammo, true, out currentCount); // deduct

                LastAttack = PlayerController.CurrentClock.ElapsedMilliseconds;
                ICommand attackCommand = PacketBuilder.AttackLaserCommand(PlayerController, PlayerController.Locked, ammo.ID);
                PlayerController.Send(attackCommand, PacketBuilder.Slotbar.LaserItemStatus(ammo.Name, currentCount, true));
                PlayerController.EntitesInRange(x => x.Send(attackCommand));

                if (PlayerController.Locked.EffectsAssembly.HasProtection ||
                    (PlayerController.Locked is PlayerController lockedPlayerController && lockedPlayerController.SpecialItemsAssembly.IsInvicible) ||
                    Miss())
                {
                    PlayerController.Locked.AttackTraceAssembly.LogAttack(PlayerController, 0, 0);
                    ICommand missCommand = new AttackMissedCommand(new AttackTypeModule(AttackTypeModule.LASER), PlayerController.Locked.ID, 0);
                    PlayerController.Locked.Send(new AttackMissedCommand(new AttackTypeModule(AttackTypeModule.LASER), PlayerController.Locked.ID, 1));
                    PlayerController.Locked.EntitiesLocked(x => x.Send(missCommand));
                    return;
                }

                CalculateLaserDamage(ammo, PlayerController.Locked, out double damage, out double shieldDamage);

                if (shieldDamage > 0)
                {
                    shieldDamage = Math.Abs(PlayerController.Locked.HangarAssembly.ChangeShield(-(int)shieldDamage, false));
                    PlayerController.HangarAssembly.ChangeShield((int)shieldDamage);
                }

                double shieldDamageDealt    = shieldDamage;
                double hitpointsDamageDealt = 0;

                if (damage > 0)
                {
                    double shieldAbsorption = Math.Max(0, Math.Min(1, PlayerController.Locked.BoosterAssembly.Get(BoosterType.SHIELD_ABSORBATION) - (PlayerController.BoosterAssembly.Get(BoosterType.LASER_SHIELD_PENETRATION) - 1)));

                    double damageShield = damage * shieldAbsorption;
                    if (PlayerController.PlayerAbilityAssembly.WeakenShieldsActive &&
                        PlayerController.PlayerAbilityAssembly.WeakenShieldsVictim.ID == PlayerController.Locked.ID)
                    {
                        damageShield *= 1.6;
                    }

                    damageShield = Math.Abs(PlayerController.Locked.HangarAssembly.ChangeShield(-(int)damageShield, false));
                    int damageHitpoints = Math.Abs(PlayerController.Locked.HangarAssembly.ChangeHitpoints(-(int)(damage - Math.Min(damage * shieldAbsorption, damageShield)), false));

                    shieldDamageDealt    += damageShield;
                    hitpointsDamageDealt += damageHitpoints;

                    // energy transfer
                    double hitpointsRegain = PlayerController.BoosterAssembly.Get(BoosterType.DAMAGE_LASER_TO_HITPOINTS_TRANSFORMER) - 1.0;
                    if (hitpointsRegain > 0 && ammo.ID == Ammuninition.UCB_100.ID)
                    {
                        int regain = PlayerController.HangarAssembly.ChangeHitpoints(Math.Max(0, (int)((damageShield + damageHitpoints) * hitpointsRegain)));
                        if (regain > 0 && !PlayerController.PlayerTechAssembly.EnergyTransferActive && ++_healCounter % 2 == 0)
                        {
                            _healCounter = 0;

                            ICommand energyTransferCommand = PacketBuilder.AttackLaserCommand(PlayerController.Locked, PlayerController, 7);
                            PlayerController.Locked.Send(energyTransferCommand);                        // send to player
                            PlayerController.Locked.EntitesInRange(y => y.Send(energyTransferCommand)); // send to all who have him in lock
                        }
                    }
                }

                // set stats
                PlayerController.Locked.AttackTraceAssembly.LogAttack(PlayerController, (int)shieldDamageDealt, (int)hitpointsDamageDealt);
                PlayerController.Locked.HangarAssembly.CheckDeath();

                ActivateLaserSpecialAttack(ammo);    // initialize special attack

                if (PlayerController.Locked != null) // Locked kann nach der CheckDeath-Methode tot sein (wahrscheinlichkeit: hoch)
                {
                    ICommand damageCommand = PacketBuilder.AttackCommand(PlayerController, PlayerController.Locked, AttackTypeModule.LASER, (int)(shieldDamageDealt + hitpointsDamageDealt));
                    PlayerController.Locked.Send(damageCommand);                        // send to player
                    PlayerController.Locked.EntitiesLocked(y => y.Send(damageCommand)); // send to all who have him in lock
                }
            }
        }