Ejemplo n.º 1
0
        public static void TryReinit(VMEntity obj, VM vm, int level)
        {
            var config = Content.Content.Get().Upgrades.GetUpgradeConfig(
                obj.Object.Resource.Iff.Filename,
                (obj.MasterDefinition ?? obj.Object.OBJ).GUID,
                level);

            if (config?.Reinit == true)
            {
                obj.ExecuteEntryPoint(0, vm.Context, true);
            }
        }
Ejemplo n.º 2
0
        public void Tick()
        {
#if IDE_COMPAT
            if (ThreadBreak == VMThreadBreakMode.Pause)
            {
                return;
            }
            else if (ThreadBreak == VMThreadBreakMode.Reset)
            {
                Entity.Reset(Context);
                ThreadBreak = VMThreadBreakMode.Active;
            }
            else if (ThreadBreak == VMThreadBreakMode.Immediate)
            {
                Breakpoint(Stack.LastOrDefault(), "Paused."); return;
            }
            if (RoutineDirty)
            {
                foreach (var frame in Stack)
                {
                    if (frame.Routine.Chunk.RuntimeVer != frame.Routine.RuntimeVer)
                    {
                        frame.Routine = Context.VM.Assemble(frame.Routine.Chunk);
                    }
                }
                RoutineDirty = false;
            }
#endif

            if (BlockingState != null)
            {
                BlockingState.WaitTime++;
            }
            if (DialogCooldown > 0)
            {
                DialogCooldown--;
            }
#if !THROW_SIMANTICS
            try
            {
#endif
            if (!Entity.Dead)
            {
                if (QueueDirty)
                {
                    EvaluateQueuePriorities();
                    TryRunImmediately();
                    QueueDirty = false;
                }
                if (Stack.Count == 0)
                {
                    if (IsCheck)
                    {
                        return;              //running out of execution means check trees have ended.
                    }
                    Entity.ExecuteEntryPoint(1, Context, false);
                    if (Stack.Count == 0)
                    {
                        return;
                    }
                }
                if ((!Stack.LastOrDefault().ActionTree) || (!Queue[0].Callee.Dead))     //main or our target is not dead
                {
#if IDE_COMPAT
                    if (ThreadBreak == VMThreadBreakMode.ReturnTrue)
                    {
                        var bf = Stack[BreakFrame];
                        HandleResult(bf, bf.GetCurrentInstruction(), VMPrimitiveExitCode.RETURN_TRUE);
                        Breakpoint(Stack.LastOrDefault(), "Returned True.");
                        return;
                    }
                    if (ThreadBreak == VMThreadBreakMode.ReturnFalse)
                    {
                        var bf = Stack[BreakFrame];
                        HandleResult(bf, bf.GetCurrentInstruction(), VMPrimitiveExitCode.RETURN_TRUE);
                        Breakpoint(Stack.LastOrDefault(), "Returned False.");
                        return;
                    }
#endif
                    ContinueExecution = true;
                    while (ContinueExecution)
                    {
                        if (TicksThisFrame++ > MAX_LOOP_COUNT)
                        {
                            throw new Exception("Thread entered infinite loop! ( >" + MAX_LOOP_COUNT + " primitives)");
                        }
                        ContinueExecution = false;
                        NextInstruction();
                    }
                }
                else     //interaction owner is dead, rip
                {
                    Entity.Reset(Context);
                }
            }

#if !THROW_SIMANTICS
        }

        catch (Exception e)
        {
#if IDE_COMPAT
            if (!IsCheck && VM.SignalBreaks)
            {
                Breakpoint(Stack.LastOrDefault(), "!" + e.Message + " " + StackTraceSimplify(e.StackTrace.Split('\n').FirstOrDefault(x => x.Contains(".cs")) ?? ""));
                ContinueExecution = false;
                return;
            }
#endif

            if (e is ThreadAbortException)
            {
                throw e;
            }
            if (Stack.Count == 0)
            {
                return;
            }
            var  context = Stack[Stack.Count - 1];
            bool Delete  = ((Entity is VMGameObject) && (DialogCooldown > 30 * 20 - 10));
            if (DialogCooldown == 0)
            {
                var          simExcept    = new VMSimanticsException(e.Message + StackTraceSimplify(e.StackTrace.Split('\n').FirstOrDefault(x => x.Contains(".cs")) ?? ""), context);
                string       exceptionStr = "A SimAntics Exception has occurred, and has been suppressed: \r\n\r\n" + simExcept.ToString() + "\r\n\r\nThe object will be reset. Please report this!";
                VMDialogInfo info         = new VMDialogInfo
                {
                    Caller  = null,
                    Icon    = context.Callee,
                    Operand = new VMDialogOperand {
                    },
                    Message = exceptionStr,
                    Title   = "SimAntics Exception!"
                };
                Context.VM.SignalDialog(info);
                DialogCooldown = 30 * 20;
            }

            if (!IsCheck)
            {
                context.Callee.Reset(context.VM.Context);
                context.Caller.Reset(context.VM.Context);
                if (Delete)
                {
                    Entity.Delete(true, context.VM.Context);
                }
            }
            else
            {
                Stack.Clear();
            }
        }
#endif
        }
Ejemplo n.º 3
0
        public override bool Execute(VM vm, VMAvatar caller)
        {
            if (Mode == DeleteMode.Delete)//ObjectPID == 0) //only has value when this is an inventory move.
            {
                VMEntity obj = vm.GetObjectById(ObjectID);
                if (obj == null || (!vm.TS1 && caller == null))
                {
                    return(false);
                }
                var value = (obj.PersistID != 0 || vm.TS1) ? obj.MultitileGroup.Price : 0;

                obj.ExecuteEntryPoint(12, vm.Context, true);
                obj.Delete(CleanupAll, vm.Context);

                // If we're the server, tell the global link to give their money back.
                if (vm.GlobalLink != null)
                {
                    vm.GlobalLink.PerformTransaction(vm, false, uint.MaxValue, caller?.PersistID ?? uint.MaxValue,
                                                     value,
                                                     (bool success, int transferAmount, uint uid1, uint budget1, uint uid2, uint budget2) =>
                    {
                    });
                }
                vm.SignalChatEvent(new VMChatEvent(caller, VMChatEventType.Arch,
                                                   caller?.Name ?? "Unknown",
                                                   vm.GetUserIP(caller?.PersistID ?? 0),
                                                   "deleted " + obj.ToString()
                                                   ));
            }
            else
            {
                //inventory move. Just delete the object.
                VMEntity obj = vm.GetObjectByPersist(ObjectPID);
                if (obj == null)
                {
                    return(false);
                }

                if (Success)
                {
                    if (((VMTSOObjectState)obj.TSOState).OwnerID == vm.MyUID)
                    {
                        //if the owner is here, tell them this object is now in their inventory.
                        //if they're elsewhere, they'll see it the next time their inventory updates.
                        //Inventory accesses are not by index, but PID, and straight to DB... so this won't cause any race conditions.
                        vm.MyInventory.Add(new VMInventoryItem()
                        {
                            ObjectPID = ObjectPID,
                            GUID      = (obj.MasterDefinition?.GUID) ?? obj.Object.OBJ.GUID,
                            Name      = obj.MultitileGroup.Name,
                            Value     = (uint)obj.MultitileGroup.Price,
                            Graphic   = (ushort)obj.GetValue(VMStackObjectVariable.Graphic),
                            DynFlags1 = obj.DynamicSpriteFlags,
                            DynFlags2 = obj.DynamicSpriteFlags2,
                        });
                    }
                    vm.Context.ObjectQueries.RemoveMultitilePersist(vm, obj.PersistID);
                    foreach (var o in obj.MultitileGroup.Objects)
                    {
                        o.PersistID = 0;                                           //no longer representative of the object in db.
                    }
                    obj.Delete(CleanupAll, vm.Context);

                    vm.SignalChatEvent(new VMChatEvent(caller, VMChatEventType.Arch,
                                                       caller?.Name ?? "disconnected user",
                                                       vm.GetUserIP(caller.PersistID),
                                                       "sent " + obj.ToString() + " back to the inventory of its owner."
                                                       ));
                }
                else
                {
                    //something bad happened. just unlock the object.
                    foreach (var o in obj.MultitileGroup.Objects)
                    {
                        ((VMGameObject)o).Disabled &= VMGameObjectDisableFlags.TransactionIncomplete;
                    }
                }
            }

            return(true);
        }