Example #1
0
        private void ParcelJoinHandler(Packet packet, LLAgent agent)
        {
            ParcelJoinPacket join = (ParcelJoinPacket)packet;

            int startX = (int)Math.Round(join.ParcelData.West) / 4;
            int startY = (int)Math.Round(join.ParcelData.South) / 4;
            int endX   = ((int)Math.Round(join.ParcelData.East) / 4) - 1;
            int endY   = ((int)Math.Round(join.ParcelData.North) / 4) - 1;

            if (startX < 0 || startY < 0 || endX < startX || endY < startY ||
                endX > 63 || endY > 63 || startX > endX || startY > endY)
            {
                m_log.Warn(agent.Name + String.Format(" sent invalid ParcelJoin: West {0} South {1} East {2} North {3}",
                                                      join.ParcelData.West, join.ParcelData.South, join.ParcelData.East, join.ParcelData.North));
                return;
            }

            int     largestArea = 0;
            Vector3 aabbMin, aabbMax;

            // Get the selected parcels
            List <SceneParcel> selectedParcels = new List <SceneParcel>();

            for (int y = startY; y <= endY; y++)
            {
                for (int x = startX; x <= endX; x++)
                {
                    SceneParcel parcel;
                    if (m_parcels.TryGetParcel(m_parcels.GetParcelID(x, y), out parcel))
                    {
                        if (!selectedParcels.Contains(parcel) && m_permissions.CanEditParcel(agent, parcel))
                        {
                            // Largest parcel is the "master" parcel that smaller parcels are joined into
                            int area = ParcelManager.GetParcelArea(parcel, out aabbMin, out aabbMax);
                            if (area > largestArea)
                            {
                                largestArea = area;
                                selectedParcels.Insert(0, parcel);
                            }
                            else
                            {
                                selectedParcels.Add(parcel);
                            }
                        }
                    }
                }
            }

            // Enough parcels selected check
            if (selectedParcels.Count < 2)
            {
                m_scene.PresenceAlert(this, agent, "Not enough leased parcels in selection to join");
                return;
            }

            // Same owner check
            for (int i = 1; i < selectedParcels.Count; i++)
            {
                if (selectedParcels[i].OwnerID != selectedParcels[0].OwnerID)
                {
                    m_scene.PresenceAlert(this, agent, "All parcels must have the same owner before joining");
                    return;
                }
            }

            m_parcels.JoinParcels(selectedParcels);

            // Broadcast the new parcel overlay info
            m_scene.ForEachPresence(SendParcelOverlay);
        }