public void _Update(double delta) { var sound = game.GetService<SoundManager>(); if (Running) { var pos = camera.Transform.Position; var forward = Vector3.TransformNormal(-Vector3.UnitZ, camera.Transform.Orientation); var up = Vector3.TransformNormal(Vector3.UnitY, camera.Transform.Orientation); sound.UpdateListener(delta, pos, forward, up); } currentTime += delta; foreach (var obj in sceneObjects.Values) obj.UpdateIfMain(); if (text != null) { if (currentTime > text.Start) { game.GetService<Interface.Typewriter>().PlayString(gameData.GetString(text.TextIDS)); text = null; } } // foreach (var instance in instances) { instance.Update(delta); } // foreach (var obj in sceneObjects.Values) obj.Update(); camera.Update(); if(Renderer != null) World.Update(delta); }
public void _Update(TimeSpan delta) { var sound = game.GetService <SoundManager>(); if (Running) { var pos = camera.Transform.Position; var forward = Vector3.TransformNormal(-Vector3.UnitZ, camera.Transform.Orientation); var up = Vector3.TransformNormal(Vector3.UnitY, camera.Transform.Orientation); sound.UpdateListener(delta, pos, forward, up); } currentTime += delta.TotalSeconds; if (text != null) { if (currentTime > text.Start) { game.GetService <Interface.Typewriter>().PlayString(gameData.GetString(text.TextIDS)); text = null; } } for (int i = (Coroutines.Count - 1); i >= 0; i--) { if (!Coroutines[i].Run(this, delta.TotalSeconds)) { Coroutines.RemoveAt(i); i--; } } while (events.Count > 0 && events.Peek().Time <= currentTime) { var ev = events.Dequeue(); ProcessEvent(ev); } foreach (var obj in Objects.Values) { obj.Update(); } camera.Update(); if (Renderer != null) { World.Update(delta); } }
public void SetDisplayText(ThnDisplayText text) { this.text = text; }
void AddEntities(ThnScript thn) { foreach (var kv in thn.Entities) { if (Objects.ContainsKey(kv.Key)) { continue; } if ((kv.Value.ObjectFlags & ThnObjectFlags.Reference) == ThnObjectFlags.Reference) { continue; } var obj = new ThnObject(); obj.Name = kv.Key; obj.Translate = kv.Value.Position ?? Vector3.Zero; obj.Rotate = kv.Value.RotationMatrix ?? Matrix4x4.Identity; //PlayerShip object if (spawnObjects && scriptContext.PlayerShip != null && kv.Value.Type == EntityTypes.Compound && kv.Value.Template.Equals("playership", StringComparison.InvariantCultureIgnoreCase)) { obj.Object = scriptContext.PlayerShip; obj.Object.RenderComponent.LitDynamic = (kv.Value.ObjectFlags & ThnObjectFlags.LitDynamic) == ThnObjectFlags.LitDynamic; obj.Object.RenderComponent.LitAmbient = (kv.Value.ObjectFlags & ThnObjectFlags.LitAmbient) == ThnObjectFlags.LitAmbient; obj.Object.RenderComponent.NoFog = kv.Value.NoFog; ((ModelRenderer)obj.Object.RenderComponent).LightGroup = kv.Value.LightGroup; obj.Entity = kv.Value; Vector3 transform = kv.Value.Position ?? Vector3.Zero; obj.Object.Transform = (kv.Value.RotationMatrix ?? Matrix4x4.Identity) * Matrix4x4.CreateTranslation(transform); obj.HpMount = scriptContext.PlayerShip.GetHardpoint("HpMount"); World.Objects.Add(obj.Object); Objects.Add(kv.Key, obj); continue; } var template = kv.Value.Template; string replacement; if (scriptContext != null && scriptContext.Substitutions.TryGetValue(kv.Value.Template, out replacement)) { template = replacement; } var resman = game.GetService <ResourceManager>(); if (spawnObjects && kv.Value.Type == EntityTypes.Compound) { bool getHpMount = false; //Fetch model IDrawable drawable = null; if (!string.IsNullOrEmpty(template)) { switch (kv.Value.MeshCategory.ToLowerInvariant()) { case "solar": drawable = gameData.GetSolar(template); break; case "ship": case "spaceship": getHpMount = true; var sh = gameData.GetShip(template); drawable = sh.ModelFile.LoadFile(resman); break; case "prop": drawable = gameData.GetProp(template); break; case "room": drawable = gameData.GetRoom(template); break; case "equipment cart": drawable = gameData.GetCart(template); break; case "equipment": var eq = gameData.GetEquipment(template); drawable = eq?.ModelFile.LoadFile(resman); break; case "asteroid": drawable = gameData.GetAsteroid(kv.Value.Template); break; default: throw new NotImplementedException("Mesh Category " + kv.Value.MeshCategory); } } else { FLLog.Warning("Thn", $"object '{kv.Value.Name}' has empty template, category " + $"'{kv.Value.MeshCategory}'"); } drawable?.Initialize(resman); if (kv.Value.UserFlag != 0) { //This is a starsphere layers.Add(new Tuple <IDrawable, ThnObject>(drawable, obj)); } else { obj.Object = new GameObject(drawable, game.GetService <ResourceManager>(), true, false, false); obj.Object.Name = kv.Value.Name; obj.Object.PhysicsComponent = null; //Jitter seems to interfere with directly setting orientation if (getHpMount) { obj.HpMount = obj.Object.GetHardpoint("HpMount"); } var r = (ModelRenderer)obj.Object.RenderComponent; if (r != null) { r.LightGroup = kv.Value.LightGroup; r.LitDynamic = (kv.Value.ObjectFlags & ThnObjectFlags.LitDynamic) == ThnObjectFlags.LitDynamic; r.LitAmbient = (kv.Value.ObjectFlags & ThnObjectFlags.LitAmbient) == ThnObjectFlags.LitAmbient; //HIDDEN just seems to be an editor flag? //r.Hidden = (kv.Value.ObjectFlags & ThnObjectFlags.Hidden) == ThnObjectFlags.Hidden; r.NoFog = kv.Value.NoFog; } } } else if (kv.Value.Type == EntityTypes.PSys) { var fx = gameData.GetEffect(kv.Value.Template); if (fx != null) { obj.Object = new GameObject(); obj.Object.RenderComponent = new ParticleEffectRenderer(fx.GetEffect(resman)) { Active = false }; } } else if (kv.Value.Type == EntityTypes.Scene) { if (kv.Value.DisplayText != null) { text = kv.Value.DisplayText; } if (hasScene) { //throw new Exception("Thn can only have one scene"); //TODO: This needs to be handled better continue; } var amb = kv.Value.Ambient.Value; if (amb.X == 0 && amb.Y == 0 && amb.Z == 0) { continue; } hasScene = true; Renderer.SystemLighting.Ambient = new Color4(amb.X / 255f, amb.Y / 255f, amb.Z / 255f, 1); } else if (kv.Value.Type == EntityTypes.Light) { var lt = new DynamicLight(); lt.LightGroup = kv.Value.LightGroup; lt.Active = kv.Value.LightProps.On; lt.Light = kv.Value.LightProps.Render; obj.Light = lt; obj.LightDir = lt.Light.Direction; if (kv.Value.RotationMatrix.HasValue) { var m = kv.Value.RotationMatrix.Value; lt.Light.Direction = Vector3.TransformNormal(lt.Light.Direction, m); } if (Renderer != null) { Renderer.SystemLighting.Lights.Add(lt); } } else if (kv.Value.Type == EntityTypes.Camera) { obj.Camera = new ThnCameraTransform(); obj.Camera.Position = kv.Value.Position.Value; obj.Camera.Orientation = kv.Value.RotationMatrix ?? Matrix4x4.Identity; obj.Camera.FovH = kv.Value.FovH ?? obj.Camera.FovH; obj.Camera.AspectRatio = kv.Value.HVAspect ?? obj.Camera.AspectRatio; if (kv.Value.NearPlane != null) { obj.Camera.Znear = kv.Value.NearPlane.Value; } if (kv.Value.FarPlane != null) { obj.Camera.Zfar = kv.Value.FarPlane.Value; } } else if (kv.Value.Type == EntityTypes.Marker) { obj.Object = new GameObject(); obj.Object.Name = "Marker"; obj.Object.Nickname = ""; } else if (kv.Value.Type == EntityTypes.Deformable) { obj.Object = new GameObject(); gameData.GetCostume(template, out DfmFile body, out DfmFile head, out DfmFile leftHand, out DfmFile rightHand); var skel = new DfmSkeletonManager(body, head, leftHand, rightHand); obj.Object.RenderComponent = new CharacterRenderer(skel); var anmComponent = new AnimationComponent(obj.Object, gameData.GetCharacterAnimations()); obj.Object.AnimationComponent = anmComponent; obj.Object.Components.Add(anmComponent); } else if (kv.Value.Type == EntityTypes.Sound) { obj.Sound = new ThnSound(kv.Value.Template, game.GetService <SoundManager>(), kv.Value.AudioProps, obj); obj.Sound.Spatial = (kv.Value.ObjectFlags & ThnObjectFlags.SoundSpatial) == ThnObjectFlags.SoundSpatial; } if (obj.Object != null) { Vector3 transform = kv.Value.Position ?? Vector3.Zero; obj.Object.Transform = (kv.Value.RotationMatrix ?? Matrix4x4.Identity) * Matrix4x4.CreateTranslation(transform); World.Objects.Add(obj.Object); } obj.Entity = kv.Value; Objects[kv.Key] = obj; } }