diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/ScenePresence.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 427 |
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 | ||
46 | namespace OpenSim.Region.Framework.Scenes | 46 | namespace OpenSim.Region.Framework.Scenes |
47 | { | 47 | { |
48 | [Flags] | ||
48 | enum ScriptControlled : uint | 49 | enum ScriptControlled : uint |
49 | { | 50 | { |
50 | CONTROL_ZERO = 0, | 51 | CONTROL_ZERO = 0, |
@@ -76,6 +77,11 @@ namespace OpenSim.Region.Framework.Scenes | |||
76 | // { | 77 | // { |
77 | // m_log.Debug("[SCENE PRESENCE] Destructor called"); | 78 | // m_log.Debug("[SCENE PRESENCE] Destructor called"); |
78 | // } | 79 | // } |
80 | private void TriggerScenePresenceUpdated() | ||
81 | { | ||
82 | if (m_scene != null) | ||
83 | m_scene.EventManager.TriggerScenePresenceUpdated(this); | ||
84 | } | ||
79 | 85 | ||
80 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 86 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
81 | 87 | ||
@@ -497,6 +503,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
497 | //m_log.DebugFormat( | 503 | //m_log.DebugFormat( |
498 | // "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}", | 504 | // "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}", |
499 | // Scene.RegionInfo.RegionName, Name, m_pos); | 505 | // Scene.RegionInfo.RegionName, Name, m_pos); |
506 | TriggerScenePresenceUpdated(); | ||
500 | } | 507 | } |
501 | } | 508 | } |
502 | 509 | ||
@@ -516,6 +523,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
516 | return; | 523 | return; |
517 | 524 | ||
518 | m_pos = value; | 525 | m_pos = value; |
526 | TriggerScenePresenceUpdated(); | ||
519 | } | 527 | } |
520 | } | 528 | } |
521 | 529 | ||
@@ -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 | { |