Пример #1
0
        private bool ExecuteAction(VMQueuedAction action)
        {
            var frame = action.ToStackFrame(Entity);

            frame.DiscardResult = true;
            return(Push(frame));
        }
Пример #2
0
        private void ExecuteAction(VMQueuedAction action)
        {
            var frame = action.ToStackFrame(Entity);

            frame.DiscardResult = true;
            Push(frame);
        }
Пример #3
0
 public static VMPrimitiveExitCode EvaluateCheck(VMContext context, VMEntity entity, VMQueuedAction action)
 {
     var temp = new VMThread(context, entity, 5);
     temp.IsCheck = true;
     temp.EnqueueAction(action);
     while (temp.Queue.Count > 0 && temp.DialogCooldown == 0) //keep going till we're done! idling is for losers!
     {
         temp.Tick();
     }
     return (temp.DialogCooldown > 0) ? VMPrimitiveExitCode.ERROR:temp.LastStackExitCode;
 }
Пример #4
0
        /// <summary>
        /// Add an item to the action queue
        /// </summary>
        /// <param name="invocation"></param>
        public void EnqueueAction(VMQueuedAction invocation)
        {
            invocation.UID = ActionUID++;
            QueueDirty     = true;
            if (!IsCheck && (invocation.Flags & TTABFlags.RunImmediately) > 0)
            {
                // shove this action in the queue to try run it next tick.
                // interaction can be run normally if we actually hit it using allow push. (unlikely)
                // otherwise next tick will detect the "run immediately" interaction's prescence.
                // and it will be pushed to the stack immediately.
                // TODO: check if any interactions of this kind clobber the temps.
                // this doesnt ""run immediately"", but is good enough.

                invocation.Mode     = VMQueueMode.Idle; //hide
                invocation.Priority = short.MinValue;
                this.Queue.Add(invocation);
                return;
            }

            if (Queue.Count == 0) //if empty, just queue right at the front
            {
                this.Queue.Add(invocation);
            }
            else if ((invocation.Flags & TTABFlags.Leapfrog) > 0)
            {
                //place right after active interaction, ignoring all priorities.
                this.Queue.Insert(ActiveQueueBlock + 1, invocation);
            }
            else //we've got an even harder job! find a place for this interaction based on its priority
            {
                bool hitParentEnd = (invocation.Mode != VMQueueMode.ParentIdle);
                for (int i = Queue.Count - 1; i > ActiveQueueBlock; i--)
                {
                    if (hitParentEnd && (invocation.Priority <= Queue[i].Priority || Queue[i].Mode == VMQueueMode.ParentExit)) //skip until we find a parent exit or something with the same or higher priority.
                    {
                        this.Queue.Insert(i + 1, invocation);
                        EvaluateQueuePriorities();
                        return;
                    }
                    if (Queue[i].Mode == VMQueueMode.ParentExit)
                    {
                        hitParentEnd = true;
                    }
                }
                this.Queue.Insert(ActiveQueueBlock + 1, invocation); //this is more important than all other queued items that are not running, so stick this to run next.
            }
            EvaluateQueuePriorities();
        }
Пример #5
0
 public static VMPrimitiveExitCode EvaluateCheck(VMContext context, VMEntity entity, VMStackFrame initFrame, VMQueuedAction action, List<VMPieMenuInteraction> actionStrings)
 {
     var temp = new VMThread(context, entity, 5);
     if (entity.Thread != null)
     {
         temp.TempRegisters = entity.Thread.TempRegisters;
         temp.TempXL = entity.Thread.TempXL;
     }
     temp.IsCheck = true;
     temp.ActionStrings = actionStrings; //generate and place action strings in here
     temp.Push(initFrame);
     if (action != null) temp.Queue.Add(action); //this check runs an action. We may need its interaction number, etc.
     while (temp.Stack.Count > 0 && temp.DialogCooldown == 0) //keep going till we're done! idling is for losers!
     {
         temp.Tick();
         temp.ThreadBreak = VMThreadBreakMode.Active; //cannot breakpoint in check trees
     }
     return (temp.DialogCooldown > 0) ? VMPrimitiveExitCode.ERROR:temp.LastStackExitCode;
 }
Пример #6
0
        private void ExecuteAction(VMQueuedAction action)
        {
            var frame = new VMStackFrame {
                Caller      = Entity,
                Callee      = action.Callee,
                CodeOwner   = action.CodeOwner,
                Routine     = action.Routine,
                StackObject = action.StackObject
            };

            if (action.Args == null)
            {
                frame.Args = new short[4];                      //always 4? i got crashes when i used the value provided by the routine, when for that same routine edith displayed 4 in the properties...
            }
            else
            {
                frame.Args = action.Args;  //WARNING - if you use this, the args array MUST have the same number of elements the routine is expecting!
            }
            Push(frame);
        }
Пример #7
0
 /// <summary>
 /// Add an item to the action queue
 /// </summary>
 /// <param name="invocation"></param>
 public void EnqueueAction(VMQueuedAction invocation)
 {
     invocation.UID = ActionUID++;
     if (Queue.Count == 0) //if empty, just queue right at the front (or end, if you're like that!)
     {
         this.Queue.Add(invocation);
     }
     else //we've got an even harder job! find a place for this interaction based on its priority
     {
         for (int i = Queue.Count - 1; i > 0; i--)
         {
             if (invocation.Priority >= Queue[i].Priority) //if the next queue element we need to skip over is of the same or a higher priority we'll stay right here, otherwise skip over it!
             {
                 this.Queue.Insert(i+1, invocation);
                 return;
             }
         }
         this.Queue.Insert(1, invocation); //this is more important than all other queued items that are not running, so stick this to run next.
     }
     EvaluateQueuePriorities();
 }
Пример #8
0
        /// <summary>
        /// Add an item to the action queue
        /// </summary>
        /// <param name="invocation"></param>
        public void EnqueueAction(VMQueuedAction invocation)
        {
            if (!IsCheck && (invocation.Flags & TTABFlags.RunImmediately) > 0)
            {
                EvaluateCheck(Context, Entity, invocation);
                return;
            }

            invocation.UID = ActionUID++;
            if (Queue.Count == 0) //if empty, just queue right at the front
            {
                this.Queue.Add(invocation);
            }
            else if ((invocation.Flags & TTABFlags.Leapfrog) > 0)
            {
                //place right after active interaction, ignoring all priorities.
                this.Queue.Insert(1, invocation);
            }
            else //we've got an even harder job! find a place for this interaction based on its priority
            {
                bool hitParentEnd = (invocation.Mode != VMQueueMode.ParentIdle);
                for (int i = Queue.Count - 1; i > 0; i--)
                {
                    if (hitParentEnd && (invocation.Priority <= Queue[i].Priority || Queue[i].Mode == VMQueueMode.ParentExit)) //skip until we find a parent exit or something with the same or higher priority.
                    {
                        this.Queue.Insert(i + 1, invocation);
                        EvaluateQueuePriorities();
                        return;
                    }
                    if (Queue[i].Mode == VMQueueMode.ParentExit)
                    {
                        hitParentEnd = true;
                    }
                }
                this.Queue.Insert(1, invocation); //this is more important than all other queued items that are not running, so stick this to run next.
            }
            EvaluateQueuePriorities();
        }
Пример #9
0
        private void ExecuteAction(VMQueuedAction action)
        {
            var frame = action.ToStackFrame(Entity);

            Push(frame);
        }
Пример #10
0
        public static VMPrimitiveExitCode EvaluateCheck(VMContext context, VMEntity entity, VMStackFrame initFrame, VMQueuedAction action, List <VMPieMenuInteraction> actionStrings)
        {
            var temp       = new VMThread(context, entity, 5);
            var forceClone = !context.VM.Scheduler.RunningNow;

            //temps should only persist on check trees running within the vm tick to avoid desyncs.
            if (entity.Thread != null)
            {
                temp.TempRegisters = forceClone?(short[])entity.Thread.TempRegisters.Clone() : entity.Thread.TempRegisters;
                temp.TempXL        = forceClone ? (int[])entity.Thread.TempXL.Clone() : entity.Thread.TempXL;
            }
            temp.IsCheck       = true;
            temp.ActionStrings = actionStrings; //generate and place action strings in here
            temp.Push(initFrame);
            if (action != null)
            {
                temp.Queue.Add(action);                              //this check runs an action. We may need its interaction number, etc.
            }
            while (temp.Stack.Count > 0 && temp.DialogCooldown == 0) //keep going till we're done! idling is for losers!
            {
                temp.Tick();
                temp.ThreadBreak = VMThreadBreakMode.Active; //cannot breakpoint in check trees
            }
            if (context.VM.Aborting)
            {
                return(VMPrimitiveExitCode.ERROR);
            }
            return((temp.DialogCooldown > 0) ? VMPrimitiveExitCode.RETURN_FALSE : temp.LastStackExitCode);
        }
Пример #11
0
 public static VMPrimitiveExitCode EvaluateCheck(VMContext context, VMEntity entity, VMStackFrame initFrame, VMQueuedAction action)
 {
     return(EvaluateCheck(context, entity, initFrame, action, null));
 }
Пример #12
0
        private void ExecuteAction(VMQueuedAction action)
        {
            var frame = new VMStackFrame {
                Caller = Entity,
                Callee = action.Callee,
                CodeOwner = action.CodeOwner,
                Routine = action.Routine,
                StackObject = action.StackObject
            };
            if (action.Args == null) frame.Args = new short[4]; //always 4? i got crashes when i used the value provided by the routine, when for that same routine edith displayed 4 in the properties...
            else frame.Args = action.Args; //WARNING - if you use this, the args array MUST have the same number of elements the routine is expecting!

            Push(frame);
        }
Пример #13
0
        public static VMPrimitiveExitCode EvaluateCheck(VMContext context, VMEntity entity, VMStackFrame initFrame, VMQueuedAction action, List <VMPieMenuInteraction> actionStrings)
        {
            var temp = new VMThread(context, entity, 5);

            if (entity.Thread != null)
            {
                temp.TempRegisters = entity.Thread.TempRegisters;
                temp.TempXL        = entity.Thread.TempXL;
            }
            temp.IsCheck       = true;
            temp.ActionStrings = actionStrings; //generate and place action strings in here
            temp.Push(initFrame);
            if (action != null)
            {
                temp.Queue.Add(action);                              //this check runs an action. We may need its interaction number, etc.
            }
            while (temp.Stack.Count > 0 && temp.DialogCooldown == 0) //keep going till we're done! idling is for losers!
            {
                temp.Tick();
                temp.ThreadBreak = VMThreadBreakMode.Active; //cannot breakpoint in check trees
            }
            return((temp.DialogCooldown > 0) ? VMPrimitiveExitCode.ERROR:temp.LastStackExitCode);
        }
Пример #14
0
        public List <VMPieMenuInteraction> CheckTS1Action(VMQueuedAction action)
        {
            var result = new List <VMPieMenuInteraction>();

            if (Entity is VMAvatar) //just let everyone use the CSR interactions
            {
                var avatar = (VMAvatar)Entity;

                if ((action.Flags & (TTABFlags.TS1AllowCats | TTABFlags.TS1AllowDogs)) > 0)
                {
                    //interaction can only be performed by cats or dogs
                    //if (!avatar.IsPet) return null;
                    //check we're the correct type
                    if (avatar.IsCat && (action.Flags & TTABFlags.TS1AllowCats) == 0)
                    {
                        return(null);
                    }
                    if (avatar.IsDog && (action.Flags & TTABFlags.TS1AllowDogs) == 0)
                    {
                        return(null);
                    }
                }
                else if (avatar.IsPet)
                {
                    return(null);                   //not allowed
                }
                var isVisitor = avatar.GetPersonData(VMPersonDataVariable.PersonType) == 1 && avatar.GetPersonData(VMPersonDataVariable.TS1FamilyNumber) != Context.VM.CurrentFamily?.ChunkID;
                //avatar.ObjectID != Context.VM.GetGlobalValue(3);

                TTABFlags ts1State =
                    ((isVisitor) ? TTABFlags.AllowVisitors : 0)
                    | ((avatar.GetPersonData(VMPersonDataVariable.PersonsAge) < 18) ? TTABFlags.TS1NoChild : 0)
                    | ((avatar.GetPersonData(VMPersonDataVariable.PersonsAge) >= 18 && !avatar.IsPet) ? TTABFlags.TS1NoAdult : 0);

                //DEBUG: enable debug interction for all CSRs.
                if ((action.Flags & TTABFlags.Debug) > 0)
                {
                    if (!isVisitor)
                    {
                        return(result); //do not bother running check
                    }
                    else
                    {
                        return(null); //disable debug for everyone else.
                    }
                }

                //NEGATIVE EFFECTS:
                var pos        = ts1State & (TTABFlags.TS1NoChild | TTABFlags.TS1NoAdult);
                var ts1Compare = action.Flags;
                if ((pos & ts1Compare) > 0)
                {
                    return(null);
                }

                var negMask = (TTABFlags.AllowVisitors);

                var negatedFlags = (~ts1Compare) & negMask;
                if ((negatedFlags & ts1State) > 0)
                {
                    return(null);                               //we are disallowed
                }
            }
            if (action.CheckRoutine != null && EvaluateCheck(Context, Entity, new VMStackFrame()
            {
                Caller = Entity,
                Callee = action.Callee,
                CodeOwner = action.CodeOwner,
                StackObject = action.StackObject,
                Routine = action.CheckRoutine,
                Args = new short[4]
            }, null, result) != VMPrimitiveExitCode.RETURN_TRUE)
            {
                return(null);
            }

            return(result);
        }
Пример #15
0
 public static VMPrimitiveExitCode EvaluateCheck(VMContext context, VMEntity entity, VMStackFrame initFrame, VMQueuedAction action)
 {
     return EvaluateCheck(context, entity, initFrame, action, null);
 }
Пример #16
0
        public List<VMPieMenuInteraction> CheckAction(VMQueuedAction action)
        {
            // 1. check action flags for permissions (if we are avatar)
            // 2. run check tree

            // rules:
            // Dogs/Cats means people CANNOT use these interactions. (DogsFlag|CatsFlag & IsDog|IsCat)

            // When Allow Object Owner is OFF it disallows the object owner, otherwise no effect
            // Visitors, Roommates, Ghosts have this same negative effect.
            // Friends apprars to override Owner, Visitors, Roommates

            // Allow CSRs:positive effect.

            if (action == null) return null;
            var result = new List<VMPieMenuInteraction>();

            if (((action.Flags & TTABFlags.MustRun) == 0) && Entity is VMAvatar && ((action.Flags2 & TSOFlags.AllowCSRs) == 0)) //just let everyone use the CSR interactions
            {
                var avatar = (VMAvatar)Entity;

                if (avatar.GetSlot(0) != null && (action.Flags | TTABFlags.TSOAvailableCarrying) == 0) return null;

                if ((action.Flags & (TTABFlags.AllowCats | TTABFlags.AllowDogs)) > 0)
                {
                    //interaction can only be performed by cats or dogs
                    if (!avatar.IsPet) return null;
                    //check we're the correct type
                    if (avatar.IsCat && (action.Flags & TTABFlags.AllowCats) == 0) return null;
                    if (avatar.IsDog && (action.Flags & TTABFlags.AllowDogs) == 0) return null;
                }
                else if (avatar.IsPet) return null; //not allowed

                if ((action.Flags & TTABFlags.TSOIsRepair) > 0) return null;

                TSOFlags tsoState =
                    ((!(action.Callee is VMGameObject) || avatar.PersistID == ((VMTSOObjectState)action.Callee.TSOState).OwnerID)
                    ? TSOFlags.AllowObjectOwner : 0)
                    | ((((VMTSOAvatarState)avatar.TSOState).Permissions == VMTSOAvatarPermissions.Visitor) ? TSOFlags.AllowVisitors : 0)
                    | ((((VMTSOAvatarState)avatar.TSOState).Permissions >= VMTSOAvatarPermissions.Roommate) ? TSOFlags.AllowRoommates : 0)
                    | ((((VMTSOAvatarState)avatar.TSOState).Permissions == VMTSOAvatarPermissions.Admin) ? TSOFlags.AllowCSRs : 0)
                    | ((avatar.GetPersonData(VMPersonDataVariable.IsGhost) > 0) ? TSOFlags.AllowGhost : 0)
                    | TSOFlags.AllowFriends;
                TSOFlags tsoCompare = action.Flags2;
                //if flags are empty apart from "Non-Empty", force everything but visitor. (a kind of default state)
                if (tsoCompare == TSOFlags.NonEmpty) tsoCompare |= TSOFlags.AllowFriends | TSOFlags.AllowRoommates | TSOFlags.AllowObjectOwner;

                //DEBUG: enable debug interction for all roommates. change to only CSRs for production!
                if ((action.Flags & TTABFlags.Debug) > 0) {

                    if ((tsoState & TSOFlags.AllowRoommates) > 0)
                        return result; //do not bother running check
                    else
                        return null; //disable debug for everyone else.
                }

                if ((action.Flags & TTABFlags.TSOAvailableWhenDead) > 0) tsoCompare |= TSOFlags.AllowGhost;
                if ((action.Flags & TTABFlags.AllowVisitors) > 0) tsoCompare |= TSOFlags.AllowVisitors; //wrong???????

                var posMask = (TSOFlags.AllowObjectOwner);
                if (((tsoState & posMask) & (tsoCompare & posMask)) == 0)
                {
                    //NEGATIVE EFFECTS:
                    var negMask = (TSOFlags.AllowVisitors | TSOFlags.AllowRoommates | TSOFlags.AllowGhost);

                    var negatedFlags = (~tsoCompare) & negMask;
                    if ((negatedFlags & tsoState) > 0) return null; //we are disallowed
                                                                    //if ((tsoCompare & TSOFlags.AllowCSRs) > 0) return null; // && (tsoState & TSOFlags.AllowCSRs) == 0
                }
            }
            if (((action.Flags & TTABFlags.MustRun) == 0 || ((action.Flags & TTABFlags.TSORunCheckAlways) > 0)) 
                && action.CheckRoutine != null && EvaluateCheck(Context, Entity, new VMStackFrame()
            {
                Caller = Entity,
                Callee = action.Callee,
                CodeOwner = action.CodeOwner,
                StackObject = action.StackObject,
                Routine = action.CheckRoutine,
                Args = new short[4]
            }, null, result) != VMPrimitiveExitCode.RETURN_TRUE) return null;

            return result;
        }
Пример #17
0
 private void ExecuteAction(VMQueuedAction action)
 {
     var frame = action.ToStackFrame(Entity);
     Push(frame);
 }
Пример #18
0
        /// <summary>
        /// Add an item to the action queue
        /// </summary>
        /// <param name="invocation"></param>
        public void EnqueueAction(VMQueuedAction invocation)
        {
            invocation.UID = ActionUID++;
            QueueDirty = true;
            if (!IsCheck && (invocation.Flags & TTABFlags.RunImmediately) > 0)
            {
                // shove this action in the queue to try run it next tick.
                // interaction can be run normally if we actually hit it using allow push. (unlikely)
                // otherwise next tick will detect the "run immediately" interaction's prescence. 
                // and it will be pushed to the stack immediately.
                // TODO: check if any interactions of this kind clobber the temps.
                // this doesnt ""run immediately"", but is good enough.

                invocation.Mode = VMQueueMode.Idle; //hide
                invocation.Priority = short.MinValue;
                this.Queue.Add(invocation);
                return;
            }

            if (Queue.Count == 0) //if empty, just queue right at the front 
                this.Queue.Add(invocation);
            else if ((invocation.Flags & TTABFlags.Leapfrog) > 0)
                //place right after active interaction, ignoring all priorities.
                this.Queue.Insert(ActiveQueueBlock+1, invocation);
            else //we've got an even harder job! find a place for this interaction based on its priority
            {
                bool hitParentEnd = (invocation.Mode != VMQueueMode.ParentIdle);
                for (int i = Queue.Count - 1; i > ActiveQueueBlock; i--)
                {
                    if (hitParentEnd && (invocation.Priority <= Queue[i].Priority || Queue[i].Mode == VMQueueMode.ParentExit)) //skip until we find a parent exit or something with the same or higher priority.
                    {
                        this.Queue.Insert(i+1, invocation);
                        EvaluateQueuePriorities();
                        return;
                    }
                    if (Queue[i].Mode == VMQueueMode.ParentExit) hitParentEnd = true;
                }
                this.Queue.Insert(ActiveQueueBlock+1, invocation); //this is more important than all other queued items that are not running, so stick this to run next.
            }
            EvaluateQueuePriorities();
        }
Пример #19
0
        public List <VMPieMenuInteraction> CheckAction(VMQueuedAction action)
        {
            // 1. check action flags for permissions (if we are avatar)
            // 2. run check tree

            // rules:
            // Dogs/Cats means people CANNOT use these interactions. (DogsFlag|CatsFlag & IsDog|IsCat)

            // When Allow Object Owner is OFF it disallows the object owner, otherwise no effect
            // Visitors, Roommates, Ghosts have this same negative effect.
            // Friends apprars to override Owner, Visitors, Roommates

            // Allow CSRs:positive effect.

            if (action == null)
            {
                return(null);
            }
            if (Context.VM.TS1)
            {
                return(CheckTS1Action(action));
            }
            var result = new List <VMPieMenuInteraction>();

            if (((action.Flags & TTABFlags.MustRun) == 0) && Entity is VMAvatar) //just let everyone use the CSR interactions
            {
                var avatar = (VMAvatar)Entity;

                if (avatar.GetSlot(0) != null && (action.Flags & TTABFlags.TSOAvailableCarrying) == 0)
                {
                    return(null);
                }

                if ((action.Flags & (TTABFlags.AllowCats | TTABFlags.AllowDogs)) > 0)
                {
                    //interaction can only be performed by cats or dogs
                    if (!avatar.IsPet)
                    {
                        return(null);
                    }
                    //check we're the correct type
                    if (avatar.IsCat && (action.Flags & TTABFlags.AllowCats) == 0)
                    {
                        return(null);
                    }
                    if (avatar.IsDog && (action.Flags & TTABFlags.AllowDogs) == 0)
                    {
                        return(null);
                    }
                }
                else if (avatar.IsPet)
                {
                    return(null);                   //not allowed
                }
                if ((action.Flags & TTABFlags.TSOIsRepair) > 0 != ((action.Callee.MultitileGroup.BaseObject.TSOState as VMTSOObjectState)?.Broken ?? false))
                {
                    return(null);
                }

                TSOFlags tsoState =
                    ((!(action.Callee is VMGameObject) || avatar.PersistID == ((VMTSOObjectState)action.Callee.TSOState).OwnerID)
                    ? TSOFlags.AllowObjectOwner : 0)
                    | ((((VMTSOAvatarState)avatar.TSOState).Permissions == VMTSOAvatarPermissions.Visitor) ? TSOFlags.AllowVisitors : 0)
                    | ((((VMTSOAvatarState)avatar.TSOState).Permissions >= VMTSOAvatarPermissions.Roommate) ? TSOFlags.AllowRoommates : 0)
                    | ((((VMTSOAvatarState)avatar.TSOState).Permissions == VMTSOAvatarPermissions.Admin) ? TSOFlags.AllowCSRs : 0)
                    | ((avatar.GetPersonData(VMPersonDataVariable.IsGhost) > 0) ? TSOFlags.AllowGhost : 0)
                    | TSOFlags.AllowFriends;
                TSOFlags tsoCompare = action.Flags2;
                //if flags are empty apart from "Non-Empty", force everything but visitor. (a kind of default state)
                if (tsoCompare == TSOFlags.NonEmpty)
                {
                    tsoCompare |= TSOFlags.AllowFriends | TSOFlags.AllowRoommates | TSOFlags.AllowObjectOwner;
                }

                //DEBUG: enable debug interction for all CSRs.
                if ((action.Flags & TTABFlags.Debug) > 0)
                {
                    if ((tsoState & TSOFlags.AllowCSRs) > 0)
                    {
                        return(result); //do not bother running check
                    }
                    else
                    {
                        return(null); //disable debug for everyone else.
                    }
                }

                if ((action.Flags & TTABFlags.TSOAvailableWhenDead) > 0)
                {
                    tsoCompare |= TSOFlags.AllowGhost;
                }
                if ((action.Flags & TTABFlags.AllowVisitors) > 0)
                {
                    tsoCompare |= TSOFlags.AllowVisitors;                                               //wrong???????
                }
                var posMask = (TSOFlags.AllowObjectOwner);
                if (((tsoState & posMask) & (tsoCompare & posMask)) == 0)
                {
                    //NEGATIVE EFFECTS:
                    var negMask = (TSOFlags.AllowVisitors | TSOFlags.AllowRoommates | TSOFlags.AllowGhost);

                    var negatedFlags = (~tsoCompare) & negMask;
                    if ((negatedFlags & tsoState) > 0)
                    {
                        return(null);                               //we are disallowed
                    }
                    if ((tsoCompare & TSOFlags.AllowCSRs) > 0 && (tsoState & TSOFlags.AllowCSRs) == 0)
                    {
                        return(null);                                                                               // only admins can run csr.
                    }
                }
            }
            if (((action.Flags & TTABFlags.MustRun) == 0 || ((action.Flags & TTABFlags.TSORunCheckAlways) > 0)) &&
                action.CheckRoutine != null && EvaluateCheck(Context, Entity, new VMStackFrame()
            {
                Caller = Entity,
                Callee = action.Callee,
                CodeOwner = action.CodeOwner,
                StackObject = action.StackObject,
                Routine = action.CheckRoutine,
                Args = new short[4]
            }, null, result) != VMPrimitiveExitCode.RETURN_TRUE)
            {
                return(null);
            }

            return(result);
        }
Пример #20
0
        public bool ExecuteEntryPoint(int entry, VMContext context, bool runImmediately, VMEntity stackOBJ, short[] args)
        {
            if (entry == 11)
            {
                //user placement, hack to do auto floor removal/placement for stairs
                if (Object.OBJ.LevelOffset > 0 && Position != LotTilePos.OUT_OF_WORLD)
                {
                    var floor = context.Architecture.GetFloor(Position.TileX, Position.TileY, Position.Level);
                    var placeFlags = (VMPlacementFlags)ObjectData[(int)VMStackObjectVariable.PlacementFlags];
                    if ((placeFlags & VMPlacementFlags.InAir) > 0)
                        context.Architecture.SetFloor(Position.TileX, Position.TileY, Position.Level, new FloorTile(), true);
                    if ((placeFlags & VMPlacementFlags.OnFloor) > 0 && (floor.Pattern == 0))
                        context.Architecture.SetFloor(Position.TileX, Position.TileY, Position.Level, new FloorTile { Pattern = 1 } , true);
                }
            }

            bool result = false;
            if (EntryPoints[entry].ActionFunction > 255)
            {
                VMSandboxRestoreState SandboxState = null;
                if (GhostImage && runImmediately)
                {
                    SandboxState = context.VM.Sandbox();
                    for (int i = 0; i < MultitileGroup.Objects.Count; i++)
                    {
                        var obj = MultitileGroup.Objects[i];
                        context.VM.AddEntity(obj);
                    }
                }

                BHAV bhav;
                GameObject CodeOwner;
                ushort ActionID = EntryPoints[entry].ActionFunction;
                if (ActionID < 4096)
                { //global
                    bhav = context.Globals.Resource.Get<BHAV>(ActionID);
                }
                else if (ActionID < 8192)
                { //local
                    bhav = Object.Resource.Get<BHAV>(ActionID);
                }
                else
                { //semi-global
                    bhav = SemiGlobal.Resource.Get<BHAV>(ActionID);
                }

                CodeOwner = Object;

                if (bhav != null)
                {
                    var routine = context.VM.Assemble(bhav);
                    var action = new VMQueuedAction
                    {
                        Callee = this,
                        CodeOwner = CodeOwner,
                        /** Main function **/
                        StackObject = stackOBJ,
                        Routine = routine,
                        Args = args
                    };

                    if (runImmediately)
                    {
                        var checkResult = VMThread.EvaluateCheck(context, this, action);
                        //if (checkResult == VMPrimitiveExitCode.ERROR) Delete(true, context);
                        result = (checkResult == VMPrimitiveExitCode.RETURN_TRUE);
                    }
                    else
                        this.Thread.EnqueueAction(action);
                }

                if (GhostImage && runImmediately)
                {
                    //restore state
                    context.VM.SandboxRestore(SandboxState);
                }
                return result;
            } else
            {
                return false;
            }
        }