示例#1
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context, VMPrimitiveOperand args)
        {
            var operand = (VMSnapOperand)args;
            var avatar  = context.Caller; //todo, can sometimes be an object?? see roaches object tile movement, snaps to its own routing slot
            var obj     = context.StackObject;

            if (obj == context.Caller)
            {
                foreach (var objSub in obj.MultitileGroup.Objects)
                {
                    objSub.MovedSelf = true;
                }
                if (obj is VMGameObject)
                {
                    if (VM.UseWorld)
                    {
                        // the object moving this object may not be the caller...
                        // for instance, we can be moved with a call tree.
                        // we want to use the idle timings for that thread rather than our own.
                        var idleObjID = context.VM.Scheduler.CurrentObjectID;
                        var idleObj   = context.VM.GetObjectById(idleObjID) ?? obj;

                        foreach (var obj2 in obj.MultitileGroup.Objects)
                        {
                            obj2.WorldUI.PrepareSnapInterpolation(idleObj.WorldUI);
                        }
                    }
                }
            }

            if (operand.OriginOnly)
            {
            }                           //origin only. unused?

            SLOTItem slot = null;

            switch (operand.Mode)
            {
            case VMSnapSlotScope.StackVariable:
                slot = VMMemory.GetSlot(context, VMSlotScope.StackVariable, operand.Index);
                break;

            case VMSnapSlotScope.BeContained:
                return((context.StackObject.PlaceInSlot(context.Caller, 0, true, context.VM.Context)) ? VMPrimitiveExitCode.GOTO_TRUE : VMPrimitiveExitCode.GOTO_FALSE);

            case VMSnapSlotScope.InFront:
                slot = new SLOTItem {
                    Type = 3, Standing = 1, MinProximity = 16, Rsflags = SLOTFlags.NORTH
                };
                break;

            case VMSnapSlotScope.Literal:
                slot = VMMemory.GetSlot(context, VMSlotScope.Literal, operand.Index);
                break;

            case VMSnapSlotScope.Global:
                slot = VMMemory.GetSlot(context, VMSlotScope.Global, operand.Index);
                break;
            }

            if (slot == null)
            {
                return(VMPrimitiveExitCode.GOTO_FALSE);
            }

            var dirSnap = (slot.Rsflags & SLOTFlags.SnapToDirection) > 0;

            if (operand.Mode != VMSnapSlotScope.BeContained)
            {
                var parser    = new VMSlotParser(slot);
                var locations = parser.FindAvaliableLocations(obj, context.VM.Context, avatar);
                if (slot.SnapTargetSlot > -1)
                {
                    if (!context.StackObject.PlaceInSlot(context.Caller, slot.SnapTargetSlot, true, context.VM.Context))
                    {
                        return(VMPrimitiveExitCode.GOTO_FALSE);
                    }
                    if (locations.Count > 0)
                    {
                        avatar.RadianDirection = ((slot.Rsflags & SLOTFlags.SnapToDirection) > 0) ? locations[0].RadianDirection: avatar.RadianDirection;
                    }
                }
                else
                {
                    if (locations.Count > 0)
                    {
                        if (!SetPosition(avatar, locations[0].Position,
                                         (dirSnap) ? locations[0].RadianDirection : avatar.RadianDirection,
                                         operand.Shoo, context.VM.Context))
                        {
                            //set direction regardless. TS1, experimental, breaks chairs snapping onto avatars. if this were correct, it also needs to be in the false branch.
                            //if (dirSnap) avatar.RadianDirection = locations[0].RadianDirection;
                            return(VMPrimitiveExitCode.GOTO_FALSE);
                        }
                    }
                    else
                    {
                        if (parser.FailCode == Model.Routing.VMRouteFailCode.NoValidGoals)
                        {
                            avatar.SetValue(VMStackObjectVariable.PrimitiveResult, 2);
                        }
                        avatar.SetValue(VMStackObjectVariable.PrimitiveResultID, (parser.Blocker == null) ? (short)0 : parser.Blocker.ObjectID);
                        return(VMPrimitiveExitCode.GOTO_FALSE);
                    }
                }
            }
            return(VMPrimitiveExitCode.GOTO_TRUE);
        }
示例#2
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand <VMGotoRoutingSlotOperand>();

            var slot   = VMMemory.GetSlot(context, operand.Type, operand.Data);
            var obj    = context.StackObject;
            var avatar = (VMAvatar)context.Caller;


            /**
             * How we should be going about this:
             *
             * Step 1: Evaluate possible positons for sim to route to
             * Step 2: Eliminate all positions intersected by an object that does not allow person intersection
             * Step 3: Evaluate routes to all positions, choose shortest route and eliminate all positions that we cannot route to (ignoring people).
             * Step 4: Route to position. Stop when the next tile has a person in it and ask them to move if possible.
             *
             **/

            //slot.Rsflags = TSO.Files.formats.iff.chunks.SLOTFlags.WEST;

            /**
             * Very little is kown about SLOTs so for now this is a place to dump comments
             *
             * Slots measure proximity in units of 16. 16 = 1 tile away from the object.
             * Global slots are in global.iff in a slot table with ID 100.
             * global.iff also has a string table #257 which provides labels for the SLOTs
             */

            //Routing slots must be type 3.
            if (slot.Type == 3)
            {
                var tilePosition = new Vector2(obj.Position.X, obj.Position.Y);

                var possibleTargets = VMSlotParser.FindAvaliableLocations(obj, slot, context.VM.Context);
                if (possibleTargets.Count == 0)
                {
                    return(VMPrimitiveExitCode.GOTO_FALSE);
                }

                //TODO: Route finding and pick best route
                var target = possibleTargets[0];

                var pathFinder = context.Thread.PushNewPathFinder(context, possibleTargets);
                if (pathFinder != null)
                {
                    return(VMPrimitiveExitCode.CONTINUE);
                }
                else
                {
                    return(VMPrimitiveExitCode.GOTO_FALSE);
                }

                //var test = new VMPathFinder();
                //test.Caller = context.Caller;
                //test.Routine = context.Routine;
                //test.InitRoutes(possibleTargets);

                //avatar.SetPersonData(TSO.Simantics.model.VMPersonDataVariable.RouteEntryFlags, (short)target.Flags);
                //avatar.Direction = (Direction)target.Flags;
                //avatar.Position = new Vector3(target.Position.X + 0.5f, target.Position.Y + 0.5f, 0.0f);
            }

            return(VMPrimitiveExitCode.GOTO_TRUE_NEXT_TICK);
        }
示例#3
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context, VMPrimitiveOperand args)
        {
            var operand = (VMSnapOperand)args;
            var avatar  = context.Caller; //todo, can sometimes be an object?? see roaches object tile movement, snaps to its own routing slot
            var obj     = context.StackObject;

            SLOTItem slot = null;

            switch (operand.Mode)
            {
            case VMSnapSlotScope.StackVariable:
                slot = VMMemory.GetSlot(context, VMSlotScope.StackVariable, operand.Index);
                break;

            case VMSnapSlotScope.BeContained:
                return((context.StackObject.PlaceInSlot(context.Caller, 0, true, context.VM.Context)) ? VMPrimitiveExitCode.GOTO_TRUE:VMPrimitiveExitCode.GOTO_FALSE);

            case VMSnapSlotScope.InFront:
                slot = new SLOTItem {
                    Type = 3, Standing = 1, MinProximity = 16, Rsflags = SLOTFlags.NORTH
                };
                break;

            case VMSnapSlotScope.Literal:
                slot = VMMemory.GetSlot(context, VMSlotScope.Literal, operand.Index);
                break;

            case VMSnapSlotScope.Global:
                slot = VMMemory.GetSlot(context, VMSlotScope.Global, operand.Index);
                break;
            }

            if (operand.Mode != VMSnapSlotScope.BeContained)
            {
                var parser    = new VMSlotParser(slot);
                var locations = parser.FindAvaliableLocations(obj, context.VM.Context, avatar);
                if (slot.SnapTargetSlot > -1)
                {
                    if (!context.StackObject.PlaceInSlot(context.Caller, slot.SnapTargetSlot, true, context.VM.Context))
                    {
                        return(VMPrimitiveExitCode.GOTO_FALSE);
                    }
                    if (locations.Count > 0)
                    {
                        avatar.RadianDirection = ((slot.Rsflags & SLOTFlags.SnapToDirection) > 0) ? locations[0].RadianDirection: avatar.RadianDirection;
                    }
                }
                else
                {
                    if (locations.Count > 0)
                    {
                        if (!SetPosition(avatar, locations[0].Position,
                                         ((slot.Rsflags & SLOTFlags.SnapToDirection) > 0) ? locations[0].RadianDirection : avatar.RadianDirection,
                                         context.VM.Context))
                        {
                            return(VMPrimitiveExitCode.GOTO_FALSE);
                        }
                    }
                    else
                    {
                        avatar.SetValue(VMStackObjectVariable.PrimitiveResultID, (parser.Blocker == null) ? (short)0 : parser.Blocker.ObjectID);
                        return(VMPrimitiveExitCode.GOTO_FALSE);
                    }
                }
            }
            return(VMPrimitiveExitCode.GOTO_TRUE);
        }
示例#4
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand <VMSnapOperand>();
            var avatar  = (VMAvatar)context.Caller; //todo, can sometimes be an object?? see roaches object tile movement, snaps to its own routing slot
            var obj     = context.StackObject;

            var prevContain = context.VM.GetObjectById(avatar.GetValue(VMStackObjectVariable.ContainerId));

            if (prevContain != null) //if we are contained in an object, drop out of it.
            {
                prevContain.ClearSlot(avatar.GetValue(VMStackObjectVariable.SlotNumber));
            }

            SLOTItem             slot;
            VMFindLocationResult location;

            switch (operand.Mode)
            {
            case 0:
                slot             = VMMemory.GetSlot(context, VMSlotScope.StackVariable, operand.Index);
                location         = VMSlotParser.FindAvaliableLocations(obj, slot, context.VM.Context)[0];
                avatar.Position  = location.Position;
                avatar.Direction = (Direction)location.Flags;
                break;

            case 1:     //be contained on stack object
                context.StackObject.PlaceInSlot(context.Caller, 0);
                break;

            case 2:
                var pos = obj.Position;
                switch (obj.Direction)
                {
                case tso.world.model.Direction.SOUTH:
                    pos += new Vector3(0.0f, 1.0f, 0.0f);
                    break;

                case tso.world.model.Direction.WEST:
                    pos += new Vector3(-1.0f, 0.0f, 0.0f);
                    break;

                case tso.world.model.Direction.EAST:
                    pos += new Vector3(1.0f, 0.0f, 0.0f);
                    break;

                case tso.world.model.Direction.NORTH:
                    pos += new Vector3(0.0f, -1.0f, 0.0f);
                    break;
                }
                avatar.Position = pos + new Vector3(0.5f, 0.5f, 0);
                break;

            case 3:
                slot             = VMMemory.GetSlot(context, VMSlotScope.Literal, operand.Index);
                location         = VMSlotParser.FindAvaliableLocations(obj, slot, context.VM.Context)[0];
                avatar.Position  = location.Position;
                avatar.Direction = (Direction)location.Flags;
                if (slot.SnapTargetSlot != -1)
                {
                    context.StackObject.PlaceInSlot(context.Caller, slot.SnapTargetSlot);
                }
                break;

            case 4:
                slot             = VMMemory.GetSlot(context, VMSlotScope.Global, operand.Index);
                location         = VMSlotParser.FindAvaliableLocations(obj, slot, context.VM.Context)[0];
                avatar.Position  = location.Position;
                avatar.Direction = (Direction)location.Flags;
                break;
            }

            return(VMPrimitiveExitCode.GOTO_TRUE);
        }