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.cs439
1 files changed, 315 insertions, 124 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 2b1fb3d..33a17db 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,33 @@ 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 }
1302// else
1303// {
1304// m_log.DebugFormat(
1305// "[SCENE PRESENCE]: No callback provided on CompleteMovement of {0} {1} to {2}",
1306// client.Name, client.AgentId, m_scene.RegionInfo.RegionName);
1307// }
1291 1308
1292// m_log.DebugFormat("[SCENE PRESENCE] Completed movement");
1293
1294 ControllingClient.MoveAgentIntoRegion(m_scene.RegionInfo, AbsolutePosition, look);
1295 ValidateAndSendAppearanceAndAgentData(); 1309 ValidateAndSendAppearanceAndAgentData();
1296 1310
1297 // Create child agents in neighbouring regions 1311 // Create child agents in neighbouring regions
@@ -1306,7 +1320,6 @@ namespace OpenSim.Region.Framework.Scenes
1306 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient); 1320 friendsModule.SendFriendsOnlineIfNeeded(ControllingClient);
1307 } 1321 }
1308 1322
1309
1310// m_log.DebugFormat( 1323// m_log.DebugFormat(
1311// "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms", 1324// "[SCENE PRESENCE]: Completing movement of {0} into region {1} took {2}ms",
1312// client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds); 1325// client.Name, Scene.RegionInfo.RegionName, (DateTime.Now - startTime).Milliseconds);
@@ -1359,7 +1372,7 @@ namespace OpenSim.Region.Framework.Scenes
1359 { 1372 {
1360// m_log.DebugFormat( 1373// m_log.DebugFormat(
1361// "[SCENE PRESENCE]: In {0} received agent update from {1}, flags {2}", 1374// "[SCENE PRESENCE]: In {0} received agent update from {1}, flags {2}",
1362// Scene.RegionInfo.RegionName, remoteClient.Name, agentData.ControlFlags); 1375// Scene.RegionInfo.RegionName, remoteClient.Name, (AgentManager.ControlFlags)agentData.ControlFlags);
1363 1376
1364 if (IsChildAgent) 1377 if (IsChildAgent)
1365 { 1378 {
@@ -1469,14 +1482,8 @@ namespace OpenSim.Region.Framework.Scenes
1469 } 1482 }
1470 } 1483 }
1471 1484
1472 lock (scriptedcontrols) 1485 uint flagsForScripts = (uint)flags;
1473 { 1486 flags = RemoveIgnoredControls(flags, IgnoredControls);
1474 if (scriptedcontrols.Count > 0)
1475 {
1476 SendControlToScripts((uint)flags);
1477 flags = RemoveIgnoredControls(flags, IgnoredControls);
1478 }
1479 }
1480 1487
1481 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0) 1488 if ((flags & AgentManager.ControlFlags.AGENT_CONTROL_SIT_ON_GROUND) != 0)
1482 HandleAgentSitOnGround(); 1489 HandleAgentSitOnGround();
@@ -1490,6 +1497,7 @@ namespace OpenSim.Region.Framework.Scenes
1490 PhysicsActor actor = PhysicsActor; 1497 PhysicsActor actor = PhysicsActor;
1491 if (actor == null) 1498 if (actor == null)
1492 { 1499 {
1500 SendControlsToScripts(flagsForScripts);
1493 return; 1501 return;
1494 } 1502 }
1495 1503
@@ -1569,7 +1577,7 @@ namespace OpenSim.Region.Framework.Scenes
1569 MovementFlag |= (byte)nudgehack; 1577 MovementFlag |= (byte)nudgehack;
1570 } 1578 }
1571 1579
1572// m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with {1}", Name, DCF); 1580 //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with {1}", Name, DCF);
1573 MovementFlag += (byte)(uint)DCF; 1581 MovementFlag += (byte)(uint)DCF;
1574 update_movementflag = true; 1582 update_movementflag = true;
1575 } 1583 }
@@ -1582,7 +1590,7 @@ namespace OpenSim.Region.Framework.Scenes
1582 && ((MovementFlag & (byte)nudgehack) == nudgehack)) 1590 && ((MovementFlag & (byte)nudgehack) == nudgehack))
1583 ) // This or is for Nudge forward 1591 ) // This or is for Nudge forward
1584 { 1592 {
1585// m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with lack of {1}", Name, DCF); 1593 //m_log.DebugFormat("[SCENE PRESENCE]: Updating MovementFlag for {0} with lack of {1}", Name, DCF);
1586 MovementFlag -= ((byte)(uint)DCF); 1594 MovementFlag -= ((byte)(uint)DCF);
1587 update_movementflag = true; 1595 update_movementflag = true;
1588 1596
@@ -1663,11 +1671,14 @@ namespace OpenSim.Region.Framework.Scenes
1663// } 1671// }
1664// } 1672// }
1665 1673
1666// if (update_movementflag && ParentID == 0) 1674 if (update_movementflag && ParentID == 0)
1667// Animator.UpdateMovementAnimations(); 1675 Animator.UpdateMovementAnimations();
1676
1677 SendControlsToScripts(flagsForScripts);
1668 } 1678 }
1669 1679
1670 m_scene.EventManager.TriggerOnClientMovement(this); 1680 m_scene.EventManager.TriggerOnClientMovement(this);
1681 TriggerScenePresenceUpdated();
1671 } 1682 }
1672 1683
1673 /// <summary> 1684 /// <summary>
@@ -2607,6 +2618,7 @@ namespace OpenSim.Region.Framework.Scenes
2607 2618
2608 m_scene.ForEachClient(SendTerseUpdateToClient); 2619 m_scene.ForEachClient(SendTerseUpdateToClient);
2609 } 2620 }
2621 TriggerScenePresenceUpdated();
2610 } 2622 }
2611 2623
2612 public void SendCoarseLocations(List<Vector3> coarseLocations, List<UUID> avatarUUIDs) 2624 public void SendCoarseLocations(List<Vector3> coarseLocations, List<UUID> avatarUUIDs)
@@ -2685,7 +2697,7 @@ namespace OpenSim.Region.Framework.Scenes
2685 // If we are using the the cached appearance then send it out to everyone 2697 // If we are using the the cached appearance then send it out to everyone
2686 if (cachedappearance) 2698 if (cachedappearance)
2687 { 2699 {
2688 m_log.DebugFormat("[SCENEPRESENCE]: baked textures are in the cache for {0}", Name); 2700 m_log.DebugFormat("[SCENE PRESENCE]: baked textures are in the cache for {0}", Name);
2689 2701
2690 // If the avatars baked textures are all in the cache, then we have a 2702 // If the avatars baked textures are all in the cache, then we have a
2691 // complete appearance... send it out, if not, then we'll send it when 2703 // complete appearance... send it out, if not, then we'll send it when
@@ -3089,8 +3101,8 @@ namespace OpenSim.Region.Framework.Scenes
3089 x = x / Constants.RegionSize; 3101 x = x / Constants.RegionSize;
3090 y = y / Constants.RegionSize; 3102 y = y / Constants.RegionSize;
3091 3103
3092 //m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX))); 3104// m_log.Debug("---> x: " + x + "; newx:" + newRegionX + "; Abs:" + (int)Math.Abs((int)(x - newRegionX)));
3093 //m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY))); 3105// m_log.Debug("---> y: " + y + "; newy:" + newRegionY + "; Abs:" + (int)Math.Abs((int)(y - newRegionY)));
3094 if (Util.IsOutsideView(DrawDistance, x, newRegionX, y, newRegionY)) 3106 if (Util.IsOutsideView(DrawDistance, x, newRegionX, y, newRegionY))
3095 { 3107 {
3096 byebyeRegions.Add(handle); 3108 byebyeRegions.Add(handle);
@@ -3147,7 +3159,7 @@ namespace OpenSim.Region.Framework.Scenes
3147 3159
3148 public void ChildAgentDataUpdate(AgentData cAgentData) 3160 public void ChildAgentDataUpdate(AgentData cAgentData)
3149 { 3161 {
3150 //m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName); 3162// m_log.Debug(" >>> ChildAgentDataUpdate <<< " + Scene.RegionInfo.RegionName);
3151 if (!IsChildAgent) 3163 if (!IsChildAgent)
3152 return; 3164 return;
3153 3165
@@ -3291,6 +3303,9 @@ namespace OpenSim.Region.Framework.Scenes
3291 m_originRegionID = cAgent.RegionID; 3303 m_originRegionID = cAgent.RegionID;
3292 3304
3293 m_callbackURI = cAgent.CallbackURI; 3305 m_callbackURI = cAgent.CallbackURI;
3306// m_log.DebugFormat(
3307// "[SCENE PRESENCE]: Set callback for {0} in {1} to {2} in CopyFrom()",
3308// Name, m_scene.RegionInfo.RegionName, m_callbackURI);
3294 3309
3295 m_pos = cAgent.Position; 3310 m_pos = cAgent.Position;
3296 m_velocity = cAgent.Velocity; 3311 m_velocity = cAgent.Velocity;
@@ -3392,6 +3407,7 @@ namespace OpenSim.Region.Framework.Scenes
3392 Velocity = force; 3407 Velocity = force;
3393 3408
3394 m_forceToApply = null; 3409 m_forceToApply = null;
3410 TriggerScenePresenceUpdated();
3395 } 3411 }
3396 } 3412 }
3397 3413
@@ -3499,23 +3515,53 @@ namespace OpenSim.Region.Framework.Scenes
3499 3515
3500 RaiseCollisionScriptEvents(coldata); 3516 RaiseCollisionScriptEvents(coldata);
3501 3517
3502 if (Invulnerable || GodLevel >= 200) 3518 // Gods do not take damage and Invulnerable is set depending on parcel/region flags
3519 if (Invulnerable || GodLevel > 0)
3503 return; 3520 return;
3504 3521
3522 // The following may be better in the ICombatModule
3523 // probably tweaking of the values for ground and normal prim collisions will be needed
3505 float starthealth = Health; 3524 float starthealth = Health;
3506 uint killerObj = 0; 3525 uint killerObj = 0;
3526 SceneObjectPart part = null;
3507 foreach (uint localid in coldata.Keys) 3527 foreach (uint localid in coldata.Keys)
3508 { 3528 {
3509 SceneObjectPart part = Scene.GetSceneObjectPart(localid); 3529 if (localid == 0)
3510 3530 {
3511 if (part != null && part.ParentGroup.Damage != -1.0f) 3531 part = null;
3512 Health -= part.ParentGroup.Damage; 3532 }
3533 else
3534 {
3535 part = Scene.GetSceneObjectPart(localid);
3536 }
3537 if (part != null)
3538 {
3539 // Ignore if it has been deleted or volume detect
3540 if (!part.ParentGroup.IsDeleted && !part.ParentGroup.IsVolumeDetect)
3541 {
3542 if (part.ParentGroup.Damage > 0.0f)
3543 {
3544 // Something with damage...
3545 Health -= part.ParentGroup.Damage;
3546 part.ParentGroup.Scene.DeleteSceneObject(part.ParentGroup, false);
3547 }
3548 else
3549 {
3550 // An ordinary prim
3551 if (coldata[localid].PenetrationDepth >= 0.10f)
3552 Health -= coldata[localid].PenetrationDepth * 5.0f;
3553 }
3554 }
3555 }
3513 else 3556 else
3514 { 3557 {
3515 if (coldata[localid].PenetrationDepth >= 0.10f) 3558 // 0 is the ground
3559 // what about collisions with other avatars?
3560 if (localid == 0 && coldata[localid].PenetrationDepth >= 0.10f)
3516 Health -= coldata[localid].PenetrationDepth * 5.0f; 3561 Health -= coldata[localid].PenetrationDepth * 5.0f;
3517 } 3562 }
3518 3563
3564
3519 if (Health <= 0.0f) 3565 if (Health <= 0.0f)
3520 { 3566 {
3521 if (localid != 0) 3567 if (localid != 0)
@@ -3531,7 +3577,16 @@ namespace OpenSim.Region.Framework.Scenes
3531 ControllingClient.SendHealth(Health); 3577 ControllingClient.SendHealth(Health);
3532 } 3578 }
3533 if (Health <= 0) 3579 if (Health <= 0)
3580 {
3534 m_scene.EventManager.TriggerAvatarKill(killerObj, this); 3581 m_scene.EventManager.TriggerAvatarKill(killerObj, this);
3582 }
3583 if (starthealth == Health && Health < 100.0f)
3584 {
3585 Health += 0.03f;
3586 if (Health > 100.0f)
3587 Health = 100.0f;
3588 ControllingClient.SendHealth(Health);
3589 }
3535 } 3590 }
3536 } 3591 }
3537 3592
@@ -3613,6 +3668,63 @@ namespace OpenSim.Region.Framework.Scenes
3613 return m_attachments.Count > 0; 3668 return m_attachments.Count > 0;
3614 } 3669 }
3615 3670
3671 /// <summary>
3672 /// Returns the total count of scripts in all parts inventories.
3673 /// </summary>
3674 public int ScriptCount()
3675 {
3676 int count = 0;
3677 lock (m_attachments)
3678 {
3679 foreach (SceneObjectGroup gobj in m_attachments)
3680 {
3681 if (gobj != null)
3682 {
3683 count += gobj.ScriptCount();
3684 }
3685 }
3686 }
3687 return count;
3688 }
3689
3690 /// <summary>
3691 /// A float the value is a representative execution time in milliseconds of all scripts in all attachments.
3692 /// </summary>
3693 public float ScriptExecutionTime()
3694 {
3695 float time = 0.0f;
3696 lock (m_attachments)
3697 {
3698 foreach (SceneObjectGroup gobj in m_attachments)
3699 {
3700 if (gobj != null)
3701 {
3702 time += gobj.ScriptExecutionTime();
3703 }
3704 }
3705 }
3706 return time;
3707 }
3708
3709 /// <summary>
3710 /// Returns the total count of running scripts in all parts.
3711 /// </summary>
3712 public int RunningScriptCount()
3713 {
3714 int count = 0;
3715 lock (m_attachments)
3716 {
3717 foreach (SceneObjectGroup gobj in m_attachments)
3718 {
3719 if (gobj != null)
3720 {
3721 count += gobj.RunningScriptCount();
3722 }
3723 }
3724 }
3725 return count;
3726 }
3727
3616 public bool HasScriptedAttachments() 3728 public bool HasScriptedAttachments()
3617 { 3729 {
3618 lock (m_attachments) 3730 lock (m_attachments)
@@ -3830,77 +3942,92 @@ namespace OpenSim.Region.Framework.Scenes
3830 } 3942 }
3831 } 3943 }
3832 3944
3833 internal void SendControlToScripts(uint flags) 3945 private void SendControlsToScripts(uint flags)
3834 { 3946 {
3835 ScriptControlled allflags = ScriptControlled.CONTROL_ZERO; 3947 // Notify the scripts only after calling UpdateMovementAnimations(), so that if a script
3836 3948 // (e.g., a walking script) checks which animation is active it will be the correct animation.
3837 if (MouseDown) 3949 lock (scriptedcontrols)
3838 { 3950 {
3839 allflags = LastCommands & (ScriptControlled.CONTROL_ML_LBUTTON | ScriptControlled.CONTROL_LBUTTON); 3951 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) 3952 return;
3953
3954 ScriptControlled allflags = ScriptControlled.CONTROL_ZERO;
3955
3956 if (MouseDown)
3957 {
3958 allflags = LastCommands & (ScriptControlled.CONTROL_ML_LBUTTON | ScriptControlled.CONTROL_LBUTTON);
3959 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP) != 0 || (flags & unchecked((uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_UP)) != 0)
3960 {
3961 allflags = ScriptControlled.CONTROL_ZERO;
3962 MouseDown = true;
3963 }
3964 }
3965
3966 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN) != 0)
3841 { 3967 {
3842 allflags = ScriptControlled.CONTROL_ZERO; 3968 allflags |= ScriptControlled.CONTROL_ML_LBUTTON;
3843 MouseDown = true; 3969 MouseDown = true;
3844 } 3970 }
3845 } 3971
3972 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0)
3973 {
3974 allflags |= ScriptControlled.CONTROL_LBUTTON;
3975 MouseDown = true;
3976 }
3977
3978 // find all activated controls, whether the scripts are interested in them or not
3979 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) != 0)
3980 {
3981 allflags |= ScriptControlled.CONTROL_FWD;
3982 }
3983
3984 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) != 0)
3985 {
3986 allflags |= ScriptControlled.CONTROL_BACK;
3987 }
3988
3989 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS) != 0)
3990 {
3991 allflags |= ScriptControlled.CONTROL_UP;
3992 }
3993
3994 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)
3995 {
3996 allflags |= ScriptControlled.CONTROL_DOWN;
3997 }
3846 3998
3847 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN) != 0) 3999 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) != 0)
3848 { 4000 {
3849 allflags |= ScriptControlled.CONTROL_ML_LBUTTON; 4001 allflags |= ScriptControlled.CONTROL_LEFT;
3850 MouseDown = true; 4002 }
3851 } 4003
3852 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0) 4004 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) != 0)
3853 { 4005 {
3854 allflags |= ScriptControlled.CONTROL_LBUTTON; 4006 allflags |= ScriptControlled.CONTROL_RIGHT;
3855 MouseDown = true; 4007 }
3856 } 4008
4009 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0)
4010 {
4011 allflags |= ScriptControlled.CONTROL_ROT_RIGHT;
4012 }
4013
4014 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0)
4015 {
4016 allflags |= ScriptControlled.CONTROL_ROT_LEFT;
4017 }
3857 4018
3858 // find all activated controls, whether the scripts are interested in them or not 4019 // 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) 4020 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 { 4021 {
3896 foreach (KeyValuePair<UUID, ScriptControllers> kvp in scriptedcontrols) 4022 foreach (KeyValuePair<UUID, ScriptControllers> kvp in scriptedcontrols)
3897 { 4023 {
3898 UUID scriptUUID = kvp.Key; 4024 UUID scriptUUID = kvp.Key;
3899 ScriptControllers scriptControlData = kvp.Value; 4025 ScriptControllers scriptControlData = kvp.Value;
3900 4026
3901 ScriptControlled localHeld = allflags & scriptControlData.eventControls; // the flags interesting for us 4027 ScriptControlled localHeld = allflags & scriptControlData.eventControls; // the flags interesting for us
3902 ScriptControlled localLast = LastCommands & scriptControlData.eventControls; // the activated controls in the last cycle 4028 ScriptControlled localLast = LastCommands & scriptControlData.eventControls; // the activated controls in the last cycle
3903 ScriptControlled localChange = localHeld ^ localLast; // the changed bits 4029 ScriptControlled localChange = localHeld ^ localLast; // the changed bits
4030
3904 if (localHeld != ScriptControlled.CONTROL_ZERO || localChange != ScriptControlled.CONTROL_ZERO) 4031 if (localHeld != ScriptControlled.CONTROL_ZERO || localChange != ScriptControlled.CONTROL_ZERO)
3905 { 4032 {
3906 // only send if still pressed or just changed 4033 // only send if still pressed or just changed
@@ -3908,9 +4035,9 @@ namespace OpenSim.Region.Framework.Scenes
3908 } 4035 }
3909 } 4036 }
3910 } 4037 }
4038
4039 LastCommands = allflags;
3911 } 4040 }
3912
3913 LastCommands = allflags;
3914 } 4041 }
3915 4042
3916 internal static AgentManager.ControlFlags RemoveIgnoredControls(AgentManager.ControlFlags flags, ScriptControlled ignored) 4043 internal static AgentManager.ControlFlags RemoveIgnoredControls(AgentManager.ControlFlags flags, ScriptControlled ignored)
@@ -3990,7 +4117,7 @@ namespace OpenSim.Region.Framework.Scenes
3990 land.LandData.UserLocation != Vector3.Zero && 4117 land.LandData.UserLocation != Vector3.Zero &&
3991 land.LandData.OwnerID != m_uuid && 4118 land.LandData.OwnerID != m_uuid &&
3992 (!m_scene.Permissions.IsGod(m_uuid)) && 4119 (!m_scene.Permissions.IsGod(m_uuid)) &&
3993 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid))) 4120 (!m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)))
3994 { 4121 {
3995 float curr = Vector3.Distance(AbsolutePosition, pos); 4122 float curr = Vector3.Distance(AbsolutePosition, pos);
3996 if (Vector3.Distance(land.LandData.UserLocation, pos) < curr) 4123 if (Vector3.Distance(land.LandData.UserLocation, pos) < curr)
@@ -4004,13 +4131,13 @@ namespace OpenSim.Region.Framework.Scenes
4004 { 4131 {
4005 if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) == 4132 if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) ==
4006 (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) || 4133 (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) ||
4007 (m_teleportFlags & TeleportFlags.ViaLandmark) != 0 || 4134 (m_scene.TelehubAllowLandmarks == true ? false : ((m_teleportFlags & TeleportFlags.ViaLandmark) != 0 )) ||
4008 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || 4135 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 ||
4009 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0) 4136 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0)
4010 { 4137 {
4011 if (GodLevel < 200 && 4138 if (GodLevel < 200 &&
4012 ((!m_scene.Permissions.IsGod(m_uuid) && 4139 ((!m_scene.Permissions.IsGod(m_uuid) &&
4013 !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)) || 4140 !m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)) ||
4014 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || 4141 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 ||
4015 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0)) 4142 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0))
4016 { 4143 {
@@ -4018,28 +4145,92 @@ namespace OpenSim.Region.Framework.Scenes
4018 if (spawnPoints.Length == 0) 4145 if (spawnPoints.Length == 0)
4019 return; 4146 return;
4020 4147
4021 float distance = 9999; 4148 int index;
4022 int closest = -1; 4149 bool selected = false;
4023 4150
4024 for (int i = 0 ; i < spawnPoints.Length ; i++) 4151 switch (m_scene.SpawnPointRouting)
4025 { 4152 {
4026 Vector3 spawnPosition = spawnPoints[i].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); 4153 case "random":
4027 Vector3 offset = spawnPosition - pos;
4028 float d = Vector3.Mag(offset);
4029 if (d >= distance)
4030 continue;
4031 ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y);
4032 if (land == null)
4033 continue;
4034 if (land.IsEitherBannedOrRestricted(UUID))
4035 continue;
4036 distance = d;
4037 closest = i;
4038 }
4039 if (closest == -1)
4040 return;
4041 4154
4042 pos = spawnPoints[closest].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); 4155 do
4156 {
4157 index = Util.RandomClass.Next(spawnPoints.Length - 1);
4158
4159 Vector3 spawnPosition = spawnPoints[index].GetLocation(
4160 telehub.AbsolutePosition,
4161 telehub.GroupRotation
4162 );
4163 // SpawnPoint sp = spawnPoints[index];
4164
4165 ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y);
4166 if (land == null || land.IsEitherBannedOrRestricted(UUID))
4167 selected = false;
4168 else
4169 selected = true;
4170
4171 } while ( selected == false);
4172
4173 pos = spawnPoints[index].GetLocation(
4174 telehub.AbsolutePosition,
4175 telehub.GroupRotation
4176 );
4177 return;
4178
4179 case "sequence":
4180
4181 do
4182 {
4183 index = m_scene.SpawnPoint();
4184
4185 Vector3 spawnPosition = spawnPoints[index].GetLocation(
4186 telehub.AbsolutePosition,
4187 telehub.GroupRotation
4188 );
4189 // SpawnPoint sp = spawnPoints[index];
4190
4191 ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y);
4192 if (land == null || land.IsEitherBannedOrRestricted(UUID))
4193 selected = false;
4194 else
4195 selected = true;
4196
4197 } while (selected == false);
4198
4199 pos = spawnPoints[index].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation);
4200 ;
4201 return;
4202
4203 default:
4204 case "closest":
4205
4206 float distance = 9999;
4207 int closest = -1;
4208
4209 for (int i = 0; i < spawnPoints.Length; i++)
4210 {
4211 Vector3 spawnPosition = spawnPoints[i].GetLocation(
4212 telehub.AbsolutePosition,
4213 telehub.GroupRotation
4214 );
4215 Vector3 offset = spawnPosition - pos;
4216 float d = Vector3.Mag(offset);
4217 if (d >= distance)
4218 continue;
4219 ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y);
4220 if (land == null)
4221 continue;
4222 if (land.IsEitherBannedOrRestricted(UUID))
4223 continue;
4224 distance = d;
4225 closest = i;
4226 }
4227 if (closest == -1)
4228 return;
4229
4230 pos = spawnPoints[closest].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation);
4231 return;
4232
4233 }
4043 } 4234 }
4044 } 4235 }
4045 } 4236 }
@@ -4084,7 +4275,7 @@ namespace OpenSim.Region.Framework.Scenes
4084 GodLevel < 200 && 4275 GodLevel < 200 &&
4085 ((land.LandData.OwnerID != m_uuid && 4276 ((land.LandData.OwnerID != m_uuid &&
4086 !m_scene.Permissions.IsGod(m_uuid) && 4277 !m_scene.Permissions.IsGod(m_uuid) &&
4087 !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)) || 4278 !m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)) ||
4088 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || 4279 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 ||
4089 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0)) 4280 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0))
4090 { 4281 {