From 464e1d8c316a386472f0ddb23275a3256ea492d0 Mon Sep 17 00:00:00 2001 From: JappaWakka Date: Sat, 9 Oct 2021 23:05:56 +0200 Subject: [PATCH] Implemented Notification system --- P3D/Content/Localization/Tokens_en.dat | 9 + .../Textures/Notifications/Backgrounds.png | Bin 0 -> 1780 bytes P3D/Content/Textures/Notifications/Boxes.png | Bin 0 -> 640 bytes P3D/Overworld/NotificationPopup.vb | 176 ++++++++++++++++++ P3D/Overworld/OverworldScreen.vb | 48 ++++- P3D/P3D.vbproj | 12 +- .../ActionScript/V2/ScriptCommands/DoText.vb | 26 +++ P3D/World/Level.vb | 9 + 8 files changed, 269 insertions(+), 11 deletions(-) create mode 100644 P3D/Content/Textures/Notifications/Backgrounds.png create mode 100644 P3D/Content/Textures/Notifications/Boxes.png create mode 100644 P3D/Overworld/NotificationPopup.vb diff --git a/P3D/Content/Localization/Tokens_en.dat b/P3D/Content/Localization/Tokens_en.dat index 443a15c48..013b0e9d5 100644 --- a/P3D/Content/Localization/Tokens_en.dat +++ b/P3D/Content/Localization/Tokens_en.dat @@ -90,6 +90,15 @@ Special_Attack,Special Attack Special_Defense,Special Defense Speed,Speed --- +GameInteractions: +game_interaction_interact,Interact +game_interaction_gamemenu,Game Menu +game_interaction_pokegear,Pokégear +game_interaction_pausemenu,Pause Menu +game_interaction_notification,Notification +game_notification_respond,Press to respond to the notification. +game_notification_dismiss,Press to dismiss the notification. +--- MainMenuScreen: main_menu_continue,Continue main_menu_load_game,Load Game diff --git a/P3D/Content/Textures/Notifications/Backgrounds.png b/P3D/Content/Textures/Notifications/Backgrounds.png new file mode 100644 index 0000000000000000000000000000000000000000..eaf06854b2d77ba5ac000d23f83a3abe14597e17 GIT binary patch literal 1780 zcmcIh`8ON*7XKzh>@VSY#*gy~Sv zQk2dVMNKWSwYn2!sC}uSwI-O%5A!F?J?C>j_ug|qpL5T-EC;)bGLqj*0sv%4M8YK@ zvxV>$7Zc`;EDh9W7)OED1Rz*$3jlpTdu=CT; zqMNT>k6Z}axtZwIzR|1~l708l%aqM#o(9v4N5$+Jsz!%xDzIc7|tSh z?GJMUF@kRO@X=U%HN^@4&pmGjjwkxxydNjs@#h|M{N2Xc{Z;&XFUq4;L)7HtJSt1@ zbz&Zpd9m^7`)p3e{%o;suxQ8u9I&#r8+(`!H#eEeiGpEt=G3BW#+*;Tuqd077+E0g z>nNv&O{Tl^NkqJn8uLDFB9;&_3@ho(o!>byJ7O#JM>=k`&N_r@U#-kptgFnK(Xqp4 zxOM%I{tN1qTJ9|@#j>PLEE>f!aPU*lOR-NVNc|dvAQh(e8V8))n?Xkm$0YI*w+a~q zBoY;W1c@BsZIfF1ld5>v7kdv^o}T$B)Z--0)uDGR#HF(-f71D~ zbErLxcqw40>16G_R0S7Gvv)XZxv{GPzqT0b;i$1LSbP2JqlL2Z($e%_)+Q5-wQAlK ziuB?7#!Vh9A^QlXf#KSf?H;J*o~)~1R^&a88)ligxCB*O2`=Z0zqgXM-Yp*?x4$xa z*O{4prVm~IVw2NNzjDQCnV>U_B$cjV8;%V4dj) zX?}-k6mDFfY0>x5jZp%uV{b6Ba%m^!|DWYEEjIbIkD1}4GD~iX5a)uF;0T2pZeXus z2Jr#crT(RRZncpdHS(k6%2)L3@<5u6mvSkg$;^&>zq{9wBymb|zbeP3ap^-Tbg(5S z^jy}r{RDG<`fYCN-oBab33>VK$GQzU>)~)Z^u*S)m5G|ppLZ8B`nLJ;OOcq-;+x&c zm=f8|Skrq${v=euv5y*yK2h?+F?Ro5_P#&ZxHhh5;vMi*eniiiAWS&*-{-zA*@E0%J13>MU<8D-YQ^qVhJKm?12HbON^^JM1%;_S#rRPVu zE@wofKwbyC#Fwi+?wC>y@@wlW>U*+WA=82%4T~LrR@8;*y`>2ZDW|J?A=5qNHdqYz%LVz$x LmUe_XoOkkHUzZS$ literal 0 HcmV?d00001 diff --git a/P3D/Content/Textures/Notifications/Boxes.png b/P3D/Content/Textures/Notifications/Boxes.png new file mode 100644 index 0000000000000000000000000000000000000000..82a4639dea937e267825e7d906c8579e6a4b1f2c GIT binary patch literal 640 zcmeAS@N?(olHy`uVBq!ia0vp^2|(trD;1#J|k}2fb!}TrFhuYf-~ez`FB68JNx2KIfHGD;Kob!T?^Xvzg|;|e``OxUV7h&t19*N*8AONFhuaiE4MJL zXitXxXZsm8oMBgBnV?XAy>7?n zXZ%3#BY*~r1Fw3d9YO%enjr3QSI5xi|KDZ&46aOH>@zlc<-5MP)^zr#{MznF23wWY zOY_e8vn^;(nf8CjOZ(aT<>&sd;M=b9>TLLjpO>qQt^Suzu-8o6$)X+76BT85^~jl@ zQ;LoC85lH@Wp{;Ma+JBgpQ%Br&VIs`ncelm@7O0k=CUZ!w*M(nwKK-2dG#u;I-Wby z@e?1{)fqBW{Rj=6+4Aad@gG&I>*w|P4rKk1Qe?RxQE#7k$4^h}z$$rp?g^{r$E!3v zt!GYV2>SM!5ydZ9I1Nh}&Ry&}0doJ=E583%)cxBXZv3mxsqp9;k%y{ZKX)^E7_zMD o)MuEsqf6_#o}}Ve(Fb#i|Eq7(du#StfEi?>r>mdKI;Vst0NynEa{vGU literal 0 HcmV?d00001 diff --git a/P3D/Overworld/NotificationPopup.vb b/P3D/Overworld/NotificationPopup.vb new file mode 100644 index 000000000..889cad02b --- /dev/null +++ b/P3D/Overworld/NotificationPopup.vb @@ -0,0 +1,176 @@ +''' +''' The notification popup. +''' +Public Class NotificationPopup + + Private _background As Texture2D + Private _box As Texture2D + Private _icon As Texture2D + Private FrameSizeBack As Integer + Private FramesizeBox As Integer + Private FramesizeIcon As Integer + Private _positionY As Single = -12 + Private _delay As Date + Private _soundEffect As String = "" + Private _text As String = "" + Private _size As Size = New Size(10, 3) + Private _backgroundIndex As Vector2 = New Vector2(0, 0) + Private _iconIndex As Vector2 = New Vector2(0, 0) + + Public _waitForInput As Boolean = False + Public _scriptFile As String = "" + + Public _show As Boolean = False + + ''' + ''' Sets the values of the NotificationPopup and displays it on the screen. + ''' + Public Sub Setup(Text As String, Optional Delay As Integer = 500, Optional BackgroundIndex As Integer = 0, Optional IconIndex As Integer = 0, Optional SoundEffect As String = "", Optional ScriptFile As String = "") + _text = Text + + If Delay <= 0 Then + _waitForInput = True + _delay = Date.Now + Else + _delay = Date.Now.AddMilliseconds(CDbl(Delay * 10)) + End If + + _backgroundIndex = New Vector2(BackgroundIndex, 0) + While _backgroundIndex.X >= 3 + _backgroundIndex.X -= 3 + _backgroundIndex.Y += 1 + End While + If _backgroundIndex.X < 0 Then + _backgroundIndex.X = 0 + End If + FrameSizeBack = CInt(TextureManager.GetTexture(GameModeManager.ActiveGameMode.ContentPath & "Textures\Notifications\Backgrounds").Width / 3) + _background = TextureManager.GetTexture(GameModeManager.ActiveGameMode.ContentPath & "Textures\Notifications\Backgrounds", New Rectangle(CInt(_backgroundIndex.X * FrameSizeBack), CInt(_backgroundIndex.Y * FrameSizeBack), FrameSizeBack, FrameSizeBack)) + + _positionY = CInt(0 - _size.Height * (FrameSizeBack / 3) - 12) + + FramesizeBox = CInt(TextureManager.GetTexture(GameModeManager.ActiveGameMode.ContentPath & "Textures\Notifications\Boxes").Width / 3) + _box = TextureManager.GetTexture(GameModeManager.ActiveGameMode.ContentPath & "Textures\Notifications\Backgrounds", New Rectangle(CInt(_backgroundIndex.X * FramesizeBox), CInt(_backgroundIndex.Y * FramesizeBox), FramesizeBox, FramesizeBox)) + + FramesizeIcon = CInt(TextureManager.GetTexture(GameModeManager.ActiveGameMode.ContentPath & "Textures\Notifications\Icons").Width / 3) + _iconIndex = New Vector2(IconIndex, 0) + While _iconIndex.X >= 3 + _iconIndex.X -= 3 + _iconIndex.Y += 1 + End While + If _iconIndex.X < 0 Then + _iconIndex.X = 0 + End If + _icon = TextureManager.GetTexture(GameModeManager.ActiveGameMode.ContentPath & "Textures\Notifications\Icons", New Rectangle(CInt(_iconIndex.X * FramesizeIcon), CInt(_iconIndex.Y * FramesizeIcon), FramesizeIcon, FramesizeIcon)) + + _scriptFile = ScriptFile + + If Me._scriptFile <> "" Then + Me._text &= "~[" & Localization.GetString("game_notification_respond") & "]" + Else + Me._text &= "~[" & Localization.GetString("game_notification_dismiss") & "]" + End If + + _soundEffect = SoundEffect + _show = True + End Sub + + ''' + ''' Execute the specified script + ''' + Public Sub Accept() + CType(Core.CurrentScreen, OverworldScreen).ActionScript.StartScript(_scriptFile, 0, False) + Me._waitForInput = False + Me._delay = Date.Now + End Sub + + ''' + ''' Dismiss the Popup + ''' + Public Sub Dismiss() + Me._waitForInput = False + Me._delay = Date.Now + End Sub + + ''' + ''' Update the NotificationPopup. + ''' + Public Sub Update() + If Date.Now < Me._delay Then + If Me._positionY < 5.0F Then + Me._positionY += CInt(0.7 * (FrameSizeBack / _size.Height)) + Else + If _soundEffect IsNot "" Then + SoundManager.PlaySound("Notifications\" & _soundEffect) + _soundEffect = "" + End If + End If + Else + If _waitForInput = False Then + Dim BackY As Integer = CInt(0 - _size.Height * FrameSizeBack - 12) + If Me._positionY > BackY Then + Me._positionY -= CInt(0.7 * (FrameSizeBack / _size.Height)) + If Me._positionY <= BackY Then + Me._positionY = BackY + Me._show = False + End If + End If + Else + If Me._scriptFile <> "" Then + CType(Core.CurrentScreen, OverworldScreen).ActionScript.StartScript(Me._scriptFile, 0, False) + Me._waitForInput = False + End If + End If + End If + End Sub + + ''' + ''' Renders the NotificationPopup. + ''' + Public Sub Draw() + If Me._show = True Then + Dim TextBody As String = "" + Dim TextHeader As String + Dim Scale As Double = SpriteBatch.InterfaceScale() * 2 + + If _text.Contains("*") Then + TextHeader = _text.GetSplit(0, "*").Replace(CChar("~"), Environment.NewLine) + TextBody = _text.GetSplit(1, "*").Replace(CChar("~"), Environment.NewLine) + Else + TextHeader = _text.Replace(CChar("~"), Environment.NewLine) + End If + + While FontManager.InGameFont.MeasureString(_text.Replace(CChar("~"), Environment.NewLine)).Y > CInt(_size.Height * FrameSizeBack - 2 * FrameSizeBack) + _size.Height += 1 + End While + + Dim BackGroundOffsetX As Integer = CInt(Core.windowSize.Width - _size.Width * FrameSizeBack - 5) + Dim TextOffset As Integer + + 'Draw the frame. + Canvas.DrawImageBorder(_background, CInt(Scale), New Rectangle(BackGroundOffsetX, CInt(Me._positionY), CInt(_size.Width * FrameSizeBack), CInt(_size.Height * FrameSizeBack)), True) + + 'Draw the (icon) box. + Core.SpriteBatch.DrawInterface(_box, New Rectangle(CInt(FramesizeBox * Scale + 5), CInt(FramesizeBox * Scale + Me._positionY), CInt(_box.Width * Scale), CInt(_box.Height * Scale)), Color.White) + + 'Draw the icon. + Core.SpriteBatch.DrawInterface(_icon, New Rectangle(CInt(FramesizeIcon * Scale + 5), CInt(FramesizeIcon * Scale + Me._positionY), CInt(_icon.Width * Scale), CInt(_icon.Height * Scale)), Color.White) + + TextOffset = CInt(FrameSizeBack * Scale + BackGroundOffsetX * Scale) + + If TextBody <> "" Then + If TextHeader <> "" Then + 'Draw the header, then the body + Core.SpriteBatch.DrawInterfaceString(FontManager.InGameFont, TextBody.CropStringToWidth(FontManager.InGameFont, CInt(Scale), CInt(_size.Width * FrameSizeBack - FrameSizeBack * 4)), New Vector2(TextOffset, CInt(Me._positionY + FrameSizeBack)), Color.Black) + Core.SpriteBatch.DrawInterfaceString(FontManager.InGameFont, TextHeader.CropStringToWidth(FontManager.InGameFont, CInt(Scale / 2), CInt(_size.Width * FrameSizeBack - FrameSizeBack * 4)), New Vector2(TextOffset, CInt(Me._positionY + FrameSizeBack + FontManager.InGameFont.MeasureString(TextHeader).Y)), Color.Black) + Else + 'Just draw the body + Core.SpriteBatch.DrawInterfaceString(FontManager.InGameFont, TextBody.CropStringToWidth(FontManager.InGameFont, CInt(Scale / 2), CInt(_size.Width * FrameSizeBack - FrameSizeBack * 4)), New Vector2(TextOffset, CInt(Me._positionY + FrameSizeBack)), Color.Black) + End If + Else + 'Just draw the header + Core.SpriteBatch.DrawInterfaceString(FontManager.InGameFont, TextHeader.CropStringToWidth(FontManager.InGameFont, CInt(Scale), CInt(_size.Width * FrameSizeBack) - FrameSizeBack * 4), New Vector2(TextOffset, CInt(Me._positionY + FrameSizeBack)), Color.Black) + End If + End If + End Sub + +End Class \ No newline at end of file diff --git a/P3D/Overworld/OverworldScreen.vb b/P3D/Overworld/OverworldScreen.vb index 191cee38e..931ac8a86 100644 --- a/P3D/Overworld/OverworldScreen.vb +++ b/P3D/Overworld/OverworldScreen.vb @@ -12,6 +12,7 @@ Public Class OverworldScreen Private Shared _fadeColor As Color = Color.Black 'Fade screen color. Private Shared _fadeValue As Integer = 0 'Fade progress value for the screen fade. Private Shared _drawRodID As Integer = -1 'The rod ID to display on the screen during the fishing animation. + Public NotificationPopupList As List(Of NotificationPopup) = Nothing Private _actionScript As ActionScript 'Private ActionScript instance. Private _particlesTexture As Texture2D 'A texture field to contain the particles texture, currently only used for the crosshair. @@ -188,6 +189,16 @@ Public Class OverworldScreen PokemonImageView.Update() End If + If Level.NotificationPopup IsNot Nothing Then + Level.NotificationPopup.Update() + If Level.NotificationPopup._show = False Then + Level.NotificationPopup = Nothing + End If + ElseIf NotificationPopupList.Count > 0 Then + Level.NotificationPopup = NotificationPopupList(0) + NotificationPopupList.RemoveAt(0) + End If + 'Middle click/Thumbstick press: Show first Pokémon in party. If ActionScript.IsReady = True Then If MouseHandler.ButtonPressed(MouseHandler.MouseButtons.MiddleButton) = True Or ControllerHandler.ButtonPressed(Buttons.LeftStick) = True Then @@ -217,7 +228,6 @@ Public Class OverworldScreen If KeyBoardHandler.KeyPressed(KeyBindings.OpenInventoryKey) = True Or ControllerHandler.ButtonPressed(Buttons.X) = True Then If Screen.Camera.IsMoving() = False And ActionScript.IsReady = True Then Level.RouteSign.Hide() - SoundManager.PlaySound("menu_open") Core.SetScreen(New NewMenuScreen(Me)) End If @@ -225,13 +235,20 @@ Public Class OverworldScreen 'Open the PokégearScreen: If KeyBoardHandler.KeyPressed(KeyBindings.SpecialKey) = True Or ControllerHandler.ButtonPressed(Buttons.Y) = True Then - If Core.Player.HasPokegear = True Or GameController.IS_DEBUG_ACTIVE = True Or Core.Player.SandBoxMode = True Then - If Screen.Camera.IsMoving() = False And ActionScript.IsReady = True Then - Core.SetScreen(New GameJolt.PokegearScreen(Me, GameJolt.PokegearScreen.EntryModes.MainMenu, {})) + If Level.NotificationPopup Is Nothing Then + If Core.Player.HasPokegear = True Or GameController.IS_DEBUG_ACTIVE = True Or Core.Player.SandBoxMode = True Then + If Screen.Camera.IsMoving() = False And ActionScript.IsReady = True Then + Core.SetScreen(New GameJolt.PokegearScreen(Me, GameJolt.PokegearScreen.EntryModes.MainMenu, {})) + End If + End If + Else + If Level.NotificationPopup._scriptFile <> "" Then + Level.NotificationPopup.Accept() + Else + Level.NotificationPopup.Dismiss() End If End If End If - ActionScript.Update() 'Update the action script. Else 'Dialogues are showing: 'Update some parts of the camera: @@ -342,17 +359,28 @@ Public Class OverworldScreen Level.RouteSign.Draw() + If Level.NotificationPopup IsNot Nothing Then + Level.NotificationPopup.Draw() + End If + 'If the XBOX render control delay is 0, render the controls. If ShowControlsDelay = 0.0F Then Dim d As New Dictionary(Of Buttons, String) - d.Add(Buttons.A, "Interact") - d.Add(Buttons.X, "Menu") - If Core.Player.HasPokegear = True Then - d.Add(Buttons.Y, "Pokégear") + If Level.NotificationPopup IsNot Nothing Then + If Level.NotificationPopup._scriptFile <> "" Then + d.Add(Buttons.A, Localization.GetString("game_interaction_notification", "Notification")) + Else + End If + Else + d.Add(Buttons.A, Localization.GetString("game_interaction_interact", "Interact")) End If - d.Add(Buttons.Start, "Game Menu") + d.Add(Buttons.X, Localization.GetString("game_interaction_gamemenu", "Game Menu")) + If Core.Player.HasPokegear = True Then + d.Add(Buttons.Y, Localization.GetString("game_interaction_pokegear", "Pokégear")) + End If + d.Add(Buttons.Start, Localization.GetString("game_interaction_pausemenu", "Game Menu")) DrawGamePadControls(d) End If diff --git a/P3D/P3D.vbproj b/P3D/P3D.vbproj index e34511bab..93c73bafe 100644 --- a/P3D/P3D.vbproj +++ b/P3D/P3D.vbproj @@ -15325,6 +15325,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -15577,6 +15580,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + PreserveNewest @@ -27523,6 +27532,8 @@ + + @@ -29322,7 +29333,6 @@ - diff --git a/P3D/World/ActionScript/V2/ScriptCommands/DoText.vb b/P3D/World/ActionScript/V2/ScriptCommands/DoText.vb index 13c82802a..e7823b0a5 100644 --- a/P3D/World/ActionScript/V2/ScriptCommands/DoText.vb +++ b/P3D/World/ActionScript/V2/ScriptCommands/DoText.vb @@ -11,6 +11,32 @@ Dim argument As String = ScriptComparer.GetSubClassArgumentPair(subClass).Argument Select Case command.ToLower() + Case "notification" + Dim _NotificationPopup As New NotificationPopup + Dim args As String() = argument.Split(CChar(",")) + Select Case args.Length + Case 1 + _NotificationPopup.Setup(args(0)) + Case 2 + _NotificationPopup.Setup(args(0), CInt(args(1))) + Case 3 + _NotificationPopup.Setup(args(0), CInt(args(1)), CInt(args(2))) + Case 4 + _NotificationPopup.Setup(args(0), CInt(args(1)), CInt(args(2)), CInt(args(3))) + Case 5 + _NotificationPopup.Setup(args(0), CInt(args(1)), CInt(args(2)), CInt(args(3)), args(4)) + Case 6, 7 + _NotificationPopup.Setup(args(0), CInt(args(1)), CInt(args(2)), CInt(args(3)), args(4), args(5)) + End Select + If args.Length = 7 AndAlso CBool(args(6)) = True Then + CType(CurrentScreen, OverworldScreen).NotificationPopupList.Insert(0, _NotificationPopup) + If Screen.Level.NotificationPopup IsNot Nothing Then + CType(CurrentScreen, OverworldScreen).NotificationPopupList.Insert(1, Screen.Level.NotificationPopup) + Screen.Level.NotificationPopup = Nothing + Else + CType(CurrentScreen, OverworldScreen).NotificationPopupList.Add(_NotificationPopup) + End If + End If Case "show" Screen.TextBox.reDelay = 0.0F Screen.TextBox.Show(argument, {}, False, False) diff --git a/P3D/World/Level.vb b/P3D/World/Level.vb index 75163c553..a7dee98b6 100644 --- a/P3D/World/Level.vb +++ b/P3D/World/Level.vb @@ -7,6 +7,7 @@ Public Class Level #Region "Fields" Private _routeSign As RouteSign = Nothing + Private _notificationPopup As NotificationPopup = Nothing Private _world As World = Nothing Private _pokemonEncounter As PokemonEncounter = Nothing @@ -98,6 +99,14 @@ Public Class Level Return Me._routeSign End Get End Property + Public Property NotificationPopup() As NotificationPopup + Set(value As NotificationPopup) + Me._notificationPopup = value + End Set + Get + Return Me._notificationPopup + End Get + End Property ''' ''' Indicates whether the player is Surfing.