// this is needed for non-convex parcels (example: rectangular parcel, and in the exact center // another, smaller rectangular parcel). Both will have the same initial coordinates. private void findPointInParcel(ILandObject land, ref uint refX, ref uint refY) { m_log.DebugFormat("[DATASNAPSHOT] trying {0}, {1}", refX, refY); // the point we started with already is in the parcel if (land.ContainsPoint((int)refX, (int)refY)) { return; } // ... otherwise, we have to search for a point within the parcel uint startX = (uint)land.LandData.AABBMin.X; uint startY = (uint)land.LandData.AABBMin.Y; uint endX = (uint)land.LandData.AABBMax.X; uint endY = (uint)land.LandData.AABBMax.Y; // default: center of the parcel refX = (startX + endX) / 2; refY = (startY + endY) / 2; // If the center point is within the parcel, take that one if (land.ContainsPoint((int)refX, (int)refY)) { return; } // otherwise, go the long way. for (uint y = startY; y <= endY; ++y) { for (uint x = startX; x <= endX; ++x) { if (land.ContainsPoint((int)x, (int)y)) { // found a point refX = x; refY = y; return; } } } }
//calculate the average center point of a parcel private Vector2 GetParcelCenter(ILandObject parcel) { int count = 0; int avgx = 0; int avgy = 0; for (int x = 0; x < Constants.RegionSize; x++) { for (int y = 0; y < Constants.RegionSize; y++) { //Just keep a running average as we check if all the points are inside or not if (parcel.ContainsPoint(x, y)) { if (count == 0) { avgx = x; avgy = y; } else { avgx = (avgx * count + x) / (count + 1); avgy = (avgy * count + y) / (count + 1); } count += 1; } } } return new Vector2(avgx, avgy); }
private Vector3? GetNearestPointInParcelAlongDirectionFromPoint(Vector3 pos, Vector3 direction, ILandObject parcel) { Vector3 unitDirection = Vector3.Normalize(direction); //Making distance to search go through some sane limit of distance for (float distance = 0; distance < Constants.RegionSize * 2; distance += .5f) { Vector3 testPos = Vector3.Add(pos, Vector3.Multiply(unitDirection, distance)); if (parcel.ContainsPoint((int)testPos.X, (int)testPos.Y)) { return testPos; } } return null; }
// this is needed for non-convex parcels (example: rectangular parcel, and in the exact center // another, smaller rectangular parcel). Both will have the same initial coordinates. private void findPointInParcel(ILandObject land, ref uint refX, ref uint refY) { m_log.DebugFormat("[DATASNAPSHOT] trying {0}, {1}", refX, refY); // the point we started with already is in the parcel if (land.ContainsPoint((int)refX, (int)refY)) return; // ... otherwise, we have to search for a point within the parcel uint startX = (uint)land.LandData.AABBMin.X; uint startY = (uint)land.LandData.AABBMin.Y; uint endX = (uint)land.LandData.AABBMax.X; uint endY = (uint)land.LandData.AABBMax.Y; // default: center of the parcel refX = (startX + endX) / 2; refY = (startY + endY) / 2; // If the center point is within the parcel, take that one if (land.ContainsPoint((int)refX, (int)refY)) return; // otherwise, go the long way. for (uint y = startY; y <= endY; ++y) { for (uint x = startX; x <= endX; ++x) { if (land.ContainsPoint((int)x, (int)y)) { // found a point refX = x; refY = y; return; } } } }
//calculate the average center point of a parcel private Vector2 GetParcelCenter(ILandObject parcel) { int count = 0; float avgx = 0; float avgy = 0; for (int x = 0; x < m_scene.RegionInfo.RegionSizeX; x++) { for (int y = 0; y < m_scene.RegionInfo.RegionSizeY; y++) { //Just keep a running average as we check if all the points are inside or not if (parcel.ContainsPoint(x, y)) { if (count == 0) { //Set this to 1 so that when we multiply down below, it doesn't lock to 0 if (x == 0) x = 1; if (y == 0) y = 1; avgx = x; avgy = y; } else { avgx = (avgx*count + x)/(count + 1); avgy = (avgy*count + y)/(count + 1); } count += 1; } } } return new Vector2(avgx, avgy); }
private Vector3? GetNearestPointInParcelAlongDirectionFromPoint(Vector3 pos, Vector3 direction, ILandObject parcel) { Vector3 unitDirection = Vector3.Normalize(direction); //Making distance to search go through some sane limit of distance int size = m_scene.RegionInfo.RegionSizeX > m_scene.RegionInfo.RegionSizeY ? m_scene.RegionInfo.RegionSizeX : m_scene.RegionInfo.RegionSizeY; for (float distance = 0; distance < size*2; distance += .5f) { Vector3 testPos = Vector3.Add(pos, Vector3.Multiply(unitDirection, distance)); if (parcel.ContainsPoint((int) testPos.X, (int) testPos.Y)) { return GetPositionAtGround(testPos.X, testPos.Y); } } return null; }
// checks and enforces bans or restrictions // returns true if enforced public bool EnforceBans(ILandObject land, ScenePresence avatar) { Vector3 agentpos = avatar.AbsolutePosition; float h = m_scene.GetGroundHeight(agentpos.X, agentpos.Y) + LandChannel.BAN_LINE_SAFETY_HEIGHT; float zdif = avatar.AbsolutePosition.Z - h; if (zdif > 0 ) { forcedPosition.Remove(avatar.UUID); avatar.lastKnownAllowedPosition = agentpos; return false; } bool ban = false; string reason = ""; if (land.IsRestrictedFromLand(avatar.UUID)) { reason = "You do not have access to the parcel"; ban = true; } if (land.IsBannedFromLand(avatar.UUID)) { if ( m_allowedForcefulBans) { reason ="You are banned from parcel"; ban = true; } else if(!ban) { if (forcedPosition.Contains(avatar.UUID)) avatar.ControllingClient.SendAlertMessage("You are banned from parcel, please leave by your own will"); forcedPosition.Remove(avatar.UUID); avatar.lastKnownAllowedPosition = agentpos; return false; } } if(ban) { if (!forcedPosition.Contains(avatar.UUID)) avatar.ControllingClient.SendAlertMessage(reason); if(zdif > -4f) { agentpos.Z = h + 4.0f; ForceAvatarToPosition(avatar, agentpos); return true; } if (land.ContainsPoint((int)avatar.lastKnownAllowedPosition.X, (int) avatar.lastKnownAllowedPosition.Y)) { Vector3? pos = m_scene.GetNearestAllowedPosition(avatar); if (pos == null) { forcedPosition.Remove(avatar.UUID); m_scene.TeleportClientHome(avatar.UUID, avatar.ControllingClient); } else ForceAvatarToPosition(avatar, (Vector3)pos); } else { ForceAvatarToPosition(avatar, avatar.lastKnownAllowedPosition); } return true; } else { forcedPosition.Remove(avatar.UUID); avatar.lastKnownAllowedPosition = agentpos; return false; } }
public void EnforceBans(ILandObject land, ScenePresence avatar) { if (avatar.AbsolutePosition.Z > LandChannel.BAN_LINE_SAFETY_HIEGHT) return; if (land.IsEitherBannedOrRestricted(avatar.UUID)) { if (land.ContainsPoint(Convert.ToInt32(avatar.lastKnownAllowedPosition.X), Convert.ToInt32(avatar.lastKnownAllowedPosition.Y))) { Vector3? pos = m_scene.GetNearestAllowedPosition(avatar); if (pos == null) m_scene.TeleportClientHome(avatar.UUID, avatar.ControllingClient); else ForceAvatarToPosition(avatar, (Vector3)pos); } else { ForceAvatarToPosition(avatar, avatar.lastKnownAllowedPosition); } } }