Пример #1
0
        public void Fire(Player player, ushort targetID, ushort targetX, ushort targetY, ushort targetZ, ushort zoneId, ushort power)
        {
            if (!HasPlayer(player) || !_weapon.AbtInterface.CanCastCooldown(_abilityId))
            {
                return;
            }

            // RB   6/25/2016   Reset timer before death every time the siege is fired
            _deathTime = TCPManager.GetTimeStampMS() + 300 * 1000;


            switch (Type)
            {
            case SiegeType.GTAOE:
                Point3D targetPos = ZoneService.GetWorldPosition(_weapon.Zone.Info, targetX, targetY, targetZ);

                if (!ArcHit(zoneId, new Point3D(targetX, targetY, targetZ), targetPos))
                {
                    player.SendClientMessage("Can't hit that position from here", ChatLogFilters.CHATLOGFILTERS_C_ABILITY_ERROR);
                    return;
                }

                Siege artillery = _weapon as Siege;
                if (artillery != null && !artillery.CanFire(player))
                {
                    return;
                }

                // 72675 is the orcapult - catapults player rather than a stone!
                if (this._weapon.Entry == 72675)
                {
                    var   targetPosition   = ZoneService.GetWorldPosition(_weapon.Zone.Info, targetX, targetY, targetZ);
                    float speed            = 6400f;
                    float flightTimePuntee = 4;    //(float)this._leader.GetDistanceSquare(new Point3D(targetPosition.X, targetPosition.Y, targetPosition.Z)) / speed / 1000f;
                    this._leader.Catapult(_weapon.Zone, new Point3D(targetPosition.X, targetPosition.Y, targetPosition.Z), (ushort)flightTimePuntee, (ushort)340);
                    this._leader.AbtInterface.Cancel(true);
                    SendSiegeResponse(_leader, Type, SiegeControlType.Leader, 1);
                }
                else
                {
                    _weapon.AbtInterface.StartCastAtPos(player, _abilityId, ZoneService.GetWorldPosition(_weapon.Zone.Info, targetX, targetY, targetZ), _weapon.Zone.ZoneId, 0);
                }


                break;

            case SiegeType.OIL:
                _weapon.AbtInterface.StartCastAtPos(player, _abilityId, ZoneService.GetWorldPosition(_weapon.Zone.Info, targetX, targetY, targetZ), _weapon.Zone.ZoneId, 0);
                break;

            case SiegeType.SNIPER:
                Unit target = _weapon.Region.GetObject(targetID) as Unit;

                if (target == null || !CombatInterface.CanAttack(player, target))
                {
                    return;
                }

                Siege cannon = _weapon as Siege;
                if (cannon != null && !cannon.CanFire(player))
                {
                    return;
                }

                _weapon.CbtInterface.SetTarget(targetID, TargetTypes.TARGETTYPES_TARGET_ENEMY);
                _weapon.AbtInterface.StartCast(player, _abilityId, 0, 0, Math.Max((byte)1, (byte)(_weapon.Level * power * 0.01f)));
                break;

            case SiegeType.RAM:
                Unit ramTarget = null;
                foreach (Object obj in _Owner.ObjectsInRange)
                {
                    KeepDoor.KeepGameObject door = obj as KeepDoor.KeepGameObject;

                    if (door == null)
                    {
                        continue;
                    }

                    if (!CombatInterface.CanAttack(player, door))
                    {
                        continue;
                    }

                    if (!_Owner.IsObjectInFront(door, 90) || !door.IsWithinRadiusFeet(_Owner, 20))
                    {
                        continue;
                    }

                    ramTarget = door;
                    break;
                }
                //Unit target = _weapon.Region.GetObject(targetID) as Unit;

                if (ramTarget != null)
                {
                    _weapon.CbtInterface.SetTarget(ramTarget.Oid, TargetTypes.TARGETTYPES_TARGET_ENEMY);
                    _weapon.AbtInterface.StartCast(player, _abilityId, 0, 0, Math.Max((byte)1, (byte)(_weapon.Level * power * 0.01f)));
                }

                else
                {
                    foreach (var plrInfo in Players)
                    {
                        plrInfo.Key.SendClientMessage("No target", ChatLogFilters.CHATLOGFILTERS_C_ABILITY_ERROR);
                    }
                }
                break;
            }

            SendSiegeCooldown();


            // Disable Firing?

            /*
             * Out = new PacketOut((byte)Opcodes.F_UPDATE_STATE);
             * Out.WriteUInt16(_Owner.Oid);
             * Out.WriteByte(0x1C);
             * Out.WriteByte(2);
             * Out.Fill(0, 6);
             * player.SendPacket(Out);
             */

            SendSiegeUserUpdate();

            /*
             * Out = new PacketOut((byte)Opcodes.F_UPDATE_STATE);
             * Out.WriteUInt16(_Owner.Oid);
             * Out.WriteByte(0x1E);
             * Out.WriteUInt16(0);
             * Out.WriteByte((byte)_Owner.Name.Length);
             * Out.WriteUInt16(0);
             * Out.WriteCString(_Owner.Name);
             * Out.WriteByte(0);
             * player.SendPacket(Out);
             */

            SendSiegeIdleTimer(player);
        }
Пример #2
0
        /// <summary>
        /// Builds a list of targets which would be hit by a line attack performed by a siege cannon.
        /// </summary>
        /// <param name="instigator">The player firing the cannon.</param>
        /// <returns>The farthest target from the siege weapon which would be struck by the attack, for use as the target of the ability.</returns>
        public Unit BuildTargetList(Unit instigator)
        {
            CurrentTargetList.Clear();

            Unit initialTarget = _weapon.CbtInterface.GetTarget(TargetTypes.TARGETTYPES_TARGET_ENEMY);

            Unit bestTarget = initialTarget;
            int  bestDist   = _weapon.GetDistanceToObject(initialTarget);

            CurrentTargetList.Add(initialTarget);

            Vector3 unitDir = new Vector3(initialTarget.WorldPosition.X - _weapon.WorldPosition.X,
                                          initialTarget.WorldPosition.Y - _weapon.WorldPosition.Y,
                                          initialTarget.WorldPosition.Z - _weapon.WorldPosition.Z);

            unitDir.Normalize();

            Vector3 toTarget   = new Vector3();
            Vector3 projection = new Vector3();

            foreach (Object obj in _weapon.ObjectsInRange)
            {
                Unit unit = obj as Unit;

                if (unit == null || unit == initialTarget || unit.Realm == instigator.Realm || !_weapon.IsObjectInFront(unit, 45) || !CombatInterface.CanAttack(instigator, unit))
                {
                    continue;
                }

                // Determine whether this unit is within 5ft on either side of the cannon's attack.

                // Unit vector in direction of cannon's view
                projection.X = unitDir.X;
                projection.Y = unitDir.Y;
                projection.Z = unitDir.Z;

                toTarget.X = unit.WorldPosition.X - _weapon.WorldPosition.X;
                toTarget.Y = unit.WorldPosition.Y - _weapon.WorldPosition.Y;
                toTarget.Z = unit.WorldPosition.Z - _weapon.WorldPosition.Z;

                // Vector projection ((a dot ^b) ^b)
                projection.Multiply(Vector3.DotProduct3D(toTarget, unitDir));

                // Vector rejection (a - (a dot ^b) ^b)
                toTarget.X -= projection.X;
                toTarget.Y -= projection.Y;
                toTarget.Z -= projection.Z;

                if (toTarget.MagnitudeSquare < 60 * 60 && _weapon.LOSHit(unit)) // 5ft either side
                {
                    CurrentTargetList.Add(unit);

                    // Select the target furthest away as the target of the ability, for the projectile effect to look best
                    if (!_weapon.IsWithinRadiusFeet(unit, bestDist))
                    {
                        bestTarget = unit;
                        bestDist   = _weapon.GetDistanceToObject(bestTarget);
                    }
                }
            }

            return(bestTarget);
        }