public VMPathFinder PushNewPathFinder(VMStackFrame frame, List <VMFindLocationResult> locations) { var childFrame = new VMPathFinder { Routine = frame.Routine, Caller = frame.Caller, Callee = frame.Callee, CodeOwner = frame.CodeOwner, StackObject = frame.StackObject, Thread = this }; var success = childFrame.InitRoutes(locations); if (!success) { return(null); //no route, don't push } else { Stack.Add(childFrame); return(childFrame); } }
public abstract VMPrimitiveExitCode Execute(VMStackFrame context);
public VMPrimitiveExitCode Tick() { if (Rooms.Count > 0) { //push portal function of next portal var portal = Rooms.Pop(); var ent = VM.GetObjectById(portal.ObjectID); if (ent.EntryPoints[15].ActionFunction != 0) //15 is portal function { bool Execute; if (ent.EntryPoints[15].ConditionFunction != 0) //check if we can definitely execute this... { var Behavior = ent.GetBHAVWithOwner(ent.EntryPoints[15].ConditionFunction, VM.Context); Execute = (VMThread.EvaluateCheck(VM.Context, Caller, new VMQueuedAction() { Callee = ent, CodeOwner = Behavior.owner, StackObject = ent, Routine = VM.Assemble(Behavior.bhav), }) == VMPrimitiveExitCode.RETURN_TRUE); } else { Execute = true; } if (Execute) { //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 Behavior = ent.GetBHAVWithOwner(ent.EntryPoints[15].ActionFunction, VM.Context); var routine = VM.Assemble(Behavior.bhav); var childFrame = new VMStackFrame { Routine = routine, Caller = Caller, Callee = ent, CodeOwner = Behavior.owner, StackObject = ent }; childFrame.Args = new short[routine.Arguments]; Thread.Push(childFrame); return(VMPrimitiveExitCode.CONTINUE); } else { return(VMPrimitiveExitCode.RETURN_FALSE); //could not execute portal function. todo: re-evaluate room route } } else { return(VMPrimitiveExitCode.RETURN_FALSE); } } else { //direct routing to a position - all required portals have been reached. var avatar = (VMAvatar)Caller; if (Turning) { if (avatar.CurrentAnimationState.EndReached) { Turning = false; ((AvatarComponent)avatar.WorldUI).RadianDirection = WalkDirection; StartWalkAnimation(); } else { ((AvatarComponent)avatar.WorldUI).RadianDirection += TurnTweak; //while we're turning, adjust our direction } return(VMPrimitiveExitCode.CONTINUE_NEXT_TICK); } else { if (WalkTo == null) { AttemptWalk(); return(VMPrimitiveExitCode.CONTINUE); } else { if (!Walking) { var remains = AdvanceWaypoint(); if (!remains) { return(VMPrimitiveExitCode.RETURN_TRUE); //we are here! } BeginWalk(); } else { if (Vector3.Distance(Caller.Position, CurrentWaypoint) < 0.10f) { var remains = AdvanceWaypoint(); if (!remains) { avatar.Direction = (Direction)((int)CurRoute.Flags & 255); avatar.SetPersonData(VMPersonDataVariable.RouteEntryFlags, (short)avatar.Direction); return(VMPrimitiveExitCode.RETURN_TRUE); //we are here! } } if (avatar.CurrentAnimationState.EndReached) { StartWalkAnimation(); } //normal sims can move 0.05 units in a frame. ((AvatarComponent)avatar.WorldUI).RadianDirection = WalkDirection; Caller.Position += new Vector3(-(float)Math.Sin(WalkDirection) * 0.05f, (float)Math.Cos(WalkDirection) * 0.05f, 0); } return(VMPrimitiveExitCode.CONTINUE_NEXT_TICK); } } } return(VMPrimitiveExitCode.RETURN_FALSE); }