diff options
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/ScenePresence.cs')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 322 |
1 files changed, 283 insertions, 39 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 9cad3fe..f5b37d3 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -118,7 +118,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
118 | /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is | 118 | /// TODO: For some reason, we effectively have a list both here and in Appearance. Need to work out if this is |
119 | /// necessary. | 119 | /// necessary. |
120 | /// </remarks> | 120 | /// </remarks> |
121 | protected List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>(); | 121 | private List<SceneObjectGroup> m_attachments = new List<SceneObjectGroup>(); |
122 | 122 | ||
123 | public Object AttachmentsSyncLock { get; private set; } | 123 | public Object AttachmentsSyncLock { get; private set; } |
124 | 124 | ||
@@ -167,6 +167,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
167 | // private int m_lastColCount = -1; //KF: Look for Collision chnages | 167 | // private int m_lastColCount = -1; //KF: Look for Collision chnages |
168 | // private int m_updateCount = 0; //KF: Update Anims for a while | 168 | // private int m_updateCount = 0; //KF: Update Anims for a while |
169 | // private static readonly int UPDATE_COUNT = 10; // how many frames to update for | 169 | // private static readonly int UPDATE_COUNT = 10; // how many frames to update for |
170 | private List<uint> m_lastColliders = new List<uint>(); | ||
170 | 171 | ||
171 | private TeleportFlags m_teleportFlags; | 172 | private TeleportFlags m_teleportFlags; |
172 | public TeleportFlags TeleportFlags | 173 | public TeleportFlags TeleportFlags |
@@ -228,6 +229,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
228 | //private int m_moveToPositionStateStatus; | 229 | //private int m_moveToPositionStateStatus; |
229 | //***************************************************** | 230 | //***************************************************** |
230 | 231 | ||
232 | private bool m_collisionEventFlag = false; | ||
233 | private object m_collisionEventLock = new Object(); | ||
234 | |||
231 | protected AvatarAppearance m_appearance; | 235 | protected AvatarAppearance m_appearance; |
232 | 236 | ||
233 | public AvatarAppearance Appearance | 237 | public AvatarAppearance Appearance |
@@ -550,8 +554,12 @@ namespace OpenSim.Region.Framework.Scenes | |||
550 | } | 554 | } |
551 | } | 555 | } |
552 | 556 | ||
553 | m_pos = value; | 557 | // Don't update while sitting |
554 | ParentPosition = Vector3.Zero; | 558 | if (ParentID == 0) |
559 | { | ||
560 | m_pos = value; | ||
561 | ParentPosition = Vector3.Zero; | ||
562 | } | ||
555 | 563 | ||
556 | //m_log.DebugFormat( | 564 | //m_log.DebugFormat( |
557 | // "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}", | 565 | // "[ENTITY BASE]: In {0} set AbsolutePosition of {1} to {2}", |
@@ -566,6 +574,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
566 | public Vector3 OffsetPosition | 574 | public Vector3 OffsetPosition |
567 | { | 575 | { |
568 | get { return m_pos; } | 576 | get { return m_pos; } |
577 | set | ||
578 | { | ||
579 | // There is no offset position when not seated | ||
580 | if (ParentID == 0) | ||
581 | return; | ||
582 | m_pos = value; | ||
583 | } | ||
569 | } | 584 | } |
570 | 585 | ||
571 | /// <summary> | 586 | /// <summary> |
@@ -879,6 +894,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
879 | pos.Y = crossedBorder.BorderLine.Z - 1; | 894 | pos.Y = crossedBorder.BorderLine.Z - 1; |
880 | } | 895 | } |
881 | 896 | ||
897 | CheckAndAdjustLandingPoint(ref pos); | ||
898 | |||
882 | if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) | 899 | if (pos.X < 0f || pos.Y < 0f || pos.Z < 0f) |
883 | { | 900 | { |
884 | m_log.WarnFormat( | 901 | m_log.WarnFormat( |
@@ -1043,6 +1060,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1043 | bool isFlying = Flying; | 1060 | bool isFlying = Flying; |
1044 | RemoveFromPhysicalScene(); | 1061 | RemoveFromPhysicalScene(); |
1045 | Velocity = Vector3.Zero; | 1062 | Velocity = Vector3.Zero; |
1063 | CheckLandingPoint(ref pos); | ||
1046 | AbsolutePosition = pos; | 1064 | AbsolutePosition = pos; |
1047 | AddToPhysicalScene(isFlying); | 1065 | AddToPhysicalScene(isFlying); |
1048 | 1066 | ||
@@ -1053,6 +1071,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1053 | { | 1071 | { |
1054 | bool isFlying = Flying; | 1072 | bool isFlying = Flying; |
1055 | RemoveFromPhysicalScene(); | 1073 | RemoveFromPhysicalScene(); |
1074 | CheckLandingPoint(ref pos); | ||
1056 | AbsolutePosition = pos; | 1075 | AbsolutePosition = pos; |
1057 | AddToPhysicalScene(isFlying); | 1076 | AddToPhysicalScene(isFlying); |
1058 | 1077 | ||
@@ -1818,6 +1837,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
1818 | if (part.SitTargetAvatar == UUID) | 1837 | if (part.SitTargetAvatar == UUID) |
1819 | part.SitTargetAvatar = UUID.Zero; | 1838 | part.SitTargetAvatar = UUID.Zero; |
1820 | 1839 | ||
1840 | part.ParentGroup.DeleteAvatar(UUID); | ||
1821 | ParentPosition = part.GetWorldPosition(); | 1841 | ParentPosition = part.GetWorldPosition(); |
1822 | ControllingClient.SendClearFollowCamProperties(part.ParentUUID); | 1842 | ControllingClient.SendClearFollowCamProperties(part.ParentUUID); |
1823 | } | 1843 | } |
@@ -2241,11 +2261,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
2241 | m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT; | 2261 | m_pos = sitTargetPos + SIT_TARGET_ADJUSTMENT; |
2242 | Rotation = sitTargetOrient; | 2262 | Rotation = sitTargetOrient; |
2243 | ParentPosition = part.AbsolutePosition; | 2263 | ParentPosition = part.AbsolutePosition; |
2264 | part.ParentGroup.AddAvatar(UUID); | ||
2244 | } | 2265 | } |
2245 | else | 2266 | else |
2246 | { | 2267 | { |
2247 | m_pos -= part.AbsolutePosition; | 2268 | m_pos -= part.AbsolutePosition; |
2248 | ParentPosition = part.AbsolutePosition; | 2269 | ParentPosition = part.AbsolutePosition; |
2270 | part.ParentGroup.AddAvatar(UUID); | ||
2249 | 2271 | ||
2250 | // m_log.DebugFormat( | 2272 | // m_log.DebugFormat( |
2251 | // "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target", | 2273 | // "[SCENE PRESENCE]: Sitting {0} at position {1} ({2} + {3}) on part {4} {5} without sit target", |
@@ -2744,6 +2766,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
2744 | if (IsChildAgent) | 2766 | if (IsChildAgent) |
2745 | return; | 2767 | return; |
2746 | 2768 | ||
2769 | if (ParentID != 0) | ||
2770 | return; | ||
2771 | |||
2747 | Vector3 pos2 = AbsolutePosition; | 2772 | Vector3 pos2 = AbsolutePosition; |
2748 | Vector3 vel = Velocity; | 2773 | Vector3 vel = Velocity; |
2749 | int neighbor = 0; | 2774 | int neighbor = 0; |
@@ -3104,30 +3129,28 @@ namespace OpenSim.Region.Framework.Scenes | |||
3104 | catch { } | 3129 | catch { } |
3105 | 3130 | ||
3106 | // Attachment objects | 3131 | // Attachment objects |
3107 | lock (m_attachments) | 3132 | List<SceneObjectGroup> attachments = GetAttachments(); |
3133 | if (attachments.Count > 0) | ||
3108 | { | 3134 | { |
3109 | if (m_attachments.Count > 0) | 3135 | cAgent.AttachmentObjects = new List<ISceneObject>(); |
3110 | { | 3136 | cAgent.AttachmentObjectStates = new List<string>(); |
3111 | cAgent.AttachmentObjects = new List<ISceneObject>(); | 3137 | // IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>(); |
3112 | cAgent.AttachmentObjectStates = new List<string>(); | 3138 | InTransitScriptStates.Clear(); |
3113 | // IScriptModule se = m_scene.RequestModuleInterface<IScriptModule>(); | ||
3114 | InTransitScriptStates.Clear(); | ||
3115 | 3139 | ||
3116 | foreach (SceneObjectGroup sog in m_attachments) | 3140 | foreach (SceneObjectGroup sog in attachments) |
3117 | { | 3141 | { |
3118 | // We need to make a copy and pass that copy | 3142 | // We need to make a copy and pass that copy |
3119 | // because of transfers withn the same sim | 3143 | // because of transfers withn the same sim |
3120 | ISceneObject clone = sog.CloneForNewScene(); | 3144 | ISceneObject clone = sog.CloneForNewScene(); |
3121 | // Attachment module assumes that GroupPosition holds the offsets...! | 3145 | // Attachment module assumes that GroupPosition holds the offsets...! |
3122 | ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos; | 3146 | ((SceneObjectGroup)clone).RootPart.GroupPosition = sog.RootPart.AttachedPos; |
3123 | ((SceneObjectGroup)clone).IsAttachment = false; | 3147 | ((SceneObjectGroup)clone).IsAttachment = false; |
3124 | cAgent.AttachmentObjects.Add(clone); | 3148 | cAgent.AttachmentObjects.Add(clone); |
3125 | string state = sog.GetStateSnapshot(); | 3149 | string state = sog.GetStateSnapshot(); |
3126 | cAgent.AttachmentObjectStates.Add(state); | 3150 | cAgent.AttachmentObjectStates.Add(state); |
3127 | InTransitScriptStates.Add(state); | 3151 | InTransitScriptStates.Add(state); |
3128 | // Let's remove the scripts of the original object here | 3152 | // Let's remove the scripts of the original object here |
3129 | sog.RemoveScriptInstances(true); | 3153 | sog.RemoveScriptInstances(true); |
3130 | } | ||
3131 | } | 3154 | } |
3132 | } | 3155 | } |
3133 | } | 3156 | } |
@@ -3350,6 +3373,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3350 | } | 3373 | } |
3351 | } | 3374 | } |
3352 | 3375 | ||
3376 | RaiseCollisionScriptEvents(coldata); | ||
3377 | |||
3353 | if (Invulnerable) | 3378 | if (Invulnerable) |
3354 | return; | 3379 | return; |
3355 | 3380 | ||
@@ -3535,26 +3560,29 @@ namespace OpenSim.Region.Framework.Scenes | |||
3535 | /// <param name="args">The arguments for the event</param> | 3560 | /// <param name="args">The arguments for the event</param> |
3536 | public void SendScriptEventToAttachments(string eventName, Object[] args) | 3561 | public void SendScriptEventToAttachments(string eventName, Object[] args) |
3537 | { | 3562 | { |
3538 | if (m_scriptEngines.Length == 0) | 3563 | Util.FireAndForget(delegate(object x) |
3539 | return; | ||
3540 | |||
3541 | lock (m_attachments) | ||
3542 | { | 3564 | { |
3543 | foreach (SceneObjectGroup grp in m_attachments) | 3565 | if (m_scriptEngines.Length == 0) |
3566 | return; | ||
3567 | |||
3568 | lock (m_attachments) | ||
3544 | { | 3569 | { |
3545 | // 16384 is CHANGED_ANIMATION | 3570 | foreach (SceneObjectGroup grp in m_attachments) |
3546 | // | ||
3547 | // Send this to all attachment root prims | ||
3548 | // | ||
3549 | foreach (IScriptModule m in m_scriptEngines) | ||
3550 | { | 3571 | { |
3551 | if (m == null) // No script engine loaded | 3572 | // 16384 is CHANGED_ANIMATION |
3552 | continue; | 3573 | // |
3574 | // Send this to all attachment root prims | ||
3575 | // | ||
3576 | foreach (IScriptModule m in m_scriptEngines) | ||
3577 | { | ||
3578 | if (m == null) // No script engine loaded | ||
3579 | continue; | ||
3553 | 3580 | ||
3554 | m.PostObjectEvent(grp.RootPart.UUID, "changed", new Object[] { (int)Changed.ANIMATION }); | 3581 | m.PostObjectEvent(grp.RootPart.UUID, "changed", new Object[] { (int)Changed.ANIMATION }); |
3582 | } | ||
3555 | } | 3583 | } |
3556 | } | 3584 | } |
3557 | } | 3585 | }); |
3558 | } | 3586 | } |
3559 | 3587 | ||
3560 | internal void PushForce(Vector3 impulse) | 3588 | internal void PushForce(Vector3 impulse) |
@@ -3786,5 +3814,221 @@ namespace OpenSim.Region.Framework.Scenes | |||
3786 | m_reprioritization_called = false; | 3814 | m_reprioritization_called = false; |
3787 | } | 3815 | } |
3788 | } | 3816 | } |
3817 | |||
3818 | private void CheckLandingPoint(ref Vector3 pos) | ||
3819 | { | ||
3820 | // Never constrain lures | ||
3821 | if ((TeleportFlags & TeleportFlags.ViaLure) != 0) | ||
3822 | return; | ||
3823 | |||
3824 | if (m_scene.RegionInfo.EstateSettings.AllowDirectTeleport) | ||
3825 | return; | ||
3826 | |||
3827 | ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y); | ||
3828 | |||
3829 | if (land.LandData.LandingType == (byte)LandingType.LandingPoint && | ||
3830 | land.LandData.UserLocation != Vector3.Zero && | ||
3831 | land.LandData.OwnerID != m_uuid && | ||
3832 | (!m_scene.Permissions.IsGod(m_uuid)) && | ||
3833 | (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid))) | ||
3834 | { | ||
3835 | float curr = Vector3.Distance(AbsolutePosition, pos); | ||
3836 | if (Vector3.Distance(land.LandData.UserLocation, pos) < curr) | ||
3837 | pos = land.LandData.UserLocation; | ||
3838 | else | ||
3839 | ControllingClient.SendAlertMessage("Can't teleport closer to destination"); | ||
3840 | } | ||
3841 | } | ||
3842 | |||
3843 | private void CheckAndAdjustLandingPoint(ref Vector3 pos) | ||
3844 | { | ||
3845 | ILandObject land = m_scene.LandChannel.GetLandObject(pos.X, pos.Y); | ||
3846 | if (land != null) | ||
3847 | { | ||
3848 | // If we come in via login, landmark or map, we want to | ||
3849 | // honor landing points. If we come in via Lure, we want | ||
3850 | // to ignore them. | ||
3851 | if ((m_teleportFlags & (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID)) == (TeleportFlags.ViaLogin | TeleportFlags.ViaRegionID) || | ||
3852 | (m_teleportFlags & TeleportFlags.ViaLandmark) != 0 || | ||
3853 | (m_teleportFlags & TeleportFlags.ViaLocation) != 0) | ||
3854 | { | ||
3855 | // Don't restrict gods, estate managers, or land owners to | ||
3856 | // the TP point. This behaviour mimics agni. | ||
3857 | if (land.LandData.LandingType == (byte)LandingType.LandingPoint && | ||
3858 | land.LandData.UserLocation != Vector3.Zero && | ||
3859 | GodLevel < 200 && | ||
3860 | ((land.LandData.OwnerID != m_uuid && | ||
3861 | (!m_scene.Permissions.IsGod(m_uuid)) && | ||
3862 | (!m_scene.RegionInfo.EstateSettings.IsEstateManager(m_uuid))) || (m_teleportFlags & TeleportFlags.ViaLocation) != 0)) | ||
3863 | { | ||
3864 | pos = land.LandData.UserLocation; | ||
3865 | } | ||
3866 | } | ||
3867 | |||
3868 | land.SendLandUpdateToClient(ControllingClient); | ||
3869 | } | ||
3870 | } | ||
3871 | |||
3872 | private void RaiseCollisionScriptEvents(Dictionary<uint, ContactPoint> coldata) | ||
3873 | { | ||
3874 | lock(m_collisionEventLock) | ||
3875 | { | ||
3876 | if (m_collisionEventFlag) | ||
3877 | return; | ||
3878 | m_collisionEventFlag = true; | ||
3879 | } | ||
3880 | |||
3881 | Util.FireAndForget(delegate(object x) | ||
3882 | { | ||
3883 | try | ||
3884 | { | ||
3885 | List<uint> thisHitColliders = new List<uint>(); | ||
3886 | List<uint> endedColliders = new List<uint>(); | ||
3887 | List<uint> startedColliders = new List<uint>(); | ||
3888 | |||
3889 | foreach (uint localid in coldata.Keys) | ||
3890 | { | ||
3891 | thisHitColliders.Add(localid); | ||
3892 | if (!m_lastColliders.Contains(localid)) | ||
3893 | { | ||
3894 | startedColliders.Add(localid); | ||
3895 | } | ||
3896 | //m_log.Debug("[SCENE PRESENCE]: Collided with:" + localid.ToString() + " at depth of: " + collissionswith[localid].ToString()); | ||
3897 | } | ||
3898 | |||
3899 | // calculate things that ended colliding | ||
3900 | foreach (uint localID in m_lastColliders) | ||
3901 | { | ||
3902 | if (!thisHitColliders.Contains(localID)) | ||
3903 | { | ||
3904 | endedColliders.Add(localID); | ||
3905 | } | ||
3906 | } | ||
3907 | //add the items that started colliding this time to the last colliders list. | ||
3908 | foreach (uint localID in startedColliders) | ||
3909 | { | ||
3910 | m_lastColliders.Add(localID); | ||
3911 | } | ||
3912 | // remove things that ended colliding from the last colliders list | ||
3913 | foreach (uint localID in endedColliders) | ||
3914 | { | ||
3915 | m_lastColliders.Remove(localID); | ||
3916 | } | ||
3917 | |||
3918 | // do event notification | ||
3919 | if (startedColliders.Count > 0) | ||
3920 | { | ||
3921 | ColliderArgs StartCollidingMessage = new ColliderArgs(); | ||
3922 | List<DetectedObject> colliding = new List<DetectedObject>(); | ||
3923 | foreach (uint localId in startedColliders) | ||
3924 | { | ||
3925 | if (localId == 0) | ||
3926 | continue; | ||
3927 | |||
3928 | SceneObjectPart obj = Scene.GetSceneObjectPart(localId); | ||
3929 | string data = ""; | ||
3930 | if (obj != null) | ||
3931 | { | ||
3932 | DetectedObject detobj = new DetectedObject(); | ||
3933 | detobj.keyUUID = obj.UUID; | ||
3934 | detobj.nameStr = obj.Name; | ||
3935 | detobj.ownerUUID = obj.OwnerID; | ||
3936 | detobj.posVector = obj.AbsolutePosition; | ||
3937 | detobj.rotQuat = obj.GetWorldRotation(); | ||
3938 | detobj.velVector = obj.Velocity; | ||
3939 | detobj.colliderType = 0; | ||
3940 | detobj.groupUUID = obj.GroupID; | ||
3941 | colliding.Add(detobj); | ||
3942 | } | ||
3943 | } | ||
3944 | |||
3945 | if (colliding.Count > 0) | ||
3946 | { | ||
3947 | StartCollidingMessage.Colliders = colliding; | ||
3948 | |||
3949 | foreach (SceneObjectGroup att in GetAttachments()) | ||
3950 | Scene.EventManager.TriggerScriptCollidingStart(att.LocalId, StartCollidingMessage); | ||
3951 | } | ||
3952 | } | ||
3953 | |||
3954 | if (endedColliders.Count > 0) | ||
3955 | { | ||
3956 | ColliderArgs EndCollidingMessage = new ColliderArgs(); | ||
3957 | List<DetectedObject> colliding = new List<DetectedObject>(); | ||
3958 | foreach (uint localId in endedColliders) | ||
3959 | { | ||
3960 | if (localId == 0) | ||
3961 | continue; | ||
3962 | |||
3963 | SceneObjectPart obj = Scene.GetSceneObjectPart(localId); | ||
3964 | string data = ""; | ||
3965 | if (obj != null) | ||
3966 | { | ||
3967 | DetectedObject detobj = new DetectedObject(); | ||
3968 | detobj.keyUUID = obj.UUID; | ||
3969 | detobj.nameStr = obj.Name; | ||
3970 | detobj.ownerUUID = obj.OwnerID; | ||
3971 | detobj.posVector = obj.AbsolutePosition; | ||
3972 | detobj.rotQuat = obj.GetWorldRotation(); | ||
3973 | detobj.velVector = obj.Velocity; | ||
3974 | detobj.colliderType = 0; | ||
3975 | detobj.groupUUID = obj.GroupID; | ||
3976 | colliding.Add(detobj); | ||
3977 | } | ||
3978 | } | ||
3979 | |||
3980 | if (colliding.Count > 0) | ||
3981 | { | ||
3982 | EndCollidingMessage.Colliders = colliding; | ||
3983 | |||
3984 | foreach (SceneObjectGroup att in GetAttachments()) | ||
3985 | Scene.EventManager.TriggerScriptCollidingEnd(att.LocalId, EndCollidingMessage); | ||
3986 | } | ||
3987 | } | ||
3988 | |||
3989 | if (thisHitColliders.Count > 0) | ||
3990 | { | ||
3991 | ColliderArgs CollidingMessage = new ColliderArgs(); | ||
3992 | List<DetectedObject> colliding = new List<DetectedObject>(); | ||
3993 | foreach (uint localId in thisHitColliders) | ||
3994 | { | ||
3995 | if (localId == 0) | ||
3996 | continue; | ||
3997 | |||
3998 | SceneObjectPart obj = Scene.GetSceneObjectPart(localId); | ||
3999 | string data = ""; | ||
4000 | if (obj != null) | ||
4001 | { | ||
4002 | DetectedObject detobj = new DetectedObject(); | ||
4003 | detobj.keyUUID = obj.UUID; | ||
4004 | detobj.nameStr = obj.Name; | ||
4005 | detobj.ownerUUID = obj.OwnerID; | ||
4006 | detobj.posVector = obj.AbsolutePosition; | ||
4007 | detobj.rotQuat = obj.GetWorldRotation(); | ||
4008 | detobj.velVector = obj.Velocity; | ||
4009 | detobj.colliderType = 0; | ||
4010 | detobj.groupUUID = obj.GroupID; | ||
4011 | colliding.Add(detobj); | ||
4012 | } | ||
4013 | } | ||
4014 | |||
4015 | if (colliding.Count > 0) | ||
4016 | { | ||
4017 | CollidingMessage.Colliders = colliding; | ||
4018 | |||
4019 | lock (m_attachments) | ||
4020 | { | ||
4021 | foreach (SceneObjectGroup att in m_attachments) | ||
4022 | Scene.EventManager.TriggerScriptColliding(att.LocalId, CollidingMessage); | ||
4023 | } | ||
4024 | } | ||
4025 | } | ||
4026 | } | ||
4027 | finally | ||
4028 | { | ||
4029 | m_collisionEventFlag = false; | ||
4030 | } | ||
4031 | }); | ||
4032 | } | ||
3789 | } | 4033 | } |
3790 | } | 4034 | } |