Пример #1
0
		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);
		}
Пример #2
0
 public RootUIComponent(UIRenderer renderer)
 {
     this.renderer = renderer;
 }
Пример #3
0
        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);
            }
        }
Пример #4
0
        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;
        }
Пример #5
0
 public RootUIComponent(UIRenderer renderer)
 {
     this.renderer = renderer;
 }
Пример #6
0
        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();
            }
        }
Пример #7
0
		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;
			}));
		}
Пример #8
0
		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;
			}));
		}
Пример #9
0
		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 };
		}