Exemplo n.º 1
0
        public void LoadAsync(VMMarshal input)
        {
            FSOVAsyncLoading = true;
            var lastBp = Context.Blueprint; //try keep this alive I suppose

            //var oldWorld = Context.World;
            //TS1 = input.TS1;
            Context    = new VMContext(input.Context, Context);
            Context.VM = this;
            var idMap = input.Context.Architecture.IDMap;

            if (idMap != null)
            {
                idMap.Apply(this);
            }
            Context.Architecture.RegenRoomMap();
            Context.RegeneratePortalInfo();
            Context.Architecture.Terrain.RegenerateCenters();

            if (VM.UseWorld)
            {
                Context.Blueprint.Altitude        = Context.Architecture.Terrain.Heights;
                Context.Blueprint.AltitudeCenters = Context.Architecture.Terrain.Centers;
            }

            var oldSounds = new List <VMSoundTransfer>();

            if (Entities != null) //free any object resources here.
            {
                foreach (var obj in Entities)
                {
                    obj.Dead = true;
                    if (obj.HeadlineRenderer != null)
                    {
                        if (UseWorld)
                        {
                            GameThread.InUpdate(() =>
                            {
                                obj.HeadlineRenderer.Dispose();
                            });
                        }
                    }
                    oldSounds.AddRange(obj.GetActiveSounds());
                }
            }

            SoundEntities = new HashSet <VMEntity>();
            Entities      = new List <VMEntity>();
            Scheduler.Reset();
            ObjectsById  = new Dictionary <short, VMEntity>();
            FSOVObjTotal = input.Entities.Length;
            foreach (var ent in input.Entities)
            {
                VMEntity realEnt;
                var      objDefinition = FSO.Content.Content.Get().WorldObjects.Get(ent.GUID);
                if (objDefinition == null)
                {
                    LoadErrors.Add(new VMLoadError(VMLoadErrorCode.MISSING_OBJECT,
                                                   "0x" + ent.GUID.ToString("X8") + " " + input.MultitileGroups.FirstOrDefault(x => x.Objects.Contains(ent.ObjectID))?.Name ?? "(unknown name)", (ushort)ent.ObjectID));
                    ent.LoadFailed = true;
                    continue;
                }
                if (ent is VMAvatarMarshal)
                {
                    var avatar = new VMAvatar(objDefinition);
                    avatar.Load((VMAvatarMarshal)ent);
                    if (UseWorld)
                    {
                        Context.Blueprint.AddAvatar((AvatarComponent)avatar.WorldUI);
                    }
                    realEnt = avatar;
                }
                else
                {
                    var worldObject = Context.MakeObjectComponent(objDefinition);
                    var obj         = new VMGameObject(objDefinition, worldObject);
                    obj.Load((VMGameObjectMarshal)ent);
                    if (UseWorld)
                    {
                        Context.Blueprint.AddObject((ObjectComponent)obj.WorldUI);
                        Context.Blueprint.ChangeObjectLocation((ObjectComponent)obj.WorldUI, obj.Position);
                    }
                    obj.Position = obj.Position;
                    realEnt      = obj;
                }
                realEnt.FetchTreeByName(Context);
                Entities.Add(realEnt);
                Context.ObjectQueries.NewObject(realEnt);
                ObjectsById.Add(ent.ObjectID, realEnt);
                FSOVObjLoaded++;
            }

            int i = 0;
            int j = 0;

            foreach (var ent in input.Entities)
            {
                if (ent.LoadFailed)
                {
                    i++;
                    continue;
                }
                var threadMarsh = input.Threads[i];
                var realEnt     = Entities[j++];
                i++;

                realEnt.Thread = new VMThread(threadMarsh, Context, realEnt);
                Scheduler.ScheduleTickIn(realEnt, 1);

                if (realEnt is VMAvatar)
                {
                    ((VMAvatar)realEnt).LoadCrossRef((VMAvatarMarshal)ent, Context);
                }
                else
                {
                    ((VMGameObject)realEnt).LoadCrossRef((VMGameObjectMarshal)ent, Context);
                }
            }

            foreach (var multi in input.MultitileGroups)
            {
                var grp = new VMMultitileGroup(multi, Context); //should self register
                if (VM.UseWorld)
                {
                    var b      = grp.BaseObject;
                    var avgPos = new LotTilePos();
                    foreach (var obj in grp.Objects)
                    {
                        avgPos += obj.Position;
                    }
                    avgPos /= Math.Max(grp.Objects.Count, 1);

                    foreach (var obj in grp.Objects)
                    {
                        var off = obj.Position - avgPos;
                        obj.WorldUI.MTOffset = new Vector3(off.x, off.y, 0);
                        obj.Position         = obj.Position;
                    }
                }
                var persist = grp.BaseObject?.PersistID ?? 0;
                if (persist != 0 && grp.BaseObject is VMGameObject)
                {
                    Context.ObjectQueries.RegisterMultitilePersist(grp, persist);
                }
            }

            foreach (var ent in Entities)
            {
                if (ent.Container == null)
                {
                    ent.PositionChange(Context, true);                        //called recursively for contained objects.
                }
            }

            GlobalState = input.GlobalState;
            if (TS1)
            {
                ((VMTS1LotState)input.PlatformState).CurrentFamily = TS1State.CurrentFamily;
            }
            var lastPlatformState = PlatformState;

            PlatformState = input.PlatformState;
            PlatformState.ActivateValidator(this);
            if (lastPlatformState != null && lastPlatformState is VMTSOLotState)
            {
                TSOState.Names = ((VMTSOLotState)lastPlatformState).Names;
            }
            ObjectId = input.ObjectId;

            //just a few final changes to refresh everything, and avoid signalling objects
            var clock = Context.Clock;

            Context.Architecture.SetTimeOfDay();

            Context.Architecture.SignalAllDirty();
            Context.DisableRouteInvalidation = true;
            Context.Architecture.Tick();
            Context.DisableRouteInvalidation = false;

            Context.Architecture.WallDirtyState(input.Context.Architecture);

            if (oldSounds.Count > 0)
            {
                GameThread.InUpdate(() =>
                {
                    foreach (var snd in oldSounds)
                    {
                        //find new owners
                        var obj = GetObjectById(snd.SourceID);
                        if (obj == null || obj.Object.GUID != snd.SourceGUID)
                        {
                            snd.SFX.Sound.RemoveOwner(snd.SourceID);
                        }
                        else
                        {
                            SoundEntities.Add(obj);
                            obj.SoundThreads.Add(snd.SFX); // successfully transfer sound to new object
                        }
                    }
                });
            }

            Context.UpdateTSOBuildableArea();
            Tuning = input.Tuning;
            UpdateTuning();
            if (OnFullRefresh != null)
            {
                OnFullRefresh();
            }
        }
Exemplo n.º 2
0
        public void Load(VMMarshal input)
        {
            var clientJoin = (Context.Architecture == null);

            //var oldWorld = Context.World;
            Context    = new VMContext(input.Context, Context);
            Context.VM = this;
            Context.Architecture.RegenRoomMap();
            Context.RegeneratePortalInfo();
            Context.Architecture.Terrain.RegenerateCenters();

            if (VM.UseWorld)
            {
                Context.Blueprint.Altitude        = Context.Architecture.Terrain.Heights;
                Context.Blueprint.AltitudeCenters = Context.Architecture.Terrain.Centers;
            }

            var oldSounds = new List <VMSoundTransfer>();

            if (Entities != null) //free any object resources here.
            {
                foreach (var obj in Entities)
                {
                    obj.Dead = true;
                    if (obj.HeadlineRenderer != null)
                    {
                        obj.HeadlineRenderer.Dispose();
                    }
                    oldSounds.AddRange(obj.GetActiveSounds());
                }
            }

            Entities = new List <VMEntity>();
            Scheduler.Reset();
            ObjectsById = new Dictionary <short, VMEntity>();
            foreach (var ent in input.Entities)
            {
                VMEntity realEnt;
                var      objDefinition = FSO.Content.Content.Get().WorldObjects.Get(ent.GUID);
                if (ent is VMAvatarMarshal)
                {
                    var avatar = new VMAvatar(objDefinition);
                    avatar.Load((VMAvatarMarshal)ent);
                    if (UseWorld)
                    {
                        Context.Blueprint.AddAvatar((AvatarComponent)avatar.WorldUI);
                    }
                    realEnt = avatar;
                }
                else
                {
                    var worldObject = Context.MakeObjectComponent(objDefinition);
                    var obj         = new VMGameObject(objDefinition, worldObject);
                    obj.Load((VMGameObjectMarshal)ent);
                    if (UseWorld)
                    {
                        Context.Blueprint.AddObject((ObjectComponent)obj.WorldUI);
                        Context.Blueprint.ChangeObjectLocation((ObjectComponent)obj.WorldUI, obj.Position);
                    }
                    obj.Position = obj.Position;
                    realEnt      = obj;
                }
                realEnt.FetchTreeByName(Context);
                Entities.Add(realEnt);
                Context.ObjectQueries.NewObject(realEnt);
                ObjectsById.Add(ent.ObjectID, realEnt);
            }

            int i = 0;

            foreach (var ent in input.Entities)
            {
                var threadMarsh = input.Threads[i];
                var realEnt     = Entities[i++];

                realEnt.Thread = new VMThread(threadMarsh, Context, realEnt);
                Scheduler.ScheduleTickIn(realEnt, 1);

                if (realEnt is VMAvatar)
                {
                    ((VMAvatar)realEnt).LoadCrossRef((VMAvatarMarshal)ent, Context);
                }
                else
                {
                    ((VMGameObject)realEnt).LoadCrossRef((VMGameObjectMarshal)ent, Context);
                }
            }

            foreach (var multi in input.MultitileGroups)
            {
                var grp = new VMMultitileGroup(multi, Context); //should self register
                if (VM.UseWorld)
                {
                    var b      = grp.BaseObject;
                    var avgPos = new LotTilePos();
                    foreach (var obj in grp.Objects)
                    {
                        avgPos += obj.Position;
                    }
                    avgPos /= grp.Objects.Count;

                    foreach (var obj in grp.Objects)
                    {
                        var off = obj.Position - avgPos;
                        obj.WorldUI.MTOffset = new Vector3(off.x, off.y, 0);
                        obj.Position         = obj.Position;
                    }
                }
                var persist = grp.BaseObject?.PersistID ?? 0;
                if (persist != 0 && grp.BaseObject is VMGameObject)
                {
                    Context.ObjectQueries.RegisterMultitilePersist(grp, persist);
                }
            }

            foreach (var ent in Entities)
            {
                if (ent.Container == null)
                {
                    ent.PositionChange(Context, true);                        //called recursively for contained objects.
                }
            }

            GlobalState   = input.GlobalState;
            PlatformState = input.PlatformState;
            ObjectId      = input.ObjectId;

            //just a few final changes to refresh everything, and avoid signalling objects
            var clock = Context.Clock;

            Context.Architecture.SetTimeOfDay(clock.Hours / 24.0 + clock.Minutes / (24.0 * 60) + clock.Seconds / (24.0 * 60 * 60));

            Context.Architecture.SignalAllDirty();
            Context.DisableRouteInvalidation = true;
            Context.Architecture.Tick();
            Context.DisableRouteInvalidation = false;

            Context.Architecture.WallDirtyState(input.Context.Architecture);

            foreach (var snd in oldSounds)
            {
                //find new owners
                var obj = GetObjectById(snd.SourceID);
                if (obj == null || obj.Object.GUID != snd.SourceGUID)
                {
                    snd.SFX.Sound.RemoveOwner(snd.SourceID);
                }
                else
                {
                    obj.SoundThreads.Add(snd.SFX);  // successfully transfer sound to new object
                }
            }

            if (clientJoin)
            {
                //run clientJoin functions to play object sounds, update some gfx.
                foreach (var obj in Entities)
                {
                    obj.ExecuteEntryPoint(30, Context, true);
                }
            }
            Context.UpdateTSOBuildableArea();
            if (OnFullRefresh != null)
            {
                OnFullRefresh();
            }
        }