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.cs495
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
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
@@ -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 {