/// <summary> /// Initializes this Virtual Machine. /// </summary> public void Init() { PlatformState = (TS1)?(VMAbstractLotState) new VMTS1LotState():new VMTSOLotState(); GlobalState = new short[38]; GlobalState[20] = 255; //Game Edition. Basically, what "expansion packs" are running. Let's just say all of them. GlobalState[25] = 4; //as seen in EA-Land edith's simulator globals, this needs to be set for people to do their idle interactions. GlobalState[17] = 4; //Runtime Code Version, is this in EA-Land. if (Driver is VMServerDriver) { EODHost = new VMEODHost(); } }
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(); } }
public void Deserialize(BinaryReader reader) { if (new string(reader.ReadChars(4)) != "FSOv") { return; } Version = reader.ReadInt32(); Compressed = reader.ReadBoolean(); var uReader = reader; if (Compressed) { var length = reader.ReadInt32(); var cStream = new MemoryStream(reader.ReadBytes(length)); var zipStream = new GZipStream(cStream, CompressionMode.Decompress); var decompStream = new MemoryStream(); zipStream.CopyTo(decompStream); decompStream.Seek(0, SeekOrigin.Begin); reader = new BinaryReader(decompStream); cStream.Close(); zipStream.Close(); } if (Version > 26) { TS1 = reader.ReadBoolean(); } Context = new VMContextMarshal(Version); Context.Deserialize(reader); int ents = reader.ReadInt32(); Entities = new VMEntityMarshal[ents]; for (int i = 0; i < ents; i++) { var type = reader.ReadByte(); var ent = (type == 1) ? (VMEntityMarshal) new VMAvatarMarshal(Version, TS1) : new VMGameObjectMarshal(Version, TS1); ent.Deserialize(reader); Entities[i] = ent; } int thrN = reader.ReadInt32(); Threads = new VMThreadMarshal[thrN]; for (int i = 0; i < thrN; i++) { Threads[i] = new VMThreadMarshal(Version); Threads[i].Deserialize(reader); } int mtgN = reader.ReadInt32(); MultitileGroups = new VMMultitileGroupMarshal[mtgN]; for (int i = 0; i < mtgN; i++) { MultitileGroups[i] = new VMMultitileGroupMarshal(Version); MultitileGroups[i].Deserialize(reader); } int globs = reader.ReadInt32(); GlobalState = new short[globs]; for (int i = 0; i < globs; i++) { GlobalState[i] = reader.ReadInt16(); } PlatformState = (TS1)?(VMAbstractLotState) new VMTS1LotState(Version):new VMTSOLotState(Version); PlatformState.Deserialize(reader); ObjectId = reader.ReadInt16(); if (Version > 23) { if (reader.ReadBoolean()) { Tuning = new DynamicTuning(reader); } } if (Compressed) { reader.BaseStream.Close(); } }