diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/ScenePresence.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 495 |
1 files changed, 325 insertions, 170 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 87b4d9f..159a92a 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 | ||
46 | namespace OpenSim.Region.Framework.Scenes | 46 | namespace 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 | ||
@@ -1086,23 +1094,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
1086 | /// <param name="pos"></param> | 1094 | /// <param name="pos"></param> |
1087 | public void Teleport(Vector3 pos) | 1095 | public void Teleport(Vector3 pos) |
1088 | { | 1096 | { |
1089 | bool isFlying = Flying; | 1097 | TeleportWithMomentum(pos, Vector3.Zero); |
1090 | RemoveFromPhysicalScene(); | ||
1091 | Velocity = Vector3.Zero; | ||
1092 | CheckLandingPoint(ref pos); | ||
1093 | AbsolutePosition = pos; | ||
1094 | AddToPhysicalScene(isFlying); | ||
1095 | |||
1096 | SendTerseUpdateToAllClients(); | ||
1097 | } | ||
1098 | |||
1099 | public void TeleportWithMomentum(Vector3 pos) | ||
1100 | { | ||
1101 | TeleportWithMomentum(pos, null); | ||
1102 | } | 1098 | } |
1103 | 1099 | ||
1104 | public void TeleportWithMomentum(Vector3 pos, Vector3? v) | 1100 | public void TeleportWithMomentum(Vector3 pos, Vector3? v) |
1105 | { | 1101 | { |
1102 | if (ParentID != (uint)0) | ||
1103 | StandUp(); | ||
1106 | bool isFlying = Flying; | 1104 | bool isFlying = Flying; |
1107 | Vector3 vel = Velocity; | 1105 | Vector3 vel = Velocity; |
1108 | RemoveFromPhysicalScene(); | 1106 | RemoveFromPhysicalScene(); |
@@ -1282,17 +1280,33 @@ namespace OpenSim.Region.Framework.Scenes | |||
1282 | 1280 | ||
1283 | bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); | 1281 | bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); |
1284 | MakeRootAgent(AbsolutePosition, flying); | 1282 | MakeRootAgent(AbsolutePosition, flying); |
1283 | ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); | ||
1284 | |||
1285 | // m_log.DebugFormat("[SCENE PRESENCE] Completed movement"); | ||
1285 | 1286 | ||
1286 | if ((m_callbackURI != null) && !m_callbackURI.Equals("")) | 1287 | if ((m_callbackURI != null) && !m_callbackURI.Equals("")) |
1287 | { | 1288 | { |
1288 | m_log.DebugFormat("[SCENE PRESENCE]: Releasing agent in URI {0}", m_callbackURI); | 1289 | // We cannot sleep here since this would hold up the inbound packet processing thread, as |
1290 | // CompleteMovement() is executed synchronously. However, it might be better to delay the release | ||
1291 | // here until we know for sure that the agent is active in this region. Sending AgentMovementComplete | ||
1292 | // is not enough for Imprudence clients - there appears to be a small delay (<200ms, <500ms) until they regard this | ||
1293 | // region as the current region, meaning that a close sent before then will fail the teleport. | ||
1294 | // System.Threading.Thread.Sleep(2000); | ||
1295 | |||
1296 | m_log.DebugFormat( | ||
1297 | "[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}", | ||
1298 | client.Name, client.AgentId, m_callbackURI); | ||
1299 | |||
1289 | Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI); | 1300 | Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI); |
1290 | m_callbackURI = null; | 1301 | m_callbackURI = null; |
1291 | } | 1302 | } |
1303 | // else | ||
1304 | // { | ||
1305 | // m_log.DebugFormat( | ||
1306 | // "[SCENE PRESENCE]: No callback provided on CompleteMovement of {0} {1} to {2}", | ||
1307 | // client.Name, client.AgentId, m_scene.RegionInfo.RegionName); | ||
1308 | // } | ||
1292 | 1309 | ||
1293 | // m_log.DebugFormat("[SCENE PRESENCE] Completed movement"); | ||
1294 | |||
1295 | ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look); | ||
1296 | ValidateAndSendAppearanceAndAgentData(); | 1310 | ValidateAndSendAppearanceAndAgentData(); |
1297 | 1311 | ||
1298 | // Create child agents in neighbouring regions | 1312 | // Create child agents in neighbouring regions |
@@ -1307,7 +1321,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
1307 | friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); | 1321 | friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); |
1308 | } | 1322 | } |
1309 | 1323 | ||
1310 | |||
1311 | // m_log.DebugFormat( | 1324 | // m_log.DebugFormat( |
1312 | // "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", | 1325 | // "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", |
1313 | // client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds); | 1326 | // client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds); |
@@ -1360,7 +1373,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1360 | { | 1373 | { |
1361 | // m_log.DebugFormat( | 1374 | // m_log.DebugFormat( |
1362 | // "[SCENE PRESENCE]: In {0} received agent update from {1}, flags {2}", | 1375 | // "[SCENE PRESENCE]: In {0} received agent update from {1}, flags {2}", |
1363 | // Scene.RegionInfo.RegionName, remoteClient.Name, agentData.ControlFlags); | 1376 | // Scene.RegionInfo.RegionName, remoteClient.Name, (AgentManager.ControlFlags)agentData.ControlFlags); |
1364 | 1377 | ||
1365 | if (IsChildAgent) | 1378 | if (IsChildAgent) |
1366 | { | 1379 | { |
@@ -1470,14 +1483,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
1470 | } | 1483 | } |
1471 | } | 1484 | } |
1472 | 1485 | ||
1473 | lock (scriptedcontrols) | 1486 | uint flagsForScripts = (uint)flags; |
1474 | { | 1487 | flags = RemoveIgnoredControls(flags, IgnoredControls); |
1475 | if (scriptedcontrols.Count > 0) | ||
1476 | { | ||
1477 | SendControlToScripts((uint)flags); | ||
1478 | flags = RemoveIgnoredControls(flags, IgnoredControls); | ||
1479 | } | ||
1480 | } | ||
1481 | 1488 | ||
1482 | if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) | 1489 | if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) |
1483 | HandleAgentSitOnGround(); | 1490 | HandleAgentSitOnGround(); |
@@ -1491,6 +1498,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1491 | PhysicsActor actor = PhysicsActor; | 1498 | PhysicsActor actor = PhysicsActor; |
1492 | if (actor == null) | 1499 | if (actor == null) |
1493 | { | 1500 | { |
1501 | SendControlsToScripts(flagsForScripts); | ||
1494 | return; | 1502 | return; |
1495 | } | 1503 | } |
1496 | 1504 | ||
@@ -1570,7 +1578,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1570 | MovementFlag |= (byte)nudgehack; | 1578 | MovementFlag |= (byte)nudgehack; |
1571 | } | 1579 | } |
1572 | 1580 | ||
1573 | // m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with {1}", Name, DCF); | 1581 | //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with {1}", Name, DCF); |
1574 | MovementFlag += (byte)(uint)DCF; | 1582 | MovementFlag += (byte)(uint)DCF; |
1575 | update_movementflag = true; | 1583 | update_movementflag = true; |
1576 | } | 1584 | } |
@@ -1583,7 +1591,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1583 | && ((MovementFlag & (byte)nudgehack) == nudgehack)) | 1591 | && ((MovementFlag & (byte)nudgehack) == nudgehack)) |
1584 | ) // This or is for Nudge forward | 1592 | ) // This or is for Nudge forward |
1585 | { | 1593 | { |
1586 | // m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with lack of {1}", Name, DCF); | 1594 | //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with lack of {1}", Name, DCF); |
1587 | MovementFlag -= ((byte)(uint)DCF); | 1595 | MovementFlag -= ((byte)(uint)DCF); |
1588 | update_movementflag = true; | 1596 | update_movementflag = true; |
1589 | 1597 | ||
@@ -1664,11 +1672,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
1664 | // } | 1672 | // } |
1665 | // } | 1673 | // } |
1666 | 1674 | ||
1667 | // if (update_movementflag && ParentID == 0) | 1675 | if (update_movementflag && ParentID == 0) |
1668 | // Animator.UpdateMovementAnimations(); | 1676 | Animator.UpdateMovementAnimations(); |
1677 | |||
1678 | SendControlsToScripts(flagsForScripts); | ||
1669 | } | 1679 | } |
1670 | 1680 | ||
1671 | m_scene.EventManager.TriggerOnClientMovement(this); | 1681 | m_scene.EventManager.TriggerOnClientMovement(this); |
1682 | TriggerScenePresenceUpdated(); | ||
1672 | } | 1683 | } |
1673 | 1684 | ||
1674 | /// <summary> | 1685 | /// <summary> |
@@ -2042,9 +2053,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2042 | { | 2053 | { |
2043 | if (SitTargetUnOccupied) | 2054 | if (SitTargetUnOccupied) |
2044 | { | 2055 | { |
2045 | m_log.DebugFormat( | 2056 | // m_log.DebugFormat( |
2046 | "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is set and unoccupied", | 2057 | // "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is set and unoccupied", |
2047 | Name, part.Name, part.LocalId); | 2058 | // Name, part.Name, part.LocalId); |
2048 | 2059 | ||
2049 | part.SitTargetAvatar = UUID; | 2060 | part.SitTargetAvatar = UUID; |
2050 | offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); | 2061 | offset = new Vector3(avSitOffSet.X, avSitOffSet.Y, avSitOffSet.Z); |
@@ -2056,9 +2067,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2056 | { | 2067 | { |
2057 | if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10) | 2068 | if (Util.GetDistanceTo(AbsolutePosition, pos) <= 10) |
2058 | { | 2069 | { |
2059 | m_log.DebugFormat( | 2070 | // m_log.DebugFormat( |
2060 | "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is unset and within 10m", | 2071 | // "[SCENE PRESENCE]: Sitting {0} on {1} {2} because sit target is unset and within 10m", |
2061 | Name, part.Name, part.LocalId); | 2072 | // Name, part.Name, part.LocalId); |
2062 | 2073 | ||
2063 | AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); | 2074 | AbsolutePosition = pos + new Vector3(0.0f, 0.0f, m_sitAvatarHeight); |
2064 | canSit = true; | 2075 | canSit = true; |
@@ -2614,6 +2625,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2614 | 2625 | ||
2615 | m_scene.ForEachClient(SendTerseUpdateToClient); | 2626 | m_scene.ForEachClient(SendTerseUpdateToClient); |
2616 | } | 2627 | } |
2628 | TriggerScenePresenceUpdated(); | ||
2617 | } | 2629 | } |
2618 | 2630 | ||
2619 | public void SendCoarseLocations(List<Vector3> coarseLocations, List<UUID> avatarUUIDs) | 2631 | public void SendCoarseLocations(List<Vector3> coarseLocations, List<UUID> avatarUUIDs) |
@@ -2692,7 +2704,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
2692 | // If we are using the the cached appearance then send it out to everyone | 2704 | // If we are using the the cached appearance then send it out to everyone |
2693 | if (cachedappearance) | 2705 | if (cachedappearance) |
2694 | { | 2706 | { |
2695 | m_log.DebugFormat("[SCENEPRESENCE]: baked textures are in the cache for {0}", Name); | 2707 | m_log.DebugFormat("[SCENE PRESENCE]: baked textures are in the cache for {0}", Name); |
2696 | 2708 | ||
2697 | // If the avatars baked textures are all in the cache, then we have a | 2709 | // If the avatars baked textures are all in the cache, then we have a |
2698 | // complete appearance... send it out, if not, then we'll send it when | 2710 | // complete appearance... send it out, if not, then we'll send it when |
@@ -3097,8 +3109,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3097 | x = x / Constants.RegionSize; | 3109 | x = x / Constants.RegionSize; |
3098 | y = y / Constants.RegionSize; | 3110 | y = y / Constants.RegionSize; |
3099 | 3111 | ||
3100 | //m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX))); | 3112 | // m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX))); |
3101 | //m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY))); | 3113 | // m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY))); |
3102 | if (Util.IsOutsideView(DrawDistance, x, newRegionX, y, newRegionY)) | 3114 | if (Util.IsOutsideView(DrawDistance, x, newRegionX, y, newRegionY)) |
3103 | { | 3115 | { |
3104 | byebyeRegions.Add(handle); | 3116 | byebyeRegions.Add(handle); |
@@ -3155,7 +3167,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3155 | 3167 | ||
3156 | public void ChildAgentDataUpdate(AgentData cAgentData) | 3168 | public void ChildAgentDataUpdate(AgentData cAgentData) |
3157 | { | 3169 | { |
3158 | //m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName); | 3170 | // m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName); |
3159 | if (!IsChildAgent) | 3171 | if (!IsChildAgent) |
3160 | return; | 3172 | return; |
3161 | 3173 | ||
@@ -3267,31 +3279,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3267 | catch { } | 3279 | catch { } |
3268 | cAgent.DefaultAnim = Animator.Animations.DefaultAnimation; | 3280 | cAgent.DefaultAnim = Animator.Animations.DefaultAnimation; |
3269 | 3281 | ||
3270 | // Attachment objects | 3282 | if (Scene.AttachmentsModule != null) |
3271 | List<SceneObjectGroup> attachments = GetAttachments(); | 3283 | Scene.AttachmentsModule.CopyAttachments(this, cAgent); |
3272 | if (attachments.Count > 0) | ||
3273 | { | ||
3274 | cAgent.AttachmentObjects = new List<ISceneObject>(); | ||
3275 | cAgent.AttachmentObjectStates = new List<string>(); | ||
3276 | // IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>(); | ||
3277 | InTransitScriptStates.Clear(); | ||
3278 | |||
3279 | foreach (SceneObjectGroup sog in attachments) | ||
3280 | { | ||
3281 | // We need to make a copy and pass that copy | ||
3282 | // because of transfers withn the same sim | ||
3283 | ISceneObject clone = sog.CloneForNewScene(); | ||
3284 | // Attachment module assumes that GroupPosition holds the offsets...! | ||
3285 | ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos; | ||
3286 | ((SceneObjectGroup)clone).IsAttachment = false; | ||
3287 | cAgent.AttachmentObjects.Add(clone); | ||
3288 | string state = sog.GetStateSnapshot(); | ||
3289 | cAgent.AttachmentObjectStates.Add(state); | ||
3290 | InTransitScriptStates.Add(state); | ||
3291 | // Let's remove the scripts of the original object here | ||
3292 | sog.RemoveScriptInstances(true); | ||
3293 | } | ||
3294 | } | ||
3295 | } | 3284 | } |
3296 | 3285 | ||
3297 | private void CopyFrom(AgentData cAgent) | 3286 | private void CopyFrom(AgentData cAgent) |
@@ -3299,6 +3288,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
3299 | m_originRegionID = cAgent.RegionID; | 3288 | m_originRegionID = cAgent.RegionID; |
3300 | 3289 | ||
3301 | m_callbackURI = cAgent.CallbackURI; | 3290 | m_callbackURI = cAgent.CallbackURI; |
3291 | // m_log.DebugFormat( | ||
3292 | // "[SCENE PRESENCE]: Set callback for {0} in {1} to {2} in CopyFrom()", | ||
3293 | // Name, m_scene.RegionInfo.RegionName, m_callbackURI); | ||
3302 | 3294 | ||
3303 | m_pos = cAgent.Position; | 3295 | m_pos = cAgent.Position; |
3304 | m_velocity = cAgent.Velocity; | 3296 | m_velocity = cAgent.Velocity; |
@@ -3363,18 +3355,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3363 | if (cAgent.DefaultAnim != null) | 3355 | if (cAgent.DefaultAnim != null) |
3364 | Animator.Animations.SetDefaultAnimation(cAgent.DefaultAnim.AnimID, cAgent.DefaultAnim.SequenceNum, UUID.Zero); | 3356 | Animator.Animations.SetDefaultAnimation(cAgent.DefaultAnim.AnimID, cAgent.DefaultAnim.SequenceNum, UUID.Zero); |
3365 | 3357 | ||
3366 | if (cAgent.AttachmentObjects != null && cAgent.AttachmentObjects.Count > 0) | 3358 | if (Scene.AttachmentsModule != null) |
3367 | { | 3359 | Scene.AttachmentsModule.CopyAttachments(cAgent, this); |
3368 | m_attachments = new List<SceneObjectGroup>(); | ||
3369 | int i = 0; | ||
3370 | foreach (ISceneObject so in cAgent.AttachmentObjects) | ||
3371 | { | ||
3372 | ((SceneObjectGroup)so).LocalId = 0; | ||
3373 | ((SceneObjectGroup)so).RootPart.ClearUpdateSchedule(); | ||
3374 | so.SetState(cAgent.AttachmentObjectStates[i++], m_scene); | ||
3375 | m_scene.IncomingCreateObject(Vector3.Zero, so); | ||
3376 | } | ||
3377 | } | ||
3378 | } | 3360 | } |
3379 | 3361 | ||
3380 | public bool CopyAgent(out IAgentData agent) | 3362 | public bool CopyAgent(out IAgentData agent) |
@@ -3400,6 +3382,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3400 | Velocity = force; | 3382 | Velocity = force; |
3401 | 3383 | ||
3402 | m_forceToApply = null; | 3384 | m_forceToApply = null; |
3385 | TriggerScenePresenceUpdated(); | ||
3403 | } | 3386 | } |
3404 | } | 3387 | } |
3405 | 3388 | ||
@@ -3507,23 +3490,53 @@ namespace OpenSim.Region.Framework.Scenes | |||
3507 | 3490 | ||
3508 | RaiseCollisionScriptEvents(coldata); | 3491 | RaiseCollisionScriptEvents(coldata); |
3509 | 3492 | ||
3510 | if (Invulnerable || GodLevel >= 200) | 3493 | // Gods do not take damage and Invulnerable is set depending on parcel/region flags |
3494 | if (Invulnerable || GodLevel > 0) | ||
3511 | return; | 3495 | return; |
3512 | 3496 | ||
3497 | // The following may be better in the ICombatModule | ||
3498 | // probably tweaking of the values for ground and normal prim collisions will be needed | ||
3513 | float starthealth = Health; | 3499 | float starthealth = Health; |
3514 | uint killerObj = 0; | 3500 | uint killerObj = 0; |
3501 | SceneObjectPart part = null; | ||
3515 | foreach (uint localid in coldata.Keys) | 3502 | foreach (uint localid in coldata.Keys) |
3516 | { | 3503 | { |
3517 | SceneObjectPart part = Scene.GetSceneObjectPart(localid); | 3504 | if (localid == 0) |
3518 | 3505 | { | |
3519 | if (part != null && part.ParentGroup.Damage != -1.0f) | 3506 | part = null; |
3520 | Health -= part.ParentGroup.Damage; | 3507 | } |
3508 | else | ||
3509 | { | ||
3510 | part = Scene.GetSceneObjectPart(localid); | ||
3511 | } | ||
3512 | if (part != null) | ||
3513 | { | ||
3514 | // Ignore if it has been deleted or volume detect | ||
3515 | if (!part.ParentGroup.IsDeleted && !part.ParentGroup.IsVolumeDetect) | ||
3516 | { | ||
3517 | if (part.ParentGroup.Damage > 0.0f) | ||
3518 | { | ||
3519 | // Something with damage... | ||
3520 | Health -= part.ParentGroup.Damage; | ||
3521 | part.ParentGroup.Scene.DeleteSceneObject(part.ParentGroup, false); | ||
3522 | } | ||
3523 | else | ||
3524 | { | ||
3525 | // An ordinary prim | ||
3526 | if (coldata[localid].PenetrationDepth >= 0.10f) | ||
3527 | Health -= coldata[localid].PenetrationDepth * 5.0f; | ||
3528 | } | ||
3529 | } | ||
3530 | } | ||
3521 | else | 3531 | else |
3522 | { | 3532 | { |
3523 | if (coldata[localid].PenetrationDepth >= 0.10f) | 3533 | // 0 is the ground |
3534 | // what about collisions with other avatars? | ||
3535 | if (localid == 0 && coldata[localid].PenetrationDepth >= 0.10f) | ||
3524 | Health -= coldata[localid].PenetrationDepth * 5.0f; | 3536 | Health -= coldata[localid].PenetrationDepth * 5.0f; |
3525 | } | 3537 | } |
3526 | 3538 | ||
3539 | |||
3527 | if (Health <= 0.0f) | 3540 | if (Health <= 0.0f) |
3528 | { | 3541 | { |
3529 | if (localid != 0) | 3542 | if (localid != 0) |
@@ -3539,7 +3552,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
3539 | ControllingClient.SendHealth(Health); | 3552 | ControllingClient.SendHealth(Health); |
3540 | } | 3553 | } |
3541 | if (Health <= 0) | 3554 | if (Health <= 0) |
3555 | { | ||
3542 | m_scene.EventManager.TriggerAvatarKill(killerObj, this); | 3556 | m_scene.EventManager.TriggerAvatarKill(killerObj, this); |
3557 | } | ||
3558 | if (starthealth == Health && Health < 100.0f) | ||
3559 | { | ||
3560 | Health += 0.03f; | ||
3561 | if (Health > 100.0f) | ||
3562 | Health = 100.0f; | ||
3563 | ControllingClient.SendHealth(Health); | ||
3564 | } | ||
3543 | } | 3565 | } |
3544 | } | 3566 | } |
3545 | 3567 | ||
@@ -3551,9 +3573,6 @@ namespace OpenSim.Region.Framework.Scenes | |||
3551 | 3573 | ||
3552 | public void Close() | 3574 | public void Close() |
3553 | { | 3575 | { |
3554 | if (!IsChildAgent) | ||
3555 | m_scene.AttachmentsModule.DeleteAttachmentsFromScene(this, false); | ||
3556 | |||
3557 | // Clear known regions | 3576 | // Clear known regions |
3558 | KnownRegions = new Dictionary<ulong, string>(); | 3577 | KnownRegions = new Dictionary<ulong, string>(); |
3559 | 3578 | ||
@@ -3621,6 +3640,63 @@ namespace OpenSim.Region.Framework.Scenes | |||
3621 | return m_attachments.Count > 0; | 3640 | return m_attachments.Count > 0; |
3622 | } | 3641 | } |
3623 | 3642 | ||
3643 | /// <summary> | ||
3644 | /// Returns the total count of scripts in all parts inventories. | ||
3645 | /// </summary> | ||
3646 | public int ScriptCount() | ||
3647 | { | ||
3648 | int count = 0; | ||
3649 | lock (m_attachments) | ||
3650 | { | ||
3651 | foreach (SceneObjectGroup gobj in m_attachments) | ||
3652 | { | ||
3653 | if (gobj != null) | ||
3654 | { | ||
3655 | count += gobj.ScriptCount(); | ||
3656 | } | ||
3657 | } | ||
3658 | } | ||
3659 | return count; | ||
3660 | } | ||
3661 | |||
3662 | /// <summary> | ||
3663 | /// A float the value is a representative execution time in milliseconds of all scripts in all attachments. | ||
3664 | /// </summary> | ||
3665 | public float ScriptExecutionTime() | ||
3666 | { | ||
3667 | float time = 0.0f; | ||
3668 | lock (m_attachments) | ||
3669 | { | ||
3670 | foreach (SceneObjectGroup gobj in m_attachments) | ||
3671 | { | ||
3672 | if (gobj != null) | ||
3673 | { | ||
3674 | time += gobj.ScriptExecutionTime(); | ||
3675 | } | ||
3676 | } | ||
3677 | } | ||
3678 | return time; | ||
3679 | } | ||
3680 | |||
3681 | /// <summary> | ||
3682 | /// Returns the total count of running scripts in all parts. | ||
3683 | /// </summary> | ||
3684 | public int RunningScriptCount() | ||
3685 | { | ||
3686 | int count = 0; | ||
3687 | lock (m_attachments) | ||
3688 | { | ||
3689 | foreach (SceneObjectGroup gobj in m_attachments) | ||
3690 | { | ||
3691 | if (gobj != null) | ||
3692 | { | ||
3693 | count += gobj.RunningScriptCount(); | ||
3694 | } | ||
3695 | } | ||
3696 | } | ||
3697 | return count; | ||
3698 | } | ||
3699 | |||
3624 | public bool HasScriptedAttachments() | 3700 | public bool HasScriptedAttachments() |
3625 | { | 3701 | { |
3626 | lock (m_attachments) | 3702 | lock (m_attachments) |
@@ -3838,77 +3914,92 @@ namespace OpenSim.Region.Framework.Scenes | |||
3838 | } | 3914 | } |
3839 | } | 3915 | } |
3840 | 3916 | ||
3841 | internal void SendControlToScripts(uint flags) | 3917 | private void SendControlsToScripts(uint flags) |
3842 | { | 3918 | { |
3843 | ScriptControlled allflags = ScriptControlled.CONTROL_ZERO; | 3919 | // Notify the scripts only after calling UpdateMovementAnimations(), so that if a script |
3844 | 3920 | // (e.g., a walking script) checks which animation is active it will be the correct animation. | |
3845 | if (MouseDown) | 3921 | lock (scriptedcontrols) |
3846 | { | 3922 | { |
3847 | allflags = LastCommands & (ScriptControlled.CONTROL_ML_LBUTTON | ScriptControlled.CONTROL_LBUTTON); | 3923 | if (scriptedcontrols.Count <= 0) |
3848 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP) != 0 || (flags & unchecked((uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_UP)) != 0) | 3924 | return; |
3925 | |||
3926 | ScriptControlled allflags = ScriptControlled.CONTROL_ZERO; | ||
3927 | |||
3928 | if (MouseDown) | ||
3929 | { | ||
3930 | allflags = LastCommands & (ScriptControlled.CONTROL_ML_LBUTTON | ScriptControlled.CONTROL_LBUTTON); | ||
3931 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP) != 0 || (flags & unchecked((uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_UP)) != 0) | ||
3932 | { | ||
3933 | allflags = ScriptControlled.CONTROL_ZERO; | ||
3934 | MouseDown = true; | ||
3935 | } | ||
3936 | } | ||
3937 | |||
3938 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN) != 0) | ||
3849 | { | 3939 | { |
3850 | allflags = ScriptControlled.CONTROL_ZERO; | 3940 | allflags |= ScriptControlled.CONTROL_ML_LBUTTON; |
3851 | MouseDown = true; | 3941 | MouseDown = true; |
3852 | } | 3942 | } |
3853 | } | 3943 | |
3944 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0) | ||
3945 | { | ||
3946 | allflags |= ScriptControlled.CONTROL_LBUTTON; | ||
3947 | MouseDown = true; | ||
3948 | } | ||
3949 | |||
3950 | // find all activated controls, whether the scripts are interested in them or not | ||
3951 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) != 0) | ||
3952 | { | ||
3953 | allflags |= ScriptControlled.CONTROL_FWD; | ||
3954 | } | ||
3955 | |||
3956 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) != 0) | ||
3957 | { | ||
3958 | allflags |= ScriptControlled.CONTROL_BACK; | ||
3959 | } | ||
3960 | |||
3961 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS) != 0) | ||
3962 | { | ||
3963 | allflags |= ScriptControlled.CONTROL_UP; | ||
3964 | } | ||
3965 | |||
3966 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0) | ||
3967 | { | ||
3968 | allflags |= ScriptControlled.CONTROL_DOWN; | ||
3969 | } | ||
3854 | 3970 | ||
3855 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN) != 0) | 3971 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) != 0) |
3856 | { | 3972 | { |
3857 | allflags |= ScriptControlled.CONTROL_ML_LBUTTON; | 3973 | allflags |= ScriptControlled.CONTROL_LEFT; |
3858 | MouseDown = true; | 3974 | } |
3859 | } | 3975 | |
3860 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0) | 3976 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) != 0) |
3861 | { | 3977 | { |
3862 | allflags |= ScriptControlled.CONTROL_LBUTTON; | 3978 | allflags |= ScriptControlled.CONTROL_RIGHT; |
3863 | MouseDown = true; | 3979 | } |
3864 | } | 3980 | |
3981 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0) | ||
3982 | { | ||
3983 | allflags |= ScriptControlled.CONTROL_ROT_RIGHT; | ||
3984 | } | ||
3985 | |||
3986 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0) | ||
3987 | { | ||
3988 | allflags |= ScriptControlled.CONTROL_ROT_LEFT; | ||
3989 | } | ||
3865 | 3990 | ||
3866 | // find all activated controls, whether the scripts are interested in them or not | 3991 | // optimization; we have to check per script, but if nothing is pressed and nothing changed, we can skip that |
3867 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) != 0) | 3992 | if (allflags != ScriptControlled.CONTROL_ZERO || allflags != LastCommands) |
3868 | { | ||
3869 | allflags |= ScriptControlled.CONTROL_FWD; | ||
3870 | } | ||
3871 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) != 0) | ||
3872 | { | ||
3873 | allflags |= ScriptControlled.CONTROL_BACK; | ||
3874 | } | ||
3875 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS) != 0) | ||
3876 | { | ||
3877 | allflags |= ScriptControlled.CONTROL_UP; | ||
3878 | } | ||
3879 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0) | ||
3880 | { | ||
3881 | allflags |= ScriptControlled.CONTROL_DOWN; | ||
3882 | } | ||
3883 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) != 0) | ||
3884 | { | ||
3885 | allflags |= ScriptControlled.CONTROL_LEFT; | ||
3886 | } | ||
3887 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) != 0) | ||
3888 | { | ||
3889 | allflags |= ScriptControlled.CONTROL_RIGHT; | ||
3890 | } | ||
3891 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0) | ||
3892 | { | ||
3893 | allflags |= ScriptControlled.CONTROL_ROT_RIGHT; | ||
3894 | } | ||
3895 | if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0) | ||
3896 | { | ||
3897 | allflags |= ScriptControlled.CONTROL_ROT_LEFT; | ||
3898 | } | ||
3899 | // optimization; we have to check per script, but if nothing is pressed and nothing changed, we can skip that | ||
3900 | if (allflags != ScriptControlled.CONTROL_ZERO || allflags != LastCommands) | ||
3901 | { | ||
3902 | lock (scriptedcontrols) | ||
3903 | { | 3993 | { |
3904 | foreach (KeyValuePair<UUID, ScriptControllers> kvp in scriptedcontrols) | 3994 | foreach (KeyValuePair<UUID, ScriptControllers> kvp in scriptedcontrols) |
3905 | { | 3995 | { |
3906 | UUID scriptUUID = kvp.Key; | 3996 | UUID scriptUUID = kvp.Key; |
3907 | ScriptControllers scriptControlData = kvp.Value; | 3997 | ScriptControllers scriptControlData = kvp.Value; |
3908 | 3998 | ||
3909 | ScriptControlled localHeld = allflags & scriptControlData.eventControls; // the flags interesting for us | 3999 | ScriptControlled localHeld = allflags & scriptControlData.eventControls; // the flags interesting for us |
3910 | ScriptControlled localLast = LastCommands & scriptControlData.eventControls; // the activated controls in the last cycle | 4000 | ScriptControlled localLast = LastCommands & scriptControlData.eventControls; // the activated controls in the last cycle |
3911 | ScriptControlled localChange = localHeld ^ localLast; // the changed bits | 4001 | ScriptControlled localChange = localHeld ^ localLast; // the changed bits |
4002 | |||
3912 | if (localHeld != ScriptControlled.CONTROL_ZERO || localChange != ScriptControlled.CONTROL_ZERO) | 4003 | if (localHeld != ScriptControlled.CONTROL_ZERO || localChange != ScriptControlled.CONTROL_ZERO) |
3913 | { | 4004 | { |
3914 | // only send if still pressed or just changed | 4005 | // only send if still pressed or just changed |
@@ -3916,9 +4007,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
3916 | } | 4007 | } |
3917 | } | 4008 | } |
3918 | } | 4009 | } |
4010 | |||
4011 | LastCommands = allflags; | ||
3919 | } | 4012 | } |
3920 | |||
3921 | LastCommands = allflags; | ||
3922 | } | 4013 | } |
3923 | 4014 | ||
3924 | internal static AgentManager.ControlFlags RemoveIgnoredControls(AgentManager.ControlFlags flags, ScriptControlled ignored) | 4015 | internal static AgentManager.ControlFlags RemoveIgnoredControls(AgentManager.ControlFlags flags, ScriptControlled ignored) |
@@ -3998,7 +4089,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
3998 | land.LandData.UserLocation != Vector3.Zero && | 4089 | land.LandData.UserLocation != Vector3.Zero && |
3999 | land.LandData.OwnerID != m_uuid && | 4090 | land.LandData.OwnerID != m_uuid && |
4000 | (!m_scene.Permissions.IsGod(m_uuid)) && | 4091 | (!m_scene.Permissions.IsGod(m_uuid)) && |
4001 | (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid))) | 4092 | (!m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid))) |
4002 | { | 4093 | { |
4003 | float curr = Vector3.Distance(AbsolutePosition, pos); | 4094 | float curr = Vector3.Distance(AbsolutePosition, pos); |
4004 | if (Vector3.Distance(land.LandData.UserLocation, pos) < curr) | 4095 | if (Vector3.Distance(land.LandData.UserLocation, pos) < curr) |
@@ -4012,13 +4103,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
4012 | { | 4103 | { |
4013 | if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) == | 4104 | if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) == |
4014 | (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) || | 4105 | (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) || |
4015 | (m_teleportFlags & TeleportFlags.ViaLandmark) != 0 || | 4106 | (m_scene.TelehubAllowLandmarks == true ? false : ((m_teleportFlags & TeleportFlags.ViaLandmark) != 0 )) || |
4016 | (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || | 4107 | (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || |
4017 | (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0) | 4108 | (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0) |
4018 | { | 4109 | { |
4019 | if (GodLevel < 200 && | 4110 | if (GodLevel < 200 && |
4020 | ((!m_scene.Permissions.IsGod(m_uuid) && | 4111 | ((!m_scene.Permissions.IsGod(m_uuid) && |
4021 | !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)) || | 4112 | !m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)) || |
4022 | (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || | 4113 | (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || |
4023 | (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0)) | 4114 | (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0)) |
4024 | { | 4115 | { |
@@ -4026,28 +4117,92 @@ namespace OpenSim.Region.Framework.Scenes | |||
4026 | if (spawnPoints.Length == 0) | 4117 | if (spawnPoints.Length == 0) |
4027 | return; | 4118 | return; |
4028 | 4119 | ||
4029 | float distance = 9999; | 4120 | int index; |
4030 | int closest = -1; | 4121 | bool selected = false; |
4031 | 4122 | ||
4032 | for (int i = 0 ; i < spawnPoints.Length ; i++) | 4123 | switch (m_scene.SpawnPointRouting) |
4033 | { | 4124 | { |
4034 | Vector3 spawnPosition = spawnPoints[i].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); | 4125 | case "random": |
4035 | Vector3 offset = spawnPosition - pos; | ||
4036 | float d = Vector3.Mag(offset); | ||
4037 | if (d >= distance) | ||
4038 | continue; | ||
4039 | ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y); | ||
4040 | if (land == null) | ||
4041 | continue; | ||
4042 | if (land.IsEitherBannedOrRestricted(UUID)) | ||
4043 | continue; | ||
4044 | distance = d; | ||
4045 | closest = i; | ||
4046 | } | ||
4047 | if (closest == -1) | ||
4048 | return; | ||
4049 | 4126 | ||
4050 | pos = spawnPoints[closest].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); | 4127 | do |
4128 | { | ||
4129 | index = Util.RandomClass.Next(spawnPoints.Length - 1); | ||
4130 | |||
4131 | Vector3 spawnPosition = spawnPoints[index].GetLocation( | ||
4132 | telehub.AbsolutePosition, | ||
4133 | telehub.GroupRotation | ||
4134 | ); | ||
4135 | // SpawnPoint sp = spawnPoints[index]; | ||
4136 | |||
4137 | ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y); | ||
4138 | if (land == null || land.IsEitherBannedOrRestricted(UUID)) | ||
4139 | selected = false; | ||
4140 | else | ||
4141 | selected = true; | ||
4142 | |||
4143 | } while ( selected == false); | ||
4144 | |||
4145 | pos = spawnPoints[index].GetLocation( | ||
4146 | telehub.AbsolutePosition, | ||
4147 | telehub.GroupRotation | ||
4148 | ); | ||
4149 | return; | ||
4150 | |||
4151 | case "sequence": | ||
4152 | |||
4153 | do | ||
4154 | { | ||
4155 | index = m_scene.SpawnPoint(); | ||
4156 | |||
4157 | Vector3 spawnPosition = spawnPoints[index].GetLocation( | ||
4158 | telehub.AbsolutePosition, | ||
4159 | telehub.GroupRotation | ||
4160 | ); | ||
4161 | // SpawnPoint sp = spawnPoints[index]; | ||
4162 | |||
4163 | ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y); | ||
4164 | if (land == null || land.IsEitherBannedOrRestricted(UUID)) | ||
4165 | selected = false; | ||
4166 | else | ||
4167 | selected = true; | ||
4168 | |||
4169 | } while (selected == false); | ||
4170 | |||
4171 | pos = spawnPoints[index].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); | ||
4172 | ; | ||
4173 | return; | ||
4174 | |||
4175 | default: | ||
4176 | case "closest": | ||
4177 | |||
4178 | float distance = 9999; | ||
4179 | int closest = -1; | ||
4180 | |||
4181 | for (int i = 0; i < spawnPoints.Length; i++) | ||
4182 | { | ||
4183 | Vector3 spawnPosition = spawnPoints[i].GetLocation( | ||
4184 | telehub.AbsolutePosition, | ||
4185 | telehub.GroupRotation | ||
4186 | ); | ||
4187 | Vector3 offset = spawnPosition - pos; | ||
4188 | float d = Vector3.Mag(offset); | ||
4189 | if (d >= distance) | ||
4190 | continue; | ||
4191 | ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y); | ||
4192 | if (land == null) | ||
4193 | continue; | ||
4194 | if (land.IsEitherBannedOrRestricted(UUID)) | ||
4195 | continue; | ||
4196 | distance = d; | ||
4197 | closest = i; | ||
4198 | } | ||
4199 | if (closest == -1) | ||
4200 | return; | ||
4201 | |||
4202 | pos = spawnPoints[closest].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); | ||
4203 | return; | ||
4204 | |||
4205 | } | ||
4051 | } | 4206 | } |
4052 | } | 4207 | } |
4053 | } | 4208 | } |
@@ -4092,7 +4247,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
4092 | GodLevel < 200 && | 4247 | GodLevel < 200 && |
4093 | ((land.LandData.OwnerID != m_uuid && | 4248 | ((land.LandData.OwnerID != m_uuid && |
4094 | !m_scene.Permissions.IsGod(m_uuid) && | 4249 | !m_scene.Permissions.IsGod(m_uuid) && |
4095 | !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)) || | 4250 | !m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)) || |
4096 | (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || | 4251 | (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || |
4097 | (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0)) | 4252 | (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0)) |
4098 | { | 4253 | { |