From 0c544a85dc62416f6b02c348ec8a27436c0ed931 Mon Sep 17 00:00:00 2001
From: Arthur Valadares
Date: Fri, 3 Apr 2009 19:20:23 +0000
Subject: * Fixes issue where of you force your avatar against a region corner,
it gets stuck and NonFinite Avatar messages floods console Addresses Mantis
#3380
---
OpenSim/Region/Framework/Scenes/ScenePresence.cs | 70 ++++++++++++++++++++++--
1 file changed, 64 insertions(+), 6 deletions(-)
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 58a2f2a..db83cb0 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -200,6 +200,10 @@ namespace OpenSim.Region.Framework.Scenes
DIR_CONTROL_FLAG_DOWN_NUDGE = AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG
}
+ protected enum Cardinals
+ {
+ N=1,NE,E,SE,S,SW,W,NW
+ }
///
/// Position at which a significant movement was made
///
@@ -2260,7 +2264,7 @@ namespace OpenSim.Region.Framework.Scenes
}
}
}
-
+
m_scene.StatsReporter.AddAgentUpdates(avatars.Count);
m_scene.StatsReporter.AddAgentTime(Environment.TickCount - m_perfMonMS);
@@ -2517,6 +2521,8 @@ namespace OpenSim.Region.Framework.Scenes
Vector3 pos2 = AbsolutePosition;
Vector3 vel = Velocity;
+ int neighbor = 0;
+ int[] fix = new int[2];
float timeStep = 0.1f;
pos2.X = pos2.X + (vel.X*timeStep);
@@ -2525,15 +2531,38 @@ namespace OpenSim.Region.Framework.Scenes
if (!IsInTransit)
{
- if ((pos2.X < 0) || (pos2.X > Constants.RegionSize))
+ // Checks if where it's headed exists a region
+ if (pos2.X < 0)
{
- CrossToNewRegion();
+ if (pos2.Y < 0)
+ neighbor = HaveNeighbor(Cardinals.SW, ref fix);
+ else if (pos2.Y > Constants.RegionSize)
+ neighbor = HaveNeighbor(Cardinals.NW, ref fix);
+ else
+ neighbor = HaveNeighbor(Cardinals.W, ref fix);
}
-
- if ((pos2.Y < 0) || (pos2.Y > Constants.RegionSize))
+ else if (pos2.X > Constants.RegionSize)
{
+ if (pos2.Y < 0)
+ neighbor = HaveNeighbor(Cardinals.SE, ref fix);
+ else if (pos2.Y > Constants.RegionSize)
+ neighbor = HaveNeighbor(Cardinals.NE, ref fix);
+ else
+ neighbor = HaveNeighbor(Cardinals.E, ref fix);
+ }
+ else if (pos2.Y < 0)
+ neighbor = HaveNeighbor(Cardinals.S, ref fix);
+ else if (pos2.Y > Constants.RegionSize)
+ neighbor = HaveNeighbor(Cardinals.N, ref fix);
+
+ // Makes sure avatar does not end up outside region
+ if (neighbor < 0)
+ AbsolutePosition = new Vector3(
+ AbsolutePosition.X + 3*fix[0],
+ AbsolutePosition.Y + 3*fix[1],
+ AbsolutePosition.Z);
+ else if (neighbor > 0)
CrossToNewRegion();
- }
}
else
{
@@ -2547,7 +2576,36 @@ namespace OpenSim.Region.Framework.Scenes
pos2.Z = pos2.Z + (vel.Z * timeStep);
m_pos = pos2;
}
+ }
+ protected int HaveNeighbor(Cardinals car, ref int[] fix)
+ {
+ uint neighbourx = m_regionInfo.RegionLocX;
+ uint neighboury = m_regionInfo.RegionLocY;
+
+ int dir = (int)car;
+
+ if (dir > 1 && dir < 5) //Heading East
+ neighbourx++;
+ else if (dir > 5) // Heading West
+ neighbourx--;
+
+ if (dir < 3 || dir == 8) // Heading North
+ neighboury++;
+ else if (dir > 3 && dir < 7) // Heading Sout
+ neighboury--;
+
+ ulong neighbourHandle = Utils.UIntsToLong((uint)(neighbourx * Constants.RegionSize), (uint)(neighboury * Constants.RegionSize));
+ SimpleRegionInfo neighbourRegion = m_scene.RequestNeighbouringRegionInfo(neighbourHandle);
+
+ if (neighbourRegion == null)
+ {
+ fix[0] = (int)(m_regionInfo.RegionLocX - neighbourx);
+ fix[1] = (int)(m_regionInfo.RegionLocY - neighboury);
+ return dir * (-1);
+ }
+ else
+ return dir;
}
///
--
cgit v1.1