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.cs427
1 files changed, 304 insertions, 123 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index ba0ed95..34362bf 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
@@ -1085,23 +1093,13 @@ namespace OpenSim.Region.Framework.Scenes
1085 /// <param name="pos"></param> 1093 /// <param name="pos"></param>
1086 public void Teleport(Vector3 pos) 1094 public void Teleport(Vector3 pos)
1087 { 1095 {
1088 bool isFlying = Flying; 1096 TeleportWithMomentum(pos, Vector3.Zero);
1089 RemoveFromPhysicalScene();
1090 Velocity = Vector3.Zero;
1091 CheckLandingPoint(ref pos);
1092 AbsolutePosition = pos;
1093 AddToPhysicalScene(isFlying);
1094
1095 SendTerseUpdateToAllClients();
1096 }
1097
1098 public void TeleportWithMomentum(Vector3 pos)
1099 {
1100 TeleportWithMomentum(pos, null);
1101 } 1097 }
1102 1098
1103 public void TeleportWithMomentum(Vector3 pos, Vector3? v) 1099 public void TeleportWithMomentum(Vector3 pos, Vector3? v)
1104 { 1100 {
1101 if (ParentID != (uint)0)
1102 StandUp();
1105 bool isFlying = Flying; 1103 bool isFlying = Flying;
1106 Vector3 vel = Velocity; 1104 Vector3 vel = Velocity;
1107 RemoveFromPhysicalScene(); 1105 RemoveFromPhysicalScene();
@@ -1281,17 +1279,27 @@ namespace OpenSim.Region.Framework.Scenes
1281 1279
1282 bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0); 1280 bool flying = ((m_AgentControlFlags & AgentManager.ControlFlags.AGENT_CONTROL_FLY) != 0);
1283 MakeRootAgent(AbsolutePosition, flying); 1281 MakeRootAgent(AbsolutePosition, flying);
1282 ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
1283
1284// m_log.DebugFormat("[SCENE PRESENCE] Completed movement");
1284 1285
1285 if ((m_callbackURI != null) && !m_callbackURI.Equals("")) 1286 if ((m_callbackURI != null) && !m_callbackURI.Equals(""))
1286 { 1287 {
1287 m_log.DebugFormat("[SCENE PRESENCE]: Releasing agent in URI {0}", m_callbackURI); 1288 // We cannot sleep here since this would hold up the inbound packet processing thread, as
1289 // CompleteMovement() is executed synchronously. However, it might be better to delay the release
1290 // here until we know for sure that the agent is active in this region. Sending AgentMovementComplete
1291 // is not enough for Imprudence clients - there appears to be a small delay (<200ms, <500ms) until they regard this
1292 // region as the current region, meaning that a close sent before then will fail the teleport.
1293// System.Threading.Thread.Sleep(2000);
1294
1295 m_log.DebugFormat(
1296 "[SCENE PRESENCE]: Releasing {0} {1} with callback to {2}",
1297 client.Name, client.AgentId, m_callbackURI);
1298
1288 Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI); 1299 Scene.SimulationService.ReleaseAgent(m_originRegionID, UUID, m_callbackURI);
1289 m_callbackURI = null; 1300 m_callbackURI = null;
1290 } 1301 }
1291 1302
1292// m_log.DebugFormat("[SCENE PRESENCE] Completed movement");
1293
1294 ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
1295 ValidateAndSendAppearanceAndAgentData(); 1303 ValidateAndSendAppearanceAndAgentData();
1296 1304
1297 // Create child agents in neighbouring regions 1305 // Create child agents in neighbouring regions
@@ -1306,7 +1314,6 @@ namespace OpenSim.Region.Framework.Scenes
1306 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); 1314 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient);
1307 } 1315 }
1308 1316
1309
1310// m_log.DebugFormat( 1317// m_log.DebugFormat(
1311// "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", 1318// "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms",
1312// client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds); 1319// client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds);
@@ -1359,7 +1366,7 @@ namespace OpenSim.Region.Framework.Scenes
1359 { 1366 {
1360// m_log.DebugFormat( 1367// m_log.DebugFormat(
1361// "[SCENE PRESENCE]: In {0} received agent update from {1}, flags {2}", 1368// "[SCENE PRESENCE]: In {0} received agent update from {1}, flags {2}",
1362// Scene.RegionInfo.RegionName, remoteClient.Name, agentData.ControlFlags); 1369// Scene.RegionInfo.RegionName, remoteClient.Name, (AgentManager.ControlFlags)agentData.ControlFlags);
1363 1370
1364 if (IsChildAgent) 1371 if (IsChildAgent)
1365 { 1372 {
@@ -1469,14 +1476,8 @@ namespace OpenSim.Region.Framework.Scenes
1469 } 1476 }
1470 } 1477 }
1471 1478
1472 lock (scriptedcontrols) 1479 uint flagsForScripts = (uint)flags;
1473 { 1480 flags = RemoveIgnoredControls(flags, IgnoredControls);
1474 if (scriptedcontrols.Count > 0)
1475 {
1476 SendControlToScripts((uint)flags);
1477 flags = RemoveIgnoredControls(flags, IgnoredControls);
1478 }
1479 }
1480 1481
1481 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1482 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1482 HandleAgentSitOnGround(); 1483 HandleAgentSitOnGround();
@@ -1490,6 +1491,7 @@ namespace OpenSim.Region.Framework.Scenes
1490 PhysicsActor actor = PhysicsActor; 1491 PhysicsActor actor = PhysicsActor;
1491 if (actor == null) 1492 if (actor == null)
1492 { 1493 {
1494 SendControlsToScripts(flagsForScripts);
1493 return; 1495 return;
1494 } 1496 }
1495 1497
@@ -1569,7 +1571,7 @@ namespace OpenSim.Region.Framework.Scenes
1569 MovementFlag |= (byte)nudgehack; 1571 MovementFlag |= (byte)nudgehack;
1570 } 1572 }
1571 1573
1572// m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with {1}", Name, DCF); 1574 //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with {1}", Name, DCF);
1573 MovementFlag += (byte)(uint)DCF; 1575 MovementFlag += (byte)(uint)DCF;
1574 update_movementflag = true; 1576 update_movementflag = true;
1575 } 1577 }
@@ -1582,7 +1584,7 @@ namespace OpenSim.Region.Framework.Scenes
1582 && ((MovementFlag & (byte)nudgehack) == nudgehack)) 1584 && ((MovementFlag & (byte)nudgehack) == nudgehack))
1583 ) // This or is for Nudge forward 1585 ) // This or is for Nudge forward
1584 { 1586 {
1585// m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with lack of {1}", Name, DCF); 1587 //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with lack of {1}", Name, DCF);
1586 MovementFlag -= ((byte)(uint)DCF); 1588 MovementFlag -= ((byte)(uint)DCF);
1587 update_movementflag = true; 1589 update_movementflag = true;
1588 1590
@@ -1663,11 +1665,14 @@ namespace OpenSim.Region.Framework.Scenes
1663// } 1665// }
1664// } 1666// }
1665 1667
1666// if (update_movementflag && ParentID == 0) 1668 if (update_movementflag && ParentID == 0)
1667// Animator.UpdateMovementAnimations(); 1669 Animator.UpdateMovementAnimations();
1670
1671 SendControlsToScripts(flagsForScripts);
1668 } 1672 }
1669 1673
1670 m_scene.EventManager.TriggerOnClientMovement(this); 1674 m_scene.EventManager.TriggerOnClientMovement(this);
1675 TriggerScenePresenceUpdated();
1671 } 1676 }
1672 1677
1673 /// <summary> 1678 /// <summary>
@@ -2607,6 +2612,7 @@ namespace OpenSim.Region.Framework.Scenes
2607 2612
2608 m_scene.ForEachClient(SendTerseUpdateToClient); 2613 m_scene.ForEachClient(SendTerseUpdateToClient);
2609 } 2614 }
2615 TriggerScenePresenceUpdated();
2610 } 2616 }
2611 2617
2612 public void SendCoarseLocations(List<Vector3> coarseLocations, List<UUID> avatarUUIDs) 2618 public void SendCoarseLocations(List<Vector3> coarseLocations, List<UUID> avatarUUIDs)
@@ -3089,8 +3095,8 @@ namespace OpenSim.Region.Framework.Scenes
3089 x = x / Constants.RegionSize; 3095 x = x / Constants.RegionSize;
3090 y = y / Constants.RegionSize; 3096 y = y / Constants.RegionSize;
3091 3097
3092 //m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX))); 3098// m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX)));
3093 //m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY))); 3099// m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY)));
3094 if (Util.IsOutsideView(DrawDistance, x, newRegionX, y, newRegionY)) 3100 if (Util.IsOutsideView(DrawDistance, x, newRegionX, y, newRegionY))
3095 { 3101 {
3096 byebyeRegions.Add(handle); 3102 byebyeRegions.Add(handle);
@@ -3392,6 +3398,7 @@ namespace OpenSim.Region.Framework.Scenes
3392 Velocity = force; 3398 Velocity = force;
3393 3399
3394 m_forceToApply = null; 3400 m_forceToApply = null;
3401 TriggerScenePresenceUpdated();
3395 } 3402 }
3396 } 3403 }
3397 3404
@@ -3497,25 +3504,53 @@ namespace OpenSim.Region.Framework.Scenes
3497 } 3504 }
3498 } 3505 }
3499 3506
3500 RaiseCollisionScriptEvents(coldata); 3507 // Gods do not take damage and Invulnerable is set depending on parcel/region flags
3501 3508 if (Invulnerable || GodLevel > 0)
3502 if (Invulnerable)
3503 return; 3509 return;
3504 3510
3511 // The following may be better in the ICombatModule
3512 // probably tweaking of the values for ground and normal prim collisions will be needed
3505 float starthealth = Health; 3513 float starthealth = Health;
3506 uint killerObj = 0; 3514 uint killerObj = 0;
3515 SceneObjectPart part = null;
3507 foreach (uint localid in coldata.Keys) 3516 foreach (uint localid in coldata.Keys)
3508 { 3517 {
3509 SceneObjectPart part = Scene.GetSceneObjectPart(localid); 3518 if (localid == 0)
3510 3519 {
3511 if (part != null && part.ParentGroup.Damage != -1.0f) 3520 part = null;
3512 Health -= part.ParentGroup.Damage; 3521 }
3513 else 3522 else
3514 { 3523 {
3515 if (coldata[localid].PenetrationDepth >= 0.10f) 3524 part = Scene.GetSceneObjectPart(localid);
3525 }
3526 if (part != null)
3527 {
3528 // Ignore if it has been deleted or volume detect
3529 if (!part.ParentGroup.IsDeleted && !part.ParentGroup.IsVolumeDetect)
3530 {
3531 if (part.ParentGroup.Damage > 0.0f)
3532 {
3533 // Something with damage...
3534 Health -= part.ParentGroup.Damage;
3535 part.ParentGroup.Scene.DeleteSceneObject(part.ParentGroup, false);
3536 }
3537 else
3538 {
3539 // An ordinary prim
3540 if (coldata[localid].PenetrationDepth >= 0.10f)
3541 Health -= coldata[localid].PenetrationDepth * 5.0f;
3542 }
3543 }
3544 }
3545 else
3546 {
3547 // 0 is the ground
3548 // what about collisions with other avatars?
3549 if (localid == 0 && coldata[localid].PenetrationDepth >= 0.10f)
3516 Health -= coldata[localid].PenetrationDepth * 5.0f; 3550 Health -= coldata[localid].PenetrationDepth * 5.0f;
3517 } 3551 }
3518 3552
3553
3519 if (Health <= 0.0f) 3554 if (Health <= 0.0f)
3520 { 3555 {
3521 if (localid != 0) 3556 if (localid != 0)
@@ -3531,7 +3566,16 @@ namespace OpenSim.Region.Framework.Scenes
3531 ControllingClient.SendHealth(Health); 3566 ControllingClient.SendHealth(Health);
3532 } 3567 }
3533 if (Health <= 0) 3568 if (Health <= 0)
3569 {
3534 m_scene.EventManager.TriggerAvatarKill(killerObj, this); 3570 m_scene.EventManager.TriggerAvatarKill(killerObj, this);
3571 }
3572 if (starthealth == Health && Health < 100.0f)
3573 {
3574 Health += 0.03f;
3575 if (Health > 100.0f)
3576 Health = 100.0f;
3577 ControllingClient.SendHealth(Health);
3578 }
3535 } 3579 }
3536 } 3580 }
3537 3581
@@ -3613,6 +3657,63 @@ namespace OpenSim.Region.Framework.Scenes
3613 return m_attachments.Count > 0; 3657 return m_attachments.Count > 0;
3614 } 3658 }
3615 3659
3660 /// <summary>
3661 /// Returns the total count of scripts in all parts inventories.
3662 /// </summary>
3663 public int ScriptCount()
3664 {
3665 int count = 0;
3666 lock (m_attachments)
3667 {
3668 foreach (SceneObjectGroup gobj in m_attachments)
3669 {
3670 if (gobj != null)
3671 {
3672 count += gobj.ScriptCount();
3673 }
3674 }
3675 }
3676 return count;
3677 }
3678
3679 /// <summary>
3680 /// A float the value is a representative execution time in milliseconds of all scripts in all attachments.
3681 /// </summary>
3682 public float ScriptExecutionTime()
3683 {
3684 float time = 0.0f;
3685 lock (m_attachments)
3686 {
3687 foreach (SceneObjectGroup gobj in m_attachments)
3688 {
3689 if (gobj != null)
3690 {
3691 time += gobj.ScriptExecutionTime();
3692 }
3693 }
3694 }
3695 return time;
3696 }
3697
3698 /// <summary>
3699 /// Returns the total count of running scripts in all parts.
3700 /// </summary>
3701 public int RunningScriptCount()
3702 {
3703 int count = 0;
3704 lock (m_attachments)
3705 {
3706 foreach (SceneObjectGroup gobj in m_attachments)
3707 {
3708 if (gobj != null)
3709 {
3710 count += gobj.RunningScriptCount();
3711 }
3712 }
3713 }
3714 return count;
3715 }
3716
3616 public bool HasScriptedAttachments() 3717 public bool HasScriptedAttachments()
3617 { 3718 {
3618 lock (m_attachments) 3719 lock (m_attachments)
@@ -3830,77 +3931,92 @@ namespace OpenSim.Region.Framework.Scenes
3830 } 3931 }
3831 } 3932 }
3832 3933
3833 internal void SendControlToScripts(uint flags) 3934 private void SendControlsToScripts(uint flags)
3834 { 3935 {
3835 ScriptControlled allflags = ScriptControlled.CONTROL_ZERO; 3936 // Notify the scripts only after calling UpdateMovementAnimations(), so that if a script
3836 3937 // (e.g., a walking script) checks which animation is active it will be the correct animation.
3837 if (MouseDown) 3938 lock (scriptedcontrols)
3838 { 3939 {
3839 allflags = LastCommands & (ScriptControlled.CONTROL_ML_LBUTTON | ScriptControlled.CONTROL_LBUTTON); 3940 if (scriptedcontrols.Count <= 0)
3840 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP) != 0 || (flags & unchecked((uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_UP)) != 0) 3941 return;
3942
3943 ScriptControlled allflags = ScriptControlled.CONTROL_ZERO;
3944
3945 if (MouseDown)
3841 { 3946 {
3842 allflags = ScriptControlled.CONTROL_ZERO; 3947 allflags = LastCommands & (ScriptControlled.CONTROL_ML_LBUTTON | ScriptControlled.CONTROL_LBUTTON);
3948 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP) != 0 || (flags & unchecked((uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_UP)) != 0)
3949 {
3950 allflags = ScriptControlled.CONTROL_ZERO;
3951 MouseDown = true;
3952 }
3953 }
3954
3955 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN) != 0)
3956 {
3957 allflags |= ScriptControlled.CONTROL_ML_LBUTTON;
3843 MouseDown = true; 3958 MouseDown = true;
3844 } 3959 }
3845 } 3960
3961 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0)
3962 {
3963 allflags |= ScriptControlled.CONTROL_LBUTTON;
3964 MouseDown = true;
3965 }
3966
3967 // find all activated controls, whether the scripts are interested in them or not
3968 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) != 0)
3969 {
3970 allflags |= ScriptControlled.CONTROL_FWD;
3971 }
3972
3973 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) != 0)
3974 {
3975 allflags |= ScriptControlled.CONTROL_BACK;
3976 }
3977
3978 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS) != 0)
3979 {
3980 allflags |= ScriptControlled.CONTROL_UP;
3981 }
3982
3983 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)
3984 {
3985 allflags |= ScriptControlled.CONTROL_DOWN;
3986 }
3846 3987
3847 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN) != 0) 3988 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) != 0)
3848 { 3989 {
3849 allflags |= ScriptControlled.CONTROL_ML_LBUTTON; 3990 allflags |= ScriptControlled.CONTROL_LEFT;
3850 MouseDown = true; 3991 }
3851 } 3992
3852 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0) 3993 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) != 0)
3853 { 3994 {
3854 allflags |= ScriptControlled.CONTROL_LBUTTON; 3995 allflags |= ScriptControlled.CONTROL_RIGHT;
3855 MouseDown = true; 3996 }
3856 } 3997
3998 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0)
3999 {
4000 allflags |= ScriptControlled.CONTROL_ROT_RIGHT;
4001 }
4002
4003 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0)
4004 {
4005 allflags |= ScriptControlled.CONTROL_ROT_LEFT;
4006 }
3857 4007
3858 // find all activated controls, whether the scripts are interested in them or not 4008 // optimization; we have to check per script, but if nothing is pressed and nothing changed, we can skip that
3859 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) != 0) 4009 if (allflags != ScriptControlled.CONTROL_ZERO || allflags != LastCommands)
3860 {
3861 allflags |= ScriptControlled.CONTROL_FWD;
3862 }
3863 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) != 0)
3864 {
3865 allflags |= ScriptControlled.CONTROL_BACK;
3866 }
3867 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS) != 0)
3868 {
3869 allflags |= ScriptControlled.CONTROL_UP;
3870 }
3871 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)
3872 {
3873 allflags |= ScriptControlled.CONTROL_DOWN;
3874 }
3875 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) != 0)
3876 {
3877 allflags |= ScriptControlled.CONTROL_LEFT;
3878 }
3879 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) != 0)
3880 {
3881 allflags |= ScriptControlled.CONTROL_RIGHT;
3882 }
3883 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0)
3884 {
3885 allflags |= ScriptControlled.CONTROL_ROT_RIGHT;
3886 }
3887 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0)
3888 {
3889 allflags |= ScriptControlled.CONTROL_ROT_LEFT;
3890 }
3891 // optimization; we have to check per script, but if nothing is pressed and nothing changed, we can skip that
3892 if (allflags != ScriptControlled.CONTROL_ZERO || allflags != LastCommands)
3893 {
3894 lock (scriptedcontrols)
3895 { 4010 {
3896 foreach (KeyValuePair<UUID, ScriptControllers> kvp in scriptedcontrols) 4011 foreach (KeyValuePair<UUID, ScriptControllers> kvp in scriptedcontrols)
3897 { 4012 {
3898 UUID scriptUUID = kvp.Key; 4013 UUID scriptUUID = kvp.Key;
3899 ScriptControllers scriptControlData = kvp.Value; 4014 ScriptControllers scriptControlData = kvp.Value;
3900 4015
3901 ScriptControlled localHeld = allflags & scriptControlData.eventControls; // the flags interesting for us 4016 ScriptControlled localHeld = allflags & scriptControlData.eventControls; // the flags interesting for us
3902 ScriptControlled localLast = LastCommands & scriptControlData.eventControls; // the activated controls in the last cycle 4017 ScriptControlled localLast = LastCommands & scriptControlData.eventControls; // the activated controls in the last cycle
3903 ScriptControlled localChange = localHeld ^ localLast; // the changed bits 4018 ScriptControlled localChange = localHeld ^ localLast; // the changed bits
4019
3904 if (localHeld != ScriptControlled.CONTROL_ZERO || localChange != ScriptControlled.CONTROL_ZERO) 4020 if (localHeld != ScriptControlled.CONTROL_ZERO || localChange != ScriptControlled.CONTROL_ZERO)
3905 { 4021 {
3906 // only send if still pressed or just changed 4022 // only send if still pressed or just changed
@@ -3908,9 +4024,9 @@ namespace OpenSim.Region.Framework.Scenes
3908 } 4024 }
3909 } 4025 }
3910 } 4026 }
4027
4028 LastCommands = allflags;
3911 } 4029 }
3912
3913 LastCommands = allflags;
3914 } 4030 }
3915 4031
3916 internal static AgentManager.ControlFlags RemoveIgnoredControls(AgentManager.ControlFlags flags, ScriptControlled ignored) 4032 internal static AgentManager.ControlFlags RemoveIgnoredControls(AgentManager.ControlFlags flags, ScriptControlled ignored)
@@ -3990,7 +4106,7 @@ namespace OpenSim.Region.Framework.Scenes
3990 land.LandData.UserLocation != Vector3.Zero && 4106 land.LandData.UserLocation != Vector3.Zero &&
3991 land.LandData.OwnerID != m_uuid && 4107 land.LandData.OwnerID != m_uuid &&
3992 (!m_scene.Permissions.IsGod(m_uuid)) && 4108 (!m_scene.Permissions.IsGod(m_uuid)) &&
3993 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid))) 4109 (!m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)))
3994 { 4110 {
3995 float curr = Vector3.Distance(AbsolutePosition, pos); 4111 float curr = Vector3.Distance(AbsolutePosition, pos);
3996 if (Vector3.Distance(land.LandData.UserLocation, pos) < curr) 4112 if (Vector3.Distance(land.LandData.UserLocation, pos) < curr)
@@ -4010,7 +4126,7 @@ namespace OpenSim.Region.Framework.Scenes
4010 { 4126 {
4011 if (GodLevel < 200 && 4127 if (GodLevel < 200 &&
4012 ((!m_scene.Permissions.IsGod(m_uuid) && 4128 ((!m_scene.Permissions.IsGod(m_uuid) &&
4013 !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)) || 4129 !m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)) ||
4014 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || 4130 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 ||
4015 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0)) 4131 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0))
4016 { 4132 {
@@ -4018,28 +4134,93 @@ namespace OpenSim.Region.Framework.Scenes
4018 if (spawnPoints.Length == 0) 4134 if (spawnPoints.Length == 0)
4019 return; 4135 return;
4020 4136
4021 float distance = 9999; 4137 int index;
4022 int closest = -1; 4138 bool selected = false;
4023 4139
4024 for (int i = 0 ; i < spawnPoints.Length ; i++) 4140 switch (m_scene.SpawnPointRouting)
4025 { 4141 {
4026 Vector3 spawnPosition = spawnPoints[i].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); 4142 case "closest":
4027 Vector3 offset = spawnPosition - pos; 4143
4028 float d = Vector3.Mag(offset); 4144 float distance = 9999;
4029 if (d >= distance) 4145 int closest = -1;
4030 continue; 4146
4031 ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y); 4147 for (int i = 0; i < spawnPoints.Length; i++)
4032 if (land == null) 4148 {
4033 continue; 4149 Vector3 spawnPosition = spawnPoints[i].GetLocation(
4034 if (land.IsEitherBannedOrRestricted(UUID)) 4150 telehub.AbsolutePosition,
4035 continue; 4151 telehub.GroupRotation
4036 distance = d; 4152 );
4037 closest = i; 4153 Vector3 offset = spawnPosition - pos;
4038 } 4154 float d = Vector3.Mag(offset);
4039 if (closest == -1) 4155 if (d >= distance)
4040 return; 4156 continue;
4157 ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y);
4158 if (land == null)
4159 continue;
4160 if (land.IsEitherBannedOrRestricted(UUID))
4161 continue;
4162 distance = d;
4163 closest = i;
4164 }
4165 if (closest == -1)
4166 return;
4167
4168 pos = spawnPoints[closest].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation);
4169 return;
4170
4171 case "random":
4041 4172
4042 pos = spawnPoints[closest].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); 4173 do
4174 {
4175 index = Util.RandomClass.Next(spawnPoints.Length - 1);
4176
4177 Vector3 spawnPosition = spawnPoints[index].GetLocation(
4178 telehub.AbsolutePosition,
4179 telehub.GroupRotation
4180 );
4181 // SpawnPoint sp = spawnPoints[index];
4182
4183 ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y);
4184 if (land == null || land.IsEitherBannedOrRestricted(UUID))
4185 selected = false;
4186 else
4187 selected = true;
4188
4189 } while ( selected == false);
4190
4191 pos = spawnPoints[index].GetLocation(
4192 telehub.AbsolutePosition,
4193 telehub.GroupRotation
4194 );
4195 return;
4196
4197 case "sequence":
4198
4199 do
4200 {
4201 index = m_scene.SpawnPoint();
4202
4203 Vector3 spawnPosition = spawnPoints[index].GetLocation(
4204 telehub.AbsolutePosition,
4205 telehub.GroupRotation
4206 );
4207 // SpawnPoint sp = spawnPoints[index];
4208
4209 ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y);
4210 if (land == null || land.IsEitherBannedOrRestricted(UUID))
4211 selected = false;
4212 else
4213 selected = true;
4214
4215 } while (selected == false);
4216
4217 pos = spawnPoints[index].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation);
4218 ;
4219 return;
4220
4221 default:
4222 return;
4223 }
4043 } 4224 }
4044 } 4225 }
4045 } 4226 }
@@ -4084,7 +4265,7 @@ namespace OpenSim.Region.Framework.Scenes
4084 GodLevel < 200 && 4265 GodLevel < 200 &&
4085 ((land.LandData.OwnerID != m_uuid && 4266 ((land.LandData.OwnerID != m_uuid &&
4086 !m_scene.Permissions.IsGod(m_uuid) && 4267 !m_scene.Permissions.IsGod(m_uuid) &&
4087 !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)) || 4268 !m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)) ||
4088 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || 4269 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 ||
4089 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0)) 4270 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0))
4090 { 4271 {