aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/ScenePresence.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/ScenePresence.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/ScenePresence.cs569
1 files changed, 357 insertions, 212 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 4940063..e27d309 100644
--- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs
+++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (c) Contributors, http://opensimulator.org/ 2 * Copyright (c) Contributors, http://opensimulator.org/
3 * See CONTRIBUTORS.TXT for a full list of copyright holders. 3 * See CONTRIBUTORS.TXT for a full list of copyright holders.
4 * 4 *
@@ -45,6 +45,7 @@ using TeleportFlags = OpenSim.Framework.Constants.TeleportFlags;
45 45
46namespace OpenSim.Region.Framework.Scenes 46namespace OpenSim.Region.Framework.Scenes
47{ 47{
48 [Flags]
48 enum ScriptControlled : uint 49 enum ScriptControlled : uint
49 { 50 {
50 CONTROL_ZERO = 0, 51 CONTROL_ZERO = 0,
@@ -76,6 +77,11 @@ namespace OpenSim.Region.Framework.Scenes
76// { 77// {
77// m_log.Debug("[SCENE PRESENCE] Destructor called"); 78// m_log.Debug("[SCENE PRESENCE] Destructor called");
78// } 79// }
80 private void TriggerScenePresenceUpdated()
81 {
82 if (m_scene != null)
83 m_scene.EventManager.TriggerScenePresenceUpdated(this);
84 }
79 85
80 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 86 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
81 87
@@ -497,6 +503,7 @@ namespace OpenSim.Region.Framework.Scenes
497 //m_log.DebugFormat( 503 //m_log.DebugFormat(
498 // "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}", 504 // "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}",
499 // Scene.RegionInfo.RegionName, Name, m_pos); 505 // Scene.RegionInfo.RegionName, Name, m_pos);
506 TriggerScenePresenceUpdated();
500 } 507 }
501 } 508 }
502 509
@@ -516,6 +523,7 @@ namespace OpenSim.Region.Framework.Scenes
516 return; 523 return;
517 524
518 m_pos = value; 525 m_pos = value;
526 TriggerScenePresenceUpdated();
519 } 527 }
520 } 528 }
521 529
@@ -586,6 +594,12 @@ namespace OpenSim.Region.Framework.Scenes
586 private UUID m_parentUUID = UUID.Zero; 594 private UUID m_parentUUID = UUID.Zero;
587 595
588 /// <summary> 596 /// <summary>
597 /// Are we sitting on an object?
598 /// </summary>
599 /// <remarks>A more readable way of testing presence sit status than ParentID == 0</remarks>
600 public bool IsSatOnObject { get { return ParentID != 0; } }
601
602 /// <summary>
589 /// If the avatar is sitting, the prim that it's sitting on. If not sitting then null. 603 /// If the avatar is sitting, the prim that it's sitting on. If not sitting then null.
590 /// </summary> 604 /// </summary>
591 /// <remarks> 605 /// <remarks>
@@ -1087,23 +1101,13 @@ namespace OpenSim.Region.Framework.Scenes
1087 /// <param name="pos"></param> 1101 /// <param name="pos"></param>
1088 public void Teleport(Vector3 pos) 1102 public void Teleport(Vector3 pos)
1089 { 1103 {
1090 bool isFlying = Flying; 1104 TeleportWithMomentum(pos, Vector3.Zero);
1091 RemoveFromPhysicalScene();
1092 Velocity = Vector3.Zero;
1093 CheckLandingPoint(ref pos);
1094 AbsolutePosition = pos;
1095 AddToPhysicalScene(isFlying);
1096
1097 SendTerseUpdateToAllClients();
1098 }
1099
1100 public void TeleportWithMomentum(Vector3 pos)
1101 {
1102 TeleportWithMomentum(pos, null);
1103 } 1105 }
1104 1106
1105 public void TeleportWithMomentum(Vector3 pos, Vector3? v) 1107 public void TeleportWithMomentum(Vector3 pos, Vector3? v)
1106 { 1108 {
1109 if (ParentID != (uint)0)
1110 StandUp();
1107 bool isFlying = Flying; 1111 bool isFlying = Flying;
1108 Vector3 vel = Velocity; 1112 Vector3 vel = Velocity;
1109 RemoveFromPhysicalScene(); 1113 RemoveFromPhysicalScene();
@@ -1283,17 +1287,33 @@ namespace OpenSim.Region.Framework.Scenes
1283 1287
1284 bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); 1288 bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
1285 MakeRootAgent(AbsolutePosition, flying); 1289 MakeRootAgent(AbsolutePosition, flying);
1290 ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
1291
1292// m_log.DebugFormat("[SCENE PRESENCE] Completed movement");
1286 1293
1287 if ((m_callbackURI != null) && !m_callbackURI.Equals("")) 1294 if ((m_callbackURI != null) && !m_callbackURI.Equals(""))
1288 { 1295 {
1289 m_log.DebugFormat("[SCENE PRESENCE]: Releasing agent in URI {0}", m_callbackURI); 1296 // We cannot sleep here since this would hold up the inbound packet processing thread, as
1297 // CompleteMovement() is executed synchronously. However, it might be better to delay the release
1298 // here until we know for sure that the agent is active in this region. Sending AgentMovementComplete
1299 // is not enough for Imprudence clients - there appears to be a small delay (<200ms, <500ms) until they regard this
1300 // region as the current region, meaning that a close sent before then will fail the teleport.
1301// System.Threading.Thread.Sleep(2000);
1302
1303 m_log.DebugFormat(
1304 "[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}",
1305 client.Name, client.AgentId, m_callbackURI);
1306
1290 Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI); 1307 Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI);
1291 m_callbackURI = null; 1308 m_callbackURI = null;
1292 } 1309 }
1310// else
1311// {
1312// m_log.DebugFormat(
1313// "[SCENE PRESENCE]: No callback provided on CompleteMovement of {0} {1} to {2}",
1314// client.Name, client.AgentId, m_scene.RegionInfo.RegionName);
1315// }
1293 1316
1294// m_log.DebugFormat("[SCENE PRESENCE] Completed movement");
1295
1296 ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
1297 ValidateAndSendAppearanceAndAgentData(); 1317 ValidateAndSendAppearanceAndAgentData();
1298 1318
1299 // Create child agents in neighbouring regions 1319 // Create child agents in neighbouring regions
@@ -1308,7 +1328,6 @@ namespace OpenSim.Region.Framework.Scenes
1308 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); 1328 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient);
1309 } 1329 }
1310 1330
1311
1312// m_log.DebugFormat( 1331// m_log.DebugFormat(
1313// "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", 1332// "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms",
1314// client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds); 1333// client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds);
@@ -1361,7 +1380,7 @@ namespace OpenSim.Region.Framework.Scenes
1361 { 1380 {
1362// m_log.DebugFormat( 1381// m_log.DebugFormat(
1363// "[SCENE PRESENCE]: In {0} received agent update from {1}, flags {2}", 1382// "[SCENE PRESENCE]: In {0} received agent update from {1}, flags {2}",
1364// Scene.RegionInfo.RegionName, remoteClient.Name, agentData.ControlFlags); 1383// Scene.RegionInfo.RegionName, remoteClient.Name, (AgentManager.ControlFlags)agentData.ControlFlags);
1365 1384
1366 if (IsChildAgent) 1385 if (IsChildAgent)
1367 { 1386 {
@@ -1471,14 +1490,8 @@ namespace OpenSim.Region.Framework.Scenes
1471 } 1490 }
1472 } 1491 }
1473 1492
1474 lock (scriptedcontrols) 1493 uint flagsForScripts = (uint)flags;
1475 { 1494 flags = RemoveIgnoredControls(flags, IgnoredControls);
1476 if (scriptedcontrols.Count > 0)
1477 {
1478 SendControlToScripts((uint)flags);
1479 flags = RemoveIgnoredControls(flags, IgnoredControls);
1480 }
1481 }
1482 1495
1483 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1496 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1484 HandleAgentSitOnGround(); 1497 HandleAgentSitOnGround();
@@ -1492,6 +1505,7 @@ namespace OpenSim.Region.Framework.Scenes
1492 PhysicsActor actor = PhysicsActor; 1505 PhysicsActor actor = PhysicsActor;
1493 if (actor == null) 1506 if (actor == null)
1494 { 1507 {
1508 SendControlsToScripts(flagsForScripts);
1495 return; 1509 return;
1496 } 1510 }
1497 1511
@@ -1571,7 +1585,7 @@ namespace OpenSim.Region.Framework.Scenes
1571 MovementFlag |= (byte)nudgehack; 1585 MovementFlag |= (byte)nudgehack;
1572 } 1586 }
1573 1587
1574// m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with {1}", Name, DCF); 1588 //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with {1}", Name, DCF);
1575 MovementFlag += (byte)(uint)DCF; 1589 MovementFlag += (byte)(uint)DCF;
1576 update_movementflag = true; 1590 update_movementflag = true;
1577 } 1591 }
@@ -1584,7 +1598,7 @@ namespace OpenSim.Region.Framework.Scenes
1584 && ((MovementFlag & (byte)nudgehack) == nudgehack)) 1598 && ((MovementFlag & (byte)nudgehack) == nudgehack))
1585 ) // This or is for Nudge forward 1599 ) // This or is for Nudge forward
1586 { 1600 {
1587// m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with lack of {1}", Name, DCF); 1601 //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with lack of {1}", Name, DCF);
1588 MovementFlag -= ((byte)(uint)DCF); 1602 MovementFlag -= ((byte)(uint)DCF);
1589 update_movementflag = true; 1603 update_movementflag = true;
1590 1604
@@ -1665,11 +1679,14 @@ namespace OpenSim.Region.Framework.Scenes
1665// } 1679// }
1666// } 1680// }
1667 1681
1668// if (update_movementflag && ParentID == 0) 1682 if (update_movementflag && ParentID == 0)
1669// Animator.UpdateMovementAnimations(); 1683 Animator.UpdateMovementAnimations();
1684
1685 SendControlsToScripts(flagsForScripts);
1670 } 1686 }
1671 1687
1672 m_scene.EventManager.TriggerOnClientMovement(this); 1688 m_scene.EventManager.TriggerOnClientMovement(this);
1689 TriggerScenePresenceUpdated();
1673 } 1690 }
1674 1691
1675 /// <summary> 1692 /// <summary>
@@ -1929,10 +1946,6 @@ namespace OpenSim.Region.Framework.Scenes
1929 } 1946 }
1930 } 1947 }
1931 1948
1932 // Reset sit target.
1933 if (part.SitTargetAvatar == UUID)
1934 part.SitTargetAvatar = UUID.Zero;
1935
1936 part.ParentGroup.DeleteAvatar(UUID); 1949 part.ParentGroup.DeleteAvatar(UUID);
1937// ParentPosition = part.GetWorldPosition(); 1950// ParentPosition = part.GetWorldPosition();
1938 ControllingClient.SendClearFollowCamProperties(part.ParentUUID); 1951 ControllingClient.SendClearFollowCamProperties(part.ParentUUID);
@@ -1950,6 +1963,8 @@ namespace OpenSim.Region.Framework.Scenes
1950 SendAvatarDataToAllAgents(); 1963 SendAvatarDataToAllAgents();
1951 m_requestedSitTargetID = 0; 1964 m_requestedSitTargetID = 0;
1952 1965
1966 part.RemoveSittingAvatar(UUID);
1967
1953 if (part != null) 1968 if (part != null)
1954 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK); 1969 part.ParentGroup.TriggerScriptChangedEvent(Changed.LINK);
1955 } 1970 }
@@ -1983,15 +1998,7 @@ namespace OpenSim.Region.Framework.Scenes
1983 //look for prims with explicit sit targets that are available 1998 //look for prims with explicit sit targets that are available
1984 foreach (SceneObjectPart part in partArray) 1999 foreach (SceneObjectPart part in partArray)
1985 { 2000 {
1986 // Is a sit target available? 2001 if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero)
1987 Vector3 avSitOffset = part.SitTargetPosition;
1988 Quaternion avSitOrientation = part.SitTargetOrientation;
1989 UUID avOnTargetAlready = part.SitTargetAvatar;
1990
1991 bool SitTargetUnOccupied = avOnTargetAlready == UUID.Zero;
1992 bool SitTargetisSet = avSitOffset != Vector3.Zero || avSitOrientation != Quaternion.Identity;
1993
1994 if (SitTargetisSet && SitTargetUnOccupied)
1995 { 2002 {
1996 //switch the target to this prim 2003 //switch the target to this prim
1997 return part; 2004 return part;
@@ -2002,10 +2009,8 @@ namespace OpenSim.Region.Framework.Scenes
2002 return targetPart; 2009 return targetPart;
2003 } 2010 }
2004 2011
2005 private void SendSitResponse(UUID targetID, Vector3 offset, Quaternion pSitOrientation) 2012 private void SendSitResponse(UUID targetID, Vector3 offset, Quaternion sitOrientation)
2006 { 2013 {
2007 Vector3 pos = new Vector3();
2008 Quaternion sitOrientation = pSitOrientation;
2009 Vector3 cameraEyeOffset = Vector3.Zero; 2014 Vector3 cameraEyeOffset = Vector3.Zero;
2010 Vector3 cameraAtOffset = Vector3.Zero; 2015 Vector3 cameraAtOffset = Vector3.Zero;
2011 bool forceMouselook = false; 2016 bool forceMouselook = false;
@@ -2017,54 +2022,39 @@ namespace OpenSim.Region.Framework.Scenes
2017 // TODO: determine position to sit at based on scene geometry; don't trust offset from client 2022 // TODO: determine position to sit at based on scene geometry; don't trust offset from client
2018 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it 2023 // see http://wiki.secondlife.com/wiki/User:Andrew_Linden/Office_Hours/2007_11_06 for details on how LL does it
2019 2024
2020 // Is a sit target available?
2021 Vector3 avSitOffSet = part.SitTargetPosition;
2022 Quaternion avSitOrientation = part.SitTargetOrientation;
2023 UUID avOnTargetAlready = part.SitTargetAvatar;
2024
2025 bool SitTargetUnOccupied = (!(avOnTargetAlready != UUID.Zero));
2026 bool SitTargetisSet =
2027 (!(avSitOffSet == Vector3.Zero &&
2028 (
2029 avSitOrientation == Quaternion.Identity // Valid Zero Rotation quaternion
2030 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 1f && avSitOrientation.W == 0f // W-Z Mapping was invalid at one point
2031 || avSitOrientation.X == 0f && avSitOrientation.Y == 0f && avSitOrientation.Z == 0f && avSitOrientation.W == 0f // Invalid Quaternion
2032 )
2033 ));
2034
2035// m_log.DebugFormat("[SCENE PRESENCE]: {0} {1}", SitTargetisSet, SitTargetUnOccupied);
2036
2037 if (PhysicsActor != null) 2025 if (PhysicsActor != null)
2038 m_sitAvatarHeight = PhysicsActor.Size.Z * 0.5f; 2026 m_sitAvatarHeight = PhysicsActor.Size.Z * 0.5f;
2039 2027
2040 bool canSit = false; 2028 bool canSit = false;
2041 pos = part.AbsolutePosition + offset; 2029 Vector3 pos = part.AbsolutePosition + offset;
2042 2030
2043 if (SitTargetisSet) 2031 if (part.IsSitTargetSet && part.SitTargetAvatar == UUID.Zero)
2044 { 2032 {
2045 if (SitTargetUnOccupied) 2033// m_log.DebugFormat(
2046 { 2034// "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is set and unoccupied",
2047 m_log.DebugFormat( 2035// Name, part.Name, part.LocalId);
2048 "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is set and unoccupied",
2049 Name, part.Name, part.LocalId);
2050 2036
2051 part.SitTargetAvatar = UUID; 2037 offset = part.SitTargetPosition;
2052 offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); 2038 sitOrientation = part.SitTargetOrientation;
2053 sitOrientation = avSitOrientation; 2039 canSit = true;
2054 canSit = true;
2055 }
2056 } 2040 }
2057 else 2041 else
2058 { 2042 {
2059 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10) 2043 if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10)
2060 { 2044 {
2061 m_log.DebugFormat( 2045// m_log.DebugFormat(
2062 "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is unset and within 10m", 2046// "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is unset and within 10m",
2063 Name, part.Name, part.LocalId); 2047// Name, part.Name, part.LocalId);
2064 2048
2065 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); 2049 AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight);
2066 canSit = true; 2050 canSit = true;
2067 } 2051 }
2052// else
2053// {
2054// m_log.DebugFormat(
2055// "[SCENE PRESENCE]: Ignoring sit request of {0} on {1} {2} because sit target is unset and outside 10m",
2056// Name, part.Name, part.LocalId);
2057// }
2068 } 2058 }
2069 2059
2070 if (canSit) 2060 if (canSit)
@@ -2075,6 +2065,8 @@ namespace OpenSim.Region.Framework.Scenes
2075 RemoveFromPhysicalScene(); 2065 RemoveFromPhysicalScene();
2076 } 2066 }
2077 2067
2068 part.AddSittingAvatar(UUID);
2069
2078 cameraAtOffset = part.GetCameraAtOffset(); 2070 cameraAtOffset = part.GetCameraAtOffset();
2079 cameraEyeOffset = part.GetCameraEyeOffset(); 2071 cameraEyeOffset = part.GetCameraEyeOffset();
2080 forceMouselook = part.GetForceMouselook(); 2072 forceMouselook = part.GetForceMouselook();
@@ -2351,6 +2343,15 @@ namespace OpenSim.Region.Framework.Scenes
2351 2343
2352 if (part != null) 2344 if (part != null)
2353 { 2345 {
2346 if (part.ParentGroup.IsAttachment)
2347 {
2348 m_log.WarnFormat(
2349 "[SCENE PRESENCE]: Avatar {0} tried to sit on part {1} from object {2} in {3} but this is an attachment for avatar id {4}",
2350 Name, part.Name, part.ParentGroup.Name, Scene.Name, part.ParentGroup.AttachedAvatar);
2351
2352 return;
2353 }
2354
2354 if (part.SitTargetAvatar == UUID) 2355 if (part.SitTargetAvatar == UUID)
2355 { 2356 {
2356 Vector3 sitTargetPos = part.SitTargetPosition; 2357 Vector3 sitTargetPos = part.SitTargetPosition;
@@ -2616,6 +2617,7 @@ namespace OpenSim.Region.Framework.Scenes
2616 2617
2617 m_scene.ForEachClient(SendTerseUpdateToClient); 2618 m_scene.ForEachClient(SendTerseUpdateToClient);
2618 } 2619 }
2620 TriggerScenePresenceUpdated();
2619 } 2621 }
2620 2622
2621 public void SendCoarseLocations(List<Vector3> coarseLocations, List<UUID> avatarUUIDs) 2623 public void SendCoarseLocations(List<Vector3> coarseLocations, List<UUID> avatarUUIDs)
@@ -2694,7 +2696,7 @@ namespace OpenSim.Region.Framework.Scenes
2694 // If we are using the the cached appearance then send it out to everyone 2696 // If we are using the the cached appearance then send it out to everyone
2695 if (cachedappearance) 2697 if (cachedappearance)
2696 { 2698 {
2697 m_log.DebugFormat("[SCENEPRESENCE]: baked textures are in the cache for {0}", Name); 2699 m_log.DebugFormat("[SCENE PRESENCE]: baked textures are in the cache for {0}", Name);
2698 2700
2699 // If the avatars baked textures are all in the cache, then we have a 2701 // If the avatars baked textures are all in the cache, then we have a
2700 // complete appearance... send it out, if not, then we'll send it when 2702 // complete appearance... send it out, if not, then we'll send it when
@@ -3099,8 +3101,8 @@ namespace OpenSim.Region.Framework.Scenes
3099 x = x / Constants.RegionSize; 3101 x = x / Constants.RegionSize;
3100 y = y / Constants.RegionSize; 3102 y = y / Constants.RegionSize;
3101 3103
3102 //m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX))); 3104// m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX)));
3103 //m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY))); 3105// m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY)));
3104 if (Util.IsOutsideView(DrawDistance, x, newRegionX, y, newRegionY)) 3106 if (Util.IsOutsideView(DrawDistance, x, newRegionX, y, newRegionY))
3105 { 3107 {
3106 byebyeRegions.Add(handle); 3108 byebyeRegions.Add(handle);
@@ -3157,7 +3159,7 @@ namespace OpenSim.Region.Framework.Scenes
3157 3159
3158 public void ChildAgentDataUpdate(AgentData cAgentData) 3160 public void ChildAgentDataUpdate(AgentData cAgentData)
3159 { 3161 {
3160 //m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName); 3162// m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName);
3161 if (!IsChildAgent) 3163 if (!IsChildAgent)
3162 return; 3164 return;
3163 3165
@@ -3269,31 +3271,8 @@ namespace OpenSim.Region.Framework.Scenes
3269 catch { } 3271 catch { }
3270 cAgent.DefaultAnim = Animator.Animations.DefaultAnimation; 3272 cAgent.DefaultAnim = Animator.Animations.DefaultAnimation;
3271 3273
3272 // Attachment objects 3274 if (Scene.AttachmentsModule != null)
3273 List<SceneObjectGroup> attachments = GetAttachments(); 3275 Scene.AttachmentsModule.CopyAttachments(this, cAgent);
3274 if (attachments.Count > 0)
3275 {
3276 cAgent.AttachmentObjects = new List<ISceneObject>();
3277 cAgent.AttachmentObjectStates = new List<string>();
3278// IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>();
3279 InTransitScriptStates.Clear();
3280
3281 foreach (SceneObjectGroup sog in attachments)
3282 {
3283 // We need to make a copy and pass that copy
3284 // because of transfers withn the same sim
3285 ISceneObject clone = sog.CloneForNewScene();
3286 // Attachment module assumes that GroupPosition holds the offsets...!
3287 ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos;
3288 ((SceneObjectGroup)clone).IsAttachment = false;
3289 cAgent.AttachmentObjects.Add(clone);
3290 string state = sog.GetStateSnapshot();
3291 cAgent.AttachmentObjectStates.Add(state);
3292 InTransitScriptStates.Add(state);
3293 // Let's remove the scripts of the original object here
3294 sog.RemoveScriptInstances(true);
3295 }
3296 }
3297 } 3276 }
3298 3277
3299 private void CopyFrom(AgentData cAgent) 3278 private void CopyFrom(AgentData cAgent)
@@ -3301,6 +3280,9 @@ namespace OpenSim.Region.Framework.Scenes
3301 m_originRegionID = cAgent.RegionID; 3280 m_originRegionID = cAgent.RegionID;
3302 3281
3303 m_callbackURI = cAgent.CallbackURI; 3282 m_callbackURI = cAgent.CallbackURI;
3283// m_log.DebugFormat(
3284// "[SCENE PRESENCE]: Set callback for {0} in {1} to {2} in CopyFrom()",
3285// Name, m_scene.RegionInfo.RegionName, m_callbackURI);
3304 3286
3305 m_pos = cAgent.Position; 3287 m_pos = cAgent.Position;
3306 m_velocity = cAgent.Velocity; 3288 m_velocity = cAgent.Velocity;
@@ -3365,18 +3347,8 @@ namespace OpenSim.Region.Framework.Scenes
3365 if (cAgent.DefaultAnim != null) 3347 if (cAgent.DefaultAnim != null)
3366 Animator.Animations.SetDefaultAnimation(cAgent.DefaultAnim.AnimID, cAgent.DefaultAnim.SequenceNum, UUID.Zero); 3348 Animator.Animations.SetDefaultAnimation(cAgent.DefaultAnim.AnimID, cAgent.DefaultAnim.SequenceNum, UUID.Zero);
3367 3349
3368 if (cAgent.AttachmentObjects != null && cAgent.AttachmentObjects.Count > 0) 3350 if (Scene.AttachmentsModule != null)
3369 { 3351 Scene.AttachmentsModule.CopyAttachments(cAgent, this);
3370 m_attachments = new List<SceneObjectGroup>();
3371 int i = 0;
3372 foreach (ISceneObject so in cAgent.AttachmentObjects)
3373 {
3374 ((SceneObjectGroup)so).LocalId = 0;
3375 ((SceneObjectGroup)so).RootPart.ClearUpdateSchedule();
3376 so.SetState(cAgent.AttachmentObjectStates[i++], m_scene);
3377 m_scene.IncomingCreateObject(Vector3.Zero, so);
3378 }
3379 }
3380 } 3352 }
3381 3353
3382 public bool CopyAgent(out IAgentData agent) 3354 public bool CopyAgent(out IAgentData agent)
@@ -3402,6 +3374,7 @@ namespace OpenSim.Region.Framework.Scenes
3402 Velocity = force; 3374 Velocity = force;
3403 3375
3404 m_forceToApply = null; 3376 m_forceToApply = null;
3377 TriggerScenePresenceUpdated();
3405 } 3378 }
3406 } 3379 }
3407 3380
@@ -3509,23 +3482,53 @@ namespace OpenSim.Region.Framework.Scenes
3509 3482
3510 RaiseCollisionScriptEvents(coldata); 3483 RaiseCollisionScriptEvents(coldata);
3511 3484
3512 if (Invulnerable || GodLevel >= 200) 3485 // Gods do not take damage and Invulnerable is set depending on parcel/region flags
3486 if (Invulnerable || GodLevel > 0)
3513 return; 3487 return;
3514 3488
3489 // The following may be better in the ICombatModule
3490 // probably tweaking of the values for ground and normal prim collisions will be needed
3515 float starthealth = Health; 3491 float starthealth = Health;
3516 uint killerObj = 0; 3492 uint killerObj = 0;
3493 SceneObjectPart part = null;
3517 foreach (uint localid in coldata.Keys) 3494 foreach (uint localid in coldata.Keys)
3518 { 3495 {
3519 SceneObjectPart part = Scene.GetSceneObjectPart(localid); 3496 if (localid == 0)
3520 3497 {
3521 if (part != null && part.ParentGroup.Damage != -1.0f) 3498 part = null;
3522 Health -= part.ParentGroup.Damage; 3499 }
3500 else
3501 {
3502 part = Scene.GetSceneObjectPart(localid);
3503 }
3504 if (part != null)
3505 {
3506 // Ignore if it has been deleted or volume detect
3507 if (!part.ParentGroup.IsDeleted && !part.ParentGroup.IsVolumeDetect)
3508 {
3509 if (part.ParentGroup.Damage > 0.0f)
3510 {
3511 // Something with damage...
3512 Health -= part.ParentGroup.Damage;
3513 part.ParentGroup.Scene.DeleteSceneObject(part.ParentGroup, false);
3514 }
3515 else
3516 {
3517 // An ordinary prim
3518 if (coldata[localid].PenetrationDepth >= 0.10f)
3519 Health -= coldata[localid].PenetrationDepth * 5.0f;
3520 }
3521 }
3522 }
3523 else 3523 else
3524 { 3524 {
3525 if (coldata[localid].PenetrationDepth >= 0.10f) 3525 // 0 is the ground
3526 // what about collisions with other avatars?
3527 if (localid == 0 && coldata[localid].PenetrationDepth >= 0.10f)
3526 Health -= coldata[localid].PenetrationDepth * 5.0f; 3528 Health -= coldata[localid].PenetrationDepth * 5.0f;
3527 } 3529 }
3528 3530
3531
3529 if (Health <= 0.0f) 3532 if (Health <= 0.0f)
3530 { 3533 {
3531 if (localid != 0) 3534 if (localid != 0)
@@ -3541,7 +3544,16 @@ namespace OpenSim.Region.Framework.Scenes
3541 ControllingClient.SendHealth(Health); 3544 ControllingClient.SendHealth(Health);
3542 } 3545 }
3543 if (Health <= 0) 3546 if (Health <= 0)
3547 {
3544 m_scene.EventManager.TriggerAvatarKill(killerObj, this); 3548 m_scene.EventManager.TriggerAvatarKill(killerObj, this);
3549 }
3550 if (starthealth == Health && Health < 100.0f)
3551 {
3552 Health += 0.03f;
3553 if (Health > 100.0f)
3554 Health = 100.0f;
3555 ControllingClient.SendHealth(Health);
3556 }
3545 } 3557 }
3546 } 3558 }
3547 3559
@@ -3553,9 +3565,6 @@ namespace OpenSim.Region.Framework.Scenes
3553 3565
3554 public void Close() 3566 public void Close()
3555 { 3567 {
3556 if (!IsChildAgent)
3557 m_scene.AttachmentsModule.DeleteAttachmentsFromScene(this, false);
3558
3559 // Clear known regions 3568 // Clear known regions
3560 KnownRegions = new Dictionary<ulong, string>(); 3569 KnownRegions = new Dictionary<ulong, string>();
3561 3570
@@ -3624,6 +3633,63 @@ namespace OpenSim.Region.Framework.Scenes
3624 return m_attachments.Count > 0; 3633 return m_attachments.Count > 0;
3625 } 3634 }
3626 3635
3636 /// <summary>
3637 /// Returns the total count of scripts in all parts inventories.
3638 /// </summary>
3639 public int ScriptCount()
3640 {
3641 int count = 0;
3642 lock (m_attachments)
3643 {
3644 foreach (SceneObjectGroup gobj in m_attachments)
3645 {
3646 if (gobj != null)
3647 {
3648 count += gobj.ScriptCount();
3649 }
3650 }
3651 }
3652 return count;
3653 }
3654
3655 /// <summary>
3656 /// A float the value is a representative execution time in milliseconds of all scripts in all attachments.
3657 /// </summary>
3658 public float ScriptExecutionTime()
3659 {
3660 float time = 0.0f;
3661 lock (m_attachments)
3662 {
3663 foreach (SceneObjectGroup gobj in m_attachments)
3664 {
3665 if (gobj != null)
3666 {
3667 time += gobj.ScriptExecutionTime();
3668 }
3669 }
3670 }
3671 return time;
3672 }
3673
3674 /// <summary>
3675 /// Returns the total count of running scripts in all parts.
3676 /// </summary>
3677 public int RunningScriptCount()
3678 {
3679 int count = 0;
3680 lock (m_attachments)
3681 {
3682 foreach (SceneObjectGroup gobj in m_attachments)
3683 {
3684 if (gobj != null)
3685 {
3686 count += gobj.RunningScriptCount();
3687 }
3688 }
3689 }
3690 return count;
3691 }
3692
3627 public bool HasScriptedAttachments() 3693 public bool HasScriptedAttachments()
3628 { 3694 {
3629 lock (m_attachments) 3695 lock (m_attachments)
@@ -3841,77 +3907,92 @@ namespace OpenSim.Region.Framework.Scenes
3841 } 3907 }
3842 } 3908 }
3843 3909
3844 internal void SendControlToScripts(uint flags) 3910 private void SendControlsToScripts(uint flags)
3845 { 3911 {
3846 ScriptControlled allflags = ScriptControlled.CONTROL_ZERO; 3912 // Notify the scripts only after calling UpdateMovementAnimations(), so that if a script
3847 3913 // (e.g., a walking script) checks which animation is active it will be the correct animation.
3848 if (MouseDown) 3914 lock (scriptedcontrols)
3849 { 3915 {
3850 allflags = LastCommands & (ScriptControlled.CONTROL_ML_LBUTTON | ScriptControlled.CONTROL_LBUTTON); 3916 if (scriptedcontrols.Count <= 0)
3851 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP) != 0 || (flags & unchecked((uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_UP)) != 0) 3917 return;
3918
3919 ScriptControlled allflags = ScriptControlled.CONTROL_ZERO;
3920
3921 if (MouseDown)
3852 { 3922 {
3853 allflags = ScriptControlled.CONTROL_ZERO; 3923 allflags = LastCommands & (ScriptControlled.CONTROL_ML_LBUTTON | ScriptControlled.CONTROL_LBUTTON);
3924 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP) != 0 || (flags & unchecked((uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_UP)) != 0)
3925 {
3926 allflags = ScriptControlled.CONTROL_ZERO;
3927 MouseDown = true;
3928 }
3929 }
3930
3931 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN) != 0)
3932 {
3933 allflags |= ScriptControlled.CONTROL_ML_LBUTTON;
3854 MouseDown = true; 3934 MouseDown = true;
3855 } 3935 }
3856 } 3936
3937 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0)
3938 {
3939 allflags |= ScriptControlled.CONTROL_LBUTTON;
3940 MouseDown = true;
3941 }
3942
3943 // find all activated controls, whether the scripts are interested in them or not
3944 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) != 0)
3945 {
3946 allflags |= ScriptControlled.CONTROL_FWD;
3947 }
3948
3949 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) != 0)
3950 {
3951 allflags |= ScriptControlled.CONTROL_BACK;
3952 }
3953
3954 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS) != 0)
3955 {
3956 allflags |= ScriptControlled.CONTROL_UP;
3957 }
3958
3959 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)
3960 {
3961 allflags |= ScriptControlled.CONTROL_DOWN;
3962 }
3857 3963
3858 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN) != 0) 3964 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) != 0)
3859 { 3965 {
3860 allflags |= ScriptControlled.CONTROL_ML_LBUTTON; 3966 allflags |= ScriptControlled.CONTROL_LEFT;
3861 MouseDown = true; 3967 }
3862 } 3968
3863 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0) 3969 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) != 0)
3864 { 3970 {
3865 allflags |= ScriptControlled.CONTROL_LBUTTON; 3971 allflags |= ScriptControlled.CONTROL_RIGHT;
3866 MouseDown = true; 3972 }
3867 } 3973
3974 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0)
3975 {
3976 allflags |= ScriptControlled.CONTROL_ROT_RIGHT;
3977 }
3978
3979 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0)
3980 {
3981 allflags |= ScriptControlled.CONTROL_ROT_LEFT;
3982 }
3868 3983
3869 // find all activated controls, whether the scripts are interested in them or not 3984 // optimization; we have to check per script, but if nothing is pressed and nothing changed, we can skip that
3870 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) != 0) 3985 if (allflags != ScriptControlled.CONTROL_ZERO || allflags != LastCommands)
3871 {
3872 allflags |= ScriptControlled.CONTROL_FWD;
3873 }
3874 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) != 0)
3875 {
3876 allflags |= ScriptControlled.CONTROL_BACK;
3877 }
3878 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS) != 0)
3879 {
3880 allflags |= ScriptControlled.CONTROL_UP;
3881 }
3882 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)
3883 {
3884 allflags |= ScriptControlled.CONTROL_DOWN;
3885 }
3886 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) != 0)
3887 {
3888 allflags |= ScriptControlled.CONTROL_LEFT;
3889 }
3890 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) != 0)
3891 {
3892 allflags |= ScriptControlled.CONTROL_RIGHT;
3893 }
3894 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0)
3895 {
3896 allflags |= ScriptControlled.CONTROL_ROT_RIGHT;
3897 }
3898 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0)
3899 {
3900 allflags |= ScriptControlled.CONTROL_ROT_LEFT;
3901 }
3902 // optimization; we have to check per script, but if nothing is pressed and nothing changed, we can skip that
3903 if (allflags != ScriptControlled.CONTROL_ZERO || allflags != LastCommands)
3904 {
3905 lock (scriptedcontrols)
3906 { 3986 {
3907 foreach (KeyValuePair<UUID, ScriptControllers> kvp in scriptedcontrols) 3987 foreach (KeyValuePair<UUID, ScriptControllers> kvp in scriptedcontrols)
3908 { 3988 {
3909 UUID scriptUUID = kvp.Key; 3989 UUID scriptUUID = kvp.Key;
3910 ScriptControllers scriptControlData = kvp.Value; 3990 ScriptControllers scriptControlData = kvp.Value;
3911 3991
3912 ScriptControlled localHeld = allflags & scriptControlData.eventControls; // the flags interesting for us 3992 ScriptControlled localHeld = allflags & scriptControlData.eventControls; // the flags interesting for us
3913 ScriptControlled localLast = LastCommands & scriptControlData.eventControls; // the activated controls in the last cycle 3993 ScriptControlled localLast = LastCommands & scriptControlData.eventControls; // the activated controls in the last cycle
3914 ScriptControlled localChange = localHeld ^ localLast; // the changed bits 3994 ScriptControlled localChange = localHeld ^ localLast; // the changed bits
3995
3915 if (localHeld != ScriptControlled.CONTROL_ZERO || localChange != ScriptControlled.CONTROL_ZERO) 3996 if (localHeld != ScriptControlled.CONTROL_ZERO || localChange != ScriptControlled.CONTROL_ZERO)
3916 { 3997 {
3917 // only send if still pressed or just changed 3998 // only send if still pressed or just changed
@@ -3919,9 +4000,9 @@ namespace OpenSim.Region.Framework.Scenes
3919 } 4000 }
3920 } 4001 }
3921 } 4002 }
4003
4004 LastCommands = allflags;
3922 } 4005 }
3923
3924 LastCommands = allflags;
3925 } 4006 }
3926 4007
3927 internal static AgentManager.ControlFlags RemoveIgnoredControls(AgentManager.ControlFlags flags, ScriptControlled ignored) 4008 internal static AgentManager.ControlFlags RemoveIgnoredControls(AgentManager.ControlFlags flags, ScriptControlled ignored)
@@ -4001,7 +4082,7 @@ namespace OpenSim.Region.Framework.Scenes
4001 land.LandData.UserLocation != Vector3.Zero && 4082 land.LandData.UserLocation != Vector3.Zero &&
4002 land.LandData.OwnerID != m_uuid && 4083 land.LandData.OwnerID != m_uuid &&
4003 (!m_scene.Permissions.IsGod(m_uuid)) && 4084 (!m_scene.Permissions.IsGod(m_uuid)) &&
4004 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid))) 4085 (!m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)))
4005 { 4086 {
4006 float curr = Vector3.Distance(AbsolutePosition, pos); 4087 float curr = Vector3.Distance(AbsolutePosition, pos);
4007 if (Vector3.Distance(land.LandData.UserLocation, pos) < curr) 4088 if (Vector3.Distance(land.LandData.UserLocation, pos) < curr)
@@ -4015,13 +4096,13 @@ namespace OpenSim.Region.Framework.Scenes
4015 { 4096 {
4016 if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) == 4097 if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) ==
4017 (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) || 4098 (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) ||
4018 (m_teleportFlags & TeleportFlags.ViaLandmark) != 0 || 4099 (m_scene.TelehubAllowLandmarks == true ? false : ((m_teleportFlags & TeleportFlags.ViaLandmark) != 0 )) ||
4019 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || 4100 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 ||
4020 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0) 4101 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0)
4021 { 4102 {
4022 if (GodLevel < 200 && 4103 if (GodLevel < 200 &&
4023 ((!m_scene.Permissions.IsGod(m_uuid) && 4104 ((!m_scene.Permissions.IsGod(m_uuid) &&
4024 !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)) || 4105 !m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)) ||
4025 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || 4106 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 ||
4026 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0)) 4107 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0))
4027 { 4108 {
@@ -4029,28 +4110,92 @@ namespace OpenSim.Region.Framework.Scenes
4029 if (spawnPoints.Length == 0) 4110 if (spawnPoints.Length == 0)
4030 return; 4111 return;
4031 4112
4032 float distance = 9999; 4113 int index;
4033 int closest = -1; 4114 bool selected = false;
4034 4115
4035 for (int i = 0 ; i < spawnPoints.Length ; i++) 4116 switch (m_scene.SpawnPointRouting)
4036 { 4117 {
4037 Vector3 spawnPosition = spawnPoints[i].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); 4118 case "random":
4038 Vector3 offset = spawnPosition - pos;
4039 float d = Vector3.Mag(offset);
4040 if (d >= distance)
4041 continue;
4042 ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y);
4043 if (land == null)
4044 continue;
4045 if (land.IsEitherBannedOrRestricted(UUID))
4046 continue;
4047 distance = d;
4048 closest = i;
4049 }
4050 if (closest == -1)
4051 return;
4052 4119
4053 pos = spawnPoints[closest].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); 4120 do
4121 {
4122 index = Util.RandomClass.Next(spawnPoints.Length - 1);
4123
4124 Vector3 spawnPosition = spawnPoints[index].GetLocation(
4125 telehub.AbsolutePosition,
4126 telehub.GroupRotation
4127 );
4128 // SpawnPoint sp = spawnPoints[index];
4129
4130 ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y);
4131 if (land == null || land.IsEitherBannedOrRestricted(UUID))
4132 selected = false;
4133 else
4134 selected = true;
4135
4136 } while ( selected == false);
4137
4138 pos = spawnPoints[index].GetLocation(
4139 telehub.AbsolutePosition,
4140 telehub.GroupRotation
4141 );
4142 return;
4143
4144 case "sequence":
4145
4146 do
4147 {
4148 index = m_scene.SpawnPoint();
4149
4150 Vector3 spawnPosition = spawnPoints[index].GetLocation(
4151 telehub.AbsolutePosition,
4152 telehub.GroupRotation
4153 );
4154 // SpawnPoint sp = spawnPoints[index];
4155
4156 ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y);
4157 if (land == null || land.IsEitherBannedOrRestricted(UUID))
4158 selected = false;
4159 else
4160 selected = true;
4161
4162 } while (selected == false);
4163
4164 pos = spawnPoints[index].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation);
4165 ;
4166 return;
4167
4168 default:
4169 case "closest":
4170
4171 float distance = 9999;
4172 int closest = -1;
4173
4174 for (int i = 0; i < spawnPoints.Length; i++)
4175 {
4176 Vector3 spawnPosition = spawnPoints[i].GetLocation(
4177 telehub.AbsolutePosition,
4178 telehub.GroupRotation
4179 );
4180 Vector3 offset = spawnPosition - pos;
4181 float d = Vector3.Mag(offset);
4182 if (d >= distance)
4183 continue;
4184 ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y);
4185 if (land == null)
4186 continue;
4187 if (land.IsEitherBannedOrRestricted(UUID))
4188 continue;
4189 distance = d;
4190 closest = i;
4191 }
4192 if (closest == -1)
4193 return;
4194
4195 pos = spawnPoints[closest].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation);
4196 return;
4197
4198 }
4054 } 4199 }
4055 } 4200 }
4056 } 4201 }
@@ -4095,7 +4240,7 @@ namespace OpenSim.Region.Framework.Scenes
4095 GodLevel < 200 && 4240 GodLevel < 200 &&
4096 ((land.LandData.OwnerID != m_uuid && 4241 ((land.LandData.OwnerID != m_uuid &&
4097 !m_scene.Permissions.IsGod(m_uuid) && 4242 !m_scene.Permissions.IsGod(m_uuid) &&
4098 !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)) || 4243 !m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)) ||
4099 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || 4244 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 ||
4100 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0)) 4245 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0))
4101 { 4246 {