diff --git a/P3D/Content/Localization/Tokens_en.dat b/P3D/Content/Localization/Tokens_en.dat index 443a15c48..7396eca37 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_accept,Press to accept. +game_notification_dismiss,Press to dismiss. +--- MainMenuScreen: main_menu_continue,Continue main_menu_load_game,Load Game diff --git a/P3D/Content/Sounds/Notifications/Phone.wav b/P3D/Content/Sounds/Notifications/Phone.wav new file mode 100644 index 000000000..e3b454056 Binary files /dev/null and b/P3D/Content/Sounds/Notifications/Phone.wav differ diff --git a/P3D/Content/Textures/Notifications/Backgrounds.png b/P3D/Content/Textures/Notifications/Backgrounds.png new file mode 100644 index 000000000..eaf06854b Binary files /dev/null and b/P3D/Content/Textures/Notifications/Backgrounds.png differ diff --git a/P3D/Content/Textures/Notifications/Icons.png b/P3D/Content/Textures/Notifications/Icons.png new file mode 100644 index 000000000..346bf6057 Binary files /dev/null and b/P3D/Content/Textures/Notifications/Icons.png differ diff --git a/P3D/Overworld/NotificationPopup.vb b/P3D/Overworld/NotificationPopup.vb new file mode 100644 index 000000000..699c7ff2f --- /dev/null +++ b/P3D/Overworld/NotificationPopup.vb @@ -0,0 +1,183 @@ +''' +''' The notification popup. +''' +Public Class NotificationPopup + + Private _background As Texture2D + Private _icon As Texture2D + Private FrameSizeBack As Integer + Private FramesizeIcon As Integer + Private _positionY As Single = -12 + + Private _started As Boolean = False + Private _scale As Single = CInt(SpriteBatch.InterfaceScale * 2) + Private _soundEffect As String = "" + Private _text As String = "" + Private _size As Size = New Size(13, 3) + Private _backgroundIndex As Vector2 = New Vector2(0, 0) + Private _iconIndex As Vector2 = New Vector2(0, 0) + Private _delay As Integer = Nothing + Public _delayDate As Date = Nothing + + Public _waitForInput As Boolean = False + Public _scriptFile As String = "" + + Public IsReady 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 <> -1 Then + If Delay = 0 Then + _waitForInput = True + End If + _delay = Delay + Else + _delay = 500 + End If + + If BackgroundIndex <> -1 Then + _backgroundIndex = New Vector2(BackgroundIndex, 0) + Else + _backgroundIndex = New Vector2(0, 0) + End If + + While _backgroundIndex.X >= 3 + _backgroundIndex.X -= 3 + _backgroundIndex.Y += 1 + End While + If _backgroundIndex.X < 0 Then + _backgroundIndex.X = 0 + End If + + Dim BackTexture As Texture2D = TextureManager.GetTexture("Textures\Notifications\Backgrounds") + FrameSizeBack = CInt(BackTexture.Width / 3) + _background = TextureManager.GetTexture(BackTexture, New Rectangle(CInt(_backgroundIndex.X * FrameSizeBack), CInt(_backgroundIndex.Y * FrameSizeBack), FrameSizeBack, FrameSizeBack)) + + _positionY = CInt(0 - _size.Height * (FrameSizeBack / 3) * _scale - 12) + + If IconIndex <> -1 Then + _iconIndex = New Vector2(IconIndex, 0) + Else + _iconIndex = New Vector2(0, 0) + End If + + While _iconIndex.X >= 3 + _iconIndex.X -= 3 + _iconIndex.Y += 1 + End While + If _iconIndex.X < 0 Then + _iconIndex.X = 0 + End If + + Dim IconTexture As Texture2D = TextureManager.GetTexture("Textures\Notifications\Icons") + FramesizeIcon = CInt(IconTexture.Width / 3) + _icon = TextureManager.GetTexture(IconTexture, New Rectangle(CInt(_iconIndex.X * FramesizeIcon), CInt(_iconIndex.Y * FramesizeIcon), FramesizeIcon, FramesizeIcon)) + + _scriptFile = ScriptFile + + _soundEffect = SoundEffect + End Sub + + ''' + ''' Dismiss the Popup + ''' + Public Sub Dismiss() + Me._waitForInput = False + Me._delayDate = Date.Now + End Sub + + ''' + ''' Update the NotificationPopup. + ''' + Public Sub Update() + If _started = False Then + _delayDate = Date.Now.AddMilliseconds(CDbl(_delay * 10)) + _started = True + End If + + If _waitForInput = True Then + If Me._positionY < 5.0F Then + Me._positionY += CInt(0.7 * (FrameSizeBack / 3 * _scale) / _size.Height) + Else + If _soundEffect IsNot "" Then + SoundManager.PlaySound("Notifications\" & _soundEffect) + _soundEffect = "" + End If + End If + Else + If Date.Now < _delayDate Then + If Me._positionY < 5.0F Then + Me._positionY += CInt(0.7 * (FrameSizeBack / 3 * _scale) / _size.Height) + Else + If _soundEffect IsNot "" Then + SoundManager.PlaySound("Notifications\" & _soundEffect) + _soundEffect = "" + End If + End If + Else + If Me._scriptFile <> "" Then + CType(Core.CurrentScreen, OverworldScreen).ActionScript.StartScript(Me._scriptFile, 0, False) + Me.IsReady = True + End If + Dim BackY As Integer = CInt(0 - _size.Height * (FrameSizeBack / 3) * _scale - (FrameSizeBack / 3 * _scale) - 5) + If Me._positionY > BackY Then + Me._positionY -= CInt(0.7 * (FrameSizeBack / 3 * _scale) / _size.Height) + If Me._positionY <= BackY Then + Me._positionY = BackY + Me.IsReady = True + End If + End If + End If + End If + End Sub + + ''' + ''' Renders the NotificationPopup. + ''' + Public Sub Draw() + Dim TextHeader As String = _text.GetSplit(0, "*").Replace(CChar("~"), Environment.NewLine).CropStringToWidth(FontManager.InGameFont, CInt(_scale), CInt((_size.Width * (FrameSizeBack / 3) - FrameSizeBack / 3 * 4) * _scale)) + Dim TextBody As String = _text.GetSplit(1, "*").Replace(CChar("~"), Environment.NewLine) + + + While FontManager.InGameFont.MeasureString(TextHeader).Y * 2 + FontManager.InGameFont.MeasureString(TextBody).Y > CInt(((_size.Height * FrameSizeBack / 3) - FrameSizeBack / 3) * _scale - 5) + _size.Height += 1 + End While + + Dim BackGroundOffsetX As Integer = CInt(Core.windowSize.Width - (_size.Width * (FrameSizeBack / 3) * _scale) - (FrameSizeBack / 3) * 2 - 5) + + 'Draw the frame. + Canvas.DrawImageBorder(_background, CInt(_scale), New Rectangle(BackGroundOffsetX, CInt(Me._positionY), CInt(_size.Width * (FrameSizeBack / 3) * _scale), CInt(_size.Height * (FrameSizeBack / 3) * _scale))) + + 'Draw the icon. + Core.SpriteBatch.DrawInterface(_icon, New Rectangle(CInt(BackGroundOffsetX + (FrameSizeBack / 3 + 3) * _scale - _icon.Width / 3), CInt(Me._positionY + ((FrameSizeBack / 3 * _size.Height / 2) - FrameSizeBack / 3 * 0.5) * _scale - _icon.Width / 3), CInt(_icon.Width * _scale), CInt(_icon.Height * _scale)), Color.White) + + Dim TextOffset = CInt(BackGroundOffsetX + FrameSizeBack / 3 * _scale * 4) + If TextBody <> "" Then + If TextHeader <> "" Then + 'Draw the header, then the body + Core.SpriteBatch.DrawString(FontManager.InGameFont, TextHeader.CropStringToWidth(FontManager.InGameFont, CInt(_scale), CInt((_size.Width * (FrameSizeBack / 3) - FrameSizeBack / 3 * 4) * _scale)), New Vector2(TextOffset, CInt(Me._positionY + FrameSizeBack / 3)), Color.Black, 0.0F, Vector2.Zero, CSng(_scale), SpriteEffects.None, 0.0F) + Core.SpriteBatch.DrawString(FontManager.InGameFont, TextBody.CropStringToWidth(FontManager.InGameFont, CInt(_scale / 2), CInt((_size.Width * (FrameSizeBack / 3) - FrameSizeBack / 3 * 4) * _scale)), New Vector2(TextOffset, CInt(Me._positionY + FrameSizeBack / 3 + (FontManager.InGameFont.MeasureString(TextHeader).Y * _scale))), Color.Black, 0.0F, Vector2.Zero, CSng(_scale / 2), SpriteEffects.None, 0.0F) + Else + 'Just draw the body + Core.SpriteBatch.DrawString(FontManager.InGameFont, TextBody.CropStringToWidth(FontManager.InGameFont, CInt(_scale / 2), CInt((_size.Width * (FrameSizeBack / 3) - FrameSizeBack / 3 * 4) * _scale)), New Vector2(TextOffset, CInt(Me._positionY + FrameSizeBack / 3)), Color.Black, 0.0F, Vector2.Zero, CSng(_scale / 2), SpriteEffects.None, 0.0F) + End If + Else + 'Just draw the header + Core.SpriteBatch.DrawString(FontManager.InGameFont, TextHeader.CropStringToWidth(FontManager.InGameFont, CInt(_scale), CInt((_size.Width * (FrameSizeBack / 3) - FrameSizeBack / 3 * 4) * _scale)), New Vector2(TextOffset, CInt(Me._positionY + FrameSizeBack / 3)), Color.Black, 0.0F, Vector2.Zero, CSng(_scale), SpriteEffects.None, 0.0F) + End If + + Dim InteractText As String = "[" & Localization.GetString("game_notification_dismiss") & "]" + If Me._scriptFile <> "" Then + InteractText = "[" & Localization.GetString("game_notification_accept") & "]" + End If + Dim InteractOffset As Vector2 = New Vector2(CInt(Core.windowSize.Width - FrameSizeBack / 3 * _scale - FontManager.InGameFont.MeasureString(InteractText).X * _scale / 2), CInt(Me._positionY + _size.Height * (FrameSizeBack / 3) * _scale + 5)) + + Core.SpriteBatch.DrawInterface(_background, New Rectangle(CInt(InteractOffset.X), CInt(InteractOffset.Y), CInt(FontManager.InGameFont.MeasureString(InteractText).X * _scale / 2), CInt(FontManager.InGameFont.MeasureString(InteractText).Y * _scale / 2)), New Rectangle(CInt(FrameSizeBack / 3), CInt(FrameSizeBack / 3), CInt(FrameSizeBack / 3), CInt(FrameSizeBack / 3)), Color.White) + Core.SpriteBatch.DrawString(FontManager.InGameFont, InteractText, New Vector2(CInt(InteractOffset.X), CInt(InteractOffset.Y)), Color.Black) + End Sub + +End Class \ No newline at end of file diff --git a/P3D/Overworld/OverworldScreen.vb b/P3D/Overworld/OverworldScreen.vb index ce59ed7dc..a92b3bcbb 100644 --- a/P3D/Overworld/OverworldScreen.vb +++ b/P3D/Overworld/OverworldScreen.vb @@ -12,6 +12,8 @@ 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) = New List(Of NotificationPopup) + 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. @@ -26,7 +28,6 @@ Public Class OverworldScreen #End Region #Region "Properties" - ''' ''' Array of Title objects to be rendered on the screen. ''' @@ -191,6 +192,13 @@ Public Class OverworldScreen ImageView.Update() End If + If NotificationPopupList.Count > 0 Then + NotificationPopupList(0).Update() + If NotificationPopupList(0).IsReady = True Then + NotificationPopupList.Remove(NotificationPopupList(0)) + End If + 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 @@ -220,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 @@ -228,13 +235,16 @@ 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 NotificationPopupList.Count > 0 Then + NotificationPopupList(0).Dismiss() + Else + 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 End If End If - ActionScript.Update() 'Update the action script. Else 'Dialogues are showing: 'Update some parts of the camera: @@ -346,17 +356,25 @@ Public Class OverworldScreen Level.RouteSign.Draw() + If NotificationPopupList.Count > 0 Then + NotificationPopupList(0).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 NotificationPopupList.Count > 0 Then + d.Add(Buttons.A, Localization.GetString("game_interaction_notification", "Notification")) + 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 baadd34c9..7f2b988ab 100644 --- a/P3D/P3D.vbproj +++ b/P3D/P3D.vbproj @@ -15334,6 +15334,9 @@ PreserveNewest + + PreserveNewest + PreserveNewest @@ -15589,6 +15592,12 @@ PreserveNewest + + PreserveNewest + + + PreserveNewest + PreserveNewest @@ -27536,6 +27545,8 @@ + + @@ -29353,7 +29364,6 @@ - diff --git a/P3D/World/ActionScript/V2/ScriptCommands/DoText.vb b/P3D/World/ActionScript/V2/ScriptCommands/DoText.vb index 13c82802a..5ee43ee09 100644 --- a/P3D/World/ActionScript/V2/ScriptCommands/DoText.vb +++ b/P3D/World/ActionScript/V2/ScriptCommands/DoText.vb @@ -11,6 +11,28 @@ 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(argument) + Case 2 + _NotificationPopup.Setup(args(0), int(args(1))) + Case 3 + _NotificationPopup.Setup(args(0), int(args(1)), int(args(2))) + Case 4 + _NotificationPopup.Setup(args(0), int(args(1)), int(args(2)), int(args(3))) + Case 5 + _NotificationPopup.Setup(args(0), int(args(1)), int(args(2)), int(args(3)), args(4)) + Case 6, 7 + _NotificationPopup.Setup(args(0), int(args(1)), int(args(2)), int(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) + Else + CType(CurrentScreen, OverworldScreen).NotificationPopupList.Add(_NotificationPopup) + End If Case "show" Screen.TextBox.reDelay = 0.0F Screen.TextBox.Show(argument, {}, False, False)