protected override void LoadContent() { this.MapContent = new ContentManager(this.Services); this.MapContent.RootDirectory = this.Content.RootDirectory; GeeUIMain.Font = this.Content.Load<SpriteFont>(this.Font); if (this.firstLoadContentCall) { this.firstLoadContentCall = false; if (!Directory.Exists(this.MapDirectory)) Directory.CreateDirectory(this.MapDirectory); string challengeDirectory = Path.Combine(this.MapDirectory, "Challenge"); if (!Directory.Exists(challengeDirectory)) Directory.CreateDirectory(challengeDirectory); #if VR if (this.VR) { this.vrLeftMesh.Load(this, Ovr.Eye.Left, this.vrLeftFov); this.vrRightMesh.Load(this, Ovr.Eye.Right, this.vrRightFov); new CommandBinding(this.ReloadedContent, (Action)this.vrLeftMesh.Reload); new CommandBinding(this.ReloadedContent, (Action)this.vrRightMesh.Reload); this.reallocateVrTargets(); this.vrCamera = new Camera(); this.AddComponent(this.vrCamera); } #endif this.GraphicsDevice.PresentationParameters.PresentationInterval = PresentInterval.Immediate; this.GeeUI = new GeeUIMain(); this.AddComponent(GeeUI); this.ConsoleUI = new ConsoleUI(); this.AddComponent(ConsoleUI); this.Console = new Console.Console(); this.AddComponent(Console); Lemma.Console.Console.BindType(null, this); Lemma.Console.Console.BindType(null, Console); // Initialize Wwise AkGlobalSoundEngineInitializer initializer = new AkGlobalSoundEngineInitializer(Path.Combine(this.Content.RootDirectory, "Wwise")); this.AddComponent(initializer); this.Listener = new AkListener(); this.Listener.Add(new Binding<Vector3>(this.Listener.Position, this.Camera.Position)); this.Listener.Add(new Binding<Vector3>(this.Listener.Forward, this.Camera.Forward)); this.Listener.Add(new Binding<Vector3>(this.Listener.Up, this.Camera.Up)); this.AddComponent(this.Listener); // Create the renderer. this.LightingManager = new LightingManager(); this.AddComponent(this.LightingManager); this.Renderer = new Renderer(this, true, true, true, true, true); this.AddComponent(this.Renderer); this.Renderer.ReallocateBuffers(this.ScreenSize); this.renderParameters = new RenderParameters { Camera = this.Camera, IsMainRender = true }; // Load strings this.Strings.Load(Path.Combine(this.Content.RootDirectory, "Strings.xlsx")); this.UI = new UIRenderer(); this.UI.GeeUI = this.GeeUI; this.AddComponent(this.UI); PCInput input = new PCInput(); this.AddComponent(input); Lemma.Console.Console.BindType(null, input); Lemma.Console.Console.BindType(null, UI); Lemma.Console.Console.BindType(null, Renderer); Lemma.Console.Console.BindType(null, LightingManager); input.Add(new CommandBinding(input.GetChord(new PCInput.Chord { Modifier = Keys.LeftAlt, Key = Keys.S }), delegate() { // High-resolution screenshot bool originalModelsVisible = Editor.EditorModelsVisible; Editor.EditorModelsVisible.Value = false; Screenshot s = new Screenshot(); this.AddComponent(s); s.Take(new Point(4096, 2304), delegate() { string desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); string path; int i = 0; do { path = Path.Combine(desktop, string.Format("lemma-screen{0}.png", i)); i++; } while (File.Exists(path)); Screenshot.SavePng(s.Buffer, path); Editor.EditorModelsVisible.Value = originalModelsVisible; s.Delete.Execute(); }); })); this.performanceMonitor = new ListContainer(); this.performanceMonitor.Add(new Binding<Vector2, Point>(performanceMonitor.Position, x => new Vector2(x.X, 0), this.ScreenSize)); this.performanceMonitor.AnchorPoint.Value = new Vector2(1, 0); this.performanceMonitor.Visible.Value = false; this.performanceMonitor.Name.Value = "PerformanceMonitor"; this.UI.Root.Children.Add(this.performanceMonitor); Action<string, Property<double>> addTimer = delegate(string label, Property<double> property) { TextElement text = new TextElement(); text.FontFile.Value = this.Font; text.Add(new Binding<string, double>(text.Text, x => label + ": " + (x * 1000.0).ToString("F") + "ms", property)); this.performanceMonitor.Children.Add(text); }; Action<string, Property<int>> addCounter = delegate(string label, Property<int> property) { TextElement text = new TextElement(); text.FontFile.Value = this.Font; text.Add(new Binding<string, int>(text.Text, x => label + ": " + x.ToString(), property)); this.performanceMonitor.Children.Add(text); }; TextElement frameRateText = new TextElement(); frameRateText.FontFile.Value = this.Font; frameRateText.Add(new Binding<string, float>(frameRateText.Text, x => "FPS: " + x.ToString("0"), this.frameRate)); this.performanceMonitor.Children.Add(frameRateText); addTimer("Physics", this.physicsTime); addTimer("Update", this.updateTime); addTimer("Render", this.renderTime); addCounter("Draw calls", this.drawCalls); addCounter("Triangles", this.triangles); addCounter("Working set", this.workingSet); Lemma.Console.Console.AddConCommand(new ConCommand("perf", "Toggle the performance monitor", delegate(ConCommand.ArgCollection args) { this.performanceMonitor.Visible.Value = !this.performanceMonitor.Visible; })); try { IEnumerable<string> globalStaticScripts = Directory.GetFiles(Path.Combine(this.Content.RootDirectory, "GlobalStaticScripts"), "*", SearchOption.AllDirectories).Select(x => Path.Combine("..\\GlobalStaticScripts", Path.GetFileNameWithoutExtension(x))); foreach (string scriptName in globalStaticScripts) this.executeStaticScript(scriptName); } catch (IOException) { } this.UIFactory = new UIFactory(); this.AddComponent(this.UIFactory); this.AddComponent(this.Menu); // Have to do this here so the menu's Awake can use all our loaded stuff this.Spawner = new Spawner(); this.AddComponent(this.Spawner); this.UI.IsMouseVisible.Value = true; AKRESULT akresult = AkBankLoader.LoadBank("SFX_Bank_01.bnk"); if (akresult != AKRESULT.AK_Success) Log.d(string.Format("Failed to load main sound bank: {0}", akresult)); #if ANALYTICS this.SessionRecorder = new Session.Recorder(this); this.SessionRecorder.Add("Position", delegate() { Entity p = PlayerFactory.Instance; if (p != null && p.Active) return p.Get<Transform>().Position; else return Vector3.Zero; }); this.SessionRecorder.Add("Health", delegate() { Entity p = PlayerFactory.Instance; if (p != null && p.Active) return p.Get<Player>().Health; else return 0.0f; }); this.SessionRecorder.Add("Framerate", delegate() { return this.frameRate; }); this.SessionRecorder.Add("WorkingSet", delegate() { return this.workingSet; }); this.AddComponent(this.SessionRecorder); this.SessionRecorder.Add(new Binding<bool, Config.RecordAnalytics>(this.SessionRecorder.EnableUpload, x => x == Config.RecordAnalytics.On, this.Settings.Analytics)); #endif this.DefaultLighting(); new SetBinding<float>(this.Settings.SoundEffectVolume, delegate(float value) { AkSoundEngine.SetRTPCValue(AK.GAME_PARAMETERS.VOLUME_SFX, MathHelper.Clamp(value, 0.0f, 1.0f)); }); new SetBinding<float>(this.Settings.MusicVolume, delegate(float value) { AkSoundEngine.SetRTPCValue(AK.GAME_PARAMETERS.VOLUME_MUSIC, MathHelper.Clamp(value, 0.0f, 1.0f)); }); new TwoWayBinding<LightingManager.DynamicShadowSetting>(this.Settings.DynamicShadows, this.LightingManager.DynamicShadows); new TwoWayBinding<float>(this.Settings.MotionBlurAmount, this.Renderer.MotionBlurAmount); new TwoWayBinding<float>(this.Settings.Gamma, this.Renderer.Gamma); new TwoWayBinding<bool>(this.Settings.Bloom, this.Renderer.EnableBloom); new TwoWayBinding<bool>(this.Settings.SSAO, this.Renderer.EnableSSAO); new Binding<float>(this.Camera.FieldOfView, this.Settings.FieldOfView); foreach (string file in Directory.GetFiles(this.MapDirectory, "*.xlsx", SearchOption.TopDirectoryOnly)) this.Strings.Load(file); new Binding<string, Config.Lang>(this.Strings.Language, x => x.ToString(), this.Settings.Language); new NotifyBinding(this.SaveSettings, this.Settings.Language); new CommandBinding(this.MapLoaded, delegate() { this.Renderer.BlurAmount.Value = 0.0f; this.Renderer.Tint.Value = new Vector3(1.0f); }); #if VR if (this.VR) { Action loadVrEffect = delegate() { this.vrEffect = this.Content.Load<Effect>("Effects\\Oculus"); }; loadVrEffect(); new CommandBinding(this.ReloadedContent, loadVrEffect); this.UI.Add(new Binding<Point>(this.UI.RenderTargetSize, this.ScreenSize)); this.VRUI = new Lemma.Components.ModelNonPostProcessed(); this.VRUI.MapContent = false; this.VRUI.DrawOrder.Value = 100000; // On top of everything this.VRUI.Filename.Value = "Models\\plane"; this.VRUI.EffectFile.Value = "Effects\\VirtualUI"; this.VRUI.Add(new Binding<Microsoft.Xna.Framework.Graphics.RenderTarget2D>(this.VRUI.GetRenderTarget2DParameter("Diffuse" + Lemma.Components.Model.SamplerPostfix), this.UI.RenderTarget)); this.VRUI.Add(new Binding<Matrix>(this.VRUI.Transform, delegate() { Matrix rot = this.Camera.RotationMatrix; Matrix mat = Matrix.Identity; mat.Forward = rot.Right; mat.Right = rot.Forward; mat.Up = rot.Up; mat *= Matrix.CreateScale(7); mat.Translation = this.Camera.Position + rot.Forward * 4.0f; return mat; }, this.Camera.Position, this.Camera.RotationMatrix)); this.AddComponent(this.VRUI); this.UI.Setup3D(this.VRUI.Transform); } #endif #if ANALYTICS bool editorLastEnabled = this.EditorEnabled; new CommandBinding<string>(this.LoadingMap, delegate(string newMap) { if (this.MapFile.Value != null && !editorLastEnabled) { this.SessionRecorder.RecordEvent("ChangedMap", newMap); if (!this.IsChallengeMap(this.MapFile) && this.MapFile.Value != Main.MenuMap) this.SaveAnalytics(); } this.SessionRecorder.Reset(); editorLastEnabled = this.EditorEnabled; }); #endif new CommandBinding<string>(this.LoadingMap, delegate(string newMap) { this.CancelScheduledSave(); }); #if !DEVELOPMENT IO.MapLoader.Load(this, MenuMap); this.Menu.Show(initial: true); #endif #if ANALYTICS if (this.Settings.Analytics.Value == Config.RecordAnalytics.Ask) { this.Menu.ShowDialog("\\analytics prompt", "\\enable analytics", delegate() { this.Settings.Analytics.Value = Config.RecordAnalytics.On; }, "\\disable analytics", delegate() { this.Settings.Analytics.Value = Config.RecordAnalytics.Off; }); } #endif #if VR if (this.oculusNotFound) this.Menu.HideMessage(null, this.Menu.ShowMessage(null, "Error: no Oculus found."), 6.0f); if (this.VR) { this.Menu.EnableInput(false); Container vrMsg = this.Menu.BuildMessage("\\vr message", 300.0f); vrMsg.AnchorPoint.Value = new Vector2(0.5f, 0.5f); vrMsg.Add(new Binding<Vector2, Point>(vrMsg.Position, x => new Vector2(x.X * 0.5f, x.Y * 0.5f), this.ScreenSize)); this.UI.Root.Children.Add(vrMsg); input.Bind(this.Settings.RecenterVRPose, PCInput.InputState.Down, this.VRHmd.RecenterPose); input.Bind(this.Settings.RecenterVRPose, PCInput.InputState.Down, delegate() { if (vrMsg != null) { vrMsg.Delete.Execute(); vrMsg = null; } this.Menu.EnableInput(true); }); } else #endif { input.Bind(this.Settings.ToggleFullscreen, PCInput.InputState.Down, delegate() { if (this.Settings.Fullscreen) // Already fullscreen. Go to windowed mode. this.ExitFullscreen(); else // In windowed mode. Go to fullscreen. this.EnterFullscreen(); }); } input.Bind(this.Settings.QuickSave, PCInput.InputState.Down, delegate() { this.SaveWithNotification(true); }); } else { this.ReloadingContent.Execute(); foreach (IGraphicsComponent c in this.graphicsComponents) c.LoadContent(true); this.ReloadedContent.Execute(); } this.GraphicsDevice.RasterizerState = new RasterizerState { MultiSampleAntiAlias = false }; if (this.spriteBatch != null) this.spriteBatch.Dispose(); this.spriteBatch = new SpriteBatch(this.GraphicsDevice); }
public RootUIComponent(UIRenderer renderer) { this.renderer = renderer; }
public static void Attach(Main main, Entity entity, Player player, AnimatedModel model, FPSInput input, Phone phone, Property <bool> enableWalking, Property <bool> phoneActive, Property <bool> noteActive) { UIRenderer phoneUi = entity.GetOrCreate <UIRenderer>("PhoneUI"); const float phoneWidth = 200.0f; phoneUi.RenderTargetBackground.Value = Microsoft.Xna.Framework.Color.White; phoneUi.RenderTargetSize.Value = new Point((int)phoneWidth, (int)(phoneWidth * 2.0f)); phoneUi.Serialize = false; phoneUi.Enabled.Value = false; #if VR if (main.VR) { phoneUi.Reticle.Tint.Value = new Color(0.0f, 0.0f, 0.0f); } #endif Model phoneModel = entity.GetOrCreate <Model>("PhoneModel"); phoneModel.Filename.Value = "Models\\phone"; phoneModel.Color.Value = new Vector3(0.13f, 0.13f, 0.13f); phoneModel.Serialize = false; phoneModel.Enabled.Value = false; Property <Matrix> phoneBone = model.GetBoneTransform("Phone"); phoneModel.Add(new Binding <Matrix>(phoneModel.Transform, () => phoneBone.Value * model.Transform, phoneBone, model.Transform)); Model screen = entity.GetOrCreate <Model>("Screen"); screen.Filename.Value = "Models\\plane"; screen.Add(new Binding <Microsoft.Xna.Framework.Graphics.RenderTarget2D>(screen.GetRenderTarget2DParameter("Diffuse" + Model.SamplerPostfix), phoneUi.RenderTarget)); screen.Add(new Binding <Matrix>(screen.Transform, x => Matrix.CreateTranslation(0.015f, 0.0f, 0.0f) * x, phoneModel.Transform)); screen.Serialize = false; screen.Enabled.Value = false; PointLight phoneLight = entity.Create <PointLight>(); phoneLight.Serialize = false; phoneLight.Enabled.Value = false; phoneLight.Attenuation.Value = 0.5f; phoneLight.Add(new Binding <Vector3, Matrix>(phoneLight.Position, x => x.Translation, screen.Transform)); PointLight noteLight = entity.Create <PointLight>(); noteLight.Serialize = false; noteLight.Enabled.Value = false; noteLight.Attenuation.Value = 1.0f; noteLight.Color.Value = new Vector3(0.3f); noteLight.Add(new Binding <Vector3>(noteLight.Position, () => Vector3.Transform(new Vector3(0.25f, 0.0f, 0.0f), phoneBone.Value * model.Transform), phoneBone, model.Transform)); const float screenScale = 0.0007f; screen.Scale.Value = new Vector3(1.0f, (float)phoneUi.RenderTargetSize.Value.Y * screenScale, (float)phoneUi.RenderTargetSize.Value.X * screenScale); // Transform screen space mouse position into 3D, then back into the 2D space of the phone UI Property <Matrix> screenTransform = new Property <Matrix>(); screen.Add(new Binding <Matrix>(screenTransform, () => Matrix.CreateScale(screen.Scale) * screen.Transform, screen.Scale, screen.Transform)); phoneUi.Setup3D(screenTransform); // Phone UI const float padding = 8.0f; const float messageWidth = phoneWidth - padding * 2.0f; Func <Property <Color>, string, float, Container> makeButton = delegate(Property <Color> color, string text, float width) { Container bg = new Container(); bg.Tint.Value = color; bg.PaddingBottom.Value = bg.PaddingLeft.Value = bg.PaddingRight.Value = bg.PaddingTop.Value = padding * 0.5f; bg.Add(new Binding <Color>(bg.Tint, () => bg.Highlighted ? new Color(color.Value.ToVector4() + new Vector4(0.2f, 0.2f, 0.2f, 0.0f)) : color, bg.Highlighted, color)); TextElement msg = new TextElement(); msg.Name.Value = "Text"; msg.FontFile.Value = main.MainFont; msg.Text.Value = text; msg.WrapWidth.Value = width; bg.Children.Add(msg); return(bg); }; Action <Container, float> centerButton = delegate(Container button, float width) { TextElement text = (TextElement)button.Children[0]; text.AnchorPoint.Value = new Vector2(0.5f, 0); text.Add(new Binding <Vector2>(text.Position, x => new Vector2(x.X * 0.5f, padding), button.Size)); button.ResizeHorizontal.Value = false; button.ResizeVertical.Value = false; button.Size.Value = new Vector2(width, 36.0f * main.MainFontMultiplier); }; Func <UIComponent, bool, Container> makeAlign = delegate(UIComponent component, bool right) { Container container = new Container(); container.Opacity.Value = 0.0f; container.PaddingBottom.Value = container.PaddingLeft.Value = container.PaddingRight.Value = container.PaddingTop.Value = 0.0f; container.ResizeHorizontal.Value = false; container.Size.Value = new Vector2(messageWidth, 0.0f); component.AnchorPoint.Value = new Vector2(right ? 1.0f : 0.0f, 0.0f); component.Position.Value = new Vector2(right ? messageWidth : 0.0f, 0.0f); container.Children.Add(component); return(container); }; Property <Color> incomingColor = new Property <Color> { Value = new Color(0.0f, 0.0f, 0.0f, 1.0f) }; Property <Color> outgoingColor = new Property <Color> { Value = new Color(0.0f, 0.175f, 0.35f, 1.0f) }; Property <Color> composeColor = new Property <Color> { Value = new Color(0.5f, 0.0f, 0.0f, 1.0f) }; Property <Color> topBarColor = new Property <Color> { Value = new Color(0.15f, 0.15f, 0.15f, 1.0f) }; Container topBarContainer = new Container(); topBarContainer.ResizeHorizontal.Value = false; topBarContainer.Size.Value = new Vector2(phoneUi.RenderTargetSize.Value.X, 0.0f); topBarContainer.Tint.Value = topBarColor; phoneUi.Root.Children.Add(topBarContainer); ListContainer phoneTopBar = new ListContainer(); phoneTopBar.Orientation.Value = ListContainer.ListOrientation.Horizontal; phoneTopBar.Spacing.Value = padding; topBarContainer.Children.Add(phoneTopBar); Sprite signalIcon = new Sprite(); signalIcon.Image.Value = "Images\\signal"; phoneTopBar.Children.Add(signalIcon); TextElement noService = new TextElement(); noService.FontFile.Value = main.MainFont; noService.Text.Value = "\\no service"; phoneTopBar.Children.Add(noService); signalIcon.Add(new Binding <bool>(signalIcon.Visible, () => player.SignalTower.Value.Target != null || phone.ActiveAnswers.Length > 0 || phone.Schedules.Length > 0, player.SignalTower, phone.ActiveAnswers.Length, phone.Schedules.Length)); noService.Add(new Binding <bool>(noService.Visible, x => !x, signalIcon.Visible)); ListContainer tabs = new ListContainer(); tabs.Orientation.Value = ListContainer.ListOrientation.Horizontal; tabs.Spacing.Value = 0; phoneUi.Root.Children.Add(tabs); Property <Color> messageTabColor = new Property <Color> { Value = outgoingColor }; phoneUi.Add(new Binding <Color, Phone.Mode>(messageTabColor, x => x == Phone.Mode.Messages ? outgoingColor : topBarColor, phone.CurrentMode)); Container messageTab = makeButton(messageTabColor, "\\messages", phoneUi.RenderTargetSize.Value.X * 0.5f - padding); centerButton(messageTab, phoneUi.RenderTargetSize.Value.X * 0.5f); tabs.Children.Add(messageTab); messageTab.Add(new CommandBinding(messageTab.MouseLeftUp, delegate() { phone.CurrentMode.Value = Phone.Mode.Messages; })); Property <Color> photoTabColor = new Property <Color> { Value = topBarColor }; phoneUi.Add(new Binding <Color, Phone.Mode>(photoTabColor, x => x == Phone.Mode.Photos ? outgoingColor : topBarColor, phone.CurrentMode)); Container photoTab = makeButton(photoTabColor, "\\photos", phoneUi.RenderTargetSize.Value.X * 0.5f - padding); centerButton(photoTab, phoneUi.RenderTargetSize.Value.X * 0.5f); tabs.Children.Add(photoTab); photoTab.Add(new CommandBinding(photoTab.MouseLeftUp, delegate() { phone.CurrentMode.Value = Phone.Mode.Photos; })); tabs.Add(new Binding <Vector2>(tabs.Position, x => new Vector2(0, x.Y), topBarContainer.Size)); ListContainer messageLayout = new ListContainer(); messageLayout.Spacing.Value = padding; messageLayout.Orientation.Value = ListContainer.ListOrientation.Vertical; messageLayout.Add(new Binding <Vector2>(messageLayout.Position, () => new Vector2(padding, topBarContainer.Size.Value.Y + tabs.Size.Value.Y), topBarContainer.Size, tabs.Size)); messageLayout.Add(new Binding <Vector2>(messageLayout.Size, () => new Vector2(phoneUi.RenderTargetSize.Value.X - padding * 2.0f, phoneUi.RenderTargetSize.Value.Y - padding - topBarContainer.Size.Value.Y - tabs.Size.Value.Y), phoneUi.RenderTargetSize, topBarContainer.Size, tabs.Size)); messageLayout.Add(new Binding <bool, Phone.Mode>(messageLayout.Visible, x => x == Phone.Mode.Messages, phone.CurrentMode)); phoneUi.Root.Children.Add(messageLayout); Container photoLayout = new Container(); photoLayout.Opacity.Value = 0; photoLayout.PaddingLeft.Value = photoLayout.PaddingRight.Value = photoLayout.PaddingTop.Value = photoLayout.PaddingBottom.Value = 0; photoLayout.Add(new Binding <Vector2>(photoLayout.Position, () => new Vector2(0, topBarContainer.Size.Value.Y + tabs.Size.Value.Y), topBarContainer.Size, tabs.Size)); photoLayout.Add(new Binding <Vector2>(photoLayout.Size, () => new Vector2(phoneUi.RenderTargetSize.Value.X, phoneUi.RenderTargetSize.Value.Y - topBarContainer.Size.Value.Y - tabs.Size.Value.Y), phoneUi.RenderTargetSize, topBarContainer.Size, tabs.Size)); photoLayout.Add(new Binding <bool>(photoLayout.Visible, x => !x, messageLayout.Visible)); phoneUi.Root.Children.Add(photoLayout); Sprite photoImage = new Sprite(); photoImage.AnchorPoint.Value = new Vector2(0.5f, 0.5f); photoImage.Add(new Binding <string>(photoImage.Image, phone.Photo)); photoImage.Add(new Binding <Vector2>(photoImage.Position, x => x * 0.5f, photoLayout.Size)); photoLayout.Children.Add(photoImage); Container composeButton = makeButton(composeColor, "\\compose", messageWidth - padding * 2.0f); TextElement composeText = (TextElement)composeButton.GetChildByName("Text"); composeText.Add(new Binding <string, bool>(composeText.Text, x => x ? "\\compose gamepad" : "\\compose", main.GamePadConnected)); UIComponent composeAlign = makeAlign(composeButton, true); Scroller phoneScroll = new Scroller(); phoneScroll.ResizeVertical.Value = false; phoneScroll.Add(new Binding <Vector2>(phoneScroll.Size, () => new Vector2(messageLayout.Size.Value.X, messageLayout.Size.Value.Y - messageLayout.Spacing.Value - composeAlign.ScaledSize.Value.Y), messageLayout.Size, messageLayout.Spacing, composeAlign.ScaledSize)); messageLayout.Children.Add(phoneScroll); messageLayout.Children.Add(composeAlign); ListContainer msgList = new ListContainer(); msgList.Spacing.Value = padding * 0.5f; msgList.Orientation.Value = ListContainer.ListOrientation.Vertical; msgList.ResizePerpendicular.Value = false; msgList.Size.Value = new Vector2(messageWidth, 0.0f); phoneScroll.Children.Add(msgList); Container answerContainer = new Container(); answerContainer.PaddingBottom.Value = answerContainer.PaddingLeft.Value = answerContainer.PaddingRight.Value = answerContainer.PaddingTop.Value = padding; answerContainer.Tint.Value = incomingColor; answerContainer.AnchorPoint.Value = new Vector2(1.0f, 1.0f); answerContainer.Add(new Binding <Vector2>(answerContainer.Position, () => composeAlign.GetAbsolutePosition() + new Vector2(composeAlign.ScaledSize.Value.X, 0), composeAlign.Position, composeAlign.ScaledSize)); phoneUi.Root.Children.Add(answerContainer); answerContainer.Visible.Value = false; ListContainer answerList = new ListContainer(); answerList.Orientation.Value = ListContainer.ListOrientation.Vertical; answerList.Alignment.Value = ListContainer.ListAlignment.Max; answerContainer.Children.Add(answerList); int selectedAnswer = 0; composeButton.Add(new CommandBinding(composeButton.MouseLeftUp, delegate() { answerContainer.Visible.Value = !answerContainer.Visible; if (answerContainer.Visible && main.GamePadConnected) { selectedAnswer = 0; foreach (UIComponent answer in answerList.Children) { answer.Highlighted.Value = false; } answerList.Children[0].Highlighted.Value = true; } })); tabs.Add(new Binding <bool>(tabs.EnableInput, () => !main.Paused && !answerContainer.Visible, answerContainer.Visible, main.Paused)); msgList.Add(new Binding <bool>(msgList.EnableInput, () => !main.Paused && !answerContainer.Visible, answerContainer.Visible, main.Paused)); answerContainer.Add(new Binding <bool>(answerContainer.EnableInput, x => !x, main.Paused)); composeButton.Add(new Binding <bool>(composeButton.EnableInput, x => !x, main.Paused)); Action scrollToBottom = delegate() { // HACK main.AddComponent(new Animation ( new Animation.Delay(0.01f), new Animation.Execute(delegate() { phoneScroll.ScrollToBottom(); }) )); }; // Note UIRenderer noteUi = entity.GetOrCreate <UIRenderer>("NoteUI"); const float noteWidth = 400.0f; noteUi.RenderTargetBackground.Value = new Microsoft.Xna.Framework.Color(0.8f, 0.75f, 0.7f); noteUi.RenderTargetSize.Value = new Point((int)noteWidth, (int)(noteWidth * 1.29f)); // 8.5x11 aspect ratio noteUi.Serialize = false; noteUi.Enabled.Value = false; Model noteModel = entity.GetOrCreate <Model>("Note"); noteModel.Filename.Value = "Models\\note"; noteModel.Add(new Binding <Microsoft.Xna.Framework.Graphics.RenderTarget2D>(noteModel.GetRenderTarget2DParameter("Diffuse" + Model.SamplerPostfix), noteUi.RenderTarget)); noteModel.Add(new Binding <Matrix>(noteModel.Transform, x => Matrix.CreateTranslation(-0.005f, 0.05f, 0.08f) * x, phoneModel.Transform)); noteModel.Serialize = false; noteModel.Enabled.Value = false; Container togglePhoneMessage = null; entity.Add(new NotifyBinding(delegate() { bool hasSignalTower = (player.SignalTower.Value.Target != null && player.SignalTower.Value.Target.Active && !string.IsNullOrEmpty(player.SignalTower.Value.Target.Get <SignalTower>().Initial)); if (hasSignalTower) { phone.Enabled.Value = true; } bool hasNoteOrSignalTower = (player.Note.Value.Target != null && player.Note.Value.Target.Active) || hasSignalTower; if (togglePhoneMessage == null && hasNoteOrSignalTower) { togglePhoneMessage = main.Menu.ShowMessage(entity, "[{{TogglePhone}}]"); } else if (togglePhoneMessage != null && !hasNoteOrSignalTower && !phoneActive && !noteActive) { main.Menu.HideMessage(entity, togglePhoneMessage); togglePhoneMessage = null; } }, player.Note, player.SignalTower)); entity.Add(new CommandBinding(entity.Delete, delegate() { main.Menu.HideMessage(null, togglePhoneMessage); })); // Note UI const float notePadding = 40.0f; ListContainer noteLayout = new ListContainer(); noteLayout.Spacing.Value = padding; noteLayout.Orientation.Value = ListContainer.ListOrientation.Vertical; noteLayout.Alignment.Value = ListContainer.ListAlignment.Min; noteLayout.Position.Value = new Vector2(notePadding, notePadding); noteLayout.Add(new Binding <Vector2, Point>(noteLayout.Size, x => new Vector2(x.X - notePadding * 2.0f, x.Y - notePadding * 2.0f), noteUi.RenderTargetSize)); noteUi.Root.Children.Add(noteLayout); Sprite noteUiImage = new Sprite(); noteLayout.Children.Add(noteUiImage); TextElement noteUiText = new TextElement(); noteUiText.FontFile.Value = main.MainFont; noteUiText.Tint.Value = new Microsoft.Xna.Framework.Color(0.1f, 0.1f, 0.1f); noteUiText.Add(new Binding <float, Vector2>(noteUiText.WrapWidth, x => x.X, noteLayout.Size)); noteLayout.Children.Add(noteUiText); // Toggle note Animation noteAnim = null; float startRotationY = 0; Action <bool> showNote = delegate(bool show) { model.Stop("Phone", "Note", "VRPhone", "VRNote"); Entity noteEntity = player.Note.Value.Target; noteActive.Value = show && noteEntity != null; Note note = noteEntity != null?noteEntity.Get <Note>() : null; if (noteActive) { input.EnableLook.Value = input.EnableMouse.Value = false; enableWalking.Value = false; noteModel.Enabled.Value = true; noteUi.Enabled.Value = true; noteLight.Enabled.Value = true; Session.Recorder.Event(main, "Note", note.Text); noteUiImage.Image.Value = note.Image; noteUiText.Text.Value = note.Text; string noteAnimation; #if VR if (main.VR) { noteAnimation = "VRNote"; } else #endif noteAnimation = "Note"; model.StartClip(noteAnimation, 6, true, AnimatedModel.DefaultBlendTime * 2.0f); AkSoundEngine.PostEvent(AK.EVENTS.PLAY_NOTE_PICKUP, entity); if (noteAnim != null && noteAnim.Active) { noteAnim.Delete.Execute(); } else { startRotationY = input.Mouse.Value.Y; } // Level the player's view noteAnim = new Animation ( new Animation.Ease ( new Animation.Custom(delegate(float x) { input.Mouse.Value = new Vector2(input.Mouse.Value.X, startRotationY * (1.0f - x)); }, 0.5f), Animation.Ease.EaseType.OutQuadratic ) ); entity.Add(noteAnim); } else { enableWalking.Value = true; if (note != null) { Session.Recorder.Event(main, "NoteEnd"); } AkSoundEngine.PostEvent(AK.EVENTS.PLAY_NOTE_DROP, entity); if (note != null && !note.IsCollected) { note.IsCollected.Value = true; } // Return the player's view if (noteAnim != null && noteAnim.Active) { noteAnim.Delete.Execute(); } noteAnim = new Animation ( new Animation.Ease ( new Animation.Custom(delegate(float x) { input.Mouse.Value = new Vector2(input.Mouse.Value.X, startRotationY * x); }, 0.5f), Animation.Ease.EaseType.OutQuadratic ), new Animation.Execute(delegate() { noteModel.Enabled.Value = false; noteUi.Enabled.Value = false; noteLight.Enabled.Value = false; input.EnableLook.Value = input.EnableMouse.Value = true; }) ); entity.Add(noteAnim); } }; // Toggle phone Animation phoneAnim = null; Action <bool> showPhone = delegate(bool show) { if (togglePhoneMessage != null) { main.Menu.HideMessage(entity, togglePhoneMessage); togglePhoneMessage = null; } if (show || (phone.Schedules.Length == 0 && !phone.WaitForAnswer)) { phoneActive.Value = show; answerContainer.Visible.Value = false; model.Stop("Phone", "Note", "VRPhone", "VRNote"); if (phoneActive) { phoneUi.IsMouseVisible.Value = true; enableWalking.Value = false; phoneModel.Enabled.Value = true; screen.Enabled.Value = true; phoneUi.Enabled.Value = true; phoneLight.Enabled.Value = true; input.EnableLook.Value = input.EnableMouse.Value = false; Session.Recorder.Event(main, "Phone"); phoneScroll.CheckLayout(); scrollToBottom(); string phoneAnimation; #if VR if (main.VR) { phoneAnimation = "VRPhone"; } else #endif phoneAnimation = "Phone"; model.StartClip(phoneAnimation, 6, true, AnimatedModel.DefaultBlendTime * 2.0f); // Level the player's view if (phoneAnim != null && phoneAnim.Active) { phoneAnim.Delete.Execute(); } else { startRotationY = input.Mouse.Value.Y; } phoneAnim = new Animation ( new Animation.Ease ( new Animation.Custom(delegate(float x) { input.Mouse.Value = new Vector2(input.Mouse.Value.X, startRotationY * (1.0f - x)); }, 0.5f), Animation.Ease.EaseType.OutQuadratic ) ); entity.Add(phoneAnim); } else { Session.Recorder.Event(main, "PhoneEnd"); enableWalking.Value = true; phoneUi.IsMouseVisible.Value = false; // Return the player's view if (phoneAnim != null && phoneAnim.Active) { phoneAnim.Delete.Execute(); } phoneAnim = new Animation ( new Animation.Ease ( new Animation.Custom(delegate(float x) { input.Mouse.Value = new Vector2(input.Mouse.Value.X, startRotationY * x); }, 0.5f), Animation.Ease.EaseType.OutQuadratic ), new Animation.Execute(delegate() { phoneModel.Enabled.Value = false; screen.Enabled.Value = false; phoneUi.Enabled.Value = false; phoneLight.Enabled.Value = false; input.EnableLook.Value = input.EnableMouse.Value = true; }) ); entity.Add(phoneAnim); } } }; input.Bind(main.Settings.TogglePhone, PCInput.InputState.Down, delegate() { // Special hack to prevent phone toggling when you're trying to open the Steam overlay if (main.Settings.TogglePhone.Value.Key == Keys.Tab && input.GetKey(Keys.LeftShift)) { return; } if (noteActive || phoneActive || phone.CanReceiveMessages) { if (!phoneActive && (noteActive || player.Note.Value.Target != null)) { showNote(!noteActive); } else if (phone.Enabled) { showPhone(!phoneActive); } } }); phone.Add(new CommandBinding(phone.Show, delegate() { phone.Enabled.Value = true; if (!phoneActive) { showPhone(true); } })); // Gamepad code for the phone input.Add(new CommandBinding(input.GetButtonUp(Buttons.A), () => phoneActive && composeButton.Visible, delegate() { if (answerContainer.Visible) { answerList.Children[selectedAnswer].MouseLeftUp.Execute(); } else { answerContainer.Visible.Value = true; } })); input.Add(new CommandBinding(input.GetButtonUp(Buttons.B), () => phoneActive && answerContainer.Visible, delegate() { answerContainer.Visible.Value = false; })); Action <int> scrollPhone = delegate(int delta) { if (answerContainer.Visible) { answerList.Children[selectedAnswer].Highlighted.Value = false; selectedAnswer += delta; while (selectedAnswer < 0) { selectedAnswer += answerList.Children.Length; } while (selectedAnswer > answerList.Children.Length - 1) { selectedAnswer -= answerList.Children.Length; } answerList.Children[selectedAnswer].Highlighted.Value = true; } else { phoneScroll.MouseScrolled.Execute(delta * -4); } }; Action switchMode = delegate() { Phone.Mode current = phone.CurrentMode; phone.CurrentMode.Value = current == Phone.Mode.Messages ? Phone.Mode.Photos : Phone.Mode.Messages; }; input.Add(new CommandBinding(input.GetButtonDown(Buttons.LeftThumbstickLeft), () => phoneActive && !answerContainer.Visible, switchMode)); input.Add(new CommandBinding(input.GetButtonDown(Buttons.LeftThumbstickRight), () => phoneActive && !answerContainer.Visible, switchMode)); input.Add(new CommandBinding(input.GetButtonDown(Buttons.DPadLeft), () => phoneActive && !answerContainer.Visible, switchMode)); input.Add(new CommandBinding(input.GetButtonDown(Buttons.DPadRight), () => phoneActive && !answerContainer.Visible, switchMode)); input.Add(new CommandBinding(input.GetButtonDown(Buttons.LeftThumbstickUp), () => phoneActive, delegate() { scrollPhone(-1); })); input.Add(new CommandBinding(input.GetButtonDown(Buttons.DPadUp), () => phoneActive, delegate() { scrollPhone(-1); })); input.Add(new CommandBinding(input.GetButtonDown(Buttons.LeftThumbstickDown), () => phoneActive, delegate() { scrollPhone(1); })); input.Add(new CommandBinding(input.GetButtonDown(Buttons.DPadDown), () => phoneActive, delegate() { scrollPhone(1); })); msgList.Add(new ListBinding <UIComponent, Phone.Message> ( msgList.Children, phone.Messages, delegate(Phone.Message msg) { return(makeAlign(makeButton(msg.Incoming ? incomingColor : outgoingColor, "\\" + msg.Name, messageWidth - padding * 2.0f), !msg.Incoming)); } )); Action <float, Container> animateMessage = delegate(float delay, Container msg) { msg.CheckLayout(); Vector2 originalSize = msg.Size; msg.Size.Value = new Vector2(0, originalSize.Y); entity.Add(new Animation ( new Animation.Delay(delay), new Animation.Ease(new Animation.Vector2MoveTo(msg.Size, originalSize, 0.5f), Animation.Ease.EaseType.OutExponential) )); }; Container typingIndicator = null; Action showTypingIndicator = delegate() { typingIndicator = makeAlign(makeButton(incomingColor, "\\...", messageWidth - padding * 2.0f), false); msgList.Children.Add(typingIndicator); animateMessage(0.2f, typingIndicator); }; if (phone.Schedules.Length > 0) { showTypingIndicator(); } answerList.Add(new ListBinding <UIComponent, Phone.Ans> ( answerList.Children, phone.ActiveAnswers, delegate(Phone.Ans answer) { UIComponent button = makeButton(outgoingColor, "\\" + answer.Name, messageWidth - padding * 4.0f); button.Add(new CommandBinding(button.MouseLeftUp, delegate() { if (!phone.WaitForAnswer) // If we're not waiting for an answer, the player must be initiating a conversation { // This is the start of a conversation // Disable the signal tower if we're in range Entity s = player.SignalTower.Value.Target; if (s != null) { s.Get <SignalTower>().Initial.Value = null; } } phone.Answer(answer); scrollToBottom(); if (phone.Schedules.Length == 0) // No more messages incoming { if (togglePhoneMessage == null) { togglePhoneMessage = main.Menu.ShowMessage(entity, "[{{TogglePhone}}]"); } } else { // More messages incoming showTypingIndicator(); } })); return(button); } )); Action refreshComposeButtonVisibility = delegate() { bool show = phone.ActiveAnswers.Length > 0 && phone.Schedules.Length == 0; answerContainer.Visible.Value &= show; composeButton.Visible.Value = show; selectedAnswer = 0; }; composeButton.Add(new ListNotifyBinding <Phone.Ans>(refreshComposeButtonVisibility, phone.ActiveAnswers)); composeButton.Add(new ListNotifyBinding <Phone.Schedule>(refreshComposeButtonVisibility, phone.Schedules)); refreshComposeButtonVisibility(); entity.Add(new CommandBinding(phone.MessageReceived, delegate() { if (typingIndicator != null) { typingIndicator.Delete.Execute(); typingIndicator = null; } if (phone.Schedules.Length > 0) { showTypingIndicator(); } float delay; if (phoneActive) { scrollToBottom(); delay = 0; } else { showPhone(true); delay = 0.5f; } // Animate the new message animateMessage(delay, (Container)msgList.Children[msgList.Children.Length - 1].Children[0]); AkSoundEngine.PostEvent(AK.EVENTS.PLAY_PHONE_VIBRATE, entity); if (togglePhoneMessage == null && phone.Schedules.Length == 0 && phone.ActiveAnswers.Length == 0) // No more messages incoming, and no more answers to give { togglePhoneMessage = main.Menu.ShowMessage(entity, "[{{TogglePhone}}]"); } })); if (noteActive) { showNote(true); } else if (phoneActive) { showPhone(true); } }
public override Entity Create(Main main) { Entity result = new Entity(main, "Editor"); result.Serialize = false; Editor editor = new Editor(); EditorUI ui = new EditorUI { Editable = false }; Model model = new Model { Editable = false, Filename = new Property<string> { Value = "Models\\selector" }, Scale = new Property<Vector3> { Value = new Vector3(0.5f) } }; UIRenderer uiRenderer = new UIRenderer { Editable = false }; FPSInput input = new FPSInput { Editable = false }; input.EnabledWhenPaused.Value = true; AudioListener audioListener = new AudioListener { Editable = false }; Scroller scroller = new Scroller(); scroller.Position.Value = new Vector2(10, 10); scroller.AnchorPoint.Value = new Vector2(0, 0); scroller.ResizeHorizontal.Value = true; scroller.Name.Value = "Scroller"; uiRenderer.Root.Children.Add(scroller); ListContainer uiList = new ListContainer(); uiList.Name.Value = "PropertyList"; uiList.AnchorPoint.Value = new Vector2(0, 0); scroller.Children.Add(uiList); Container popup = new Container(); popup.Name.Value = "Popup"; popup.Opacity.Value = 0.5f; popup.Tint.Value = Microsoft.Xna.Framework.Color.Black; uiRenderer.Root.Children.Add(popup); ListContainer popupLayout = new ListContainer(); popup.Children.Add(popupLayout); Container popupSearchContainer = new Container(); popupSearchContainer.Tint.Value = Microsoft.Xna.Framework.Color.Black; popupLayout.Children.Add(popupSearchContainer); TextElement popupSearch = new TextElement(); popupSearch.Name.Value = "PopupSearch"; popupSearch.FontFile.Value = "Font"; popupSearchContainer.Children.Add(popupSearch); Scroller popupScroller = new Scroller(); popupScroller.Size.Value = new Vector2(200.0f, 300.0f); popupLayout.Children.Add(popupScroller); ListContainer popupList = new ListContainer(); popupList.Name.Value = "PopupList"; popupScroller.Children.Add(popupList); result.Add("Editor", editor); result.Add("UI", ui); result.Add("UIRenderer", uiRenderer); result.Add("Model", model); result.Add("Input", input); result.Add("AudioListener", audioListener); result.Add("StartSpawnPoint", new Property<string>()); result.Add("ProceduralGenerator", new ProceduralGenerator()); return result; }
protected override void LoadContent() { if (this.firstLoadContentCall) { // First time loading content. Create the renderer. this.LightingManager = new LightingManager(); this.AddComponent(this.LightingManager); this.Renderer = new Renderer(this, this.ScreenSize, true, true, false); this.AddComponent(this.Renderer); this.renderParameters = new RenderParameters { Camera = this.Camera, IsMainRender = true }; this.firstLoadContentCall = false; this.UI = new UIRenderer(); this.AddComponent(this.UI); #if PERFORMANCE_MONITOR ListContainer performanceMonitor = new ListContainer(); performanceMonitor.Add(new Binding<Vector2, Point>(performanceMonitor.Position, x => new Vector2(0, x.Y), this.ScreenSize)); performanceMonitor.AnchorPoint.Value = new Vector2(0, 1); performanceMonitor.Visible.Value = false; performanceMonitor.Name.Value = "PerformanceMonitor"; this.UI.Root.Children.Add(performanceMonitor); Action<string, Property<double>> addLabel = delegate(string label, Property<double> property) { TextElement text = new TextElement(); text.FontFile.Value = "Font"; text.Add(new Binding<string, double>(text.Text, x => label + ": " + (x * 1000.0).ToString("F") + "ms", property)); performanceMonitor.Children.Add(text); }; TextElement frameRateText = new TextElement(); frameRateText.FontFile.Value = "Font"; frameRateText.Add(new Binding<string, float>(frameRateText.Text, x => "FPS: " + x.ToString("0"), this.frameRate)); performanceMonitor.Children.Add(frameRateText); addLabel("Physics", this.physicsTime); addLabel("Update", this.updateTime); addLabel("Pre-frame", this.preframeTime); addLabel("Raw render", this.rawRenderTime); addLabel("Shadow render", this.shadowRenderTime); addLabel("Post-process", this.postProcessTime); PCInput input = new PCInput(); input.Add(new CommandBinding(input.GetChord(new PCInput.Chord { Modifier = Keys.LeftAlt, Key = Keys.P }), delegate() { performanceMonitor.Visible.Value = !performanceMonitor.Visible; })); this.AddComponent(input); #endif IEnumerable<string> globalStaticScripts = Directory.GetFiles(Path.Combine(this.Content.RootDirectory, "Maps", "GlobalStaticScripts"), "*", SearchOption.AllDirectories).Select(x => Path.Combine("Maps", "GlobalStaticScripts", Path.GetFileNameWithoutExtension(x))); foreach (string scriptName in globalStaticScripts) this.executeStaticScript(scriptName); } else { foreach (IComponent c in this.components) c.LoadContent(true); this.ReloadedContent.Execute(); } }
public static void Attach(Main main, UIRenderer ui, Property<float> health) { Sprite damageOverlay = new Sprite(); damageOverlay.Image.Value = "Images\\damage"; damageOverlay.AnchorPoint.Value = new Vector2(0.5f); ui.Root.Children.Add(damageOverlay); // Center the damage overlay and scale it to fit the screen damageOverlay.Add(new Binding<Vector2, Point>(damageOverlay.Position, x => new Vector2(x.X * 0.5f, x.Y * 0.5f), main.ScreenSize)); damageOverlay.Add(new Binding<Vector2>(damageOverlay.Scale, () => new Vector2(main.ScreenSize.Value.X / damageOverlay.Size.Value.X, main.ScreenSize.Value.Y / damageOverlay.Size.Value.Y), main.ScreenSize, damageOverlay.Size)); damageOverlay.Add(new Binding<float, float>(damageOverlay.Opacity, x => 1.0f - x, health)); UIComponent targets = new UIComponent(); ui.Root.Children.Add(targets); const string targetOnScreen = "Images\\target"; const string targetOffScreen = "Images\\target-pointer"; ui.Add(new ListBinding<UIComponent, Transform>(targets.Children, TargetFactory.Positions, delegate(Transform target) { Sprite sprite = new Sprite(); sprite.Image.Value = "Images\\target"; sprite.Opacity.Value = 0.5f; sprite.AnchorPoint.Value = new Vector2(0.5f, 0.5f); sprite.Add(new Binding<bool>(sprite.Visible, target.Enabled)); sprite.Add(new Binding<Vector2>(sprite.Position, delegate() { Vector3 pos = target.Position.Value; Vector4 projectionSpace = Vector4.Transform(new Vector4(pos.X, pos.Y, pos.Z, 1.0f), main.Camera.ViewProjection); float originalDepth = projectionSpace.Z; projectionSpace /= projectionSpace.W; Point screenSize = main.ScreenSize; Vector2 screenCenter = new Vector2(screenSize.X * 0.5f, screenSize.Y * 0.5f); Vector2 offset = new Vector2(projectionSpace.X * (float)screenSize.X * 0.5f, -projectionSpace.Y * (float)screenSize.Y * 0.5f); float radius = Math.Min(screenSize.X, screenSize.Y) * 0.95f * 0.5f; float offsetLength = offset.Length(); Vector2 normalizedOffset = offset / offsetLength; bool offscreen = offsetLength > radius; bool behind = originalDepth < main.Camera.NearPlaneDistance; string img = offscreen || behind ? targetOffScreen : targetOnScreen; if (sprite.Image.Value != img) sprite.Image.Value = img; if (behind) normalizedOffset *= -1.0f; if (offscreen || behind) sprite.Rotation.Value = -(float)Math.Atan2(normalizedOffset.Y, -normalizedOffset.X) - (float)Math.PI * 0.5f; else sprite.Rotation.Value = 0.0f; if (behind || offscreen) offset = normalizedOffset * radius; return screenCenter + offset; }, target.Position, main.Camera.ViewProjection, main.ScreenSize)); return sprite; })); }
public static void Attach(Main main, Entity entity, UIRenderer ui, Property<float> health, Property<float> rotation, Property<bool> noteActive, Property<bool> phoneActive, Property<Vector3> linearVelocity, Property<bool> enableDebugVelocity) { Sprite damageOverlay = new Sprite(); damageOverlay.Image.Value = "Images\\damage"; damageOverlay.AnchorPoint.Value = new Vector2(0.5f); ui.Root.Children.Add(damageOverlay); // Center the damage overlay and scale it to fit the screen damageOverlay.Add(new Binding<Vector2, Point>(damageOverlay.Position, x => new Vector2(x.X * 0.5f, x.Y * 0.5f), main.ScreenSize)); damageOverlay.Add(new Binding<Vector2>(damageOverlay.Scale, () => new Vector2(main.ScreenSize.Value.X / damageOverlay.Size.Value.X, main.ScreenSize.Value.Y / damageOverlay.Size.Value.Y), main.ScreenSize, damageOverlay.Size)); damageOverlay.Add(new Binding<float, float>(damageOverlay.Opacity, x => 1.0f - x, health)); Container debugVelocityContainer = main.UIFactory.CreateContainer(); debugVelocityContainer.Opacity.Value = UIFactory.Opacity; debugVelocityContainer.AnchorPoint.Value = new Vector2(1.0f, 0.0f); bool vr = false; #if VR vr = main.VR; #endif debugVelocityContainer.Add(new Binding<Vector2, Point>(debugVelocityContainer.Position, x => new Vector2(x.X * 0.9f, x.Y * (vr ? 0.7f : 0.9f)), main.ScreenSize)); debugVelocityContainer.Add(new Binding<bool>(debugVelocityContainer.Visible, enableDebugVelocity)); ui.Root.Children.Add(debugVelocityContainer); ListContainer debugVelocityList = new ListContainer(); debugVelocityList.Orientation.Value = ListContainer.ListOrientation.Vertical; debugVelocityContainer.Children.Add(debugVelocityList); TextElement debugVelocity = main.UIFactory.CreateLabel(); debugVelocity.Add(new Binding<string, Vector3>(debugVelocity.Text, x => Math.Abs(x.Y).ToString("00.00"), linearVelocity)); debugVelocityList.Children.Add(debugVelocity); TextElement debugHorizontalVelocity = main.UIFactory.CreateLabel(); debugHorizontalVelocity.Add(new Binding<string, Vector3>(debugHorizontalVelocity.Text, x => { x.Y = 0.0f; return x.Length().ToString("00.00"); }, linearVelocity)); debugVelocityList.Children.Add(debugHorizontalVelocity); #if VR if (main.VR) { VirtualReticle reticleController = entity.GetOrCreate<VirtualReticle>(); reticleController.Add(new Binding<float>(reticleController.Rotation, rotation)); ModelNonPostProcessed reticle = entity.Create<ModelNonPostProcessed>(); reticle.Filename.Value = "Models\\plane"; reticle.EffectFile.Value = "Effects\\VirtualUI"; reticle.DiffuseTexture.Value = "Images\\reticle"; reticle.Add(new Binding<Matrix>(reticle.Transform, reticleController.Transform)); reticle.Add(new Binding<bool>(reticle.Enabled, () => !main.Paused && !phoneActive && !noteActive && main.Settings.EnableReticleVR, main.Paused, phoneActive, noteActive, main.Settings.EnableReticleVR)); } else #endif { Sprite reticle = new Sprite(); reticle.Image.Value = "Images\\reticle"; reticle.AnchorPoint.Value = new Vector2(0.5f); reticle.Opacity.Value = 0.5f; ui.Root.Children.Add(reticle); reticle.Add(new Binding<bool>(reticle.Visible, main.Settings.EnableReticle)); // Center the reticle reticle.Add(new Binding<Vector2, Point>(reticle.Position, x => new Vector2(x.X * 0.5f, x.Y * 0.5f), main.ScreenSize)); } UIComponent targets = new UIComponent(); ui.Root.Children.Add(targets); TargetUI targetUi = entity.GetOrCreate<TargetUI>(); targetUi.Add(new ListBinding<UIComponent>(targetUi.Sprites, targets.Children)); targets.Add(new ListBinding<UIComponent, Transform>(targets.Children, TargetFactory.Positions, delegate(Transform target) { Sprite sprite = new Sprite(); sprite.Image.Value = "Images\\target"; sprite.AnchorPoint.Value = new Vector2(0.5f, 0.5f); sprite.UserData.Value = target; sprite.Add(new Binding<bool>(sprite.Visible, () => target.Enabled && main.Settings.EnableWaypoints, target.Enabled, main.Settings.EnableWaypoints)); return sprite; })); }
protected override void LoadContent() { if (this.firstLoadContentCall) { // Initialize Wwise AkGlobalSoundEngineInitializer initializer = new AkGlobalSoundEngineInitializer(Path.Combine(this.Content.RootDirectory, "Wwise")); this.AddComponent(initializer); this.Listener = new AkListener(); this.Listener.Add(new Binding<Vector3>(this.Listener.Position, this.Camera.Position)); this.Listener.Add(new Binding<Vector3>(this.Listener.Forward, this.Camera.Forward)); this.Listener.Add(new Binding<Vector3>(this.Listener.Up, this.Camera.Up)); this.AddComponent(this.Listener); // Create the renderer. this.LightingManager = new LightingManager(); this.AddComponent(this.LightingManager); this.Renderer = new Renderer(this, this.ScreenSize, true, true, true, true); this.AddComponent(this.Renderer); this.renderParameters = new RenderParameters { Camera = this.Camera, IsMainRender = true }; this.firstLoadContentCall = false; this.UI = new UIRenderer(); this.AddComponent(this.UI); GeeUI.GeeUI.Initialize(this); this.ConsoleUI = new ConsoleUI(); this.AddComponent(ConsoleUI); this.Console = new Console.Console(); this.AddComponent(Console); PCInput input = new PCInput(); this.AddComponent(input); #if DEVELOPMENT input.Add(new CommandBinding(input.GetChord(new PCInput.Chord { Modifier = Keys.LeftAlt, Key = Keys.S }), delegate() { // High-resolution screenshot Screenshot s = new Screenshot(); this.AddComponent(s); s.Take(new Point(4096, 2304), delegate() { string desktop = Environment.GetFolderPath(Environment.SpecialFolder.Desktop); string path; int i = 0; do { path = Path.Combine(desktop, "lemma-screen" + i.ToString() + ".png"); i++; } while (File.Exists(path)); using (Stream stream = File.OpenWrite(path)) s.Buffer.SaveAsPng(stream, s.Size.X, s.Size.Y); s.Delete.Execute(); }); })); #endif #if PERFORMANCE_MONITOR this.performanceMonitor = new ListContainer(); this.performanceMonitor.Add(new Binding<Vector2, Point>(performanceMonitor.Position, x => new Vector2(0, x.Y), this.ScreenSize)); this.performanceMonitor.AnchorPoint.Value = new Vector2(0, 1); this.performanceMonitor.Visible.Value = false; this.performanceMonitor.Name.Value = "PerformanceMonitor"; this.UI.Root.Children.Add(this.performanceMonitor); Action<string, Property<double>> addTimer = delegate(string label, Property<double> property) { TextElement text = new TextElement(); text.FontFile.Value = "Font"; text.Add(new Binding<string, double>(text.Text, x => label + ": " + (x * 1000.0).ToString("F") + "ms", property)); this.performanceMonitor.Children.Add(text); }; Action<string, Property<int>> addCounter = delegate(string label, Property<int> property) { TextElement text = new TextElement(); text.FontFile.Value = "Font"; text.Add(new Binding<string, int>(text.Text, x => label + ": " + x.ToString(), property)); this.performanceMonitor.Children.Add(text); }; TextElement frameRateText = new TextElement(); frameRateText.FontFile.Value = "Font"; frameRateText.Add(new Binding<string, float>(frameRateText.Text, x => "FPS: " + x.ToString("0"), this.frameRate)); this.performanceMonitor.Children.Add(frameRateText); addTimer("Physics", this.physicsTime); addTimer("Update", this.updateTime); addTimer("Pre-frame", this.preframeTime); addTimer("Raw render", this.rawRenderTime); addTimer("Shadow render", this.shadowRenderTime); addTimer("Post-process", this.postProcessTime); addTimer("Non-post-processed", this.unPostProcessedTime); addCounter("Draw calls", this.drawCalls); addCounter("Triangles", this.triangles); input.Add(new CommandBinding(input.GetChord(new PCInput.Chord { Modifier = Keys.LeftAlt, Key = Keys.P }), delegate() { this.performanceMonitor.Visible.Value = !this.performanceMonitor.Visible; })); #endif try { IEnumerable<string> globalStaticScripts = Directory.GetFiles(Path.Combine(this.Content.RootDirectory, "GlobalStaticScripts"), "*", SearchOption.AllDirectories).Select(x => Path.Combine("..\\GlobalStaticScripts", Path.GetFileNameWithoutExtension(x))); foreach (string scriptName in globalStaticScripts) this.executeStaticScript(scriptName); } catch (IOException) { } } else { foreach (IDrawableComponent c in this.drawables) c.LoadContent(true); foreach (IDrawableAlphaComponent c in this.alphaDrawables) c.LoadContent(true); foreach (IDrawablePostAlphaComponent c in this.postAlphaDrawables) c.LoadContent(true); foreach (IDrawablePreFrameComponent c in this.preframeDrawables) c.LoadContent(true); foreach (INonPostProcessedDrawableComponent c in this.nonPostProcessedDrawables) c.LoadContent(true); this.ReloadedContent.Execute(); } this.GraphicsDevice.RasterizerState = new RasterizerState { MultiSampleAntiAlias = false }; }