コード例 #1
0
        private bool ArcHit(ushort zoneId, Point3D pinPos, Point3D worldPos)
        {
            if (_weapon.LOSHit(zoneId, pinPos))
            {
                return(true);
            }

            #if DEBUG && ARTILLERY_ARC_DEBUG
            Log.Info("Artillery", "Direct LOS check failed, checking arc...");
            #endif

            WarZoneLib.Vector3 playnice = new WarZoneLib.Vector3();

            int maxZDisplacement = Math.Min(_Owner.Z, pinPos.Z) + 100 * 12; // check 100 feet upwards

            Point3D weaponTopPoint = new Point3D();
            Point3D destPoint      = new Point3D();

            Vector2 toTarget = new Vector2(worldPos.X - _weapon.WorldPosition.X, worldPos.Y - _weapon.WorldPosition.Y);
            toTarget.Normalize();

            weaponTopPoint.SetCoordsFrom(_weapon);
            destPoint.SetCoordsFrom(_weapon);

            #if DEBUG && ARTILLERY_ARC_DEBUG
            Log.Info("Artillery", "Weapon location: " + weaponTopPoint);
            #endif

            // Check LOS between weapon and close apex (if applicable)
            if (weaponTopPoint.Z < maxZDisplacement)
            {
                destPoint.Z = maxZDisplacement;

                // Check 50 feet in front of the weapon
                destPoint.X += (int)(toTarget.X * 50 * 12);
                destPoint.Y += (int)(toTarget.Y * 50 * 12);

                #if DEBUG && ARTILLERY_ARC_DEBUG
                Log.Info("Artillery", "Checking weapon to destination point: " + destPoint);
                #endif

                RegionData.OcclusionResult arc1Result = RegionData.OcclusionQuery(
                    zoneId, weaponTopPoint.X, weaponTopPoint.Y, weaponTopPoint.Z + 120,
                    zoneId, destPoint.X, destPoint.Y, destPoint.Z, ref playnice);

                if (arc1Result == RegionData.OcclusionResult.Occluded)
                {
                    #if DEBUG && ARTILLERY_ARC_DEBUG
                    Log.Info("Artillery", "Arc check failed (obstruction between cannon and arc apex 1)");
                    foreach (var player in Players)
                    {
                        player.Key.ZoneTeleport((ushort)destPoint.X, (ushort)destPoint.Y, (ushort)destPoint.Z, 0);
                    }
                    #endif
                    return(false);
                }

                weaponTopPoint.SetCoordsFrom(destPoint);
            }

            // Check LOS between target and far apex (if applicable)
            destPoint.SetCoordsFrom(pinPos);
            #if DEBUG && ARTILLERY_ARC_DEBUG
            Log.Info("Artillery", "Target location: " + pinPos);
            #endif

            if (pinPos.Z < maxZDisplacement)
            {
                destPoint.Z = maxZDisplacement;

                // Much more lenient on drop - 10ft
                destPoint.X -= (int)(toTarget.X * 10 * 12);
                destPoint.Y -= (int)(toTarget.Y * 10 * 12);
                #if DEBUG && ARTILLERY_ARC_DEBUG
                Log.Info("Artillery", "Checking target location to destination point: " + destPoint);
                #endif

                RegionData.OcclusionResult arc2Result = RegionData.OcclusionQuery(
                    zoneId, pinPos.X, pinPos.Y, pinPos.Z + 120,
                    zoneId, destPoint.X, destPoint.Y, destPoint.Z, ref playnice);

                if (arc2Result == RegionData.OcclusionResult.Occluded)
                {
                    #if DEBUG && ARTILLERY_ARC_DEBUG
                    Log.Info("Artillery", "Arc check failed (obstruction between target point and arc apex 2)");
                    foreach (var player in Players)
                    {
                        player.Key.ZoneTeleport((ushort)destPoint.X, (ushort)destPoint.Y, (ushort)destPoint.Z, 0);
                    }
                    #endif
                    return(false);
                }

                pinPos.SetCoordsFrom(destPoint);
            }

            #if DEBUG && ARTILLERY_ARC_DEBUG
            Log.Info("Artillery", "Checking apex 1 " + weaponTopPoint + " to apex 2 " + pinPos);
            #endif

            // Check LOS between two apex points
            RegionData.OcclusionResult result = RegionData.OcclusionQuery(
                zoneId, weaponTopPoint.X, weaponTopPoint.Y, weaponTopPoint.Z + 120,
                zoneId, pinPos.X, pinPos.Y, pinPos.Z + 120, ref playnice);

            if (result == RegionData.OcclusionResult.Occluded)
            {
                #if DEBUG && ARTILLERY_ARC_DEBUG
                Log.Info("Artillery", "Arc check failed (obstruction between arc apexes)");
                //foreach (var player in Players)
                //    player.Key.ZoneTeleport((ushort)weaponTopPoint.X, (ushort)weaponTopPoint.Y, (ushort)weaponTopPoint.Z, 0);
                foreach (var player in Players)
                {
                    player.Key.ZoneTeleport((ushort)pinPos.X, (ushort)pinPos.Y, (ushort)pinPos.Z, 0);
                }
                #endif
                return(false);
            }

            #if DEBUG && ARTILLERY_ARC_DEBUG
            Log.Info("Artillery", "Arc check passed");
            #endif
            return(true);
        }