示例#1
0
        public void Connect(uint UID, VMEntity invoker, VMEntity obj, VMAvatar avatar, bool joinable, VM vm)
        {
            if (InvokerToEOD.ContainsKey(invoker.ObjectID)) return; //uh, what?

            VMEODServer server = null;
            if (avatar != null && AvatarToEOD.ContainsKey(avatar.PersistID))
            {
                //avatar already using an EOD... quickly abort this attempt with the stub EOD.
                joinable = false;
                UID = 0;
                avatar = null;
            }

            if (joinable)
            {
                if (!JoinableEODs.TryGetValue(obj.ObjectID, out server))
                {
                    server = new VMEODServer(UID, obj, joinable, vm);
                    JoinableEODs[obj.ObjectID] = server;
                    Servers.Add(server);
                }
            }
            else
            {
                server = new VMEODServer(UID, obj, joinable, vm);
                Servers.Add(server);
            }

            if (avatar != null) RegisterAvatar(avatar, server);
            RegisterInvoker(invoker, server);
            server.Connect(new VMEODClient(invoker, avatar, vm, UID));
        }
示例#2
0
 public void AddObject(VMEntity obj)
 {
     AddDynamicObject(obj,
         new LotTilePos((short)((sbyte)(((ushort)obj.Object.OBJ.SubIndex) >> 8) * 16),
         (short)((sbyte)(((ushort)obj.Object.OBJ.SubIndex) & 0xFF) * 16),
         (sbyte)obj.Object.OBJ.LevelOffset));
 }
示例#3
0
 public VMRuntimeHeadline(VMSetBalloonHeadlineOperand op, VMEntity targ, VMEntity icon, sbyte index)
 {
     Operand = op;
     Target = targ;
     IconTarget = icon;
     Index = index;
     Duration = (op.DurationInLoops && op.Duration != -1) ? op.Duration * 15 : op.Duration;
 }
示例#4
0
        public VMThread(VMContext context, VMEntity entity, int stackSize)
        {
            this.Context = context;
            this.Entity = entity;

            this.Stack = new List<VMStackFrame>(stackSize);
            this.Queue = new List<VMQueuedAction>();
        }
示例#5
0
        //type 2 will be function callback.
        public void Run(VMEntity cbOwner)
        {
            if (type == 1) {
                BHAV bhav;
                GameObject CodeOwner = null;
                ushort ActionID;
                TTABFlags ActionFlags;
                string ActionName = "";
                if (IsTree)
                {
                    ActionFlags = TTABFlags.Leapfrog;
                    ActionID = (ushort)Interaction;
                }
                else
                {
                    var Action = Target.TreeTable.InteractionByIndex[(byte)Interaction];
                    ActionID = Action.ActionFunction;
                    ActionFlags = Action.Flags;
                    ActionName = Target.TreeTableStrings.GetString((int)Action.TTAIndex);
                }

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

                CodeOwner = Target.Object;
                var routine = vm.Assemble(bhav);
                var args = new short[4];
                if (SetParam) args[0] = cbOwner.ObjectID;

                Caller.Thread.EnqueueAction(
                    new FSO.SimAntics.Engine.VMQueuedAction
                    {
                        Callee = Target,
                        CodeOwner = CodeOwner,
                        ActionRoutine = routine,
                        Name = ActionName,
                        StackObject = this.StackObject,
                        Args = args,
                        InteractionNumber = Interaction,
                        Priority = (short)VMQueuePriority.Maximum, //not sure if this is meant to be the case!
                        Flags = ActionFlags
                    }
                );
            }
        }
示例#6
0
 public void Load(VMFindLocationResultMarshal input, VMContext context)
 {
     RadianDirection = input.RadianDirection;
     Position = input.Position;
     Score = input.Score;
     FaceAnywhere = input.FaceAnywhere;
     Chair = context.VM.GetObjectById(input.Chair);
     RouteEntryFlags = input.RouteEntryFlags;
 }
示例#7
0
 public VMRuntimeHeadline(VMRuntimeHeadlineMarshal input, VMContext context)
 {
     Operand = input.Operand;
     Target = context.VM.GetObjectById(input.Target);
     IconTarget = context.VM.GetObjectById(input.IconTarget);
     Index = input.Index;
     Duration = input.Duration;
     Anim = input.Anim;
 }
示例#8
0
 public void Load(VMActionCallbackMarshal input, VMContext context)
 {
     type = input.Type;
     Target = context.VM.GetObjectById(input.Target);
     Interaction = input.Interaction;
     SetParam = input.SetParam;
     StackObject = context.VM.GetObjectById(input.StackObject);
     Caller = context.VM.GetObjectById(input.Caller);
 }
示例#9
0
 //type 1: interaction callback
 public VMActionCallback(VM vm, byte interactionNumber, VMEntity target, VMEntity stackObj, VMEntity caller, bool paramAsObjectID)
 {
     this.type = 1;
     this.Target = target;
     this.Interaction = interactionNumber;
     this.SetParam = paramAsObjectID;
     this.StackObject = stackObj;
     this.vm = vm;
     this.Caller = caller;
 }
示例#10
0
        private short StackPointer; /** -1 means idle **/

        #endregion Fields

        #region Constructors

        public VMThread(VMContext context, VMEntity entity, int stackSize)
        {
            this.Context = context;
            this.Entity = entity;

            this.Stack = new VMStackFrame[stackSize];
            this.StackPointer = -1;
            this.Queue = new List<VMQueuedAction>();

            Context.ThreadIdle(this);
        }
示例#11
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;
 }
示例#12
0
 public static VMPrimitiveExitCode EvaluateCheck(VMContext context, VMEntity entity, VMQueuedAction action)
 {
     var temp = new VMThread(context, entity, 5);
     temp.EnqueueAction(action);
     while (temp.Queue.Count > 0) //keep going till we're done! idling is for losers!
     {
         temp.Tick();
     }
     context.ThreadRemove(temp); //hopefully this thread should be completely dereferenced...
     return temp.LastStackExitCode;
 }
示例#13
0
        public void RemoveObject(VMEntity obj)
        {
            var guid = obj.Object.OBJ.GUID;
            List<VMEntity> list = null;
            ObjectsByGUID.TryGetValue(guid, out list);
            if (list != null)
            {
                list.Remove(obj);
                if (list.Count == 0) ObjectsByGUID.Remove(guid);
            }

            if (obj is VMAvatar) Avatars.Remove(obj);
        }
示例#14
0
 public void RegisterObjectPos(VMEntity ent)
 {
     var off = GetOffest(ent.Position);
     List<VMEntity> tile = null;
     TileToObjects.TryGetValue(off, out tile);
     if (tile == null)
     {
         tile = new List<VMEntity>();
         TileToObjects.Add(off, tile);
     }
     if (!tile.Contains(ent)) VM.AddToObjList(tile, ent); //shouldn't be a problem any more, but just in case check first.
     else { }
 }
示例#15
0
        public void NewObject(VMEntity obj)
        {
            var guid = obj.Object.OBJ.GUID;
            List<VMEntity> list = null;
            ObjectsByGUID.TryGetValue(guid, out list);
            if (list == null)
            {
                list = new List<VMEntity>();
                ObjectsByGUID.Add(guid, list);
            }
            VM.AddToObjList(list, obj);

            if (obj is VMAvatar) VM.AddToObjList(Avatars, obj);
        }
示例#16
0
 public static bool FindLocationVector(VMEntity obj, VMEntity refObj, VMContext context, int dir)
 {
     LotTilePos step = DirectionVectors[dir];
     for (int i = 0; i < 32; i++)
     {
         if (obj.SetPosition(new LotTilePos(refObj.Position) + step * i,
             (Direction)(1 << (dir)), context).Status == VMPlacementError.Success)
             return true;
         if (i != 0)
         {
             if (obj.SetPosition(new LotTilePos(refObj.Position) - step * i,
                 (Direction)(1 << (dir)), context).Status == VMPlacementError.Success)
                 return true;
         }
     }
     return false;
 }
示例#17
0
        //type 2 will be function callback.
        public void Run(VMEntity cbOwner)
        {
            if (type == 1) {
                BHAV bhav;
                GameObject CodeOwner = null;
                var Action = Target.TreeTable.InteractionByIndex[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 = Target.Object.Resource.Get<BHAV>(ActionID);

                }
                else
                { //semi-global
                    bhav = Target.SemiGlobal.Resource.Get<BHAV>(ActionID);
                    //CodeOwner = Target.SemiGlobal.Resource;
                }

                CodeOwner = Target.Object;
                var routine = vm.Assemble(bhav);
                var args = new short[4];
                if (SetParam) args[0] = cbOwner.ObjectID;

                Caller.Thread.EnqueueAction(
                    new FSO.SimAntics.Engine.VMQueuedAction
                    {
                        Callee = Target,
                        CodeOwner = CodeOwner,
                        Routine = routine,
                        Name = Target.TreeTableStrings.GetString((int)Action.TTAIndex),
                        StackObject = this.StackObject,
                        Args = args,
                        InteractionNumber = Interaction,
                        Priority = VMQueuePriority.Maximum //not sure if this is meant to be the case!
                    }
                );
            }
        }
示例#18
0
        public static VMPrimitiveExitCode EvaluateCheck(VMContext context, VMEntity entity, 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.EnqueueAction(action);
            while (temp.Queue.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);
        }
示例#19
0
        public void ProcessQTRDay(VM vm, VMEntity owner)
        {
            if (((VMGameObject)owner).Disabled > 0)
            {
                return;
            }
            if (ObjectFlags.HasFlag(VMTSOObjectFlags.FSODonated))
            {
                Wear = 0;
                QtrDaysSinceLastRepair = 0;
                return;
            }
            Wear += 1;
            if (Wear > 90 * 4)
            {
                Wear = 90 * 4;
            }

            if (QtrDaysSinceLastRepair <= 7 * 4)
            {
                QtrDaysSinceLastRepair++;
            }

            //can break if the object has a repair interaction.
            if (QtrDaysSinceLastRepair > 7 * 4 && Wear > 50 * 4 && owner.TreeTable?.Interactions?.Any(x => (x.Flags & TTABFlags.TSOIsRepair) > 0) == true)
            {
                //object can break. calculate probability
                var rand = (int)vm.Context.NextRandom(10000);
                //lerp
                //1% at 50%, 4% at 90%
                var prob = 100 + ((Wear - (50 * 4)) * 75) / 40;
                if (rand < prob && owner.MultitileGroup.BaseObject == owner)
                {
                    //break the object
                    QtrDaysSinceLastRepair = 255;
                    //apply the broken object particle to all parts
                    foreach (var item in owner.MultitileGroup.Objects)
                    {
                        ((VMGameObject)item).EnableParticle(256);
                    }
                }
            }
        }
示例#20
0
        public void RegisterObjectPos(VMEntity ent)
        {
            var             off  = GetOffest(ent.Position);
            List <VMEntity> tile = null;

            TileToObjects.TryGetValue(off, out tile);
            if (tile == null)
            {
                tile = new List <VMEntity>();
                TileToObjects.Add(off, tile);
            }
            if (!tile.Contains(ent))
            {
                VM.AddToObjList(tile, ent);                      //shouldn't be a problem any more, but just in case check first.
            }
            else
            {
            }
        }
示例#21
0
        public static bool FindLocationVector(VMEntity obj, VMEntity refObj, VMContext context, int dir, VMPlaceRequestFlags flags, bool preferNonEmpty = false)
        {
            LotTilePos step     = DirectionVectors[dir];
            var        dirf     = (Direction)(1 << (dir));
            var        deferred = new List <LotTilePos>();

            Func <LotTilePos, bool> evaluate = (LotTilePos pos) =>
            {
                if (preferNonEmpty && TileOccupied(context, pos))
                {
                    deferred.Add(pos);
                    return(false);
                }
                else
                {
                    return(obj.SetPosition(pos, dirf, context, flags).Status == VMPlacementError.Success);
                }
            };

            for (int i = 0; i < 32; i++)
            {
                if (evaluate(new LotTilePos(refObj.Position) + step * (i / 2)))
                {
                    return(true);
                }
                if (i % 2 != 0)
                {
                    if (evaluate(new LotTilePos(refObj.Position) - step * (i / 2)))
                    {
                        return(true);
                    }
                }
            }

            foreach (var tile in deferred)
            {
                if (obj.SetPosition(tile, dirf, context, flags).Status == VMPlacementError.Success)
                {
                    return(true);
                }
            }
            return(false);
        }
示例#22
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;
 }
示例#23
0
        private void RecursiveUnhide(VMEntity fake, VMEntity real)
        {
            var rgrp = real.MultitileGroup;

            for (int i = 0; i < rgrp.Objects.Count; i++)
            {
                rgrp.Objects[i].SetValue(VMStackObjectVariable.Hidden, fake.MultitileGroup.Objects[i].GetValue(VMStackObjectVariable.Hidden));
                var slots = rgrp.Objects[i].TotalSlots();
                for (int j = 0; j < slots; j++)
                {
                    var slot  = rgrp.Objects[i].GetSlot(j);
                    var slot2 = fake.GetSlot(j);
                    if (slot != null && slot2 != null && slot.GetValue(VMStackObjectVariable.Hidden) != slot2.GetValue(VMStackObjectVariable.Hidden))
                    {
                        RecursiveUnhide(slot2, slot);
                    }
                }
            }
        }
        public override bool Execute(VM vm)
        {
            VMEntity obj = vm.GetObjectById(ObjectID);

            if (obj == null || (obj is VMAvatar))
            {
                return(false);
            }
            if (obj.PersistID > 0)
            {
                vm.Context.ObjectQueries.RemoveMultitilePersist(vm, obj.PersistID);                    //in case persist is reassigned somehow
            }
            foreach (var e in obj.MultitileGroup.Objects)
            {
                e.PersistID = PersistID;
            }
            vm.Context.ObjectQueries.RegisterMultitilePersist(obj.MultitileGroup, obj.PersistID);
            return(true);
        }
示例#25
0
 private uint GetOwnerID(VMEntity obj, VMStackFrame context)
 {
     if (obj is VMAvatar)
     {
         return(0);
     }
     else
     {
         var objState = (obj.TSOState as VMTSOObjectState);
         if (objState.ObjectFlags.HasFlag(VMTSOObjectFlags.FSODonated) && context.VM.TSOState.CommunityLot)
         {
             return(context.VM.TSOState.OwnerID);
         }
         else
         {
             return(objState.OwnerID);
         }
     }
 }
示例#26
0
        public override bool Execute(VM vm, VMAvatar caller)
        {
            VMEntity callee = vm.GetObjectById(CalleeID);

            if (callee == null || caller == null)
            {
                return(false);
            }
            if (callee is VMGameObject && ((VMGameObject)callee).Disabled > 0)
            {
                return(false);
            }
            if (caller.Thread.Queue.Count >= VMThread.MAX_USER_ACTIONS)
            {
                return(false);
            }
            callee.PushUserInteraction(Interaction, caller, vm.Context, Global, new short[] { Param0, 0, 0, 0 });

            return(true);
        }
示例#27
0
        public void RemoveObject(VMEntity obj)
        {
            var             guid = obj.Object.OBJ.GUID;
            List <VMEntity> list = null;

            ObjectsByGUID.TryGetValue(guid, out list);
            if (list != null)
            {
                list.Remove(obj);
                if (list.Count == 0)
                {
                    ObjectsByGUID.Remove(guid);
                }
            }

            if (obj is VMAvatar)
            {
                Avatars.Remove(obj);
            }
        }
示例#28
0
 public void IDEBreakpointHit(VM vm, VMEntity targetEnt)
 {
     new Thread(() =>
     {
         if (MainWindow.Instance == null)
         {
             return;
         }
         try
         {
             MainWindow.Instance.Invoke(new MainWindowDelegate(() =>
             {
                 MainWindow.Instance.BHAVManager.OpenTracer(vm, targetEnt);
             }), null);
         } catch (Exception)
         {
             //oops?
         }
     }).Start();
 }
示例#29
0
 private void RecursiveDelete(VMContext context, VMEntity real)
 {
     var rgrp = real.MultitileGroup;
     for (int i = 0; i < rgrp.Objects.Count; i++)
     {
         var slots = rgrp.Objects[i].TotalSlots();
         var objs = new List<VMEntity>();
         for (int j = 0; j < slots; j++)
         {
             var slot = rgrp.Objects[i].GetSlot(j);
             if (slot != null)
             {
                 objs.Add(slot);
             }
                 
         }
         foreach (var obj in objs) RecursiveDelete(context, obj);
     }
     rgrp.Delete(context);
 }
示例#30
0
文件: VMAI.cs 项目: Ne-Ice/FreeSims
        public void RunAction(VMEntity entity)
        {
            bool PetAction = entity.Object.GUID == VMAvatar.DOG_TEMPLATE ? true : false;

            if (Objects.Count > 0)
            {
                Random rand = new Random();
                int    n    = rand.Next(0, Objects.Count - 1);

                Target = Objects[n];
                Objects.RemoveAt(n);

                SetSelected(Target, PetAction);

                if (entity != Target)
                {
                    ExecuteAction(entity, Target);
                }
            }
        }
示例#31
0
        public override bool Execute(VM vm)
        {
            VMEntity obj = vm.GetObjectById(ObjectID);

            if (obj == null || (obj is VMAvatar))
            {
                return(false);
            }
            var result = obj.SetPosition(new LotTilePos(x, y, level), dir, vm.Context);

            if (result.Status == VMPlacementError.Success)
            {
                obj.MultitileGroup.ExecuteEntryPoint(11, vm.Context); //User Placement
                return(true);
            }
            else
            {
                return(false);
            }
        }
示例#32
0
        public override bool Execute(VM vm, VMAvatar caller)
        {
            if (caller == null || ((VMTSOAvatarState)caller.TSOState).Permissions < VMTSOAvatarPermissions.Roommate)
            {
                return(false);
            }
            VMEntity obj = vm.GetObjectByPersist(ObjectPID);

            //object must not be in use to set it for sale (will be disabled).
            if (obj == null || (obj is VMAvatar) || (NewPrice > 0 && obj.IsUserMovable(vm.Context, true) != VMPlacementError.Success))
            {
                return(false);
            }
            if ((((VMGameObject)obj).Disabled & VMGameObjectDisableFlags.TransactionIncomplete) > 0)
            {
                return(false);                                                                                     //can't change price mid trasaction...
            }
            //must own the object to set it for sale
            if (obj.PersistID == 0 || ((VMTSOObjectState)obj.TSOState).OwnerID != caller.PersistID)
            {
                return(false);
            }

            if (NewPrice >= 0)
            {
                foreach (var o in obj.MultitileGroup.Objects)
                {
                    ((VMGameObject)o).Disabled |= VMGameObjectDisableFlags.ForSale;
                }
                obj.MultitileGroup.SalePrice = NewPrice;
            }
            else
            {
                foreach (var o in obj.MultitileGroup.Objects)
                {
                    ((VMGameObject)o).Disabled &= ~VMGameObjectDisableFlags.ForSale;
                }
                obj.MultitileGroup.SalePrice = -1;
            }
            return(true);
        }
示例#33
0
        public void SetSelected(VMMultitileGroup Group)
        {
            if (Holding != null)
            {
                ClearSelected();
            }
            Holding              = new UIObjectSelection();
            Holding.Group        = Group;
            Holding.PreviousTile = Holding.Group.BaseObject.Position;
            Holding.Dir          = Group.Objects[0].Direction;
            VMEntity[] CursorTiles = new VMEntity[Group.Objects.Count];
            for (int i = 0; i < Group.Objects.Count; i++)
            {
                var target = Group.Objects[i];
                target.SetRoom(65534);
                if (target is VMGameObject)
                {
                    ((ObjectComponent)target.WorldUI).ForceDynamic = true;
                }
                CursorTiles[i] = vm.Context.CreateObjectInstance(0x00000437, new LotTilePos(target.Position), FSO.LotView.Model.Direction.NORTH, true).Objects[0];
                CursorTiles[i].SetPosition(new LotTilePos(0, 0, 1), Direction.NORTH, vm.Context);
                ((ObjectComponent)CursorTiles[i].WorldUI).ForceDynamic = true;
            }
            Holding.TilePosOffset = new Vector2(0, 0);
            Holding.CursorTiles   = CursorTiles;

            uint guid;
            var  bobj = Group.BaseObject;

            guid = bobj.Object.OBJ.GUID;
            if (bobj.MasterDefinition != null)
            {
                guid = bobj.MasterDefinition.GUID;
            }
            var catalogItem = Content.Content.Get().WorldCatalog.GetItemByGUID(guid);

            if (catalogItem != null)
            {
                Holding.Price = (int)catalogItem.Price;
            }
        }
示例#34
0
        public override VMPrimitiveExitCode Execute(VMStackFrame context, VMPrimitiveOperand args)
        {
            var      operand = (VMRefreshOperand)args;
            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 is VMGameObject)
                {
                    var TargObj = (VMGameObject)target;
                    TargObj.RefreshGraphic();
                }
                break;

            case 1:     //light
                context.VM.Context.RefreshLighting(context.VM.Context.GetObjectRoom(target), true, new HashSet <ushort>());
                if (target is VMGameObject)
                {
                    ((VMGameObject)target).RefreshLight();
                }
                break;

            case 2:     //area contribution
                context.VM.Context.RefreshRoomScore(context.VM.Context.GetObjectRoom(target));
                break;
            }

            return(VMPrimitiveExitCode.GOTO_TRUE);
        }
示例#35
0
        public void SetInfo(Texture2D thumb, string name, string description, int price)
        {
            ActiveEntity = null;
            DescriptionText.CurrentText = name + "\r\n" + description;
            ObjectNameText.Caption      = name;

            StringBuilder motivesString = new StringBuilder();

            motivesString.AppendFormat(GameFacade.Strings.GetString("206", "19") + "${0}\r\n", price);
            MotivesText.CurrentText = motivesString.ToString();

            SpecificTabButton.Disabled = true;
            SellBackButton.Disabled    = true;

            if (Thumbnail.Texture != null)
            {
                Thumbnail.Texture.Dispose();
            }
            Thumbnail.Texture = thumb;
            UpdateImagePosition();
        }
示例#36
0
        public void InitBHAV(BHAV bhav, EditorScope scope, VMEntity debugEnt, VMStackFrame debugFrame, BHAVPrimSelect callback)
        {
            if (FSOUI == null)
            {
                var mainCont = new UIExternalContainer(1024, 768);
                Editor = new UIBHAVEditor(bhav, scope, debugEnt);
                mainCont.Add(Editor);
                GameFacade.Screens.AddExternal(mainCont);

                SetUI(mainCont);
                Editor.BHAVView.OnSelectedChanged += callback;
            }
            else
            {
                //reuse existing
                lock (FSOUI)
                {
                    Editor.QueueCommand(new ChangeBHAVCommand(bhav, scope, debugFrame, callback));
                }
            }
        }
示例#37
0
        public override bool Execute(VM vm, VMAvatar caller)
        {
            VMEntity obj = vm.GetObjectById(ObjectID);

            if (!vm.TS1)
            {
                if (obj == null || caller == null || (obj is VMAvatar) ||
                    (caller.AvatarState.Permissions < VMTSOAvatarPermissions.Owner &&
                     obj.IsUserMovable(vm.Context, false) != VMPlacementError.Success))
                {
                    return(false);
                }
                if (caller.AvatarState.Permissions < VMTSOAvatarPermissions.Roommate)
                {
                    return(false);
                }
            }
            else if (obj == null)
            {
                return(false);
            }
            var result = obj.SetPosition(new LotTilePos(x, y, level), dir, vm.Context, VMPlaceRequestFlags.UserPlacement);

            if (result.Status == VMPlacementError.Success)
            {
                obj.MultitileGroup.ExecuteEntryPoint(11, vm.Context); //User Placement

                vm.SignalChatEvent(new VMChatEvent(caller, VMChatEventType.Arch,
                                                   caller?.Name ?? "Unknown",
                                                   vm.GetUserIP(caller?.PersistID ?? 0),
                                                   "moved " + obj.ToString() + " to (" + x / 16f + ", " + y / 16f + ", " + level + ")"
                                                   ));

                return(true);
            }
            else
            {
                return(false);
            }
        }
示例#38
0
        public override bool Execute(VM vm)
        {
            if (ResponseText.Length > 32)
            {
                ResponseText = ResponseText.Substring(0, 32);
            }

            VMEntity caller = vm.Entities.FirstOrDefault(x => x.PersistID == ActorUID);

            //TODO: check if net user owns caller!
            if (caller == null || caller is VMGameObject ||
                caller.Thread.BlockingState == null || !(caller.Thread.BlockingState is VMDialogResult))
            {
                return(false);
            }
            var state = (VMDialogResult)caller.Thread.BlockingState;

            state.Responded    = true;
            state.ResponseCode = ResponseCode;
            state.ResponseText = ResponseText;
            return(true);
        }
示例#39
0
        public void NewObject(VMEntity obj)
        {
            var             guid = obj.Object.OBJ.GUID;
            List <VMEntity> list = null;

            ObjectsByGUID.TryGetValue(guid, out list);
            if (list == null)
            {
                list = new List <VMEntity>();
                ObjectsByGUID.Add(guid, list);
            }
            VM.AddToObjList(list, obj);

            if (obj is VMAvatar)
            {
                VM.AddToObjList(Avatars, obj);
                if (obj.PersistID != 0)
                {
                    AvatarsByPersist[obj.PersistID] = (VMAvatar)obj;
                }
            }
        }
示例#40
0
        public void RemoveObject(VMEntity obj)
        {
            var             guid = obj.Object.OBJ.GUID;
            List <VMEntity> list = null;

            ObjectsByGUID.TryGetValue(guid, out list);
            if (list != null)
            {
                VM.DeleteFromObjList(list, obj);
                if (list.Count == 0)
                {
                    ObjectsByGUID.Remove(guid);
                }
            }
            RemoveCategory(obj, obj.GetValue(VMStackObjectVariable.Category));

            if (obj is VMAvatar)
            {
                Avatars.Remove(obj);
                AvatarsByPersist.Remove(obj.PersistID);
            }
            else if (obj.PersistID > 0 && obj.MultitileGroup.Objects.Count == 1)
            {
                MultitileByPersist.Remove(obj.PersistID);
                if (obj.Thread != null)
                {
                    var vm = obj.Thread.Context.VM;
                    if (vm.PlatformState.LimitExceeded)
                    {
                        VMBuildableAreaInfo.UpdateOverbudgetObjects(vm);
                    }
                }
            }

            if (obj.TreeTable != null && obj.TreeTable.AutoInteractions.Length > 0)
            {
                WithAutonomy.Remove(obj);
            }
        }
示例#41
0
        public static bool FindLocationVector(VMEntity obj, VMEntity refObj, VMContext context, int dir, VMPlaceRequestFlags flags)
        {
            LotTilePos step = DirectionVectors[dir];

            for (int i = 0; i < 32; i++)
            {
                if (obj.SetPosition(new LotTilePos(refObj.Position) + step * (i / 2),
                                    (Direction)(1 << (dir)), context, flags).Status == VMPlacementError.Success)
                {
                    return(true);
                }
                if (i % 2 != 0)
                {
                    if (obj.SetPosition(new LotTilePos(refObj.Position) - step * (i / 2),
                                        (Direction)(1 << (dir)), context, flags).Status == VMPlacementError.Success)
                    {
                        return(true);
                    }
                }
            }
            return(false);
        }
示例#42
0
        public ushort ResultCheckCounter = 0;  //how many times the interaction result has been checked. used for timeout.

        public VMStackFrame ToStackFrame(VMEntity caller)
        {
            var frame = new VMStackFrame
            {
                Caller      = caller,
                Callee      = Callee,
                CodeOwner   = CodeOwner,
                Routine     = ActionRoutine,
                StackObject = StackObject,
                ActionTree  = true
            };

            if (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 = Args;  //WARNING - if you use this, the args array MUST have the same number of elements the routine is expecting!
            }
            return(frame);
        }
示例#43
0
        private void SetSelected(VMEntity entity)
        {
            SelectedEntity = entity;
            propertyGrid.SelectedObject = entity;

            bhavList.Items.Clear();
            var resource = entity.Object;
            var bhavs    = resource.Resource.List <BHAV>();

            if (bhavs != null)
            {
                foreach (var bhav in bhavs)
                {
                    bhavList.Items.Add(bhav);
                }
            }

            if (entity.SemiGlobal != null)
            {
                var sglobbhavs = entity.SemiGlobal.List <BHAV>();
                if (bhavs != null)
                {
                    foreach (var bhav in sglobbhavs)
                    {
                        bhavList.Items.Add(bhav);
                    }
                }
            }

            interactionList.Items.Clear();
            if (entity.TreeTable != null)
            {
                TreeTableSel = entity.TreeTable;
                foreach (var interaction in entity.TreeTable.Interactions)
                {
                    interactionList.Items.Add(entity.TreeTableStrings.GetString((int)interaction.TTAIndex));
                }
            }
        }
示例#44
0
        public void NewObject(VMEntity obj)
        {
            var guid = obj.Object.OBJ.GUID;

            ObjectsByGUID.TryGetValue(guid, out var list);
            if (list == null)
            {
                list = new List <VMEntity>();
                ObjectsByGUID.Add(guid, list);
            }
            VM.AddToObjList(list, obj);
            RegisterCategory(obj, obj.GetValue(VMStackObjectVariable.Category));

            if (obj is VMAvatar)
            {
                VM.AddToObjList(Avatars, obj);
                if (obj.PersistID != 0)
                {
                    AvatarsByPersist[obj.PersistID] = (VMAvatar)obj;
                }
            }
        }
        public override bool Execute(VM vm)
        {
            var type = State.GetType();

            //if ID is 0, there is no thread to unblock, and we just have to do the extra functionality below.
            if (ID != 0)
            {
                VMEntity obj = vm.GetObjectById(ID);
                //we can only update an object's blocking state if it exists and is of the same type exactly.
                if (obj == null || obj.Thread.BlockingState == null || obj.Thread.BlockingState.GetType() != type)
                {
                    return(false);
                }
                obj.Thread.BlockingState = State;
            }

            if (type == typeof(VMTransferFundsState))
            {
                //special handling. update visual budgets of involved elements.
                //note: if we are the server and the reference budget IS the visual, do not update.
                if (vm.GlobalLink == null || !(vm.GlobalLink is VMTSOGlobalLinkStub))
                {
                    var state = (VMTransferFundsState)State;
                    var obj1  = vm.GetObjectByPersist(state.UID1);
                    if (obj1 != null)
                    {
                        obj1.TSOState.Budget.Value = state.Budget1;
                    }
                    var obj2 = vm.GetObjectByPersist(state.UID2);
                    if (obj2 != null)
                    {
                        obj2.TSOState.Budget.Value = state.Budget2;
                    }
                }
            }

            return(true);
        }
示例#46
0
        public void SetSelected(VMMultitileGroup Group)
        {
            if (Holding != null) ClearSelected();
            Holding = new UIObjectSelection();
            Holding.Group = Group;
            Holding.PreviousTile = Holding.Group.BaseObject.Position;
            Holding.Dir = Group.Objects[0].Direction;
            VMEntity[] CursorTiles = new VMEntity[Group.Objects.Count];
            for (int i = 0; i < Group.Objects.Count; i++)
            {
                var target = Group.Objects[i];
                target.ExecuteEntryPoint(10, vm.Context, true, target);
                target.SetRoom(65534);
                if (target is VMGameObject) ((ObjectComponent)target.WorldUI).ForceDynamic = true;
                CursorTiles[i] = vm.Context.CreateObjectInstance(0x00000437, new LotTilePos(target.Position), FSO.LotView.Model.Direction.NORTH, true).Objects[0];
                CursorTiles[i].SetPosition(new LotTilePos(0,0,1), Direction.NORTH, vm.Context);
                CursorTiles[i].SetRoom(65535);
                ((ObjectComponent)CursorTiles[i].WorldUI).ForceDynamic = true;
            }
            Holding.TilePosOffset = new Vector2(0, 0);
            Holding.CursorTiles = CursorTiles;

            uint guid;
            var bobj = Group.BaseObject;
            guid = bobj.Object.OBJ.GUID;
            if (bobj.MasterDefinition != null) guid = bobj.MasterDefinition.GUID;
            var catalogItem = Content.Content.Get().WorldCatalog.GetItemByGUID(guid);
            if (catalogItem != null)
            {
                var price = Group.InitialPrice; //(int)catalogItem.Value.Price;
                var dcPercent = VMBuildableAreaInfo.GetDiscountFor(catalogItem.Value, vm);
                var finalPrice = (price * (100 - dcPercent)) / 100;
                if (DonateMode) finalPrice -= (finalPrice * 2) / 3;
                Holding.Price = finalPrice;
                Group.InitialPrice = finalPrice;
                Group.BeforeDCPrice = price;
            }
        }
示例#47
0
 public static short MultitilePart(VMStackFrame context, VMEntity pointer, short targetValue)
 {
     if (pointer == null || (!pointer.MultitileGroup.MultiTile))
     {
         return(0);                                                        //single part
     }
     else
     {
         var   group      = pointer.MultitileGroup.Objects;
         bool  found      = false;
         short bestID     = 0;
         short smallestID = 0;
         for (int i = 0; i < group.Count; i++)
         {
             var temp = group[i];
             if (temp.ObjectID < smallestID || smallestID == 0)
             {
                 smallestID = temp.ObjectID;
             }
             if (temp.ObjectID > targetValue)
             {
                 if ((!found) || (temp.ObjectID < bestID))
                 {
                     found  = true;
                     bestID = temp.ObjectID;
                 }
             }
         }
         if (found)
         {
             return(bestID);
         }
         else
         {
             return(smallestID);
         }
     }
 }
示例#48
0
        public static bool FindLocationFor(VMEntity obj, VMEntity refObj, VMContext context)
        {
            for (int i = 0; i < 10; i++)
            {
                if (i == 0)
                {
                    for (int j = 0; j < 4; j++)
                    {
                        if (obj.SetPosition(new LotTilePos(refObj.Position), (Direction)(1 << (j * 2)), context).Status == VMPlacementError.Success)
                            return true;
                    }
                }
                else
                {
                    LotTilePos bPos = refObj.Position;
                    for (int x = -i; x <= i; x++)
                    {
                        for (int j = 0; j < 8; j++)
                        {
                            if (obj.SetPosition(LotTilePos.FromBigTile((short)(bPos.TileX + x), (short)(bPos.TileY + ((j % 2) * 2 - 1) * i), bPos.Level),
                                (Direction)(1 << ((j / 2) * 2)), context).Status == VMPlacementError.Success)
                                return true;
                        }
                    }

                    for (int y = 1 - i; y < i; y++)
                    {
                        for (int j = 0; j < 8; j++)
                        {
                            if (obj.SetPosition(LotTilePos.FromBigTile((short)(bPos.TileX + ((j % 2) * 2 - 1) * i), (short)(bPos.TileY + y), bPos.Level),
                                (Direction)(1 << ((j / 2) * 2)), context).Status == VMPlacementError.Success)
                                return true;
                        }
                    }
                }
            }
            return false;
        }
示例#49
0
        public void Connect(uint UID, VMEntity invoker, VMEntity obj, VMAvatar avatar, bool joinable, VM vm)
        {
            if (InvokerToEOD.ContainsKey(invoker.ObjectID))
            {
                return;                                             //uh, what?
            }
            VMEODServer server = null;

            if (avatar != null && AvatarToEOD.ContainsKey(avatar.PersistID))
            {
                //avatar already using an EOD... quickly abort this attempt with the stub EOD.
                joinable = false;
                UID      = 0;
                avatar   = null;
            }

            if (joinable)
            {
                if (!JoinableEODs.TryGetValue(obj.ObjectID, out server))
                {
                    server = new VMEODServer(UID, obj, joinable, vm);
                    JoinableEODs[obj.ObjectID] = server;
                    Servers.Add(server);
                }
            }
            else
            {
                server = new VMEODServer(UID, obj, joinable, vm);
                Servers.Add(server);
            }

            if (avatar != null)
            {
                RegisterAvatar(avatar, server);
            }
            RegisterInvoker(invoker, server);
            server.Connect(new VMEODClient(invoker, avatar, vm, UID));
        }
示例#50
0
 public void ForceDisconnectObj(VMEntity invoker)
 {
     VMEODServer server = null;
     if (InvokerToEOD.TryGetValue(invoker.ObjectID, out server))
     {
         var invokerClient = server.Clients.FirstOrDefault(x => x.Invoker == invoker);
         if (invokerClient != null)
         {
             server.Disconnect(invokerClient);
         }
     }
 }
示例#51
0
 public static VMPrimitiveExitCode EvaluateCheck(VMContext context, VMEntity entity, VMStackFrame initFrame)
 {
     return EvaluateCheck(context, entity, initFrame, null, null);
 }
示例#52
0
 public static VMPrimitiveExitCode EvaluateCheck(VMContext context, VMEntity entity, VMStackFrame initFrame, VMQueuedAction action)
 {
     return EvaluateCheck(context, entity, initFrame, action, null);
 }
示例#53
0
        public bool RunInMyStack(BHAV bhav, GameObject CodeOwner, short[] passVars, VMEntity stackObj)
        {
            //a little bit hacky. We may not need to do as serious a context switch as this.
            var OldStack = Stack;
            var OldQueue = Queue;
            var OldCheck = IsCheck;
            var OldQueueBlock = ActiveQueueBlock;

            VMStackFrame prevFrame = new VMStackFrame() { Caller = Entity, Callee = Entity };
            if (Stack.Count > 0)
            {
                prevFrame = Stack[Stack.Count - 1];
                Stack = new List<VMStackFrame>() { prevFrame };
            } else
            {
                Stack = new List<VMStackFrame>();
            }

            Queue = new List<VMQueuedAction>();
            if (Queue.Count > 0) Queue.Add(Queue[0]);
            IsCheck = true;

            ExecuteSubRoutine(prevFrame, bhav, CodeOwner, new VMSubRoutineOperand(passVars));
            Stack.RemoveAt(0);
            if (Stack.Count == 0)
            {
                Stack = OldStack;
                Queue = OldQueue;
                return false;
                //bhav was invalid/empty
            }
            var frame = Stack[Stack.Count - 1];
            frame.StackObject = stackObj;

            try {
                while (Stack.Count > 0)
                {
                    NextInstruction();
                }
            } catch (Exception)
            {
                //we need to catch these so that the parent can be restored.
            }

            //copy child stack things to parent stack
            Stack = OldStack;
            Queue = OldQueue;
            IsCheck = OldCheck;
            ActiveQueueBlock = OldQueueBlock;

            return (LastStackExitCode == VMPrimitiveExitCode.RETURN_TRUE) ? true : false;
        }
示例#54
0
        // TODO: float values may desync if devices are not both x86 or using a different C# library.
        // Might need to replace with fixed point library for position and rotation
        /// <summary>
        /// This method will find all the avaliable locations within the criteria ordered by proximity to the optimal proximity
        /// External functions can then decide which is most desirable. E.g. the nearest slot to the object may be the longest route if
        /// its in another room.
        /// </summary>
        /// <param name="obj"></param>
        /// <param name="slot"></param>
        /// <param name="context"></param>
        /// <returns></returns>
        public List<VMFindLocationResult> FindAvaliableLocations(VMEntity obj, VMContext context, VMEntity caller)
        {
            /**
             * Start at min proximity and circle around the object to find the avaliable locations.
             * Then pick the one nearest to the optimal value
             */

            /**
             * ------ MAJOR TODO: ------
             * Avoid vector math at all costs! Small differences in hardware could cause desyncs.
             * This really goes for all areas of the SimAntics engine, but here it's particularly bad.
             */
            Vector2 center;
            if (OnlySit) FailCode = VMRouteFailCode.NoChair;

            // if we need to use the average location of an object group, it needs to be calculated.
            if (((Flags & SLOTFlags.UseAverageObjectLocation) > 0) && (obj.MultitileGroup.MultiTile)) {
                center = new Vector2(0, 0);
                var objs = obj.MultitileGroup.Objects;
                for (int i = 0; i < objs.Count; i++)
                {
                    center += new Vector2(objs[i].Position.x/16f, objs[i].Position.y/16f);
                }
                center /= objs.Count;
            } else center = new Vector2(obj.Position.x/16f, obj.Position.y/16f);

            //add offset of slot if it exists. must be rotated to be relative to object
            var rotOff = Vector3.Transform(Slot.Offset, Matrix.CreateRotationZ(obj.RadianDirection));
            var circleCtr = new Vector2(center.X + rotOff.X / 16, center.Y + rotOff.Y / 16);

            ushort room = context.VM.Context.GetRoomAt(obj.Position);
            Results = new List<VMFindLocationResult>();

            if ((Flags & SLOTFlags.SnapToDirection) > 0)
            { //snap to the specified direction, on the specified point.
                double baseRot;
                if (Slot.Facing > SLOTFacing.FaceAwayFromObject)
                {
                    // bit of a legacy thing here. Facing field did not use to exist,
                    // which is why SnapToDirection was hacked to use the directional flags.
                    // now that it exists, it is used instead, to encode the same information...
                    // just transform back into old format.
                    Flags |= (SLOTFlags)(1 << (int)Slot.Facing);
                }
                else
                {
                    if (((int)Flags & 255) == 0) Flags |= SLOTFlags.NORTH;
                }

                var flagRot = DirectionUtils.PosMod(obj.RadianDirection+FlagsAsRad(Flags), Math.PI*2);
                if (flagRot > Math.PI) flagRot -= Math.PI * 2;

                VerifyAndAddLocation(obj, circleCtr, center, Flags, Double.MaxValue, context, caller, (float)flagRot);
                return Results;
            }
            else
            {
                if (((int)Flags & 255) == 0 || Slot.Offset != new Vector3())
                {
                    //exact position
                    //Flags |= (SLOTFlags)255;

                    // special case, walk directly to point.
                    VerifyAndAddLocation(obj, circleCtr, center, Flags, Double.MaxValue, context, caller, float.NaN);
                    return Results;
                }
                var maxScore = Math.Max(DesiredProximity - MinProximity, MaxProximity - DesiredProximity) + (LotTilePos.Distance(obj.Position, caller.Position)+MaxProximity)/3 + 2;
                var ignoreRooms = (Flags & SLOTFlags.IgnoreRooms) > 0;

                var resolutionBound = (MaxProximity / Slot.Resolution) * Slot.Resolution;

                for (int x = -resolutionBound; x <= resolutionBound; x += Slot.Resolution)
                {
                    for (int y = -resolutionBound; y <= resolutionBound; y += Slot.Resolution)
                    {
                        var pos = new Vector2(circleCtr.X + x / 16.0f, circleCtr.Y + y / 16.0f);
                        double distance = Math.Sqrt(x * x + y * y);
                        if (distance >= MinProximity - 0.01 && distance <= MaxProximity + 0.01 && (ignoreRooms || context.VM.Context.GetRoomAt(new LotTilePos((short)Math.Round(pos.X * 16), (short)Math.Round(pos.Y * 16), obj.Position.Level)) == room)) //slot is within proximity
                        {
                            var routeEntryFlags = (GetSearchDirection(circleCtr, pos, obj.RadianDirection) & Flags); //the route needs to know what conditions it fulfilled
                            if (routeEntryFlags > 0) //within search location
                            {
                                double baseScore = ((maxScore - Math.Abs(DesiredProximity - distance)) + context.VM.Context.NextRandom(1024) / 1024.0f);
                                VerifyAndAddLocation(obj, pos, center, routeEntryFlags, baseScore, context, caller, float.NaN);
                            }
                        }
                    }
                }
            }
            /** Sort by how close they are to desired proximity **/

            if (Results.Count > 1) Results = Results.OrderBy(x => -x.Score).ToList(); //avoid sort because it acts incredibly unusually
            if (Results.Count > 0) FailCode = VMRouteFailCode.Success;
            return Results;
        }
示例#55
0
 private void SetFail(VMRouteFailCode code, VMEntity blocker)
 {
     if (Array.IndexOf(FailPrio, code) > Array.IndexOf(FailPrio, FailCode))
     {
         FailCode = code;
         Blocker = blocker;
     }
 }
示例#56
0
        private void VerifyAndAddLocation(VMEntity obj, Vector2 pos, Vector2 center, SLOTFlags entryFlags, double score, VMContext context, VMEntity caller, float facingDir)
        {
            //note: verification is not performed if snap target slot is enabled.
            var tpos = new LotTilePos((short)Math.Round(pos.X * 16), (short)Math.Round(pos.Y * 16), obj.Position.Level);

            if (context.IsOutOfBounds(tpos)) return;

            score -= LotTilePos.Distance(tpos, caller.Position)/3.0;

            if (Slot.SnapTargetSlot < 0 && context.Architecture.RaycastWall(new Point((int)pos.X, (int)pos.Y), new Point(obj.Position.TileX, obj.Position.TileY), obj.Position.Level))
            {
                SetFail(VMRouteFailCode.WallInWay, null);
                return;
            }

            bool faceAnywhere = false;
            if (float.IsNaN(facingDir))
            {
                var obj3P = obj.Position.ToVector3();
                var objP = new Vector2(obj3P.X, obj3P.Y);
                switch (Slot.Facing)
                {
                    case SLOTFacing.FaceTowardsObject:
                        facingDir = (float)GetDirectionTo(pos, objP); break;
                    case SLOTFacing.FaceAwayFromObject:
                        facingDir = (float)GetDirectionTo(objP, pos); break;
                    case SLOTFacing.FaceAnywhere:
                        faceAnywhere = true;
                        facingDir = 0.0f; break;
                    default:
                        int intDir = (int)Math.Round(Math.Log((double)obj.Direction, 2));
                        var rotatedF = ((int)Slot.Facing + intDir) % 8;
                        facingDir = (float)(((int)rotatedF > 4) ? ((double)rotatedF * Math.PI / 4.0) : (((double)rotatedF - 8.0) * Math.PI / 4.0)); break;
                }
            }

            VMEntity chair = null;
            if (Slot.SnapTargetSlot < 0)
            {
                var solid = caller.PositionValid(tpos, Direction.NORTH, context);
                if (solid.Status != Model.VMPlacementError.Success)
                {
                    if (solid.Object != null && solid.Object is VMGameObject)
                    {
                        if (Slot.Sitting > 0 && solid.Object.EntryPoints[26].ActionFunction != 0)
                        {
                            chair = solid.Object;
                        }
                        else
                        {
                            SetFail(VMRouteFailCode.DestTileOccupied, solid.Object);
                            return;
                        }
                    }
                }

                if (chair != null && (Math.Abs(DirectionUtils.Difference(chair.RadianDirection, facingDir)) > Math.PI / 4))
                    return; //not a valid goal.
                if (chair == null && OnlySit) return;
            }

            Results.Add(new VMFindLocationResult
            {
                Position = new LotTilePos((short)Math.Round(pos.X * 16), (short)Math.Round(pos.Y * 16), obj.Position.Level),
                Score = score * ((chair != null) ? Slot.Sitting : Slot.Standing), //todo: prefer closer?
                RadianDirection = facingDir,
                Chair = chair,
                FaceAnywhere = faceAnywhere,
                RouteEntryFlags = entryFlags
            });
        }
示例#57
0
        public VMPlacementResult ChangePosition(LotTilePos pos, Direction direction, VMContext context)
        {
            if (pos.Level > context.Architecture.Stories) return new VMPlacementResult(VMPlacementError.NotAllowedOnFloor);

            VMEntity[] OldContainers = new VMEntity[Objects.Count];
            short[] OldSlotNum = new short[Objects.Count];
            for (int i = 0; i < Objects.Count(); i++)
            {
                OldContainers[i] = Objects[i].Container;
                OldSlotNum[i] = Objects[i].ContainerSlot;
                Objects[i].PrePositionChange(context);
            }

            int Dir = 0;
            switch (direction)
            {
                case Direction.NORTH:
                    Dir = 0; break;
                case Direction.EAST:
                    Dir = 2; break;
                case Direction.SOUTH:
                    Dir = 4; break;
                case Direction.WEST:
                    Dir = 6; break;
            }

            Matrix rotMat = Matrix.CreateRotationZ((float)(Dir * Math.PI / 4.0));
            VMPlacementResult[] places = new VMPlacementResult[Objects.Count];

            var bObj = BaseObject;
            var leadOff = new Vector3(((sbyte)(((ushort)bObj.Object.OBJ.SubIndex) >> 8) * 16), ((sbyte)(((ushort)bObj.Object.OBJ.SubIndex) & 0xFF) * 16), 0);

            //TODO: optimize so we don't have to recalculate all of this
            if (pos != LotTilePos.OUT_OF_WORLD)
            {
                for (int i = 0; i < Objects.Count(); i++)
                {
                    var sub = Objects[i];
                    var off = new Vector3((sbyte)(((ushort)sub.Object.OBJ.SubIndex) >> 8) * 16, (sbyte)(((ushort)sub.Object.OBJ.SubIndex) & 0xFF) * 16, 0);
                    off = Vector3.Transform(off-leadOff, rotMat);

                    var offPos = new LotTilePos((short)Math.Round(pos.x + off.X), (short)Math.Round(pos.y + off.Y), (sbyte)(pos.Level + sub.Object.OBJ.LevelOffset));
                    places[i] = sub.PositionValid(offPos, direction, context);
                    if (places[i].Status != VMPlacementError.Success)
                    {
                        //go back to where we started: we're no longer out of world.
                        for (int j = 0; j < Objects.Count(); j++)
                        {
                            //need to restore slot we were in
                            if (OldContainers[j] != null) {
                                OldContainers[j].PlaceInSlot(Objects[j], OldSlotNum[j], false, context);
                            }
                            Objects[j].PositionChange(context, false);
                        }
                        return places[i];
                    }
                }
            }

            //verification success

            for (int i = 0; i < Objects.Count(); i++)
            {
                var sub = Objects[i];
                var off = new Vector3((sbyte)(((ushort)sub.Object.OBJ.SubIndex) >> 8) * 16, (sbyte)(((ushort)sub.Object.OBJ.SubIndex) & 0xFF)*16, 0);
                off = Vector3.Transform(off-leadOff, rotMat);

                var offPos = (pos==LotTilePos.OUT_OF_WORLD)?
                    LotTilePos.OUT_OF_WORLD :
                    new LotTilePos((short)Math.Round(pos.x + off.X), (short)Math.Round(pos.y + off.Y), (sbyte)(pos.Level+sub.Object.OBJ.LevelOffset));

                sub.SetIndivPosition(offPos, direction, context, places[i]);
            }
            for (int i = 0; i < Objects.Count(); i++) Objects[i].PositionChange(context, false);
            return new VMPlacementResult(VMPlacementError.Success);
        }
示例#58
0
 public void UnregisterInvoker(VMEntity invoker)
 {
     if (invoker == null) return;
     InvokerToEOD.Remove(invoker.ObjectID);
 }
示例#59
0
        public bool RunInMyStack(BHAV bhav, GameObject CodeOwner, short[] passVars, VMEntity stackObj)
        {
            var OldStack = Stack;
            var OldQueue = Queue;
            VMStackFrame prevFrame = new VMStackFrame() { Caller = Entity, Callee = Entity };
            if (Stack.Count > 0)
            {
                prevFrame = Stack[Stack.Count - 1];
                Stack = new List<VMStackFrame>() { prevFrame };
            } else
            {
                Stack = new List<VMStackFrame>();
            }

            if (Queue.Count > 0)
            {
                Queue = new List<VMQueuedAction>() { Queue[0] };
            } else
            {
                Queue = new List<VMQueuedAction>();
            }

            ExecuteSubRoutine(prevFrame, bhav, CodeOwner, new VMSubRoutineOperand(passVars));
            Stack.RemoveAt(0);
            if (Stack.Count == 0)
            {
                Stack = OldStack;
                Queue = OldQueue;
                return false;
                //bhav was invalid/empty
            }
            var frame = Stack[Stack.Count - 1];
            frame.StackObject = stackObj;

            while (Stack.Count > 0)
            {
                NextInstruction();
            }

            //copy child stack things to parent stack

            //prevFrame.Args = frame.Args;
            //prevFrame.StackObject = frame.StackObject;
            Stack = OldStack;
            Queue = OldQueue;

            return (LastStackExitCode == VMPrimitiveExitCode.RETURN_TRUE) ? true : false;
        }
示例#60
0
 public VMThread(VMThreadMarshal input, VMContext context, VMEntity entity)
 {
     Context = context;
     Entity = entity;
     Load(input, context);
 }