예제 #1
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand<VMRunTreeByNameOperand>();

            string name;

            if (operand.StringScope == 1)
            {//global
                name = context.Global.Resource.Get<STR>(operand.StringTable).GetString(operand.StringID-1);
            }
            else
            {//local
                name = context.CodeOwner.Get<STR>(operand.StringTable).GetString(operand.StringID-1);
            }

            if (context.Callee.TreeByName.ContainsKey(name))
            {
                var tree = context.Callee.TreeByName[name];
                //found it! now lets call the tree ;)
            }
            else
            {
                return VMPrimitiveExitCode.GOTO_FALSE;
            }

            return VMPrimitiveExitCode.GOTO_TRUE;
        }
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand<VMChangeSuitOrAccessoryOperand>();

            var avatar = (VMAvatar)context.Caller;

            if ((operand.Flags & VMChangeSuitOrAccessoryFlags.Update) == VMChangeSuitOrAccessoryFlags.Update)
            { //update outfit with outfit in stringset 304 with index in temp 0
                avatar.BodyOutfit = Convert.ToUInt64(context.Callee.Object.Resource.Get<STR>(304).GetString((context.Thread.TempRegisters[0])), 16);
            }
            else
            {
                var suit = VMMemory.GetSuit(context, operand.SuitScope, operand.SuitData);
                if(suit == null){
                    return VMPrimitiveExitCode.GOTO_TRUE;
                }

                if ((operand.Flags & VMChangeSuitOrAccessoryFlags.Remove) == VMChangeSuitOrAccessoryFlags.Remove)
                {
                    avatar.Avatar.RemoveAccessory(suit);
                }
                else
                {
                    avatar.Avatar.AddAccessory(suit);
                }
            }

            return VMPrimitiveExitCode.GOTO_TRUE;
        }
        //TODO: Behaviour for being notified out of idle and interaction canceling
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand<VMIdleForInputOperand>();

            if (operand.AllowPush == 1 && context.Thread.Queue.Count > 1)
            { //if there are any more interactions, we have been interrupted
                return VMPrimitiveExitCode.INTERRUPT;
            }

            if (context.Thread.Queue[0].Cancelled)
            {
                context.Caller.SetFlag(VMEntityFlags.NotifiedByIdleForInput, true);
                return VMPrimitiveExitCode.GOTO_TRUE;
            }

            if (context.Caller.Interrupt)
            {
                context.Caller.Interrupt = false;
                return VMPrimitiveExitCode.GOTO_TRUE;
            }

            var ticks = VMMemory.GetVariable(context, TSO.Simantics.engine.scopes.VMVariableScope.Parameters, operand.StackVarToDec);
            ticks--;

            if (ticks < 0)
            {
                return VMPrimitiveExitCode.GOTO_TRUE;
            }
            else
            {
                VMMemory.SetVariable(context, TSO.Simantics.engine.scopes.VMVariableScope.Parameters, operand.StackVarToDec, ticks);
                return VMPrimitiveExitCode.CONTINUE_NEXT_TICK;
            }
        }
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand<VMGotoRelativePositionOperand>();

            var obj = (VMGameObject)context.Callee;
            var avatar = (VMAvatar)context.Caller;

            /**
             * Examples for reference
             * Fridge - Have Snack - In front of, facing
             */
            if (operand.Location == VMGotoRelativeLocation.InFrontOf){
                /** Need to work out which side is in front? **/

                //TODO: My positions are wrong, what i call left front etc is wrong. Need to correct this eventually
                var location = obj.Position;
                switch(obj.Direction){
                    case tso.world.model.Direction.LeftFront:
                        location += new Vector3(0.0f, 1.0f, 0.0f);
                        break;
                    case tso.world.model.Direction.LeftBack:
                        location += new Vector3(-1.0f, 0.0f, 0.0f);
                        break;
                    case tso.world.model.Direction.RightFront:
                        location += new Vector3(1.0f, 0.0f, 0.0f);
                        break;
                    case tso.world.model.Direction.RightBack:
                        location += new Vector3(0.0f, -1.0f, 0.0f);
                        break;
                }
                avatar.Position = location + new Vector3(0.5f, 0.5f, 0.0f);
                return VMPrimitiveExitCode.GOTO_TRUE_NEXT_TICK;
            }
            throw new Exception("Unknown goto relative");
        }
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand<VMLookTowardsOperand>();
            //TODO: primitive fails if object calls it
            VMAvatar sim = (VMAvatar)context.Caller;

            var result = new VMFindLocationResult();
            result.Position = new LotTilePos(sim.Position);

            switch (operand.Mode)
            {
                case VMLookTowardsMode.HeadTowardsObject:
                    return VMPrimitiveExitCode.GOTO_TRUE; //TODO: turning head towards things, with head seek timeout
                case VMLookTowardsMode.BodyTowardsCamera:
                    return VMPrimitiveExitCode.GOTO_TRUE; //does not work in TSO
                case VMLookTowardsMode.BodyTowardsStackObj:
                    result.RadianDirection = (float)GetDirectionTo(sim.Position, context.StackObject.Position);
                    result.Flags = RadianToFlags(result.RadianDirection);
                    break;
                case VMLookTowardsMode.BodyAwayFromStackObj:
                    result.RadianDirection = (float)GetDirectionTo(sim.Position, context.StackObject.Position);
                    result.RadianDirection = (float)((result.RadianDirection + Math.PI) % (Math.PI*2));
                    result.Flags = RadianToFlags(result.RadianDirection);
                    break;

            }

            var pathFinder = context.Thread.PushNewPathFinder(context, new List<VMFindLocationResult>() { result });
            if (pathFinder != null) return VMPrimitiveExitCode.CONTINUE;
            else return VMPrimitiveExitCode.GOTO_TRUE;
        }
예제 #6
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand<VMRefreshOperand>();
            VMEntity target = null;
            switch (operand.TargetObject)
            {
                case 0:
                    target = context.Caller;
                    break;
                case 1:
                    target = context.StackObject;
                    break;
            }

            switch (operand.RefreshType)
            {
                case 0: //graphic
                    if (target.GetType() == typeof(VMGameObject))
                    {
                        var TargObj = (VMGameObject)target;
                        TargObj.RefreshGraphic();
                    }
                    break;
            }

            return VMPrimitiveExitCode.GOTO_TRUE;
        }
예제 #7
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand<VMPlaySoundOperand>();
            FWAV fwav = context.CodeOwner.Get<FWAV>(operand.EventID);
            if (fwav == null) fwav = context.VM.Context.Globals.Resource.Get<FWAV>(operand.EventID);

            if (fwav != null)
            {
                var thread = HITVM.Get().PlaySoundEvent(fwav.Name);
                if (thread != null)
                {
                    var owner = (operand.StackObjAsSource)?context.StackObject:context.Caller;

                    if (!thread.AlreadyOwns(owner.ObjectID)) thread.AddOwner(owner.ObjectID);

                    var entry = new VMSoundEntry()
                    {
                        Thread = thread,
                        Pan = !operand.NoPan,
                        Zoom = !operand.NoZoom,
                        Loop = operand.Loop,
                        Name = fwav.Name
                    };
                    owner.SoundThreads.Add(entry);
                    owner.TickSounds();
                }
            }

            return VMPrimitiveExitCode.GOTO_TRUE;
        }
예제 #8
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand<VMGenericTSOCallOperand>();

            if (
                operand.Call == VMGenericTSOCallMode.GetIsPendingDeletion ||
                operand.Call == VMGenericTSOCallMode.IsTemp0AvatarIgnoringTemp1Avatar ||
                operand.Call == VMGenericTSOCallMode.IsGlobalBroken
                ) return VMPrimitiveExitCode.GOTO_FALSE;
            else if (operand.Call == VMGenericTSOCallMode.SwapMyAndStackObjectsSlots)
            {
                int total = Math.Min(context.StackObject.TotalSlots(), context.Caller.TotalSlots());
                for (int i = 0; i < total; i++)
                {
                    VMEntity temp1 = context.Caller.GetSlot(i);
                    VMEntity temp2 = context.StackObject.GetSlot(i);
                    context.Caller.ClearSlot(i);
                    context.StackObject.ClearSlot(i);
                    context.Caller.PlaceInSlot(temp2, i);
                    context.StackObject.PlaceInSlot(temp1, i);
                }
            }
            else if (operand.Call == VMGenericTSOCallMode.TestStackObject) return (context.StackObject != null) ? VMPrimitiveExitCode.GOTO_TRUE : VMPrimitiveExitCode.GOTO_FALSE;
            return VMPrimitiveExitCode.GOTO_TRUE;
        }
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand<VMGotoRelativePositionOperand>();

            var obj = context.StackObject;
            var avatar = (VMAvatar)context.Caller;

            if (obj.Position == LotTilePos.OUT_OF_WORLD) return VMPrimitiveExitCode.GOTO_FALSE;

            var result = new VMFindLocationResult();
            LotTilePos relative;
            int intDir = (int)Math.Round(Math.Log((double)obj.Direction, 2));

            /**
             * Examples for reference
             * Fridge - Have Snack - In front of, facing
             */
            if (operand.Location == VMGotoRelativeLocation.OnTopOf)
            {
                relative = new LotTilePos(0, 0, obj.Position.Level);
                result.Position = new LotTilePos(obj.Position);
                //result.Flags = (SLOTFlags)obj.Direction;
            }
            else
            {
                int dir;
                if (operand.Location == VMGotoRelativeLocation.AnywhereNear) dir = (int)context.VM.Context.NextRandom(8);
                else dir = ((int)operand.Location + intDir) % 8;

                relative = Positions[dir];

                var location = obj.Position;
                location += relative;
                result.Position = location;
            }
            //throw new Exception("Unknown goto relative");

            if (operand.Direction == VMGotoRelativeDirection.Facing)
            {
                result.RadianDirection = (float)GetDirectionTo(relative, new LotTilePos(0, 0, relative.Level));
                result.Flags = RadianToFlags(result.RadianDirection);
            }
            else if (operand.Direction == VMGotoRelativeDirection.AnyDirection)
            {
                result.RadianDirection = 0;
                result.Flags = SLOTFlags.NORTH;
            }
            else
            {
                var dir = ((int)operand.Direction + intDir) % 8;
                result.RadianDirection = (float)dir*(float)(Math.PI/4.0);
                if (result.RadianDirection > Math.PI) result.RadianDirection -= (float)(Math.PI * 2.0);
                result.Flags = (SLOTFlags)(1<<(int)dir);
            }

            var pathFinder = context.Thread.PushNewPathFinder(context, new List<VMFindLocationResult>() { result });
            if (pathFinder != null) return VMPrimitiveExitCode.CONTINUE;
            else return VMPrimitiveExitCode.GOTO_FALSE;
        }
예제 #10
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand<VMTransferFundsOperand>();
            /** Bit of a legacy thing going on here so there is a helper to translate old owner values into the new scope handler **/
            var ammount = VMMemory.GetVariable(context, operand.GetAmmountOwner(), operand.AmmountData);

            return VMPrimitiveExitCode.GOTO_TRUE;
        }
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand<VMFindBestObjectForFunctionOperand>();

            var entities = context.VM.Entities;

            int bestScore = int.MinValue;
            VMEntity bestObj = null;

            var entry = VMFindBestObjectForFunction.FunctionToEntryPoint[operand.Function];
            for (int i=0; i<entities.Count; i++) {
                var ent = entities[i];
                if (ent.ObjectData[(int)VMStackObjectVariable.LockoutCount] > 0) continue; //this object is not important!!!
                if (ent.EntryPoints[entry].ActionFunction != 0) {
                    bool Execute;
                    if (ent.EntryPoints[entry].ConditionFunction != 0) {

                        var Behavior = ent.GetBHAVWithOwner(ent.EntryPoints[entry].ConditionFunction, context.VM.Context);

                        var test = VMThread.EvaluateCheck(context.VM.Context, context.Caller, new VMQueuedAction(){
                            Callee = ent,
                            CodeOwner = Behavior.owner,
                            StackObject = ent,
                            Routine = context.VM.Assemble(Behavior.bhav),
                        });

                        Execute = (test == VMPrimitiveExitCode.RETURN_TRUE);

                    } else {
                        Execute = true;
                    }

                    if (Execute)
                    {
                        //calculate the score for this object.
                        int score = 0;
                        if (ScoreVar[operand.Function] != VMStackObjectVariable.Invalid) {
                            score = ent.GetValue(ScoreVar[operand.Function]);
                        }

                        LotTilePos posDiff = ent.Position - context.Caller.Position;
                        score -= (int)Math.Sqrt(posDiff.x*posDiff.x+posDiff.y*posDiff.y)/3;

                        if (score > bestScore)
                        {
                            bestScore = score;
                            bestObj = ent;
                        }
                    }
                }
            }

            if (bestObj != null)
            {
                context.StackObject = bestObj;
                return VMPrimitiveExitCode.GOTO_TRUE;
            } else return VMPrimitiveExitCode.GOTO_FALSE; //couldn't find an object! :'(
        }
예제 #12
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;
        }
 public override VMPrimitiveExitCode Execute(VMStackFrame context)
 {
     //TODO: Implement this.
     var operand = context.GetCurrentOperand<VMSetBalloonHeadlineOperand>();
     if (operand.Duration == 0)
     {
         /** Clear **/
     }
     return VMPrimitiveExitCode.GOTO_TRUE;
 }
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand<VMRunFunctionalTreeOperand>();

            var entry = VMFindBestObjectForFunction.FunctionToEntryPoint[operand.Function];
            var ent = context.StackObject;
            if (ent.EntryPoints[entry].ActionFunction != 0)
            {
                bool Execute;
                if (ent.EntryPoints[entry].ConditionFunction != 0) //check if we can definitely execute this...
                {
                    var Behavior = ent.GetBHAVWithOwner(ent.EntryPoints[entry].ConditionFunction, context.VM.Context);
                    Execute = (VMThread.EvaluateCheck(context.VM.Context, context.Caller, new VMQueuedAction()
                    {
                        Callee = ent,
                        CodeOwner = Behavior.owner,
                        StackObject = ent,
                        Routine = context.VM.Assemble(Behavior.bhav),
                    }) == VMPrimitiveExitCode.RETURN_TRUE);

                }
                else
                {
                    Execute = true;
                }

                if (Execute)
                {
                    //push it onto our stack, except now the stack object owns our soul!
                    var Behavior = ent.GetBHAVWithOwner(ent.EntryPoints[entry].ActionFunction, context.VM.Context);
                    var routine = context.VM.Assemble(Behavior.bhav);
                    var childFrame = new VMStackFrame
                    {
                        Routine = routine,
                        Caller = context.Caller,
                        Callee = ent,
                        CodeOwner = Behavior.owner,
                        StackObject = ent
                    };
                    if (operand.Flags > 0) context.Thread.Queue[0].IconOwner = context.StackObject;
                    childFrame.Args = new short[routine.Arguments];
                    context.Thread.Push(childFrame);
                    return VMPrimitiveExitCode.CONTINUE;
                }
                else
                {
                    return VMPrimitiveExitCode.GOTO_FALSE;
                }
            }
            else
            {
                return VMPrimitiveExitCode.GOTO_FALSE;
            }
        }
예제 #15
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand<VMRandomNumberOperand>();

            var rangeValue = (ushort)VMMemory.GetVariable(context, operand.RangeScope, operand.RangeData);

            var result = context.VM.Context.NextRandom(rangeValue);
            VMMemory.SetVariable(context, operand.DestinationScope, operand.DestinationData, (short)result);
            if (operand.RangeData == 8327) result = 0;
            return VMPrimitiveExitCode.GOTO_TRUE;
        }
예제 #16
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            //TODO: Implement this.
            var operand = context.GetCurrentOperand <VMSetBalloonHeadlineOperand>();

            if (operand.Duration == 0)
            {
                /** Clear **/
            }
            return(VMPrimitiveExitCode.GOTO_TRUE);
        }
예제 #17
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand<VMSetToNextOperand>();
            var targetValue = VMMemory.GetVariable(context, operand.GetTargetOwner(), operand.GetTargetData());

            if (operand.SearchType == VMSetToNextSearchType.ObjectOfType){
                //TODO: Implement!
                return VMPrimitiveExitCode.GOTO_FALSE;
            }
            throw new Exception("Unknown search type");
        }
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand<VMPushInteractionOperand>();
            VMEntity interactionSource;

            if ((operand.Flags & (1 << 1)) > 0) interactionSource = context.VM.GetObjectById((short)context.Locals[operand.ObjectLocation]);
            else interactionSource = context.VM.GetObjectById((short)context.Args[operand.ObjectLocation]);

            VMQueuePriority priority;
            if (operand.Priority == 0)
            {
                priority = context.Thread.Queue[0].Priority;
            }
            else
            {
                priority = (VMQueuePriority)(operand.Priority - 1);
            }

            BHAV bhav;
            GameIffResource CodeOwner = null;
            var Action = interactionSource.TreeTable.InteractionByIndex[operand.Interaction];
            ushort ActionID = Action.ActionFunction;

            CodeOwner = interactionSource.Object.Resource;
            if (ActionID < 4096)
            { //global
                bhav = null;
                //unimp as it has to access the context to get this.
            }
            else if (ActionID < 8192)
            { //local
                bhav = interactionSource.Object.Resource.Get<BHAV>(ActionID);
            }
            else
            { //semi-global
                bhav = interactionSource.SemiGlobal.Resource.Get<BHAV>(ActionID);
            }

            var routine = context.VM.Assemble(bhav);
            context.StackObject.Thread.EnqueueAction(
                new TSO.Simantics.engine.VMQueuedAction
                {
                    Callee = interactionSource,
                    CodeOwner = CodeOwner,
                    Routine = routine,
                    Name = interactionSource.TreeTableStrings.GetString((int)Action.TTAIndex),
                    StackObject = interactionSource,
                    InteractionNumber = operand.Interaction,
                    Priority = priority
                }
            );

            return VMPrimitiveExitCode.GOTO_TRUE;
        }
예제 #19
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand     = context.GetCurrentOperand <VMSetToNextOperand>();
            var targetValue = VMMemory.GetVariable(context, operand.GetTargetOwner(), operand.GetTargetData());

            if (operand.SearchType == VMSetToNextSearchType.ObjectOfType)
            {
                //TODO: Implement!
                return(VMPrimitiveExitCode.GOTO_FALSE);
            }
            throw new Exception("Unknown search type");
        }
예제 #20
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand <VMRunFunctionalTreeOperand>();

            var entry = VMFindBestObjectForFunction.FunctionToEntryPoint[operand.Function];
            var ent   = context.StackObject;

            if (ent.EntryPoints[entry].ActionFunction != 0)
            {
                bool Execute;
                if (ent.EntryPoints[entry].ConditionFunction != 0) //check if we can definitely execute this...
                {
                    var Behavior = ent.GetBHAVWithOwner(ent.EntryPoints[entry].ConditionFunction, context.VM.Context);
                    Execute = (VMThread.EvaluateCheck(context.VM.Context, context.Caller, new VMQueuedAction()
                    {
                        Callee = ent,
                        CodeOwner = Behavior.owner,
                        StackObject = ent,
                        Routine = context.VM.Assemble(Behavior.bhav),
                    }) == VMPrimitiveExitCode.RETURN_TRUE);
                }
                else
                {
                    Execute = true;
                }

                if (Execute)
                {
                    //push it onto our stack, except now the stack object owns our soul!
                    var Behavior   = ent.GetBHAVWithOwner(ent.EntryPoints[entry].ActionFunction, context.VM.Context);
                    var routine    = context.VM.Assemble(Behavior.bhav);
                    var childFrame = new VMStackFrame
                    {
                        Routine     = routine,
                        Caller      = context.Caller,
                        Callee      = ent,
                        CodeOwner   = Behavior.owner,
                        StackObject = ent
                    };
                    childFrame.Args = new short[routine.Arguments];
                    context.Thread.Push(childFrame);
                    return(VMPrimitiveExitCode.CONTINUE);
                }
                else
                {
                    return(VMPrimitiveExitCode.GOTO_FALSE);
                }
            }
            else
            {
                return(VMPrimitiveExitCode.GOTO_FALSE);
            }
        }
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand<VMOnlineJobsCallOperand>();

            switch (operand.Call)
            {
                case VMOnlineJobsCallMode.SetControllerID:
                    context.VM.SetGlobalValue(21, (context.StackObject == null)?(short)0:context.StackObject.ObjectID);
                    break;
            }

            return VMPrimitiveExitCode.GOTO_TRUE;
        }
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand<VMRemoveObjectInstanceOperand>();
            VMEntity obj;
            if (operand.Target == 0) obj = context.Caller;
            else obj = context.StackObject;

            obj.Delete(operand.CleanupAll, context.VM.Context);

            //if (obj == context.StackObject) context.StackObject = null;

            return VMPrimitiveExitCode.GOTO_TRUE;
        }
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand<VMTestObjectTypeOperand>();
            var objectID = VMMemory.GetVariable(context, operand.IdOwner, operand.IdData);

            var obj = context.VM.GetObjectById(objectID);
            //var obj = context.StackObject;
            if (obj == null){
                return VMPrimitiveExitCode.ERROR;
            }

            if (obj.Object.GUID == operand.GUID) return VMPrimitiveExitCode.GOTO_TRUE; //is my guid same?
            else if (obj.MasterDefinition != null && (obj.MasterDefinition.GUID == operand.GUID)) return VMPrimitiveExitCode.GOTO_TRUE; //is master guid same?
            else return VMPrimitiveExitCode.GOTO_FALSE;
        }
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand <VMStopAllSoundsOperand>();

            var owner   = (operand.Flags == 1)?context.StackObject:context.Caller;
            var threads = owner.SoundThreads;

            for (int i = 0; i < threads.Count; i++)
            {
                threads[i].Thread.RemoveOwner(owner.ObjectID);
            }
            threads.Clear();

            return(VMPrimitiveExitCode.GOTO_TRUE);
        }
예제 #25
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand<VMStopAllSoundsOperand>();

            var owner = (operand.Flags == 1)?context.StackObject:context.Caller;
            var threads = owner.SoundThreads;

            for (int i = 0; i < threads.Count; i++)
            {
                threads[i].Thread.RemoveOwner(owner.ObjectID);
            }
            threads.Clear();

            return VMPrimitiveExitCode.GOTO_TRUE;
        }
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand<VMRemoveObjectInstanceOperand>();
            VMEntity obj;
            if (operand.Target == 0) obj = context.Caller;
            else obj = context.StackObject;

            if (operand.CleanupAll && obj.MultitileGroup != null)
            {
                for (int i = 0; i < obj.MultitileGroup.Objects.Count; i++) context.VM.Context.RemoveObjectInstance(obj.MultitileGroup.Objects[i]); //remove all multitile parts
            }
            else context.VM.Context.RemoveObjectInstance(obj);

            return VMPrimitiveExitCode.GOTO_TRUE;
        }
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand <VMRunTreeByNameOperand>();

            string name;

            if (operand.StringScope == 1)
            {//global
                name = context.Global.Resource.Get <STR>(operand.StringTable).GetString(operand.StringID - 1);
            }
            else
            {//local
                name = context.CodeOwner.Get <STR>(operand.StringTable).GetString(operand.StringID - 1);
            }

            if (context.StackObject.TreeByName == null)
            {
                return(VMPrimitiveExitCode.GOTO_FALSE);
            }
            if (context.StackObject.TreeByName.ContainsKey(name))
            {
                var tree = context.StackObject.TreeByName[name];

                if (operand.Destination == 2)
                {
                    context.Thread.ExecuteSubRoutine(context, tree.bhav, tree.Owner, new VMSubRoutineOperand());
                    return(VMPrimitiveExitCode.CONTINUE);
                    //push onto my stack - acts like a subroutine.
                }
                else if (operand.Destination == 0)
                {
                    context.Caller.Thread.RunInMyStack(tree.bhav, tree.Owner);
                    return(VMPrimitiveExitCode.GOTO_TRUE);
                    //run in my stack
                }
                else
                {
                    context.StackObject.Thread.RunInMyStack(tree.bhav, tree.Owner);
                    return(VMPrimitiveExitCode.GOTO_TRUE);
                    //run in stack obj's stack
                }
                //found it! now lets call the tree ;)
            }
            else
            {
                return(VMPrimitiveExitCode.GOTO_FALSE);
            }
        }
예제 #28
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand <VMFindBestObjectForFunctionOperand>();

            var entities = context.VM.Entities;
            var entry    = VMFindBestObjectForFunction.FunctionToEntryPoint[operand.Function];

            for (int i = 0; i < entities.Count; i++)
            {
                var ent = entities[i];
                if (ent.ObjectData[(int)VMStackObjectVariable.LockoutCount] > 0)
                {
                    continue;                                                              //this object is not important!!!
                }
                if (ent.EntryPoints[entry].ActionFunction != 0)
                {
                    bool Execute;
                    if (ent.EntryPoints[entry].ConditionFunction != 0)
                    {
                        var Behavior = ent.GetBHAVWithOwner(ent.EntryPoints[entry].ConditionFunction, context.VM.Context);

                        var test = VMThread.EvaluateCheck(context.VM.Context, context.Caller, new VMQueuedAction()
                        {
                            Callee      = ent,
                            CodeOwner   = Behavior.owner,
                            StackObject = ent,
                            Routine     = context.VM.Assemble(Behavior.bhav),
                        });

                        Execute = (test == VMPrimitiveExitCode.RETURN_TRUE);
                    }
                    else
                    {
                        Execute = true;
                    }

                    if (Execute)
                    {
                        //we can run this, it's suitable, yes I'LL TAKE IT
                        context.StackObject = ent;
                        return(VMPrimitiveExitCode.GOTO_TRUE);
                    }
                    //if not just keep searching
                }
            }

            return(VMPrimitiveExitCode.GOTO_FALSE); //couldn't find an object! :'(
        }
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand<VMRunTreeByNameOperand>();

            string name;
            STR res = null;
            if (operand.StringScope == 1)
            {//global
                res = context.Global.Resource.Get<STR>(operand.StringTable);
            }
            else
            {//local
                if (context.Routine.ID >= 8192 && context.CodeOwner.SemiGlobal != null) res = context.CodeOwner.SemiGlobal.Get<STR>(operand.StringTable);
                if (res == null) res = context.CodeOwner.Get<STR>(operand.StringTable);
            }
            if (res == null) return VMPrimitiveExitCode.GOTO_FALSE;
            name = res.GetString(operand.StringID-1);

            if (context.StackObject.TreeByName == null) return VMPrimitiveExitCode.GOTO_FALSE;
            if (context.StackObject.TreeByName.ContainsKey(name))
            {
                var tree = context.StackObject.TreeByName[name];

                if (operand.Destination == 2)
                {
                    context.Thread.ExecuteSubRoutine(context, tree.bhav, tree.Owner, new VMSubRoutineOperand(context.Thread.TempRegisters));
                    return VMPrimitiveExitCode.CONTINUE;
                    //push onto my stack - acts like a subroutine.
                }
                else if (operand.Destination == 0)
                {
                    return context.Caller.Thread.RunInMyStack(tree.bhav, tree.Owner, context.Thread.TempRegisters, context.StackObject)
                        ? VMPrimitiveExitCode.GOTO_TRUE : VMPrimitiveExitCode.GOTO_FALSE;
                    //run in my stack
                }
                else
                {
                    return context.StackObject.Thread.RunInMyStack(tree.bhav, tree.Owner, context.Thread.TempRegisters, context.StackObject)
                        ? VMPrimitiveExitCode.GOTO_TRUE : VMPrimitiveExitCode.GOTO_FALSE;
                    //run in stack obj's stack
                }
                //found it! now lets call the tree ;)
            }
            else
            {
                return VMPrimitiveExitCode.GOTO_FALSE;
            }
        }
예제 #30
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand<VMFindLocationForOperand>();
            var refObj = (operand.UseLocalAsRef) ? context.VM.GetObjectById((short)context.Locals[operand.Local]) : context.Caller;

            short container = context.StackObject.GetValue(VMStackObjectVariable.ContainerId);
            if (container != 0) context.VM.GetObjectById(container).ClearSlot(context.StackObject.GetValue(VMStackObjectVariable.SlotNumber)); //if object is in a slot, eject it

            if (operand.Mode == 0) //todo: detect collisions and place close to intended position if AllowIntersection is false.
            { //default
                //also todo.. a better way of moving objects lol (especially for multitile)
                context.StackObject.SetPosition((short)refObj.Position.X, (short)refObj.Position.Y, (sbyte)refObj.WorldUI.Level, context.StackObject.Direction, context.VM.Context);
            }

            return VMPrimitiveExitCode.GOTO_TRUE;
        }
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand <VMRandomNumberOperand>();

            var rangeValue = (ushort)VMMemory.GetVariable(context, operand.RangeScope, operand.RangeData);


            var result = context.VM.Context.NextRandom(rangeValue);

            VMMemory.SetVariable(context, operand.DestinationScope, operand.DestinationData, (short)result);
            if (operand.RangeData == 8327)
            {
                result = 0;
            }
            return(VMPrimitiveExitCode.GOTO_TRUE);
        }
예제 #32
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand <VMGotoRoutingSlotOperand>();
            var slot    = VMMemory.GetSlot(context, operand.Type, operand.Data);
            var obj     = (VMGameObject)context.Callee;
            var avatar  = (VMAvatar)context.Caller;

            //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
             */

            //Dont really know what 3 means, maybe relative to object?
            if (slot.Type == 3)
            {
                var tilePosition = new Vector2(obj.Position.X, obj.Position.Y);
                var min          = slot.MinProximity;
                var max          = slot.MaxProximity;
                var desired      = slot.OptimalProximity;

                if (max == 0)
                {
                    max = min;
                }
                if (desired == 0)
                {
                    desired = min;
                }

                var possibleTargets = VMRouteFinder.FindAvaliableLocations(tilePosition, slot.Rsflags, min, max, desired);
                if (possibleTargets.Count == 0)
                {
                    return(VMPrimitiveExitCode.GOTO_FALSE);
                }

                //TODO: Route finding and pick best route
                var target = possibleTargets[0];
                avatar.Position = new Vector3(target.Position.X + 0.5f, target.Position.Y + 0.5f, 0.0f);
            }

            return(VMPrimitiveExitCode.GOTO_TRUE_NEXT_TICK);
        }
예제 #33
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand<VMRandomNumberOperand>();

            var description = "random: less than " + VMMemory.DescribeVariable(context, operand.RangeScope, operand.RangeData);
            description += " written to " + VMMemory.DescribeVariable(context, operand.DestinationScope, operand.DestinationData);
            Trace(description);

            //TODO: Make this deterministic
            var rangeValue = VMMemory.GetVariable(context, operand.RangeScope, operand.RangeData);

            var rand = new Random();
            var result = rand.Next(rangeValue);
            VMMemory.SetVariable(context, operand.DestinationScope, operand.DestinationData, (short)result);
            Trace("set " + operand.DestinationScope + " #" + operand.DestinationData + " to random " + result);
            return VMPrimitiveExitCode.GOTO_TRUE;
        }
예제 #34
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand<VMGetDistanceToOperand>();

            var obj1 = context.StackObject;
            VMEntity obj2;
            if ((operand.Flags & 1) > 0) obj2 = context.Caller;
            else obj2 = context.VM.GetObjectById(VMMemory.GetVariable(context, (VMVariableScope)operand.ObjectScope, operand.OScopeData));

            var pos1 = obj1.Position;
            var pos2 = obj2.Position;

            var result = (short)Math.Floor(Math.Sqrt(Math.Pow(Math.Floor(pos1.X) - Math.Floor(pos2.X), 2) + Math.Pow(Math.Floor(pos1.Y) - Math.Floor(pos2.Y), 2)));

            context.Thread.TempRegisters[operand.TempNum] = result;
            return VMPrimitiveExitCode.GOTO_TRUE;
        }
예제 #35
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand <VMGenericTSOCallOperand>();

            if (operand.Call == 48 || operand.Call == 31)
            {
                return(VMPrimitiveExitCode.GOTO_FALSE);
            }
            else if (operand.Call == 40)
            {
                return((context.StackObject != null) ? VMPrimitiveExitCode.GOTO_TRUE : VMPrimitiveExitCode.GOTO_FALSE);
            }
            else
            {
                return(VMPrimitiveExitCode.GOTO_TRUE);
            }
        }
예제 #36
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand <VMSetMotiveChangeOperand>();
            var avatar  = ((VMAvatar)context.Caller);

            if ((operand.Flags & VMSetMotiveChangeFlags.ClearAll) > 0)
            {
                avatar.ClearMotiveChanges();
            }
            else
            {
                var PerHourChange = VMMemory.GetVariable(context, (VMVariableScope)operand.DeltaOwner, (ushort)operand.DeltaData);
                var MaxValue      = VMMemory.GetVariable(context, (VMVariableScope)operand.MaxOwner, (ushort)operand.MaxData);
                avatar.SetMotiveChange(operand.Motive, PerHourChange, MaxValue);
            }

            return(VMPrimitiveExitCode.GOTO_TRUE);
        }
예제 #37
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand<VMTestObjectTypeOperand>();
            var objectID = VMMemory.GetVariable(context, operand.IdOwner, operand.IdData);

            var obj = context.VM.GetObjectById(objectID);
            if (obj == null){
                return VMPrimitiveExitCode.ERROR;
            }

            //TODO: This should check if obj or masterID is type not just single tile
            if (obj.Object.GUID == operand.GUID)
            {
                return VMPrimitiveExitCode.GOTO_TRUE;
            }else{
                return VMPrimitiveExitCode.GOTO_FALSE;
            }
        }
예제 #38
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand<VMSetMotiveChangeOperand>();
            var avatar = ((VMAvatar)context.Caller);

            if ((operand.Flags & VMSetMotiveChangeFlags.ClearAll) > 0)
            {
                avatar.ClearMotiveChanges();
            }
            else
            {
                var PerHourChange = VMMemory.GetVariable(context, (VMVariableScope)operand.DeltaOwner, (ushort)operand.DeltaData);
                var MaxValue = VMMemory.GetVariable(context, (VMVariableScope)operand.MaxOwner, (ushort)operand.MaxData);
                avatar.SetMotiveChange(operand.Motive, PerHourChange, MaxValue);
            }

            return VMPrimitiveExitCode.GOTO_TRUE;
        }
        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 = 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.
             *
             **/

            //Routing slots must be type 3.
            if (slot.Type == 3){
                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;
        }
예제 #40
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand<VMSleepOperand>();

            Trace("sleep: --(" + VMMemory.DescribeVariable(context, VMVariableScope.Local, operand.StackVarToDec) + ") != 0");

            var ticks = VMMemory.GetVariable(context, tso.simantics.engine.scopes.VMVariableScope.Local, operand.StackVarToDec);
            ticks--;

            if (ticks <= 0)
            {
                return VMPrimitiveExitCode.GOTO_TRUE;
            }
            else
            {
                VMMemory.SetVariable(context, tso.simantics.engine.scopes.VMVariableScope.Local, operand.StackVarToDec, ticks);
                return VMPrimitiveExitCode.CONTINUE_NEXT_TICK;
            }
        }
예제 #41
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand <VMFindLocationForOperand>();
            var refObj  = (operand.UseLocalAsRef) ? context.VM.GetObjectById((short)context.Locals[operand.Local]) : context.Caller;

            short container = context.StackObject.GetValue(VMStackObjectVariable.ContainerId);

            if (container != 0)
            {
                context.VM.GetObjectById(container).ClearSlot(context.StackObject.GetValue(VMStackObjectVariable.SlotNumber)); //if object is in a slot, eject it
            }
            if (operand.Mode == 0)                                                                                             //todo: detect collisions and place close to intended position if AllowIntersection is false.
            {                                                                                                                  //default
                //also todo.. a better way of moving objects lol (especially for multitile)
                context.StackObject.SetPosition((short)refObj.Position.X, (short)refObj.Position.Y, (sbyte)refObj.WorldUI.Level, context.StackObject.Direction, context.VM.Context);
            }

            return(VMPrimitiveExitCode.GOTO_TRUE);
        }
예제 #42
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand <VMSleepOperand>();

            Trace("sleep: --(" + VMMemory.DescribeVariable(context, VMVariableScope.Local, operand.StackVarToDec) + ") != 0");

            var ticks = VMMemory.GetVariable(context, tso.simantics.engine.scopes.VMVariableScope.Local, operand.StackVarToDec);

            ticks--;

            if (ticks < 0)
            {
                return(VMPrimitiveExitCode.GOTO_TRUE);
            }
            else
            {
                VMMemory.SetVariable(context, tso.simantics.engine.scopes.VMVariableScope.Local, operand.StackVarToDec, ticks);
                return(VMPrimitiveExitCode.CONTINUE_NEXT_TICK);
            }
        }
예제 #43
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand <VMSleepOperand>();

            var ticks = VMMemory.GetVariable(context, TSO.Simantics.engine.scopes.VMVariableScope.Parameters, operand.StackVarToDec);

            //if (ticks > 0) Trace("sleeping...") ;

            ticks--;

            if (ticks < 0)
            {
                return(VMPrimitiveExitCode.GOTO_TRUE);
            }
            else
            {
                VMMemory.SetVariable(context, TSO.Simantics.engine.scopes.VMVariableScope.Parameters, operand.StackVarToDec, ticks);
                return(VMPrimitiveExitCode.CONTINUE_NEXT_TICK);
            }
        }
예제 #44
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand <VMRandomNumberOperand>();

            var description = "random: less than " + VMMemory.DescribeVariable(context, operand.RangeScope, operand.RangeData);

            description += " written to " + VMMemory.DescribeVariable(context, operand.DestinationScope, operand.DestinationData);
            Trace(description);


            //TODO: Make this deterministic
            var rangeValue = VMMemory.GetVariable(context, operand.RangeScope, operand.RangeData);

            var rand   = new Random();
            var result = rand.Next(rangeValue);

            VMMemory.SetVariable(context, operand.DestinationScope, operand.DestinationData, (short)result);
            Trace("set " + operand.DestinationScope + " #" + operand.DestinationData + " to random " + result);
            return(VMPrimitiveExitCode.GOTO_TRUE);
        }
예제 #45
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand <VMGotoRelativePositionOperand>();

            var obj    = (VMGameObject)context.Callee;
            var avatar = (VMAvatar)context.Caller;

            /**
             * Examples for reference
             * Fridge - Have Snack - In front of, facing
             */
            if (operand.Location == VMGotoRelativeLocation.InFrontOf)
            {
                /** Need to work out which side is in front? **/

                //TODO: My positions are wrong, what i call left front etc is wrong. Need to correct this eventually
                var location = obj.Position;
                switch (obj.Direction)
                {
                case tso.world.model.Direction.LeftFront:
                    location += new Vector3(0.0f, 1.0f, 0.0f);
                    break;

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

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

                case tso.world.model.Direction.RightBack:
                    location += new Vector3(0.0f, -1.0f, 0.0f);
                    break;
                }
                avatar.Position = location + new Vector3(0.5f, 0.5f, 0.0f);
                return(VMPrimitiveExitCode.GOTO_TRUE_NEXT_TICK);
            }
            throw new Exception("Unknown goto relative");
        }
예제 #46
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand  = context.GetCurrentOperand <VMTestObjectTypeOperand>();
            var objectID = VMMemory.GetVariable(context, operand.IdOwner, operand.IdData);

            var obj = context.VM.GetObjectById(objectID);

            if (obj == null)
            {
                return(VMPrimitiveExitCode.ERROR);
            }

            //TODO: This should check if obj or masterID is type not just single tile
            if (obj.Object.GUID == operand.GUID)
            {
                return(VMPrimitiveExitCode.GOTO_TRUE);
            }
            else
            {
                return(VMPrimitiveExitCode.GOTO_FALSE);
            }
        }
예제 #47
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand <VMChangeSuitOrAccessoryOperand>();
            var suit    = VMMemory.GetSuit(context, operand.SuitScope, operand.SuitData);
            var avatar  = (VMAvatar)context.Caller;

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

            if ((operand.Flags & VMChangeSuitOrAccessoryFlags.Remove) == VMChangeSuitOrAccessoryFlags.Remove)
            {
                avatar.Avatar.RemoveAccessory(suit);
            }
            else
            {
                avatar.Avatar.AddAccessory(suit);
            }

            return(VMPrimitiveExitCode.GOTO_TRUE_NEXT_TICK);
        }
예제 #48
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var  operand = context.GetCurrentOperand <VMPlaySoundOperand>();
            FWAV fwav    = context.CodeOwner.Get <FWAV>(operand.EventID);

            if (fwav == null)
            {
                fwav = context.VM.Context.Globals.Resource.Get <FWAV>(operand.EventID);
            }

            if (fwav != null)
            {
                var thread = HITVM.Get().PlaySoundEvent(fwav.Name);
                if (thread != null)
                {
                    var owner = (operand.StackObjAsSource)?context.StackObject:context.Caller;

                    if (!thread.AlreadyOwns(owner.ObjectID))
                    {
                        thread.AddOwner(owner.ObjectID);
                    }

                    var entry = new VMSoundEntry()
                    {
                        Thread = thread,
                        Pan    = !operand.NoPan,
                        Zoom   = !operand.NoZoom,
                        Loop   = operand.Loop,
                        Name   = fwav.Name
                    };
                    owner.SoundThreads.Add(entry);
                    owner.TickSounds();
                }
            }

            return(VMPrimitiveExitCode.GOTO_TRUE);
        }
예제 #49
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand <VMGrabOperand>();

            if (context.Caller.GetSlot(0) == null)
            {
                var prevContain = context.VM.GetObjectById(context.StackObject.GetValue(VMStackObjectVariable.ContainerId));
                if (prevContain != null)
                {
                    prevContain.ClearSlot(context.StackObject.GetValue(VMStackObjectVariable.SlotNumber));
                }
                context.Caller.PlaceInSlot(context.StackObject, 0);

                var avatar = (VMAvatar)context.Caller;
                avatar.CarryAnimation      = TSO.Content.Content.Get().AvatarAnimations.Get("a2o-rarm-carry-loop.anim");
                avatar.CarryAnimationState = new VMAnimationState(); //set default carry animation
            }
            else
            {
                return(VMPrimitiveExitCode.GOTO_FALSE);
            }

            return(VMPrimitiveExitCode.GOTO_TRUE);
        }
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand <VMGetDistanceToOperand>();

            var      obj1 = context.StackObject;
            VMEntity obj2;

            if ((operand.Flags & 1) > 0)
            {
                obj2 = context.Caller;
            }
            else
            {
                obj2 = context.VM.GetObjectById(VMMemory.GetVariable(context, (VMVariableScope)operand.ObjectScope, operand.OScopeData));
            }

            var pos1 = obj1.Position;
            var pos2 = obj2.Position;

            var result = (short)Math.Floor(Math.Sqrt(Math.Pow(Math.Floor(pos1.X) - Math.Floor(pos2.X), 2) + Math.Pow(Math.Floor(pos1.Y) - Math.Floor(pos2.Y), 2)));

            context.Thread.TempRegisters[operand.TempNum] = result;
            return(VMPrimitiveExitCode.GOTO_TRUE);
        }
예제 #51
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand <VMRelationshipOperand>();

            VMEntity obj1;
            VMEntity obj2;

            switch (operand.Mode)
            {
            case 0:     //from me to stack object
                obj1 = context.Caller;
                obj2 = context.StackObject;
                break;

            case 1:     //from stack object to me
                obj1 = context.StackObject;
                obj2 = context.Caller;
                break;

            case 2:     //from stack object to object in local
                obj1 = context.StackObject;
                obj2 = context.VM.GetObjectById((short)context.Locals[operand.Local]);
                break;

            case 3:     //from object in local to stack object
                obj1 = context.VM.GetObjectById((short)context.Locals[operand.Local]);
                obj2 = context.StackObject;
                break;

            default:
                throw new Exception("Invalid relationship type!");
            }

            var rels   = obj1.MeToObject;
            var targId = (ushort)obj2.ObjectID;

            //check if exists
            if (!rels.ContainsKey(targId))
            {
                if (operand.FailIfTooSmall)
                {
                    return(VMPrimitiveExitCode.GOTO_FALSE);
                }
                else
                {
                    rels.Add(targId, new Dictionary <short, short>());
                }
            }
            if (!rels[targId].ContainsKey(operand.RelVar))
            {
                if (operand.FailIfTooSmall)
                {
                    return(VMPrimitiveExitCode.GOTO_FALSE);
                }
                else
                {
                    rels[targId].Add(operand.RelVar, 0);
                }
            }

            if (operand.SetMode == 1)
            { //todo, special system for server persistent avatars and pets
                var value = VMMemory.GetVariable(context, (VMVariableScope)operand.VarScope, operand.VarData);
                rels[targId][operand.RelVar] = value;
            }
            else if (operand.SetMode == 2)
            {
                var value = VMMemory.GetVariable(context, (VMVariableScope)operand.VarScope, operand.VarData);
                rels[targId][operand.RelVar] += value;
            }
            else if (operand.SetMode == 0)
            {
                VMMemory.SetVariable(context, (VMVariableScope)operand.VarScope, operand.VarData, rels[targId][operand.RelVar]);
            }

            return(VMPrimitiveExitCode.GOTO_TRUE);
        }
예제 #52
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand <VMReachOperand>();

            int height;

            if (operand.Mode == 0)
            {                                                                         //reach to stack object
                height = (int)Math.Round(context.StackObject.WorldUI.Position.Z * 4); //todo, factor in second floor by making height differential to sim height
            }
            else if (operand.Mode == 1)
            {
                var slotNum = context.Args[operand.SlotParam];
                var slot    = context.StackObject.Slots.Slots[0][slotNum];
                if (slot != null)
                {
                    height = (int)Math.Round((slot.Offset.Z == 0) ? slot.Height : slot.Offset.Z);
                }
                else
                {
                    return(VMPrimitiveExitCode.GOTO_FALSE);
                }
            }
            else
            {
                //reach to mouth is unimplemented so no, also none others exist after
                throw new Exception("Reach to mouth not implemented!");
            }

            string animationName;

            if (height < 2)
            {
                animationName = "a2o-reach-floorht.anim";
            }
            else if (height < 4)
            {
                animationName = "a2o-reach-seatht.anim";
            }
            else
            {
                animationName = "a2o-reach-tableht.anim";
            }

            var animation = TSO.Content.Content.Get().AvatarAnimations.Get(animationName);

            if (animation == null)
            {
                return(VMPrimitiveExitCode.ERROR);
            }
            var avatar = (VMAvatar)context.Caller;

            /** Are we starting the animation or progressing it? **/
            if (avatar.CurrentAnimation == null || avatar.CurrentAnimation != animation)
            { //start the grab!
                /** Start it **/
                avatar.CurrentAnimation        = animation;
                avatar.CurrentAnimationState   = new VMAnimationState();
                avatar.Avatar.LeftHandGesture  = SimHandGesture.Idle;
                avatar.Avatar.RightHandGesture = SimHandGesture.Idle;
                failed = false;

                foreach (var motion in animation.Motions)
                {
                    if (motion.TimeProperties == null)
                    {
                        continue;
                    }

                    foreach (var tp in motion.TimeProperties)
                    {
                        foreach (var item in tp.Items)
                        {
                            avatar.CurrentAnimationState.TimePropertyLists.Add(item);
                        }
                    }
                }

                /** Sort time property lists by time **/
                avatar.CurrentAnimationState.TimePropertyLists.Sort(new TimePropertyListItemSorter());
                return(VMPrimitiveExitCode.CONTINUE_NEXT_TICK);
            }
            else
            {
                if (avatar.CurrentAnimationState.EndReached)
                {
                    avatar.CurrentAnimation = null;
                    if (failed)
                    {
                        return(VMPrimitiveExitCode.GOTO_FALSE);
                    }
                    return(VMPrimitiveExitCode.GOTO_TRUE);
                }
                else if (avatar.CurrentAnimationState.EventFired)
                {
                    if (avatar.CurrentAnimationState.EventCode == 0)
                    {
                        //do the grab/drop
                        if (operand.Mode == 0)
                        { //pick up stack object. no drop condition
                            if (context.Caller.GetSlot(0) == null)
                            {
                                var prevContain = context.VM.GetObjectById(context.StackObject.GetValue(VMStackObjectVariable.ContainerId));
                                if (prevContain != null)
                                {
                                    prevContain.ClearSlot(context.StackObject.GetValue(VMStackObjectVariable.SlotNumber));
                                }
                                context.Caller.PlaceInSlot(context.StackObject, 0);

                                avatar.CarryAnimation      = TSO.Content.Content.Get().AvatarAnimations.Get("a2o-rarm-carry-loop.anim");
                                avatar.CarryAnimationState = new VMAnimationState(); //set default carry animation
                            }
                            else
                            {
                                failed = true;
                            }
                        }
                        else if (operand.Mode == 1)
                        { //grab or drop, depending on if we're holding something
                            var holding = context.Caller.GetSlot(0);
                            var slotNum = context.Args[operand.SlotParam];

                            if (holding == null)
                            { //grab
                                var item = context.StackObject.GetSlot(slotNum);
                                if (item != null)
                                {
                                    context.StackObject.ClearSlot(slotNum);
                                    context.Caller.PlaceInSlot(item, 0);

                                    avatar.CarryAnimation      = TSO.Content.Content.Get().AvatarAnimations.Get("a2o-rarm-carry-loop.anim");
                                    avatar.CarryAnimationState = new VMAnimationState(); //set default carry animation
                                }
                                else
                                {
                                    failed = true;  //can't grab from an empty space
                                }
                            }
                            else //drop
                            {
                                var itemTest = context.StackObject.GetSlot(slotNum);
                                if (itemTest == null)
                                {
                                    context.Caller.ClearSlot(0);
                                    context.StackObject.PlaceInSlot(holding, slotNum);

                                    avatar.CarryAnimation = null;
                                }
                                else
                                {
                                    failed = true;  //can't drop in an occupied space
                                }
                            }
                        }
                    }

                    avatar.CurrentAnimationState.EventFired = false; //clear fired flag
                    return(VMPrimitiveExitCode.CONTINUE_NEXT_TICK);
                }
                else
                {
                    return(VMPrimitiveExitCode.CONTINUE_NEXT_TICK);
                }
            }
        }
예제 #53
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand <VMExpressionOperand>();

            var description = "expression: " + VMMemory.DescribeVariable(context, operand.LhsOwner, operand.LhsData);

            description += " ";
            description += OperatorToString(operand.Operator);
            description += " ";
            description += VMMemory.DescribeVariable(context, operand.RhsOwner, operand.RhsData);
            Trace(description);

            short rhsValue  = 0;
            short lhsValue  = 0;
            bool  setResult = false;

            switch (operand.Operator)
            {
            /** Modifiers **/
            case VMExpressionOperator.Assign:
                rhsValue  = VMMemory.GetVariable(context, operand.RhsOwner, operand.RhsData);
                setResult = VMMemory.SetVariable(context, operand.LhsOwner, operand.LhsData, rhsValue);
                if (setResult)
                {
                    return(VMPrimitiveExitCode.GOTO_TRUE);
                }
                else
                {
                    return(VMPrimitiveExitCode.GOTO_FALSE);
                }

            /** ++ and < **/
            case VMExpressionOperator.IncAndLessThan:
                lhsValue = VMMemory.GetVariable(context, operand.LhsOwner, operand.LhsData);
                lhsValue++;
                VMMemory.SetVariable(context, operand.LhsOwner, operand.LhsData, lhsValue);
                rhsValue = VMMemory.GetVariable(context, operand.RhsOwner, operand.RhsData);

                if (lhsValue < rhsValue)
                {
                    return(VMPrimitiveExitCode.GOTO_TRUE);
                }
                else
                {
                    return(VMPrimitiveExitCode.GOTO_FALSE);
                }

            case VMExpressionOperator.SetFlag:
                lhsValue = VMMemory.GetVariable(context, operand.LhsOwner, operand.LhsData);
                rhsValue = VMMemory.GetVariable(context, operand.RhsOwner, operand.RhsData);
                var bitval = 1 << (rhsValue - 1);
                lhsValue |= (short)bitval;
                if (VMMemory.SetVariable(context, operand.LhsOwner, operand.LhsData, lhsValue))
                {
                    return(VMPrimitiveExitCode.GOTO_TRUE);
                }
                else
                {
                    return(VMPrimitiveExitCode.GOTO_FALSE);
                }

            case VMExpressionOperator.ClearFlag:
                lhsValue = VMMemory.GetVariable(context, operand.LhsOwner, operand.LhsData);
                rhsValue = VMMemory.GetVariable(context, operand.RhsOwner, operand.RhsData);
                var clearBitval = ~(1 << (rhsValue - 1));
                lhsValue &= (short)clearBitval;
                if (VMMemory.SetVariable(context, operand.LhsOwner, operand.LhsData, lhsValue))
                {
                    return(VMPrimitiveExitCode.GOTO_TRUE);
                }
                else
                {
                    return(VMPrimitiveExitCode.GOTO_FALSE);
                }

            /** %= **/
            case VMExpressionOperator.PlusEquals:
            case VMExpressionOperator.ModEquals:
            case VMExpressionOperator.MinusEquals:
            case VMExpressionOperator.DivEquals:
            case VMExpressionOperator.MulEquals:
            case VMExpressionOperator.AndEquals:
                lhsValue = VMMemory.GetVariable(context, operand.LhsOwner, operand.LhsData);
                rhsValue = VMMemory.GetVariable(context, operand.RhsOwner, operand.RhsData);
                switch (operand.Operator)
                {
                case VMExpressionOperator.ModEquals:
                    lhsValue %= rhsValue;
                    break;

                case VMExpressionOperator.PlusEquals:
                    lhsValue += rhsValue;
                    break;

                case VMExpressionOperator.MinusEquals:
                    lhsValue -= rhsValue;
                    break;

                case VMExpressionOperator.DivEquals:
                    lhsValue /= rhsValue;
                    break;

                case VMExpressionOperator.MulEquals:
                    lhsValue *= rhsValue;
                    break;

                case VMExpressionOperator.AndEquals:
                    lhsValue &= rhsValue;
                    break;
                }
                VMMemory.SetVariable(context, operand.LhsOwner, operand.LhsData, lhsValue);
                return(VMPrimitiveExitCode.GOTO_TRUE);

            /** == **/
            case VMExpressionOperator.Equals:
            case VMExpressionOperator.LessThan:
            case VMExpressionOperator.GreaterThan:
            case VMExpressionOperator.GreaterThanOrEqualTo:
            case VMExpressionOperator.NotEqualTo:
            case VMExpressionOperator.LessThanOrEqualTo:
            case VMExpressionOperator.IsFlagSet:
                lhsValue = VMMemory.GetVariable(context, operand.LhsOwner, operand.LhsData);
                rhsValue = VMMemory.GetVariable(context, operand.RhsOwner, operand.RhsData);

                bool result = false;
                switch (operand.Operator)
                {
                case VMExpressionOperator.Equals:
                    result = lhsValue == rhsValue;
                    break;

                case VMExpressionOperator.LessThan:
                    result = lhsValue < rhsValue;
                    break;

                case VMExpressionOperator.GreaterThan:
                    result = lhsValue > rhsValue;
                    break;

                case VMExpressionOperator.GreaterThanOrEqualTo:
                    result = lhsValue >= rhsValue;
                    break;

                case VMExpressionOperator.NotEqualTo:
                    result = lhsValue != rhsValue;
                    break;

                case VMExpressionOperator.LessThanOrEqualTo:
                    result = lhsValue <= rhsValue;
                    break;

                case VMExpressionOperator.IsFlagSet:
                    result = ((lhsValue & (1 << (rhsValue - 1))) > 0);
                    break;
                }

                if (result)
                {
                    return(VMPrimitiveExitCode.GOTO_TRUE);
                }
                else
                {
                    return(VMPrimitiveExitCode.GOTO_FALSE);
                }

            default:
                throw new Exception("Unknown expression type");
            }
        }
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand <VMAnimateSimOperand>();

            var avatar = (VMAvatar)context.Caller;

            if (operand.AnimationID == 0)
            {                                  //reset
                avatar.CurrentAnimation = null;
                if (avatar.GetSlot(0) != null) //if we're carrying something, set carry animation to default carry.
                {
                    avatar.CarryAnimation      = TSO.Content.Content.Get().AvatarAnimations.Get("a2o-rarm-carry-loop.anim");
                    avatar.CarryAnimationState = new VMAnimationState();
                }
                else
                {
                    avatar.CarryAnimation = null;
                }
                return(VMPrimitiveExitCode.GOTO_TRUE);
            }

            var animation = VMMemory.GetAnimation(context, operand.Source, operand.AnimationID);

            if (animation == null)
            {
                return(VMPrimitiveExitCode.ERROR);
            }

            if (operand.Mode == 3) //stop standard carry, then play and wait
            {
                avatar.CarryAnimation = null;
            }

            if (operand.Mode == 0 || operand.Mode == 3) //Play and Wait
            {
                /** Are we starting the animation or progressing it? **/
                if (avatar.CurrentAnimation == null || avatar.CurrentAnimation != animation)
                {
                    /** Start it **/
                    avatar.CurrentAnimation        = animation;
                    avatar.CurrentAnimationState   = new VMAnimationState();
                    avatar.Avatar.LeftHandGesture  = SimHandGesture.Idle;
                    avatar.Avatar.RightHandGesture = SimHandGesture.Idle;

                    if (operand.PlayBackwards)
                    {
                        avatar.CurrentAnimationState.PlayingBackwards = true;
                        avatar.CurrentAnimationState.CurrentFrame     = avatar.CurrentAnimation.NumFrames;
                    }

                    foreach (var motion in animation.Motions)
                    {
                        if (motion.TimeProperties == null)
                        {
                            continue;
                        }

                        foreach (var tp in motion.TimeProperties)
                        {
                            foreach (var item in tp.Items)
                            {
                                avatar.CurrentAnimationState.TimePropertyLists.Add(item);
                            }
                        }
                    }

                    /** Sort time property lists by time **/
                    avatar.CurrentAnimationState.TimePropertyLists.Sort(new TimePropertyListItemSorter());
                    return(VMPrimitiveExitCode.CONTINUE_NEXT_TICK);
                }
                else
                {
                    if (avatar.CurrentAnimationState.EndReached)
                    {
                        avatar.CurrentAnimation = null;
                        return(VMPrimitiveExitCode.GOTO_TRUE);
                    }
                    else if (avatar.CurrentAnimationState.EventFired)
                    {
                        avatar.CurrentAnimationState.EventFired = false; //clear fired flag
                        if (operand.StoreFrameInLocal)
                        {
                            VMMemory.SetVariable(context, VMVariableScope.Local, operand.LocalEventNumber, avatar.CurrentAnimationState.EventCode);
                        }
                        else
                        {
                            VMMemory.SetVariable(context, VMVariableScope.Parameters, 0, avatar.CurrentAnimationState.EventCode);
                        }
                        return(VMPrimitiveExitCode.GOTO_FALSE);
                    }
                    else
                    {
                        return(VMPrimitiveExitCode.CONTINUE_NEXT_TICK);
                    }
                }
            }
            else if (operand.Mode == 2) //set custom carry animation
            {
                avatar.CarryAnimation      = animation;
                avatar.CarryAnimationState = new VMAnimationState();
                return(VMPrimitiveExitCode.GOTO_TRUE);
            }
            else
            {
                return(VMPrimitiveExitCode.GOTO_TRUE);
            }
        }
예제 #55
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var       operand = context.GetCurrentOperand <VMCreateObjectInstanceOperand>();
            short     x       = 0;
            short     y       = 0;
            sbyte     level   = 0;
            Direction dir;

            switch (operand.Position)
            {
            case VMCreateObjectPosition.UnderneathMe:
            case VMCreateObjectPosition.OnTopOfMe:
                var pos = context.Caller.Position;
                x     = (short)pos.X;
                y     = (short)pos.Y;
                level = 0;     //for now..
                dir   = Direction.NORTH;
                break;

            case VMCreateObjectPosition.BelowObjectInLocal:
                var pos2 = context.VM.GetObjectById((short)context.Locals[operand.LocalToUse]).Position;
                x     = (short)pos2.X;
                y     = (short)pos2.Y;
                level = 0;     //for now..
                dir   = Direction.NORTH;
                break;

            case VMCreateObjectPosition.OutOfWorld:
                x     = 0; //need a system for out of world objects.
                y     = 0;
                level = 0; //for now..
                dir   = Direction.NORTH;
                break;

            case VMCreateObjectPosition.InSlot0OfStackObject:
            case VMCreateObjectPosition.InMyHand:
                x     = 0; //need a system for out of world objects.
                y     = 0;
                level = 0; //for no..
                dir   = Direction.NORTH;
                //this object should start in slot 0 of the stack object!
                //we have to create it first tho so hold your horses
                break;

            case VMCreateObjectPosition.InFrontOfStackObject:
            case VMCreateObjectPosition.InFrontOfMe:
                var objp     = (operand.Position == VMCreateObjectPosition.InFrontOfStackObject)?context.StackObject:context.Caller;
                var location = objp.Position;
                switch (objp.Direction)
                {
                case tso.world.model.Direction.SOUTH:
                    location += new Vector3(0.0f, 1.0f, 0.0f);
                    break;

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

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

                case tso.world.model.Direction.NORTH:
                    location += new Vector3(0.0f, -1.0f, 0.0f);
                    break;
                }
                x     = (short)Math.Floor(location.X);
                y     = (short)Math.Floor(location.Y);
                level = 0;
                dir   = objp.Direction;
                break;

            default:
                throw new Exception("Where do I put this??");
            }

            var obj = context.VM.Context.CreateObjectInstance(operand.GUID, x, y, level, dir);

            if (operand.PassObjectIds)
            {
                obj.MainStackOBJ = context.StackObject.ObjectID;
                obj.MainParam    = context.Caller.ObjectID;
            }
            if (operand.PassTemp0)
            {
                obj.MainParam = context.Thread.TempRegisters[0];
            }

            obj.Init(context.VM.Context);

            if (operand.Position == VMCreateObjectPosition.InSlot0OfStackObject)
            {
                context.StackObject.PlaceInSlot(obj, 0);
            }
            else if (operand.Position == VMCreateObjectPosition.InMyHand)
            {
                context.Caller.PlaceInSlot(obj, 0);
            }

            if ((operand.Flags & (1 << 6)) > 0)
            {
                var interaction = operand.InteractionCallback;
                if (interaction == 254)
                {
                    var temp = context.Caller.Thread.Queue[0].InteractionNumber;
                    if (temp == -1)
                    {
                        throw new Exception("Set callback as 'this interaction' when queue item has no interaction number!");
                    }
                    interaction = (byte)temp;
                }
                var callback = new VMActionCallback(context.VM, interaction, context.Callee, context.StackObject, context.Caller, true);
                callback.Run(obj);
            }
            else
            {
                context.StackObject = obj;
            }

            return(VMPrimitiveExitCode.GOTO_TRUE);
        }
예제 #56
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand = context.GetCurrentOperand <VMPlaySoundOperand>();

            return(VMPrimitiveExitCode.GOTO_TRUE);
        }
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var operand     = context.GetCurrentOperand <VMSetToNextOperand>();
            var targetValue = VMMemory.GetVariable(context, operand.GetTargetOwner(), operand.GetTargetData());
            var entities    = context.VM.Entities;

            bool     foundCurrent = false;
            VMEntity FirstOfType  = null; //used for looparound if no next
            VMEntity Pointer      = context.VM.GetObjectById(targetValue);

            if (operand.SearchType == VMSetToNextSearchType.PartOfAMultipartTile)
            {
                if (context.Callee.MultitileGroup == null)
                {
                    return(VMPrimitiveExitCode.GOTO_FALSE);                                       //single part
                }
                else
                {
                    var group = context.Callee.MultitileGroup.Objects;

                    for (int i = 0; i < group.Count; i++)
                    {
                        var temp = group[i];
                        if (Pointer == null || context.SetToNextStart == null)
                        {
                            context.SetToNextStart = temp;
                            VMMemory.SetVariable(context, operand.GetTargetOwner(), operand.GetTargetData(), temp.ObjectID);
                            return(VMPrimitiveExitCode.GOTO_TRUE);
                        }
                        else
                        {
                            if (foundCurrent)
                            {
                                if (temp == context.SetToNextStart)
                                {
                                    return(VMPrimitiveExitCode.GOTO_FALSE);
                                }
                                else
                                {
                                    VMMemory.SetVariable(context, operand.GetTargetOwner(), operand.GetTargetData(), temp.ObjectID);
                                    return(VMPrimitiveExitCode.GOTO_TRUE);
                                }
                            }
                            else
                            {
                                if (temp == Pointer)
                                {
                                    foundCurrent = true;
                                }
                                else if (FirstOfType == null)
                                {
                                    FirstOfType = temp;
                                }
                            }
                        }
                    }
                }
            }
            else
            {
                for (int i = 0; i < entities.Count; i++) //generic search through all objects
                {
                    var      temp = entities[i];
                    VMEntity temp2; //used in some places
                    bool     found = false;

                    switch (operand.SearchType)   //search types
                    {
                    case VMSetToNextSearchType.Object:
                        found = true;
                        break;

                    case VMSetToNextSearchType.Person:
                        found = (temp.GetType() == typeof(VMAvatar));
                        break;

                    case VMSetToNextSearchType.NonPerson:
                        found = (temp.GetType() == typeof(VMGameObject));
                        break;

                    case VMSetToNextSearchType.ObjectOfType:
                        found = (temp.Object.OBJ.GUID == operand.GUID);
                        break;

                    case VMSetToNextSearchType.NeighborId:
                        throw new Exception("Not implemented!");

                    case VMSetToNextSearchType.ObjectWithCategoryEqualToSP0:
                        found = (temp.Object.OBJ.FunctionFlags == context.Args[0]);     //I'm assuming that means "Stack parameter 0", that category means function and that it needs to be exactly the same (no subsets)
                        break;

                    case VMSetToNextSearchType.NeighborOfType:
                        throw new Exception("Not implemented!");

                    case VMSetToNextSearchType.ObjectOnSameTile:
                        temp2 = context.Caller;     //.VM.GetObjectById((short)context.Locals[operand.Local]); //sure, it doesn't have this in the name, but it seems like the object is chosen from a local.
                        found = (Math.Round(temp.Position.X) == Math.Round(temp2.Position.X) && Math.Round(temp.Position.Y) == Math.Round(temp2.Position.Y));
                        break;

                    case VMSetToNextSearchType.ObjectAdjacentToObjectInLocal:
                        temp2 = context.VM.GetObjectById((short)context.Locals[operand.Local]);
                        found = (Math.Abs(Math.Round(temp.Position.X) - Math.Round(temp2.Position.X)) < 2 && Math.Abs(Math.Round(temp.Position.Y) - Math.Round(temp2.Position.Y)) < 2);
                        break;

                    case VMSetToNextSearchType.Career:
                        throw new Exception("Not implemented!");

                    case VMSetToNextSearchType.ClosestHouse:
                        throw new Exception("Not implemented!");
                    }
                    if (found)
                    {
                        if (Pointer == null || context.SetToNextStart == null)
                        {
                            context.SetToNextStart = temp;
                            VMMemory.SetVariable(context, operand.GetTargetOwner(), operand.GetTargetData(), temp.ObjectID);
                            return(VMPrimitiveExitCode.GOTO_TRUE);
                        }
                        else
                        {
                            if (foundCurrent)
                            {
                                if (temp == context.SetToNextStart)
                                {
                                    return(VMPrimitiveExitCode.GOTO_FALSE);
                                }
                                else
                                {
                                    VMMemory.SetVariable(context, operand.GetTargetOwner(), operand.GetTargetData(), temp.ObjectID);
                                    return(VMPrimitiveExitCode.GOTO_TRUE);
                                }
                            }
                            else
                            {
                                if (temp == Pointer)
                                {
                                    foundCurrent = true;
                                }
                                else if (FirstOfType == null)
                                {
                                    FirstOfType = temp;
                                }
                            }
                        }
                    }
                }
            }
            //if we exit, we didn't find next. go for first of type if not where we started
            if (FirstOfType != null)
            {
                if (FirstOfType == context.SetToNextStart)
                {
                    return(VMPrimitiveExitCode.GOTO_FALSE);
                }
                else
                {
                    VMMemory.SetVariable(context, operand.GetTargetOwner(), operand.GetTargetData(), FirstOfType.ObjectID);
                    return(VMPrimitiveExitCode.GOTO_TRUE);
                }
            }
            return(VMPrimitiveExitCode.GOTO_FALSE); //no first, didn't find a next.
        }
예제 #58
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);
        }
예제 #59
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);
        }
        public override VMPrimitiveExitCode Execute(VMStackFrame context)
        {
            var      operand = context.GetCurrentOperand <VMPushInteractionOperand>();
            VMEntity interactionSource;

            if ((operand.Flags & (1 << 1)) > 0)
            {
                interactionSource = context.VM.GetObjectById((short)context.Locals[operand.ObjectLocation]);
            }
            else
            {
                interactionSource = context.VM.GetObjectById((short)context.Args[operand.ObjectLocation]);
            }

            VMQueuePriority priority;

            if (operand.Priority == 0)
            {
                priority = context.Thread.Queue[0].Priority;
            }
            else
            {
                priority = (VMQueuePriority)(operand.Priority - 1);
            }

            BHAV            bhav;
            GameIffResource CodeOwner = null;
            var             Action    = interactionSource.TreeTable.InteractionByIndex[operand.Interaction];
            ushort          ActionID  = Action.ActionFunction;

            if (ActionID < 4096)
            { //global
                bhav = null;
                //unimp as it has to access the context to get this.
            }
            else if (ActionID < 8192)
            { //local
                bhav      = interactionSource.Object.Resource.Get <BHAV>(ActionID);
                CodeOwner = interactionSource.Object.Resource;
            }
            else
            { //semi-global
                bhav      = interactionSource.SemiGlobal.Resource.Get <BHAV>(ActionID);
                CodeOwner = interactionSource.SemiGlobal.Resource;
            }

            var routine = context.VM.Assemble(bhav);

            context.StackObject.Thread.EnqueueAction(
                new TSO.Simantics.engine.VMQueuedAction
            {
                Callee            = interactionSource,
                CodeOwner         = CodeOwner,
                Routine           = routine,
                Name              = interactionSource.TreeTableStrings.GetString((int)Action.TTAIndex),
                StackObject       = interactionSource,
                InteractionNumber = operand.Interaction,
                Priority          = priority
            }
                );

            return(VMPrimitiveExitCode.GOTO_TRUE);
        }