Exemplo n.º 1
0
        public override void Deserialize(BinaryReader reader)
        {
            base.Deserialize(reader);

            var roomN = reader.ReadInt32();
            Rooms = new VMRoomPortal[roomN];
            for (int i=0; i< roomN; i++) Rooms[i] = new VMRoomPortal(reader);

            if (reader.ReadBoolean()) CurrentPortal = new VMRoomPortal(reader);

            var wtLen = reader.ReadInt32();
            if (wtLen > -1)
            {
                WalkTo = new Point[wtLen];
                for (int i = 0; i < wtLen; i++) WalkTo[i] = new Point(reader.ReadInt32(), reader.ReadInt32());
            }

            WalkDirection = reader.ReadDouble();
            TargetDirection = reader.ReadDouble();
            IgnoreRooms = reader.ReadBoolean();

            State = (VMRoutingFrameState)reader.ReadByte();
            PortalTurns = reader.ReadInt32();
            WaitTime = reader.ReadInt32();
            Timeout = reader.ReadInt32();
            Retries = reader.ReadInt32();

            AttemptedChair = reader.ReadBoolean();
            TurnTweak = reader.ReadSingle();
            TurnFrames = reader.ReadInt32();

            MoveTotalFrames = reader.ReadInt32();
            MoveFrames = reader.ReadInt32();
            Velocity = reader.ReadInt32();

            CallFailureTrees = reader.ReadBoolean();

            var igrN = reader.ReadInt32();
            IgnoredRooms = new VMRoomPortal[igrN];
            for (int i = 0; i < igrN; i++) IgnoredRooms[i] = new VMRoomPortal(reader);

            var avaN = reader.ReadInt32();
            AvatarsToConsider = new short[avaN];
            for (int i = 0; i < avaN; i++) AvatarsToConsider[i] = reader.ReadInt16();

            PreviousPosition.Deserialize(reader);
            CurrentWaypoint.Deserialize(reader);

            RoomRouteInvalid = reader.ReadBoolean();

            if (reader.ReadBoolean()) {
                Slot = SLOTItemSerializer.Deserialize(reader);
            }
            Target = reader.ReadInt16();

            var chLen = reader.ReadInt32();
            if (chLen > -1)
            {
                Choices = new VMFindLocationResultMarshal[chLen];
                for (int i = 0; i < chLen; i++)
                {
                    Choices[i] = new VMFindLocationResultMarshal();
                    Choices[i].Deserialize(reader);
                }
            }

            if (reader.ReadBoolean())
            {
                CurRoute = new VMFindLocationResultMarshal();
                CurRoute.Deserialize(reader);
            }
        }
Exemplo n.º 2
0
        public override void Deserialize(BinaryReader reader)
        {
            base.Deserialize(reader);

            var roomN = reader.ReadInt32();

            Rooms = new VMRoomPortal[roomN];
            for (int i = 0; i < roomN; i++)
            {
                Rooms[i] = new VMRoomPortal(reader);
            }

            if (reader.ReadBoolean())
            {
                CurrentPortal = new VMRoomPortal(reader);
            }

            var wtLen = reader.ReadInt32();

            if (wtLen > -1)
            {
                WalkTo = new Point[wtLen];
                for (int i = 0; i < wtLen; i++)
                {
                    WalkTo[i] = new Point(reader.ReadInt32(), reader.ReadInt32());
                }
            }

            WalkDirection   = reader.ReadDouble();
            TargetDirection = reader.ReadDouble();
            IgnoreRooms     = reader.ReadBoolean();

            State       = (VMRoutingFrameState)reader.ReadByte();
            PortalTurns = reader.ReadInt32();
            WaitTime    = reader.ReadInt32();
            Timeout     = reader.ReadInt32();
            Retries     = reader.ReadInt32();

            AttemptedChair = reader.ReadBoolean();
            TurnTweak      = reader.ReadSingle();
            TurnFrames     = reader.ReadInt32();

            MoveTotalFrames = reader.ReadInt32();
            MoveFrames      = reader.ReadInt32();
            Velocity        = reader.ReadInt32();

            CallFailureTrees = reader.ReadBoolean();

            var igrN = reader.ReadInt32();

            IgnoredRooms = new VMRoomPortal[igrN];
            for (int i = 0; i < igrN; i++)
            {
                IgnoredRooms[i] = new VMRoomPortal(reader);
            }

            var avaN = reader.ReadInt32();

            AvatarsToConsider = new short[avaN];
            for (int i = 0; i < avaN; i++)
            {
                AvatarsToConsider[i] = reader.ReadInt16();
            }

            PreviousPosition.Deserialize(reader);
            CurrentWaypoint.Deserialize(reader);

            RoomRouteInvalid = reader.ReadBoolean();

            if (reader.ReadBoolean())
            {
                Slot = SLOTItemSerializer.Deserialize(reader);
            }
            Target = reader.ReadInt16();

            var chLen = reader.ReadInt32();

            if (chLen > -1)
            {
                Choices = new VMFindLocationResultMarshal[chLen];
                for (int i = 0; i < chLen; i++)
                {
                    Choices[i] = new VMFindLocationResultMarshal();
                    Choices[i].Deserialize(reader);
                }
            }

            if (reader.ReadBoolean())
            {
                CurRoute = new VMFindLocationResultMarshal();
                CurRoute.Deserialize(reader);
            }

            if (Version > 29)
            {
                LastWalkStyle = reader.ReadInt16();
            }
        }
Exemplo n.º 3
0
        private void BeginWalk()
        {
            //faces the avatar towards the initial walk direction and begins walking.
            WalkDirection = Caller.RadianDirection;
            var directionDiff = DirectionUtils.Difference(Caller.RadianDirection, TargetDirection);

            bool hardStart = CanPortalTurn();
            Velocity = (hardStart) ? 0 : 8;

            if (hardStart && Turn(directionDiff))
            {
                State = VMRoutingFrameState.BEGIN_TURN;
            }
            else
            {
                State = VMRoutingFrameState.WALKING;
                Caller.RadianDirection = (float)TargetDirection;
                StartWalkAnimation();
            }
        }
Exemplo n.º 4
0
        //returns true if we should exit immediately.
        private bool EndWalk()
        {
            var avatar = (VMAvatar)Caller;
            WalkDirection = Caller.RadianDirection;
            TargetDirection = CurRoute.RadianDirection;

            avatar.SetPersonData(VMPersonDataVariable.RouteEntryFlags, (short)CurRoute.RouteEntryFlags);
            avatar.Velocity = new Vector3();

            var directionDiff = DirectionUtils.Difference(Caller.RadianDirection, TargetDirection);
            if (!CurRoute.FaceAnywhere && CanPortalTurn() && Turn(directionDiff))
            {
                State = VMRoutingFrameState.END_TURN;
            }
            else
            {
                if (!CurRoute.FaceAnywhere) avatar.RadianDirection = CurRoute.RadianDirection;
                return true; //we are here!
            }
            return false;
        }
Exemplo n.º 5
0
        /// <summary>
        /// Pathfinds to the destination position from the current. The room pathfind should get us to the same room before we do this.
        /// </summary>
        private bool AttemptWalk()
        {
            //find shortest path to destination tile. Simple A* pathfind.
            //portals are used to traverse floors, so we do not care about the floor each point is on.
            //when evaluating possible adjacent tiles we use the Caller's current floor.

            LotTilePos startPos = Caller.Position;
            CurrentWaypoint = LotTilePos.OUT_OF_WORLD;
            var myRoom = VM.Context.GetRoomAt(startPos);

            var roomInfo = VM.Context.RoomInfo[myRoom];
            var obstacles = new List<VMObstacle>();

            int bx = (roomInfo.Room.Bounds.X-1) << 4;
            int by = (roomInfo.Room.Bounds.Y-1) << 4;
            int width = (roomInfo.Room.Bounds.Width+2) << 4;
            int height = (roomInfo.Room.Bounds.Height+2) << 4;
            obstacles.Add(new VMObstacle(bx-16, by-16, bx+width+16, by));
            obstacles.Add(new VMObstacle(bx-16, by+height, bx+width+16, by+height+16));

            obstacles.Add(new VMObstacle(bx-16, by-16, bx, by+height+16));
            obstacles.Add(new VMObstacle(bx+width, by-16, bx+width+16, by+height+16));

            foreach (var obj in roomInfo.Entities)
            {
                var ft = obj.Footprint;

                var flags = (VMEntityFlags)obj.GetValue(VMStackObjectVariable.Flags);
                if (obj != Caller && ft != null && (obj is VMGameObject || AvatarsToConsider.Contains(obj)) && ((flags & VMEntityFlags.DisallowPersonIntersection) > 0 || (flags & VMEntityFlags.AllowPersonIntersection) == 0))
                    obstacles.Add(new VMObstacle(ft.x1-3, ft.y1-3, ft.x2+3, ft.y2+3));
            }

            obstacles.AddRange(roomInfo.Room.WallObs);
            if (!IgnoreRooms) obstacles.AddRange(roomInfo.Room.RoomObs);

            var startPoint = new Point((int)startPos.x, (int)startPos.y);
            var endPoint = new Point((int)CurRoute.Position.x, (int)CurRoute.Position.y);

            foreach (var rect in obstacles)
            {
                if (rect.HardContains(startPoint)) return false;
            }

            var router = new VMRectRouter(obstacles);

            if (startPoint == endPoint)
            {
                State = VMRoutingFrameState.TURN_ONLY;
                return true;
            }

            WalkTo = router.Route(startPoint, endPoint);
            if (WalkTo != null)
            {
                if (WalkTo.First.Value != endPoint) WalkTo.RemoveFirst();
                AdvanceWaypoint();
            }
            return (WalkTo != null);
        }
Exemplo n.º 6
0
        public VMPrimitiveExitCode Tick()
        {
            var avatar = (VMAvatar)Caller;
            avatar.Velocity = new Vector3(0, 0, 0);

            if (State != VMRoutingFrameState.FAILED && avatar.GetFlag(VMEntityFlags.InteractionCanceled) && avatar.GetPersonData(VMPersonDataVariable.NonInterruptable) == 0)
            {
                HardFail(VMRouteFailCode.Interrupted, null);
                return VMPrimitiveExitCode.CONTINUE;
            }

            if (WaitTime > 0)
            {
                if (Velocity > 0) Velocity--;

                if (avatar.Animations.Count < 3) StartWalkAnimation();
                avatar.Animations[0].Weight = (8 - Velocity) / 8f;
                avatar.Animations[1].Weight = (Velocity / 8f) * 0.66f;
                avatar.Animations[2].Weight = (Velocity / 8f) * 0.33f;

                WaitTime--;
                Timeout--;
                if (Timeout <= 0)
                {
                    //try again. not sure if we should reset timeout for the new route
                    SoftFail(VMRouteFailCode.NoPath, null);
                    if (State != VMRoutingFrameState.FAILED) {
                        Velocity = 0;
                        State = VMRoutingFrameState.WALKING;
                    }
                } else return VMPrimitiveExitCode.CONTINUE_NEXT_TICK;
            }

            if (RoomRouteInvalid && State != VMRoutingFrameState.BEGIN_TURN && State != VMRoutingFrameState.END_TURN)
            {
                RoomRouteInvalid = false;
                IgnoredRooms.Clear();

                WalkTo = null; //reset routing state
                if (!DoRoomRoute(CurRoute))
                {
                    if (CurRoute != null) SoftFail(VMRouteFailCode.NoRoomRoute, null);
                    else HardFail(VMRouteFailCode.NoRoomRoute, null);
                }
                else if (Rooms.Count > 0)
                {
                    State = VMRoutingFrameState.INITIAL;
                }
            }

            switch (State)
            {
                case VMRoutingFrameState.STAND_FUNC:
                    if (Thread.LastStackExitCode == VMPrimitiveExitCode.RETURN_TRUE)
                    {
                        State = VMRoutingFrameState.INITIAL;
                        if (avatar.GetPersonData(VMPersonDataVariable.Posture) == 1) avatar.SetPersonData(VMPersonDataVariable.Posture, 0);
                    }
                    else
                        SoftFail(VMRouteFailCode.CantStand, null);
                    return VMPrimitiveExitCode.CONTINUE;
                case VMRoutingFrameState.INITIAL:
                case VMRoutingFrameState.ROOM_PORTAL:
                    //check if the room portal that just finished succeeded.
                    if (State == VMRoutingFrameState.ROOM_PORTAL) {
                        if (Thread.LastStackExitCode != VMPrimitiveExitCode.RETURN_TRUE)
                        {
                            IgnoredRooms.Add(CurrentPortal);
                            State = VMRoutingFrameState.INITIAL;
                            if (!DoRoomRoute(CurRoute))
                            {
                                SoftFail(VMRouteFailCode.NoRoomRoute, null); //todo: reattempt room route with portal we tried removed.
                                return VMPrimitiveExitCode.CONTINUE;
                            }
                        }
                    }

                    if (Rooms.Count > 0)
                    { //push portal function of next portal
                        CurrentPortal = Rooms.Pop();
                        var ent = VM.GetObjectById(CurrentPortal.ObjectID);
                        State = VMRoutingFrameState.ROOM_PORTAL;
                        if (!PushEntryPoint(15, ent)) //15 is portal function
                            SoftFail(VMRouteFailCode.NoRoomRoute, null); //could not execute portal function
                        return VMPrimitiveExitCode.CONTINUE;
                    }

                    //if we're here, room route is OK. start routing to a destination.
                    if (Choices == null)
                    {
                        //perform slot parse.
                        if (Slot == null)
                        {
                            HardFail(VMRouteFailCode.Unknown, null);
                            return VMPrimitiveExitCode.CONTINUE; //this should never happen. If it does, someone has used the routing system incorrectly.
                        }

                        var parser = new VMSlotParser(Slot);

                        Choices = parser.FindAvaliableLocations(Target, VM.Context, avatar);
                        if (Choices.Count == 0)
                        {
                            HardFail(parser.FailCode, parser.Blocker);
                            return VMPrimitiveExitCode.CONTINUE;
                        }
                        else
                        {
                            CurRoute = Choices[0];
                            Choices.RemoveAt(0);
                        }
                    }

                    //do we need to sit in a seat? it should take over.
                    if (CurRoute.Chair != null)
                    {
                        if (!AttemptedChair)
                        {
                            AttemptedChair = true;
                            if (PushEntryPoint(26, CurRoute.Chair)) return VMPrimitiveExitCode.CONTINUE;
                            else
                            {
                                SoftFail(VMRouteFailCode.CantSit, null);
                                return VMPrimitiveExitCode.CONTINUE;
                            }
                        }
                        else
                        {
                            if (Thread.LastStackExitCode == VMPrimitiveExitCode.RETURN_TRUE) return VMPrimitiveExitCode.RETURN_TRUE;
                            else
                            {
                                SoftFail(VMRouteFailCode.CantSit, null);
                                return VMPrimitiveExitCode.CONTINUE;
                            }
                        }
                    }

                    //If we are sitting, and the target is not this seat we need to call the stand function on the object we are contained within.
                    if (avatar.GetPersonData(VMPersonDataVariable.Posture) == 1)
                    {
                        State = VMRoutingFrameState.STAND_FUNC;
                        //push it onto our stack, except now the portal owns our soul! when we are returned to we can evaluate the result and determine if the route failed.
                        var chair = Caller.Container;

                        if (chair == null) avatar.SetPersonData(VMPersonDataVariable.Posture, 0); //we're sitting, but are not bound to a chair. Just instantly get up..
                        else
                        {
                            if (!PushEntryPoint(27, chair)) //27 is stand. TODO: set up an enum for these
                                HardFail(VMRouteFailCode.CantStand, null);
                            return VMPrimitiveExitCode.CONTINUE;
                        }
                    }

                    //no chair, we just need to walk to the spot. Start the within-room routing.
                    if (WalkTo == null)
                    {
                        if (!AttemptWalk())
                        {
                            SoftFail(VMRouteFailCode.NoPath, null);
                            return VMPrimitiveExitCode.CONTINUE;
                        }
                    }
                    if (State != VMRoutingFrameState.TURN_ONLY) BeginWalk();

                    return VMPrimitiveExitCode.CONTINUE;
                case VMRoutingFrameState.FAILED:
                    return VMPrimitiveExitCode.RETURN_FALSE;
                case VMRoutingFrameState.TURN_ONLY:
                    return (EndWalk()) ? VMPrimitiveExitCode.RETURN_TRUE : VMPrimitiveExitCode.CONTINUE;
                case VMRoutingFrameState.SHOOED:
                    StartWalkAnimation();
                    State = VMRoutingFrameState.WALKING;
                    return VMPrimitiveExitCode.CONTINUE;
                case VMRoutingFrameState.BEGIN_TURN:
                case VMRoutingFrameState.END_TURN:
                    if (avatar.CurrentAnimationState.EndReached)
                    {
                        if (State == VMRoutingFrameState.BEGIN_TURN)
                        {
                            State = VMRoutingFrameState.WALKING;
                            WalkDirection = TargetDirection;
                            avatar.RadianDirection = (float)TargetDirection;
                            StartWalkAnimation();
                            return VMPrimitiveExitCode.CONTINUE;
                        }
                        else
                        {
                            if (!CurRoute.FaceAnywhere) avatar.RadianDirection = CurRoute.RadianDirection;

                            //reset animation, so that we're facing the correct direction afterwards.
                            avatar.Animations.Clear();
                            var animation = FSO.Content.Content.Get().AvatarAnimations.Get(avatar.WalkAnimations[3] + ".anim");
                            var state = new VMAnimationState(animation, false);
                            state.Loop = true;
                            avatar.Animations.Add(state);

                            return VMPrimitiveExitCode.RETURN_TRUE; //we are here!
                        }
                    }
                    else
                    {
                        avatar.RadianDirection += TurnTweak; //while we're turning, adjust our direction
                        return VMPrimitiveExitCode.CONTINUE_NEXT_TICK;
                    }
                case VMRoutingFrameState.WALKING:
                    if (WalkTo == null)
                    {
                        if (!AttemptWalk())
                        {
                            SoftFail(VMRouteFailCode.NoPath, null);
                        }
                        return VMPrimitiveExitCode.CONTINUE;
                    }

                    if (WalkTo.Count == 0 && MoveTotalFrames - MoveFrames <= 28 && CanPortalTurn()) //7+6+5+4...
                    {
                        //tail off
                        if (Velocity <= 0) Velocity = 1;
                        if (Velocity > 1) Velocity--;
                    }
                    else
                    {
                        //get started
                        if (Velocity < 8) Velocity++;
                    }

                    avatar.Animations[0].Weight = (8 - Velocity) / 8f;
                    avatar.Animations[1].Weight = (Velocity / 8f) * 0.66f;
                    avatar.Animations[2].Weight = (Velocity / 8f) * 0.33f;

                    MoveFrames += Velocity;
                    if (MoveFrames >= MoveTotalFrames)
                    {
                        MoveFrames = MoveTotalFrames;
                        //move us to the final spot, then attempt an advance.
                    }
                    //normal sims can move 0.05 units in a frame.

                    if (TurnFrames > 0)
                    {
                        avatar.RadianDirection = (float)(TargetDirection + DirectionUtils.Difference(TargetDirection, WalkDirection) * (TurnFrames / 10.0));
                        TurnFrames--;
                    }
                    else avatar.RadianDirection = (float)TargetDirection;

                    var diff = CurrentWaypoint - PreviousPosition;
                    diff.x = (short)((diff.x * MoveFrames) / MoveTotalFrames);
                    diff.y = (short)((diff.y * MoveFrames) / MoveTotalFrames);

                    var storedDir = avatar.RadianDirection;
                    var result = Caller.SetPosition(PreviousPosition + diff, Direction.NORTH, VM.Context);
                    avatar.RadianDirection = storedDir;
                    if (result.Status != VMPlacementError.Success && result.Status != VMPlacementError.CantBeThroughWall)
                    {
                        //route failure, either something changed or we hit an avatar
                        //on both cases try again, but if we hit an avatar then detect if they have a routing frame and stop us for a bit.
                        //we stop the first collider because in most cases they're walking across our walk direction and the problem will go away after a second once they're past.
                        //
                        //if we need to route around a stopped avatar we add them to our "avatars to consider" set.

                        bool routeAround = true;
                        VMRoutingFrame colRoute = null;

                        if (result.Object != null && result.Object is VMAvatar)
                        {
                            var colAvatar = (VMAvatar)result.Object;
                            var colTopFrame = colAvatar.Thread.Stack.LastOrDefault();

                            //we already attempted to move around this avatar... if this happens too much give up.
                            if (AvatarsToConsider.Contains(colAvatar) && --Retries <= 0)
                            {
                                SoftFail(VMRouteFailCode.NoPath, avatar);
                                return VMPrimitiveExitCode.CONTINUE;
                            }

                            if (colTopFrame != null && colTopFrame is VMRoutingFrame)
                            {
                                colRoute = (VMRoutingFrame)colTopFrame;
                                routeAround = (colRoute.WaitTime > 0);
                            }
                            if (routeAround) AvatarsToConsider.Add(colAvatar);
                        }

                        if (result.Object == null || result.Object is VMGameObject)
                        {
                            //this should not happen often. An object or other feature has blocked our path due to some change in its position.
                            //repeated occurances indicate that we are stuck in something.
                            //todo: is this safe for the robot lot?
                            if (--Retries <= 0)
                            {
                                SoftFail(VMRouteFailCode.NoPath, avatar);
                                return VMPrimitiveExitCode.CONTINUE;
                            }
                        }

                        if (routeAround)
                        {
                            var oldWalk = new LinkedList<Point>(WalkTo);
                            if (AttemptWalk()) return VMPrimitiveExitCode.CONTINUE;
                            else
                            {
                                //failed to walk around the object
                                if (result.Object is VMAvatar)
                                {
                                    WalkTo = oldWalk;
                                    //if they're a person, shoo them away.
                                    //if they're in a routing frame we can push the tree directly onto their stack
                                    //otherwise we push an interaction and just hope they move (todo: does tso do this?)

                                    //DO NOT push tree if:
                                    // - sim is already being shooed. (the parent of the top routing frame is in state "SHOOED" or shoo interaction is present)
                                    // - we are being shooed.
                                    // - sim is waiting on someone they just shooed. (presumably can move out of our way once they finish waiting)
                                    //instead just wait a small duration and try again later.

                                    //cases where we cannot continue moving increase the retry count. if this is greater than RETRY_COUNT then we fail.
                                    //not sure how the original game works.

                                    if (CanShooAvatar((VMAvatar)result.Object))
                                    {
                                        AvatarsToConsider.Remove((VMAvatar)result.Object);
                                        VMEntity callee = VM.Context.CreateObjectInstance(GOTO_GUID, new LotTilePos(result.Object.Position), Direction.NORTH).Objects[0];
                                        if (colRoute != null)
                                        {
                                            colRoute.State = VMRoutingFrameState.SHOOED;
                                            colRoute.WalkTo = null;
                                            colRoute.AvatarsToConsider.Add(avatar); //just to make sure they don't try route through us.

                                            var tree = callee.GetBHAVWithOwner(SHOO_TREE, VM.Context);
                                            result.Object.Thread.ExecuteSubRoutine(colRoute, tree.bhav, tree.owner, new VMSubRoutineOperand());

                                            WalkInterrupt(60);
                                        }
                                        else
                                        {
                                            callee.PushUserInteraction(SHOO_INTERACTION, result.Object, VM.Context);
                                            WalkInterrupt(60);
                                        }
                                    }
                                    else
                                    {
                                        WalkInterrupt(60); //wait for a little while, they're moving out of the way.
                                    }
                                    return VMPrimitiveExitCode.CONTINUE;
                                }
                                SoftFail(VMRouteFailCode.DestTileOccupied, result.Object);
                                return VMPrimitiveExitCode.CONTINUE;
                            }
                        }
                        else
                        {
                            WalkInterrupt(30);
                            return VMPrimitiveExitCode.CONTINUE;
                        }

                    }
                    Caller.VisualPosition = Vector3.Lerp(PreviousPosition.ToVector3(), CurrentWaypoint.ToVector3(), MoveFrames / (float)MoveTotalFrames);

                    var velocity = Vector3.Lerp(PreviousPosition.ToVector3(), CurrentWaypoint.ToVector3(), Velocity / (float)MoveTotalFrames) - PreviousPosition.ToVector3();
                    velocity.Z = 0;
                    avatar.Velocity = velocity;

                    if (MoveTotalFrames == MoveFrames)
                    {
                        MoveTotalFrames = 0;
                        while (MoveTotalFrames == 0)
                        {
                            var remains = AdvanceWaypoint();
                            if (!remains)
                            {
                                MoveTotalFrames = -1;
                                if (EndWalk()) return VMPrimitiveExitCode.RETURN_TRUE;
                            }
                        }
                    }
                return VMPrimitiveExitCode.CONTINUE_NEXT_TICK;
            }
            return VMPrimitiveExitCode.GOTO_FALSE; //???
        }
Exemplo n.º 7
0
        public override void Load(VMStackFrameMarshal input, VMContext context)
        {
            base.Load(input, context);
            var inR = (VMRoutingFrameMarshal)input;

            Rooms = new Stack<VMRoomPortal>();
            for (int i=inR.Rooms.Length-1; i>=0; i--) Rooms.Push(inR.Rooms[i]);
            CurrentPortal = inR.CurrentPortal;

            ParentRoute = GetParentFrame(); //should be able to, since all arrays are generated left to right, including the stacks.

            WalkTo = (inR.WalkTo == null)?null:new LinkedList<Point>(inR.WalkTo);
            WalkDirection = inR.WalkDirection;
            TargetDirection = inR.TargetDirection;
            IgnoreRooms = inR.IgnoreRooms;

            State = inR.State;
            PortalTurns = inR.PortalTurns;
            WaitTime = inR.WaitTime;
            Timeout = inR.Timeout;
            Retries = inR.Retries;

            AttemptedChair = inR.AttemptedChair;
            TurnTweak = inR.TurnTweak;
            TurnFrames = inR.TurnFrames;

            MoveTotalFrames = inR.MoveTotalFrames;
            MoveFrames = inR.MoveFrames;
            Velocity = inR.Velocity;

            CallFailureTrees = inR.CallFailureTrees;

            IgnoredRooms = new HashSet<VMRoomPortal>(inR.IgnoredRooms);
            AvatarsToConsider = new HashSet<VMAvatar>();

            foreach (var avatar in inR.AvatarsToConsider)
                AvatarsToConsider.Add((VMAvatar)context.VM.GetObjectById(avatar));

            PreviousPosition = inR.PreviousPosition;
            CurrentWaypoint = inR.CurrentWaypoint;

            RoomRouteInvalid = inR.RoomRouteInvalid;
            Slot = inR.Slot; //NULLable
            Target = context.VM.GetObjectById(inR.Target); //object id
            if (inR.Choices != null)
            {
                Choices = new List<VMFindLocationResult>();
                foreach (var c in inR.Choices) Choices.Add(new VMFindLocationResult(c, context));
            }
            else Choices = null;
            CurRoute = (inR.CurRoute == null)?null:new VMFindLocationResult(inR.CurRoute, context); //NULLable
        }
Exemplo n.º 8
0
 private void HardFail(VMRouteFailCode code, VMEntity blocker)
 {
     State = VMRoutingFrameState.FAILED;
     var avatar = (VMAvatar)Caller;
     if (CallFailureTrees)
     {
         avatar.SetPersonData(VMPersonDataVariable.Priority, 100); //TODO: what is this meant to be? what dictates it?
         //probably has to do with interaction priority.
         //we just set it to 100 here so that failure trees work.
         var bhav = Global.Resource.Get<BHAV>(ROUTE_FAIL_TREE);
         Thread.ExecuteSubRoutine(this, bhav, CodeOwner, new VMSubRoutineOperand(new short[] { (short)code, (blocker==null)?(short)0:blocker.ObjectID, 0, 0 }));
     }
     avatar.SetPersonData(VMPersonDataVariable.RouteResult, (short)code);
 }
        public override void Deserialize(BinaryReader reader)
        {
            base.Deserialize(reader);
            var bezierRouting = (Version > 31);

            var roomN = reader.ReadInt32();

            Rooms = new VMRoomPortal[roomN];
            for (int i = 0; i < roomN; i++)
            {
                Rooms[i] = new VMRoomPortal(reader);
            }

            if (reader.ReadBoolean())
            {
                CurrentPortal = new VMRoomPortal(reader);
            }

            var wtLen = reader.ReadInt32();

            Point[] points = null;
            if (wtLen > -1)
            {
                WalkTo = new VMIPathSegment[wtLen];
                if (bezierRouting)
                {
                    for (int i = 0; i < wtLen; i++)
                    {
                        WalkTo[i] = ReadGenericSegment(reader);
                    }
                }
                else
                {
                    //old point list. convert to line segments.
                    points = new Point[wtLen];
                    for (int i = 0; i < wtLen; i++)
                    {
                        points[i] = new Point(reader.ReadInt32(), reader.ReadInt32());
                    }
                }
            }

            WalkDirection   = reader.ReadDouble();
            TargetDirection = reader.ReadDouble();
            IgnoreRooms     = reader.ReadBoolean();

            State       = (VMRoutingFrameState)reader.ReadByte();
            PortalTurns = reader.ReadInt32();
            WaitTime    = reader.ReadInt32();
            Timeout     = reader.ReadInt32();
            Retries     = reader.ReadInt32();

            AttemptedChair = reader.ReadBoolean();
            TurnTweak      = reader.ReadSingle();
            TurnFrames     = reader.ReadInt32();

            MoveTotalFrames = reader.ReadInt32();
            MoveFrames      = reader.ReadInt32();
            Velocity        = reader.ReadInt32();

            CallFailureTrees = reader.ReadBoolean();

            var igrN = reader.ReadInt32();

            IgnoredRooms = new VMRoomPortal[igrN];
            for (int i = 0; i < igrN; i++)
            {
                IgnoredRooms[i] = new VMRoomPortal(reader);
            }

            var avaN = reader.ReadInt32();

            AvatarsToConsider = new short[avaN];
            for (int i = 0; i < avaN; i++)
            {
                AvatarsToConsider[i] = reader.ReadInt16();
            }

            LotTilePos CurrentWaypoint = new LotTilePos();

            PreviousPosition.Deserialize(reader);
            if (bezierRouting)
            {
                CurrentPath = ReadGenericSegment(reader);
            }
            else
            {
                //convert old format into new
                CurrentWaypoint.Deserialize(reader);
                CurrentPath = new VMPathLineSegment(
                    new Point(PreviousPosition.x * 0x8000, PreviousPosition.y * 0x8000),
                    new Point(CurrentWaypoint.x * 0x8000, CurrentWaypoint.y * 0x8000));
                if (points != null)
                {
                    if (points.Length > 0)
                    {
                        WalkTo    = new VMIPathSegment[points.Length];
                        WalkTo[0] = new VMPathLineSegment(
                            new Point(CurrentWaypoint.x * 0x8000, CurrentWaypoint.y * 0x8000),
                            new Point(points[0].X * 0x8000, points[0].Y * 0x8000));
                        for (int i = 1; i < WalkTo.Length; i++)
                        {
                            WalkTo[i] = new VMPathLineSegment(
                                new Point(points[i - 1].X * 0x8000, points[i - 1].Y * 0x8000),
                                new Point(points[i].X * 0x8000, points[i].Y * 0x8000));
                        }
                    }
                    else
                    {
                        WalkTo = new VMIPathSegment[0];
                    }
                }
                else
                {
                    WalkTo = null;
                }
            }

            CurrentPath.CalculateTotalFrames();
            CurrentPath.UpdateTotalFrames(MoveTotalFrames);
            CurrentPath.ResetToFrame(MoveFrames);

            RoomRouteInvalid = reader.ReadBoolean();

            if (reader.ReadBoolean())
            {
                Slot = SLOTItemSerializer.Deserialize(reader);
            }
            Target = reader.ReadInt16();

            var chLen = reader.ReadInt32();

            if (chLen > -1)
            {
                Choices = new VMFindLocationResultMarshal[chLen];
                for (int i = 0; i < chLen; i++)
                {
                    Choices[i] = new VMFindLocationResultMarshal();
                    Choices[i].Deserialize(reader);
                }
            }

            if (reader.ReadBoolean())
            {
                CurRoute = new VMFindLocationResultMarshal();
                CurRoute.Deserialize(reader);
            }

            if (Version > 29)
            {
                LastWalkStyle = reader.ReadInt16();
            }
        }