public void SetAbsolutePosition(bool UpdatePrimActor, Vector3 val)
{
if (!IsAttachment && RootPart != null && RootPart.Shape != null && Scene != null && Scene.RegionInfo != null &&
RootPart.Shape.State == 0 && !IsDeleted)
{
IBackupModule backup = Scene.RequestModuleInterface<IBackupModule>();
if ((val.X < 0f || val.Y < 0f || val.Z < 0f ||
val.X > Scene.RegionInfo.RegionSizeX || val.Y > Scene.RegionInfo.RegionSizeY)
&& !IsAttachmentCheckFull() && (backup != null && !backup.LoadingPrims))
//Don't do it when backup is loading prims, otherwise it lags the region out
{
if (Scene.RegionInfo.InfiniteRegion && !IsInTransit)
{
IsInTransit = true;
double TargetX = Scene.RegionInfo.RegionLocX + (double)val.X;
double TargetY = Scene.RegionInfo.RegionLocY + (double)val.Y;
if (m_lastSigInfiniteRegionPos.X - AbsolutePosition.X > 256 ||
m_lastSigInfiniteRegionPos.X - AbsolutePosition.X < -256 ||
m_lastSigInfiniteRegionPos.Y - AbsolutePosition.Y > 256 ||
m_lastSigInfiniteRegionPos.Y - AbsolutePosition.Y < -256)
{
m_lastSigInfiniteRegionPos = AbsolutePosition;
m_nearbyInfiniteRegions = Scene.GridService.GetRegionRange(null,
(int)
(TargetX -
Scene.GridService
.GetMaxRegionSize()),
(int)(TargetX + 256),
(int)
(TargetY -
Scene.GridService
.GetMaxRegionSize()),
(int)(TargetY + 256));
}
GridRegion neighborRegion =
m_nearbyInfiniteRegions.FirstOrDefault(
region =>
TargetX >= region.RegionLocX && TargetY >= region.RegionLocY &&
TargetX < (region.RegionLocX + region.RegionSizeX) &&
TargetY < (region.RegionLocY + region.RegionSizeY));
if (neighborRegion != null)
{
//Fix the location that the prim will land
if (val.X < 0)
val.X += neighborRegion.RegionSizeX;
if (val.X > Scene.RegionInfo.RegionSizeX)
val.X -= Scene.RegionInfo.RegionSizeX;
if (val.Y < 0)
val.Y += neighborRegion.RegionSizeY;
if (val.Y > Scene.RegionInfo.RegionSizeY)
val.Y -= Scene.RegionInfo.RegionSizeY;
IEntityTransferModule transferModule = Scene.RequestModuleInterface<IEntityTransferModule>();
if (transferModule != null)
{
if (transferModule.CrossGroupToNewRegion(this, val, neighborRegion))
{
IsInTransit = false;
return;
}
}
}
IsInTransit = false;
return;
}
//If we are headed out of the region, make sure we have a region there
IGridRegisterModule neighborService = Scene.RequestModuleInterface<IGridRegisterModule>();
if (neighborService != null && !IsInTransit)
{
IsInTransit = true;
List<GridRegion> neighbors = neighborService.GetNeighbors(Scene);
int RegionCrossX = Scene.RegionInfo.RegionLocX;
int RegionCrossY = Scene.RegionInfo.RegionLocY;
if (val.X < 0f)
RegionCrossX -= Constants.RegionSize;
if (val.Y < 0f)
RegionCrossY -= Constants.RegionSize;
if (val.X > Scene.RegionInfo.RegionSizeX)
RegionCrossX += Scene.RegionInfo.RegionSizeX;
if (val.Y > Scene.RegionInfo.RegionSizeY)
RegionCrossY += Scene.RegionInfo.RegionSizeY;
GridRegion neighborRegion =
neighbors.FirstOrDefault(
region => region.RegionLocX == RegionCrossX && region.RegionLocY == RegionCrossY);
if (neighborRegion != null)
{
//Fix the location that the prim will land
if (val.X < 0)
val.X += neighborRegion.RegionSizeX;
if (val.X > Scene.RegionInfo.RegionSizeX)
val.X -= Scene.RegionInfo.RegionSizeX;
if (val.Y < 0)
val.Y += neighborRegion.RegionSizeY;
if (val.Y > Scene.RegionInfo.RegionSizeY)
val.Y -= Scene.RegionInfo.RegionSizeY;
IEntityTransferModule transferModule =
Scene.RequestModuleInterface<IEntityTransferModule>();
if (transferModule != null)
{
if (transferModule.CrossGroupToNewRegion(this, val, neighborRegion))
{
IsInTransit = false;
return;
}
}
}
IsInTransit = false;
if(RootPart.VehicleType == (int)Vehicle.TYPE_NONE) {
//The group should have crossed a region, but no region was found so return it instead
MainConsole.Instance.Info("[SceneObjectGroup]: Returning prim " + Name + " @ " +
AbsolutePosition +
" because it has gone out of bounds.");
ILLClientInventory inventoryModule = Scene.RequestModuleInterface<ILLClientInventory>();
if (inventoryModule != null)
inventoryModule.ReturnObjects(new ISceneEntity[] { this }, UUID.Zero);
}
return;
}
}
}
if (RootPart != null && RootPart.GetStatusSandbox())
{
if (Util.GetDistanceTo(RootPart.StatusSandboxPos, val) > 10)
{
ScriptSetPhysicsStatus(false);
if (Scene != null)
{
IChatModule chatModule = Scene.RequestModuleInterface<IChatModule>();
if (chatModule != null)
chatModule.SimChat("Hit Sandbox Limit",
ChatTypeEnum.DebugChannel, 0x7FFFFFFF, RootPart.AbsolutePosition, Name,
UUID,
false, Scene);
}
return;
}
}
foreach (SceneObjectPart part in m_partsList)
{
part.FixGroupPositionComum(UpdatePrimActor, val, false);
}
}