示例#1
0
        public override async Task StateEntry()
        {
            //no matter what happens at this point we want to make sure the avatar doesnt try to immediately recross should we have
            //a failure. bounce them off the border
            if (_avatar.TransitArgs.Type == TransitType.OutboundCrossing && _avatar.TransitArgs.RideOnGroup == null)
            {
                Vector3 backVel = -_avatar.ScenePresence.Velocity;
                RollbackActions.Push(() =>
                {
                    Vector3 newpos = _avatar.ScenePresence.AbsolutePosition + (backVel * 2.0f);
                    Util.ForceValidRegionXYZ(ref newpos);
                    _avatar.ScenePresence.AbsolutePosition = newpos;
                });
            }

            //assert that this avatar is fully in this region before beginning a send
            if (_avatar.ScenePresence.Connection.State != OpenSim.Framework.AvatarConnectionState.Established)
            {
                throw new InvalidOperationException("An avatar can not begin transition to a new region while already in transit");
            }

            //assert that this avatar is not currently establishing connections to other regions
            if (_avatar.ScenePresence.RemotePresences.HasConnectionsEstablishing())
            {
//                _avatar.ScenePresence.ControllingClient.SendAlertMessage("Can not move to a new region, connections are still being established");
                throw new InvalidOperationException("An avatar can not begin transition to a new region while connections are being established to neighbor regions");
            }

            //if we're riding on a prim, wait for the all clear before moving on
            if (_avatar.TransitArgs.RideOnPart != null)
            {
                bool success = await _avatar.WaitForRemoteObjectCreation();

                if (!success)
                {
                    _avatar.ScenePresence.ControllingClient.SendAlertMessage("Unable to create object in remote region");
                    throw new SendAvatarException("Remote object creation failed");
                }
            }

            //listeners to this event will stop all traffic and suspend physics for the avatar
            //there is nothing else we need to do in this state
            await _avatar.TriggerOnTransitStageChanged(TransitStage.SendBegin, _avatar.RideOnPrims);

            RollbackActions.Push(() =>
            {
                var task = _avatar.TriggerOnTransitStageChanged(TransitStage.SendError, _avatar.RideOnPrims);
                task.Wait();
            });

            var nextState = new SendAvatarState(_avatar, this);
            await _avatar.SetNewState(nextState);
        }
        public override async Task StateEntry()
        {
            //no matter what happens at this point we want to make sure the avatar doesnt try to immediately recross should we have
            //a failure. bounce them off the border
            Vector3 pos = _avatar.ScenePresence.AbsolutePosition;
            if (_avatar.TransitArgs.Type == TransitType.OutboundCrossing && _avatar.TransitArgs.RideOnGroup == null)
            {
                Vector3 backVel = -_avatar.ScenePresence.Velocity;
                RollbackActions.Push(() =>
                {
                    Vector3 newpos = pos + (backVel * 2.0f);
                    // Check if "bounce back leaves region". If so, don't apply bounce.
                    if (!Util.IsValidRegionXY(newpos))
                        newpos = pos;    // just limit current pos to valid.
                    Util.ForceValidRegionXYZ(ref newpos);
                    _avatar.ScenePresence.AbsolutePosition = newpos;
                });
            }

            //assert that this avatar is fully in this region before beginning a send
            if (_avatar.ScenePresence.Connection.State != OpenSim.Framework.AvatarConnectionState.Established)
            {
                throw new InvalidOperationException("An avatar can not begin transition to a new region while already in transit");
            }

            //assert that this avatar is ready to leave the region
            if (!_avatar.ScenePresence.IsFullyInRegion)
            {
//                _avatar.ScenePresence.ControllingClient.SendAlertMessage("Can not move to a new region, until established in the current region");
                throw new InvalidOperationException("An avatar can not begin transition to a new region until established in the current region");
            }

            //assert that the dest region is available and this avatar has an established connection to that region
            if (_avatar.ScenePresence.RemotePresences.HasConnectionsEstablishing())
            {
//                _avatar.ScenePresence.ControllingClient.SendAlertMessage("Can not move to a new region, connections are still being established");
                throw new InvalidOperationException("An avatar can not begin transition to a neighbor region while the connections are still being established");
            }

            //if we're riding on a prim, wait for the all clear before moving on
            if (_avatar.TransitArgs.RideOnPart != null)
            {
                bool success = await _avatar.WaitForRemoteObjectCreation();
                if (!success)
                {
                    _avatar.ScenePresence.ControllingClient.SendAlertMessage("Unable to create object in remote region");
                    throw new SendAvatarException("Remote object creation failed");
                }
            }

            //listeners to this event will stop all traffic and suspend physics for the avatar
            //there is nothing else we need to do in this state
            await _avatar.TriggerOnTransitStageChanged(TransitStage.SendBegin, _avatar.RideOnPrims);

            RollbackActions.Push(() => 
                {
                    var task = _avatar.TriggerOnTransitStageChanged(TransitStage.SendError, _avatar.RideOnPrims);
                    task.Wait();
                });

            var nextState = new SendAvatarState(_avatar, this);
            await _avatar.SetNewState(nextState);
        }