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.cs441
1 files changed, 315 insertions, 126 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs
index 5a3b518..225d4c9 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
@@ -3497,25 +3513,53 @@ namespace OpenSim.Region.Framework.Scenes
3497 } 3513 }
3498 } 3514 }
3499 3515
3500 RaiseCollisionScriptEvents(coldata); 3516 // Gods do not take damage and Invulnerable is set depending on parcel/region flags
3501 3517 if (Invulnerable || GodLevel > 0)
3502 if (Invulnerable)
3503 return; 3518 return;
3504 3519
3520 // The following may be better in the ICombatModule
3521 // probably tweaking of the values for ground and normal prim collisions will be needed
3505 float starthealth = Health; 3522 float starthealth = Health;
3506 uint killerObj = 0; 3523 uint killerObj = 0;
3524 SceneObjectPart part = null;
3507 foreach (uint localid in coldata.Keys) 3525 foreach (uint localid in coldata.Keys)
3508 { 3526 {
3509 SceneObjectPart part = Scene.GetSceneObjectPart(localid); 3527 if (localid == 0)
3510 3528 {
3511 if (part != null && part.ParentGroup.Damage != -1.0f) 3529 part = null;
3512 Health -= part.ParentGroup.Damage; 3530 }
3531 else
3532 {
3533 part = Scene.GetSceneObjectPart(localid);
3534 }
3535 if (part != null)
3536 {
3537 // Ignore if it has been deleted or volume detect
3538 if (!part.ParentGroup.IsDeleted && !part.ParentGroup.IsVolumeDetect)
3539 {
3540 if (part.ParentGroup.Damage > 0.0f)
3541 {
3542 // Something with damage...
3543 Health -= part.ParentGroup.Damage;
3544 part.ParentGroup.Scene.DeleteSceneObject(part.ParentGroup, false);
3545 }
3546 else
3547 {
3548 // An ordinary prim
3549 if (coldata[localid].PenetrationDepth >= 0.10f)
3550 Health -= coldata[localid].PenetrationDepth * 5.0f;
3551 }
3552 }
3553 }
3513 else 3554 else
3514 { 3555 {
3515 if (coldata[localid].PenetrationDepth >= 0.10f) 3556 // 0 is the ground
3557 // what about collisions with other avatars?
3558 if (localid == 0 && coldata[localid].PenetrationDepth >= 0.10f)
3516 Health -= coldata[localid].PenetrationDepth * 5.0f; 3559 Health -= coldata[localid].PenetrationDepth * 5.0f;
3517 } 3560 }
3518 3561
3562
3519 if (Health <= 0.0f) 3563 if (Health <= 0.0f)
3520 { 3564 {
3521 if (localid != 0) 3565 if (localid != 0)
@@ -3531,7 +3575,16 @@ namespace OpenSim.Region.Framework.Scenes
3531 ControllingClient.SendHealth(Health); 3575 ControllingClient.SendHealth(Health);
3532 } 3576 }
3533 if (Health <= 0) 3577 if (Health <= 0)
3578 {
3534 m_scene.EventManager.TriggerAvatarKill(killerObj, this); 3579 m_scene.EventManager.TriggerAvatarKill(killerObj, this);
3580 }
3581 if (starthealth == Health && Health < 100.0f)
3582 {
3583 Health += 0.03f;
3584 if (Health > 100.0f)
3585 Health = 100.0f;
3586 ControllingClient.SendHealth(Health);
3587 }
3535 } 3588 }
3536 } 3589 }
3537 3590
@@ -3613,6 +3666,63 @@ namespace OpenSim.Region.Framework.Scenes
3613 return m_attachments.Count > 0; 3666 return m_attachments.Count > 0;
3614 } 3667 }
3615 3668
3669 /// <summary>
3670 /// Returns the total count of scripts in all parts inventories.
3671 /// </summary>
3672 public int ScriptCount()
3673 {
3674 int count = 0;
3675 lock (m_attachments)
3676 {
3677 foreach (SceneObjectGroup gobj in m_attachments)
3678 {
3679 if (gobj != null)
3680 {
3681 count += gobj.ScriptCount();
3682 }
3683 }
3684 }
3685 return count;
3686 }
3687
3688 /// <summary>
3689 /// A float the value is a representative execution time in milliseconds of all scripts in all attachments.
3690 /// </summary>
3691 public float ScriptExecutionTime()
3692 {
3693 float time = 0.0f;
3694 lock (m_attachments)
3695 {
3696 foreach (SceneObjectGroup gobj in m_attachments)
3697 {
3698 if (gobj != null)
3699 {
3700 time += gobj.ScriptExecutionTime();
3701 }
3702 }
3703 }
3704 return time;
3705 }
3706
3707 /// <summary>
3708 /// Returns the total count of running scripts in all parts.
3709 /// </summary>
3710 public int RunningScriptCount()
3711 {
3712 int count = 0;
3713 lock (m_attachments)
3714 {
3715 foreach (SceneObjectGroup gobj in m_attachments)
3716 {
3717 if (gobj != null)
3718 {
3719 count += gobj.RunningScriptCount();
3720 }
3721 }
3722 }
3723 return count;
3724 }
3725
3616 public bool HasScriptedAttachments() 3726 public bool HasScriptedAttachments()
3617 { 3727 {
3618 lock (m_attachments) 3728 lock (m_attachments)
@@ -3830,77 +3940,92 @@ namespace OpenSim.Region.Framework.Scenes
3830 } 3940 }
3831 } 3941 }
3832 3942
3833 internal void SendControlToScripts(uint flags) 3943 private void SendControlsToScripts(uint flags)
3834 { 3944 {
3835 ScriptControlled allflags = ScriptControlled.CONTROL_ZERO; 3945 // Notify the scripts only after calling UpdateMovementAnimations(), so that if a script
3836 3946 // (e.g., a walking script) checks which animation is active it will be the correct animation.
3837 if (MouseDown) 3947 lock (scriptedcontrols)
3838 { 3948 {
3839 allflags = LastCommands & (ScriptControlled.CONTROL_ML_LBUTTON | ScriptControlled.CONTROL_LBUTTON); 3949 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) 3950 return;
3951
3952 ScriptControlled allflags = ScriptControlled.CONTROL_ZERO;
3953
3954 if (MouseDown)
3841 { 3955 {
3842 allflags = ScriptControlled.CONTROL_ZERO; 3956 allflags = LastCommands & (ScriptControlled.CONTROL_ML_LBUTTON | ScriptControlled.CONTROL_LBUTTON);
3957 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_UP) != 0 || (flags & unchecked((uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_UP)) != 0)
3958 {
3959 allflags = ScriptControlled.CONTROL_ZERO;
3960 MouseDown = true;
3961 }
3962 }
3963
3964 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN) != 0)
3965 {
3966 allflags |= ScriptControlled.CONTROL_ML_LBUTTON;
3843 MouseDown = true; 3967 MouseDown = true;
3844 } 3968 }
3845 } 3969
3970 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0)
3971 {
3972 allflags |= ScriptControlled.CONTROL_LBUTTON;
3973 MouseDown = true;
3974 }
3975
3976 // find all activated controls, whether the scripts are interested in them or not
3977 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_POS) != 0)
3978 {
3979 allflags |= ScriptControlled.CONTROL_FWD;
3980 }
3981
3982 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_AT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_AT_NEG) != 0)
3983 {
3984 allflags |= ScriptControlled.CONTROL_BACK;
3985 }
3986
3987 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_POS) != 0)
3988 {
3989 allflags |= ScriptControlled.CONTROL_UP;
3990 }
3991
3992 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_UP_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_UP_NEG) != 0)
3993 {
3994 allflags |= ScriptControlled.CONTROL_DOWN;
3995 }
3846 3996
3847 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_ML_LBUTTON_DOWN) != 0) 3997 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_POS) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_POS) != 0)
3848 { 3998 {
3849 allflags |= ScriptControlled.CONTROL_ML_LBUTTON; 3999 allflags |= ScriptControlled.CONTROL_LEFT;
3850 MouseDown = true; 4000 }
3851 } 4001
3852 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LBUTTON_DOWN) != 0) 4002 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_LEFT_NEG) != 0 || (flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_NUDGE_LEFT_NEG) != 0)
3853 { 4003 {
3854 allflags |= ScriptControlled.CONTROL_LBUTTON; 4004 allflags |= ScriptControlled.CONTROL_RIGHT;
3855 MouseDown = true; 4005 }
3856 } 4006
4007 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_NEG) != 0)
4008 {
4009 allflags |= ScriptControlled.CONTROL_ROT_RIGHT;
4010 }
4011
4012 if ((flags & (uint)AgentManager.ControlFlags.AGENT_CONTROL_YAW_POS) != 0)
4013 {
4014 allflags |= ScriptControlled.CONTROL_ROT_LEFT;
4015 }
3857 4016
3858 // find all activated controls, whether the scripts are interested in them or not 4017 // 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) 4018 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 { 4019 {
3896 foreach (KeyValuePair<UUID, ScriptControllers> kvp in scriptedcontrols) 4020 foreach (KeyValuePair<UUID, ScriptControllers> kvp in scriptedcontrols)
3897 { 4021 {
3898 UUID scriptUUID = kvp.Key; 4022 UUID scriptUUID = kvp.Key;
3899 ScriptControllers scriptControlData = kvp.Value; 4023 ScriptControllers scriptControlData = kvp.Value;
3900 4024
3901 ScriptControlled localHeld = allflags & scriptControlData.eventControls; // the flags interesting for us 4025 ScriptControlled localHeld = allflags & scriptControlData.eventControls; // the flags interesting for us
3902 ScriptControlled localLast = LastCommands & scriptControlData.eventControls; // the activated controls in the last cycle 4026 ScriptControlled localLast = LastCommands & scriptControlData.eventControls; // the activated controls in the last cycle
3903 ScriptControlled localChange = localHeld ^ localLast; // the changed bits 4027 ScriptControlled localChange = localHeld ^ localLast; // the changed bits
4028
3904 if (localHeld != ScriptControlled.CONTROL_ZERO || localChange != ScriptControlled.CONTROL_ZERO) 4029 if (localHeld != ScriptControlled.CONTROL_ZERO || localChange != ScriptControlled.CONTROL_ZERO)
3905 { 4030 {
3906 // only send if still pressed or just changed 4031 // only send if still pressed or just changed
@@ -3908,9 +4033,9 @@ namespace OpenSim.Region.Framework.Scenes
3908 } 4033 }
3909 } 4034 }
3910 } 4035 }
4036
4037 LastCommands = allflags;
3911 } 4038 }
3912
3913 LastCommands = allflags;
3914 } 4039 }
3915 4040
3916 internal static AgentManager.ControlFlags RemoveIgnoredControls(AgentManager.ControlFlags flags, ScriptControlled ignored) 4041 internal static AgentManager.ControlFlags RemoveIgnoredControls(AgentManager.ControlFlags flags, ScriptControlled ignored)
@@ -3990,7 +4115,7 @@ namespace OpenSim.Region.Framework.Scenes
3990 land.LandData.UserLocation != Vector3.Zero && 4115 land.LandData.UserLocation != Vector3.Zero &&
3991 land.LandData.OwnerID != m_uuid && 4116 land.LandData.OwnerID != m_uuid &&
3992 (!m_scene.Permissions.IsGod(m_uuid)) && 4117 (!m_scene.Permissions.IsGod(m_uuid)) &&
3993 (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid))) 4118 (!m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)))
3994 { 4119 {
3995 float curr = Vector3.Distance(AbsolutePosition, pos); 4120 float curr = Vector3.Distance(AbsolutePosition, pos);
3996 if (Vector3.Distance(land.LandData.UserLocation, pos) < curr) 4121 if (Vector3.Distance(land.LandData.UserLocation, pos) < curr)
@@ -4004,13 +4129,13 @@ namespace OpenSim.Region.Framework.Scenes
4004 { 4129 {
4005 if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) == 4130 if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) ==
4006 (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) || 4131 (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) ||
4007 (m_teleportFlags & TeleportFlags.ViaLandmark) != 0 || 4132 (m_scene.TelehubAllowLandmarks == true ? false : ((m_teleportFlags & TeleportFlags.ViaLandmark) != 0 )) ||
4008 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || 4133 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 ||
4009 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0) 4134 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0)
4010 { 4135 {
4011 if (GodLevel < 200 && 4136 if (GodLevel < 200 &&
4012 ((!m_scene.Permissions.IsGod(m_uuid) && 4137 ((!m_scene.Permissions.IsGod(m_uuid) &&
4013 !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)) || 4138 !m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)) ||
4014 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || 4139 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 ||
4015 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0)) 4140 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0))
4016 { 4141 {
@@ -4018,28 +4143,92 @@ namespace OpenSim.Region.Framework.Scenes
4018 if (spawnPoints.Length == 0) 4143 if (spawnPoints.Length == 0)
4019 return; 4144 return;
4020 4145
4021 float distance = 9999; 4146 int index;
4022 int closest = -1; 4147 bool selected = false;
4023 4148
4024 for (int i = 0 ; i < spawnPoints.Length ; i++) 4149 switch (m_scene.SpawnPointRouting)
4025 { 4150 {
4026 Vector3 spawnPosition = spawnPoints[i].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); 4151 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 4152
4042 pos = spawnPoints[closest].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation); 4153 do
4154 {
4155 index = Util.RandomClass.Next(spawnPoints.Length - 1);
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(
4172 telehub.AbsolutePosition,
4173 telehub.GroupRotation
4174 );
4175 return;
4176
4177 case "sequence":
4178
4179 do
4180 {
4181 index = m_scene.SpawnPoint();
4182
4183 Vector3 spawnPosition = spawnPoints[index].GetLocation(
4184 telehub.AbsolutePosition,
4185 telehub.GroupRotation
4186 );
4187 // SpawnPoint sp = spawnPoints[index];
4188
4189 ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y);
4190 if (land == null || land.IsEitherBannedOrRestricted(UUID))
4191 selected = false;
4192 else
4193 selected = true;
4194
4195 } while (selected == false);
4196
4197 pos = spawnPoints[index].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation);
4198 ;
4199 return;
4200
4201 default:
4202 case "closest":
4203
4204 float distance = 9999;
4205 int closest = -1;
4206
4207 for (int i = 0; i < spawnPoints.Length; i++)
4208 {
4209 Vector3 spawnPosition = spawnPoints[i].GetLocation(
4210 telehub.AbsolutePosition,
4211 telehub.GroupRotation
4212 );
4213 Vector3 offset = spawnPosition - pos;
4214 float d = Vector3.Mag(offset);
4215 if (d >= distance)
4216 continue;
4217 ILandObject land = m_scene.LandChannel.GetLandObject(spawnPosition.X, spawnPosition.Y);
4218 if (land == null)
4219 continue;
4220 if (land.IsEitherBannedOrRestricted(UUID))
4221 continue;
4222 distance = d;
4223 closest = i;
4224 }
4225 if (closest == -1)
4226 return;
4227
4228 pos = spawnPoints[closest].GetLocation(telehub.AbsolutePosition, telehub.GroupRotation);
4229 return;
4230
4231 }
4043 } 4232 }
4044 } 4233 }
4045 } 4234 }
@@ -4084,7 +4273,7 @@ namespace OpenSim.Region.Framework.Scenes
4084 GodLevel < 200 && 4273 GodLevel < 200 &&
4085 ((land.LandData.OwnerID != m_uuid && 4274 ((land.LandData.OwnerID != m_uuid &&
4086 !m_scene.Permissions.IsGod(m_uuid) && 4275 !m_scene.Permissions.IsGod(m_uuid) &&
4087 !m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid)) || 4276 !m_scene.RegionInfo.EstateSettings.IsEstateManagerOrOwner(m_uuid)) ||
4088 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 || 4277 (m_teleportFlags & TeleportFlags.ViaLocation) != 0 ||
4089 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0)) 4278 (m_teleportFlags & Constants.TeleportFlags.ViaHGLogin) != 0))
4090 { 4279 {