diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/ScenePresence.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 441 |
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 | ||
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,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 | { |