2018-12-30 18:00:05 +08:00
using System ;
2016-10-20 15:01:51 +08:00
using System.Collections.Generic ;
2017-07-28 08:28:39 +08:00
using System.IO ;
2016-10-20 15:01:51 +08:00
using System.Linq ;
2018-09-19 09:04:38 +08:00
using Microsoft.Xna.Framework ;
using Microsoft.Xna.Framework.Graphics ;
2017-07-31 11:07:07 +08:00
using Omegasis.HappyBirthday.Framework ;
2019-12-05 17:25:46 +08:00
using StardustCore.Events ;
2016-10-20 15:01:51 +08:00
using StardewModdingAPI ;
2017-07-30 06:02:49 +08:00
using StardewModdingAPI.Events ;
2016-10-20 15:01:51 +08:00
using StardewValley ;
2017-07-30 06:02:49 +08:00
using StardewValley.Characters ;
2018-09-19 09:04:38 +08:00
using StardewValley.Menus ;
2017-07-30 06:02:49 +08:00
using StardewValley.Monsters ;
2019-12-07 07:04:48 +08:00
using StardustCore.Utilities ;
2016-10-20 15:01:51 +08:00
2017-07-28 08:28:39 +08:00
namespace Omegasis.HappyBirthday
2016-10-20 15:01:51 +08:00
{
2017-07-30 06:02:49 +08:00
/// <summary>The mod entry point.</summary>
2018-09-19 09:04:38 +08:00
public class HappyBirthday : Mod , IAssetEditor
2016-10-20 15:01:51 +08:00
{
2017-07-30 06:02:49 +08:00
/ * * * * * * * * *
2019-01-06 15:23:07 +08:00
* * Fields
2017-07-30 06:02:49 +08:00
* * * * * * * * * /
2017-08-06 03:51:44 +08:00
/// <summary>The relative path for the current player's data file.</summary>
2018-05-10 05:23:42 +08:00
private string DataFilePath ;
2017-08-06 03:51:44 +08:00
/// <summary>The absolute path for the current player's legacy data file.</summary>
2018-05-01 09:21:31 +08:00
private string LegacyDataFilePath = > Path . Combine ( this . Helper . DirectoryPath , "Player_Birthdays" , $"HappyBirthday_{Game1.player.Name}.txt" ) ;
2017-08-06 03:51:44 +08:00
/// <summary>The mod configuration.</summary>
2018-09-19 09:04:38 +08:00
public static ModConfig Config ;
2017-08-06 03:51:44 +08:00
/// <summary>The data for the current player.</summary>
2018-12-10 11:57:12 +08:00
public static PlayerData PlayerBirthdayData ;
2018-12-30 18:00:05 +08:00
/// <summary>Wrapper for static field PlayerBirthdayData;</summary>
2018-12-10 11:57:12 +08:00
public PlayerData PlayerData
{
2018-12-30 18:00:05 +08:00
get = > PlayerBirthdayData ;
set = > PlayerBirthdayData = value ;
2018-12-10 11:57:12 +08:00
}
2016-10-20 15:01:51 +08:00
2017-07-30 06:02:49 +08:00
/// <summary>Whether the player has chosen a birthday.</summary>
2017-08-06 03:51:44 +08:00
private bool HasChosenBirthday = > ! string . IsNullOrEmpty ( this . PlayerData . BirthdaySeason ) & & this . PlayerData . BirthdayDay ! = 0 ;
2016-11-08 17:19:56 +08:00
2017-07-30 06:02:49 +08:00
/// <summary>The queue of villagers who haven't given a gift yet.</summary>
2019-07-08 08:09:28 +08:00
private Dictionary < string , VillagerInfo > VillagerQueue ;
2016-10-20 15:01:51 +08:00
2017-07-30 06:02:49 +08:00
/// <summary>Whether we've already checked for and (if applicable) set up the player's birthday today.</summary>
private bool CheckedForBirthday ;
//private Dictionary<string, Dialogue> Dialogue;
//private bool SeenEvent;
2018-03-04 11:24:36 +08:00
2018-09-19 09:04:38 +08:00
public static IModHelper ModHelper ;
2018-12-06 10:06:11 +08:00
public static IMonitor ModMonitor ;
2018-12-30 18:00:05 +08:00
/// <summary>Class to handle all birthday messages for this mod.</summary>
2018-09-19 13:35:36 +08:00
public BirthdayMessages messages ;
2018-09-19 09:04:38 +08:00
2018-12-30 18:00:05 +08:00
/// <summary>Class to handle all birthday gifts for this mod.</summary>
2018-12-06 09:16:28 +08:00
public GiftManager giftManager ;
2017-07-30 06:02:49 +08:00
2018-12-30 18:00:05 +08:00
/// <summary>Checks if the current billboard is the daily quest screen or not.</summary>
2018-12-07 07:06:26 +08:00
bool isDailyQuestBoard ;
2018-12-30 18:00:05 +08:00
Dictionary < long , PlayerData > othersBirthdays ;
2018-12-10 11:57:12 +08:00
2019-01-15 04:26:36 +08:00
public static HappyBirthday Instance ;
2018-12-10 11:57:12 +08:00
2019-07-08 08:09:28 +08:00
private NPC lastSpeaker ;
2019-12-05 10:14:45 +08:00
private EventManager eventManager ;
2017-07-30 06:02:49 +08:00
/ * * * * * * * * *
* * Public methods
* * * * * * * * * /
/// <summary>The mod entry point, called after the mod is first loaded.</summary>
/// <param name="helper">Provides simplified APIs for writing mods.</param>
2016-12-09 08:34:28 +08:00
public override void Entry ( IModHelper helper )
2016-10-20 15:01:51 +08:00
{
2019-01-15 04:26:36 +08:00
Instance = this ;
2018-09-19 13:35:36 +08:00
Config = helper . ReadConfig < ModConfig > ( ) ;
2017-08-06 03:51:44 +08:00
2019-01-06 15:21:06 +08:00
helper . Events . GameLoop . DayStarted + = this . OnDayStarted ;
helper . Events . GameLoop . UpdateTicked + = this . OnUpdateTicked ;
helper . Events . GameLoop . SaveLoaded + = this . OnSaveLoaded ;
helper . Events . GameLoop . Saving + = this . OnSaving ;
helper . Events . Input . ButtonPressed + = this . OnButtonPressed ;
helper . Events . Display . MenuChanged + = this . OnMenuChanged ;
helper . Events . Display . RenderedActiveMenu + = this . OnRenderedActiveMenu ;
helper . Events . Display . RenderedHud + = this . OnRenderedHud ;
2019-12-03 12:54:30 +08:00
helper . Events . Multiplayer . ModMessageReceived + = this . Multiplayer_ModMessageReceived ;
helper . Events . Multiplayer . PeerDisconnected + = this . Multiplayer_PeerDisconnected ;
helper . Events . GameLoop . GameLaunched + = this . GameLoop_GameLaunched ;
2019-12-05 10:14:45 +08:00
helper . Events . Player . Warped + = this . Player_Warped ;
2019-12-14 08:00:06 +08:00
helper . Events . GameLoop . ReturnedToTitle + = this . GameLoop_ReturnedToTitle ;
2018-12-30 18:00:05 +08:00
ModHelper = this . Helper ;
ModMonitor = this . Monitor ;
2018-09-19 13:35:36 +08:00
2019-12-03 12:54:30 +08:00
this . othersBirthdays = new Dictionary < long , PlayerData > ( ) ;
2019-12-05 10:14:45 +08:00
this . eventManager = new EventManager ( ) ;
2019-12-10 11:02:24 +08:00
2019-12-05 10:14:45 +08:00
}
2019-12-14 08:00:06 +08:00
private void GameLoop_ReturnedToTitle ( object sender , ReturnedToTitleEventArgs e )
{
this . eventManager = new EventManager ( ) ;
}
2019-12-05 10:14:45 +08:00
private void Player_Warped ( object sender , WarpedEventArgs e )
{
if ( e . NewLocation = = Game1 . getLocationFromName ( "CommunityCenter" ) )
{
2019-12-31 13:37:42 +08:00
this . eventManager . startEventAtLocationIfPossible ( "CommunityCenterBirthday" ) ;
2019-12-05 10:14:45 +08:00
}
2019-12-07 12:59:05 +08:00
if ( e . NewLocation = = Game1 . getLocationFromName ( "Trailer" ) )
{
2019-12-31 13:37:42 +08:00
this . eventManager . startEventAtLocationIfPossible ( "BirthdayDating:Penny" ) ;
2019-12-07 12:59:05 +08:00
}
2019-12-11 09:16:25 +08:00
if ( e . NewLocation = = Game1 . getLocationFromName ( "Trailer_Big" ) )
{
2019-12-31 13:37:42 +08:00
this . eventManager . startEventAtLocationIfPossible ( "BirthdayDating:Penny_BigHome" ) ;
2019-12-11 09:16:25 +08:00
}
2019-12-08 09:09:40 +08:00
if ( e . NewLocation = = Game1 . getLocationFromName ( "ScienceHouse" ) )
{
2019-12-31 13:37:42 +08:00
this . eventManager . startEventAtLocationIfPossible ( "BirthdayDating:Maru" ) ;
this . eventManager . startEventAtLocationIfPossible ( "BirthdayDating:Sebastian" ) ;
2019-12-08 09:09:40 +08:00
}
2019-12-08 09:54:49 +08:00
if ( e . NewLocation = = Game1 . getLocationFromName ( "LeahHouse" ) )
{
2019-12-31 13:37:42 +08:00
this . eventManager . startEventAtLocationIfPossible ( "BirthdayDating:Leah" ) ;
2019-12-08 09:54:49 +08:00
}
2019-12-08 10:27:34 +08:00
if ( e . NewLocation = = Game1 . getLocationFromName ( "SeedShop" ) )
{
2019-12-31 13:37:42 +08:00
this . eventManager . startEventAtLocationIfPossible ( "BirthdayDating:Abigail" ) ;
2019-12-08 10:27:34 +08:00
}
2019-12-10 10:12:29 +08:00
if ( e . NewLocation = = Game1 . getLocationFromName ( "HaleyHouse" ) )
{
2019-12-31 13:37:42 +08:00
this . eventManager . startEventAtLocationIfPossible ( "BirthdayDating:Emily" ) ;
this . eventManager . startEventAtLocationIfPossible ( "BirthdayDating:Haley" ) ;
2019-12-10 11:02:24 +08:00
}
if ( e . NewLocation = = Game1 . getLocationFromName ( "HarveyRoom" ) )
{
2019-12-31 13:37:42 +08:00
this . eventManager . startEventAtLocationIfPossible ( "BirthdayDating:Harvey" ) ;
2019-12-10 10:12:29 +08:00
}
2019-12-11 07:08:01 +08:00
if ( e . NewLocation = = Game1 . getLocationFromName ( "ElliottHouse" ) )
{
2019-12-31 13:37:42 +08:00
this . eventManager . startEventAtLocationIfPossible ( "BirthdayDating:Elliott" ) ;
2019-12-11 07:08:01 +08:00
}
2019-12-11 07:33:41 +08:00
if ( e . NewLocation = = Game1 . getLocationFromName ( "SamHouse" ) )
{
2019-12-31 13:37:42 +08:00
this . eventManager . startEventAtLocationIfPossible ( "BirthdayDating:Sam" ) ;
2019-12-11 07:33:41 +08:00
}
2019-12-11 09:16:25 +08:00
if ( e . NewLocation = = Game1 . getLocationFromName ( "JoshHouse" ) )
{
2019-12-31 13:37:42 +08:00
this . eventManager . startEventAtLocationIfPossible ( "BirthdayDating:Alex" ) ;
2019-12-11 09:16:25 +08:00
}
if ( e . NewLocation = = Game1 . getLocationFromName ( "AnimalShop" ) )
{
2019-12-31 13:37:42 +08:00
this . eventManager . startEventAtLocationIfPossible ( "BirthdayDating:Shane" ) ;
2019-12-11 09:16:25 +08:00
}
2019-12-31 13:37:42 +08:00
2019-12-03 12:54:30 +08:00
}
private void GameLoop_GameLaunched ( object sender , GameLaunchedEventArgs e )
{
2018-12-30 18:00:05 +08:00
this . messages = new BirthdayMessages ( ) ;
this . giftManager = new GiftManager ( ) ;
this . isDailyQuestBoard = false ;
2019-12-05 10:14:45 +08:00
2018-12-30 18:00:05 +08:00
}
2018-12-10 11:57:12 +08:00
2018-12-30 18:00:05 +08:00
/// <summary>Get whether this instance can edit the given asset.</summary>
/// <param name="asset">Basic metadata about the asset being loaded.</param>
public bool CanEdit < T > ( IAssetInfo asset )
{
return asset . AssetNameEquals ( @"Data\mail" ) ;
}
/// <summary>Edit a matched asset.</summary>
/// <param name="asset">A helper which encapsulates metadata about an asset and enables changes to it.</param>
public void Edit < T > ( IAssetData asset )
{
2019-01-06 15:21:06 +08:00
IDictionary < string , string > data = asset . AsDictionary < string , string > ( ) . Data ;
2019-01-15 04:26:36 +08:00
2019-12-07 07:18:23 +08:00
data [ "birthdayMom" ] = BirthdayMessages . GetTranslatedString ( "Mail:birthdayMom" ) ;
data [ "birthdayDad" ] = BirthdayMessages . GetTranslatedString ( "Mail:birthdayDad" ) ;
data [ "birthdayJunimos" ] = BirthdayMessages . GetTranslatedString ( "Mail:birthdayJunimos" ) ;
2019-12-07 12:59:05 +08:00
data [ "birthdayDatingPenny" ] = BirthdayMessages . GetTranslatedString ( "Mail:birthdayDatingPenny" ) ;
2019-12-08 09:09:40 +08:00
data [ "birthdayDatingMaru" ] = BirthdayMessages . GetTranslatedString ( "Mail:birthdayDatingMaru" ) ;
data [ "birthdayDatingSebastian" ] = BirthdayMessages . GetTranslatedString ( "Mail:birthdayDatingSebastian" ) ;
2019-12-08 09:54:49 +08:00
data [ "birthdayDatingLeah" ] = BirthdayMessages . GetTranslatedString ( "Mail:birthdayDatingLeah" ) ;
2019-12-08 10:27:34 +08:00
data [ "birthdayDatingAbigail" ] = BirthdayMessages . GetTranslatedString ( "Mail:birthdayDatingAbigail" ) ;
2019-12-10 10:12:29 +08:00
data [ "birthdayDatingEmily" ] = BirthdayMessages . GetTranslatedString ( "Mail:birthdayDatingEmily" ) ;
2019-12-10 11:02:24 +08:00
data [ "birthdayDatingHaley" ] = BirthdayMessages . GetTranslatedString ( "Mail:birthdayDatingHaley" ) ;
data [ "birthdayDatingHarvey" ] = BirthdayMessages . GetTranslatedString ( "Mail:birthdayDatingHarvey" ) ;
2019-12-11 07:08:01 +08:00
data [ "birthdayDatingElliott" ] = BirthdayMessages . GetTranslatedString ( "Mail:birthdayDatingElliott" ) ;
2019-12-11 07:33:41 +08:00
data [ "birthdayDatingSam" ] = BirthdayMessages . GetTranslatedString ( "Mail:birthdayDatingSam" ) ;
2019-12-11 09:16:25 +08:00
data [ "birthdayDatingAlex" ] = BirthdayMessages . GetTranslatedString ( "Mail:birthdayDatingAlex" ) ;
data [ "birthdayDatingShane" ] = BirthdayMessages . GetTranslatedString ( "Mail:birthdayDatingShane" ) ;
2018-12-10 11:57:12 +08:00
}
2018-12-30 18:00:05 +08:00
/ * * * * * * * * *
* * Private methods
* * * * * * * * * /
/// <summary>Used to check for player disconnections.</summary>
/// <param name="sender">The event sender.</param>
/// <param name="e">The event arguments.</param>
2018-12-10 13:04:41 +08:00
private void Multiplayer_PeerDisconnected ( object sender , PeerDisconnectedEventArgs e )
{
this . othersBirthdays . Remove ( e . Peer . PlayerID ) ;
}
2018-12-10 11:57:12 +08:00
private void Multiplayer_ModMessageReceived ( object sender , ModMessageReceivedEventArgs e )
{
2018-12-30 18:00:05 +08:00
if ( e . FromModID = = ModHelper . Multiplayer . ModID & & e . Type = = MultiplayerSupport . FSTRING_SendBirthdayMessageToOthers )
2018-12-10 11:57:12 +08:00
{
string message = e . ReadAs < string > ( ) ;
2018-12-30 18:00:05 +08:00
Game1 . hudMessages . Add ( new HUDMessage ( message , 1 ) ) ;
2018-12-10 11:57:12 +08:00
}
2018-12-10 13:04:41 +08:00
if ( e . FromModID = = ModHelper . Multiplayer . ModID & & e . Type = = MultiplayerSupport . FSTRING_SendBirthdayInfoToOthers )
2018-12-10 11:57:12 +08:00
{
2018-12-30 18:00:05 +08:00
KeyValuePair < long , PlayerData > message = e . ReadAs < KeyValuePair < long , PlayerData > > ( ) ;
2018-12-10 13:04:41 +08:00
if ( ! this . othersBirthdays . ContainsKey ( message . Key ) )
{
2018-12-30 18:00:05 +08:00
this . othersBirthdays . Add ( message . Key , message . Value ) ;
2018-12-10 13:04:41 +08:00
MultiplayerSupport . SendBirthdayInfoToConnectingPlayer ( e . FromPlayerID ) ;
2019-04-12 08:25:54 +08:00
this . Monitor . Log ( "Got other player's birthday data from: " + Game1 . getFarmer ( e . FromPlayerID ) . Name ) ;
2018-12-10 13:04:41 +08:00
}
else
{
//Brute force update birthday info if it has already been recevived but dont send birthday info again.
this . othersBirthdays . Remove ( message . Key ) ;
this . othersBirthdays . Add ( message . Key , message . Value ) ;
2019-04-12 08:25:54 +08:00
this . Monitor . Log ( "Got other player's birthday data from: " + Game1 . getFarmer ( e . FromPlayerID ) . Name ) ;
2018-12-10 13:04:41 +08:00
}
2018-12-10 11:57:12 +08:00
}
2018-09-19 09:04:38 +08:00
}
2019-01-06 15:21:06 +08:00
/// <summary>Raised after drawing the HUD (item toolbar, clock, etc) to the sprite batch, but before it's rendered to the screen.</summary>
2018-12-30 18:00:05 +08:00
/// <param name="sender">The event sender.</param>
/// <param name="e">The event arguments.</param>
2019-01-06 15:21:06 +08:00
private void OnRenderedHud ( object sender , RenderedHudEventArgs e )
2018-12-07 07:06:26 +08:00
{
2019-01-06 15:21:06 +08:00
if ( Game1 . activeClickableMenu = = null | | this . PlayerData ? . BirthdaySeason ? . ToLower ( ) ! = Game1 . currentSeason . ToLower ( ) )
return ;
2018-12-07 07:06:26 +08:00
2019-01-06 15:21:06 +08:00
if ( Game1 . activeClickableMenu is Billboard billboard )
2018-09-19 09:04:38 +08:00
{
2019-01-06 15:21:06 +08:00
if ( this . isDailyQuestBoard | | billboard . calendarDays = = null )
return ;
2018-12-07 07:06:26 +08:00
2018-09-19 09:04:38 +08:00
string hoverText = "" ;
2018-12-06 16:54:12 +08:00
List < string > texts = new List < string > ( ) ;
2018-12-07 07:06:26 +08:00
2019-01-06 15:21:06 +08:00
foreach ( var clicky in billboard . calendarDays )
2018-09-19 09:04:38 +08:00
{
if ( clicky . containsPoint ( Game1 . getMouseX ( ) , Game1 . getMouseY ( ) ) )
{
2018-12-30 18:00:05 +08:00
if ( ! string . IsNullOrEmpty ( clicky . hoverText ) )
2018-12-06 16:54:12 +08:00
texts . Add ( clicky . hoverText ) ; //catches npc birhday names.
2018-12-30 18:00:05 +08:00
else if ( ! string . IsNullOrEmpty ( clicky . name ) )
2018-12-06 16:54:12 +08:00
texts . Add ( clicky . name ) ; //catches festival dates.
2018-09-19 09:04:38 +08:00
}
2018-12-06 16:54:12 +08:00
}
2018-12-30 18:00:05 +08:00
for ( int i = 0 ; i < texts . Count ; i + + )
{
2018-12-06 16:54:12 +08:00
hoverText + = texts [ i ] ; //Append text.
2018-12-30 18:00:05 +08:00
if ( i ! = texts . Count - 1 )
2018-12-06 16:54:12 +08:00
hoverText + = Environment . NewLine ; //Append new line.
2018-09-19 09:04:38 +08:00
}
2018-12-06 16:54:12 +08:00
2018-12-30 18:00:05 +08:00
if ( ! string . IsNullOrEmpty ( hoverText ) )
2018-09-19 09:04:38 +08:00
{
2018-12-30 18:00:05 +08:00
var oldText = this . Helper . Reflection . GetField < string > ( Game1 . activeClickableMenu , "hoverText" ) ;
2018-09-19 09:04:38 +08:00
oldText . SetValue ( hoverText ) ;
}
}
}
2019-01-06 15:21:06 +08:00
/// <summary>When a menu is open (<see cref="Game1.activeClickableMenu"/> isn't null), raised after that menu is drawn to the sprite batch but before it's rendered to the screen.</summary>
2018-12-30 18:00:05 +08:00
/// <param name="sender">The event sender.</param>
/// <param name="e">The event arguments.</param>
2019-01-06 15:21:06 +08:00
private void OnRenderedActiveMenu ( object sender , RenderedActiveMenuEventArgs e )
2018-09-19 09:04:38 +08:00
{
2018-12-30 18:00:05 +08:00
if ( Game1 . activeClickableMenu = = null | | this . isDailyQuestBoard )
return ;
2018-12-10 13:04:41 +08:00
2018-12-30 18:00:05 +08:00
//Don't do anything if birthday has not been chosen yet.
if ( this . PlayerData = = null )
return ;
2018-12-06 10:06:11 +08:00
2018-09-19 09:04:38 +08:00
if ( Game1 . activeClickableMenu is Billboard )
{
2018-12-30 18:00:05 +08:00
if ( ! string . IsNullOrEmpty ( this . PlayerData . BirthdaySeason ) )
2018-12-10 13:04:41 +08:00
{
2018-12-30 18:00:05 +08:00
if ( this . PlayerData . BirthdaySeason . ToLower ( ) = = Game1 . currentSeason . ToLower ( ) )
2018-12-10 13:04:41 +08:00
{
2018-12-30 18:00:05 +08:00
int index = this . PlayerData . BirthdayDay ;
2018-12-10 13:04:41 +08:00
Game1 . player . FarmerRenderer . drawMiniPortrat ( Game1 . spriteBatch , new Vector2 ( Game1 . activeClickableMenu . xPositionOnScreen + 152 + ( index - 1 ) % 7 * 32 * 4 , Game1 . activeClickableMenu . yPositionOnScreen + 230 + ( index - 1 ) / 7 * 32 * 4 ) , 0.5f , 4f , 2 , Game1 . player ) ;
2019-04-12 08:25:54 +08:00
( Game1 . activeClickableMenu as Billboard ) . drawMouse ( e . SpriteBatch ) ;
string hoverText = this . Helper . Reflection . GetField < string > ( ( Game1 . activeClickableMenu as Billboard ) , "hoverText" , true ) . GetValue ( ) ;
if ( hoverText . Length > 0 )
{
IClickableMenu . drawHoverText ( Game1 . spriteBatch , hoverText , Game1 . dialogueFont , 0 , 0 , - 1 , ( string ) null , - 1 , ( string [ ] ) null , ( Item ) null , 0 , - 1 , - 1 , - 1 , - 1 , 1f , ( CraftingRecipe ) null ) ;
}
2018-12-10 13:04:41 +08:00
}
}
2018-12-30 18:00:05 +08:00
foreach ( var pair in this . othersBirthdays )
2018-12-10 13:04:41 +08:00
{
int index = pair . Value . BirthdayDay ;
if ( pair . Value . BirthdaySeason ! = Game1 . currentSeason . ToLower ( ) ) continue ; //Hide out of season birthdays.
index = pair . Value . BirthdayDay ;
Game1 . player . FarmerRenderer . drawMiniPortrat ( Game1 . spriteBatch , new Vector2 ( Game1 . activeClickableMenu . xPositionOnScreen + 152 + ( index - 1 ) % 7 * 32 * 4 , Game1 . activeClickableMenu . yPositionOnScreen + 230 + ( index - 1 ) / 7 * 32 * 4 ) , 0.5f , 4f , 2 , Game1 . getFarmer ( pair . Key ) ) ;
2019-04-12 08:25:54 +08:00
( Game1 . activeClickableMenu as Billboard ) . drawMouse ( e . SpriteBatch ) ;
string hoverText = this . Helper . Reflection . GetField < string > ( ( Game1 . activeClickableMenu as Billboard ) , "hoverText" , true ) . GetValue ( ) ;
if ( hoverText . Length > 0 )
{
IClickableMenu . drawHoverText ( Game1 . spriteBatch , hoverText , Game1 . dialogueFont , 0 , 0 , - 1 , ( string ) null , - 1 , ( string [ ] ) null , ( Item ) null , 0 , - 1 , - 1 , - 1 , - 1 , 1f , ( CraftingRecipe ) null ) ;
}
2018-12-10 13:04:41 +08:00
}
2019-07-08 08:09:28 +08:00
( Game1 . activeClickableMenu ) . drawMouse ( e . SpriteBatch ) ;
2018-09-19 09:04:38 +08:00
}
}
2019-01-06 15:21:06 +08:00
/// <summary>Raised after a game menu is opened, closed, or replaced.</summary>
2018-12-30 18:00:05 +08:00
/// <param name="sender">The event sender.</param>
/// <param name="e">The event arguments.</param>
2019-01-06 15:21:06 +08:00
private void OnMenuChanged ( object sender , MenuChangedEventArgs e )
2018-09-19 09:04:38 +08:00
{
2019-01-06 15:21:06 +08:00
switch ( e . NewMenu )
2018-12-07 07:06:26 +08:00
{
2019-01-06 15:21:06 +08:00
case null :
this . isDailyQuestBoard = false ;
2019-07-08 08:09:28 +08:00
//Validate the gift and give it to the player.
if ( this . lastSpeaker ! = null )
{
if ( this . giftManager . BirthdayGiftToReceive ! = null & & this . VillagerQueue [ this . lastSpeaker . Name ] . hasGivenBirthdayGift = = false )
{
while ( this . giftManager . BirthdayGiftToReceive . Name = = "Error Item" | | this . giftManager . BirthdayGiftToReceive . Name = = "Rock" | | this . giftManager . BirthdayGiftToReceive . Name = = "???" )
this . giftManager . SetNextBirthdayGift ( this . lastSpeaker . Name ) ;
Game1 . player . addItemByMenuIfNecessaryElseHoldUp ( this . giftManager . BirthdayGiftToReceive ) ;
this . giftManager . BirthdayGiftToReceive = null ;
this . VillagerQueue [ this . lastSpeaker . Name ] . hasGivenBirthdayGift = true ;
this . lastSpeaker = null ;
}
}
2019-01-06 15:21:06 +08:00
return ;
2018-12-10 13:04:41 +08:00
2019-01-06 15:21:06 +08:00
case Billboard billboard :
2018-12-10 13:04:41 +08:00
{
2019-01-06 15:21:06 +08:00
this . isDailyQuestBoard = ModHelper . Reflection . GetField < bool > ( ( Game1 . activeClickableMenu as Billboard ) , "dailyQuestBoard" , true ) . GetValue ( ) ;
if ( this . isDailyQuestBoard )
return ;
Texture2D text = new Texture2D ( Game1 . graphics . GraphicsDevice , 1 , 1 ) ;
Color [ ] col = new Color [ 1 ] ;
col [ 0 ] = new Color ( 0 , 0 , 0 , 1 ) ;
text . SetData < Color > ( col ) ;
//players birthday position rect=new ....
if ( ! string . IsNullOrEmpty ( this . PlayerData . BirthdaySeason ) )
{
if ( this . PlayerData . BirthdaySeason . ToLower ( ) = = Game1 . currentSeason . ToLower ( ) )
{
int index = this . PlayerData . BirthdayDay ;
2019-12-02 12:47:31 +08:00
string bdayDisplay = Game1 . content . LoadString ( "Strings\\UI:Billboard_Birthday" ) ;
2019-01-06 15:21:06 +08:00
Rectangle birthdayRect = new Rectangle ( Game1 . activeClickableMenu . xPositionOnScreen + 152 + ( index - 1 ) % 7 * 32 * 4 , Game1 . activeClickableMenu . yPositionOnScreen + 200 + ( index - 1 ) / 7 * 32 * 4 , 124 , 124 ) ;
2019-12-02 12:47:31 +08:00
billboard . calendarDays . Add ( new ClickableTextureComponent ( "" , birthdayRect , "" , string . Format ( bdayDisplay , Game1 . player . Name ) , text , new Rectangle ( 0 , 0 , 124 , 124 ) , 1f , false ) ) ;
//billboard.calendarDays.Add(new ClickableTextureComponent("", birthdayRect, "", $"{Game1.player.Name}'s Birthday", text, new Rectangle(0, 0, 124, 124), 1f, false));
2019-01-06 15:21:06 +08:00
}
}
foreach ( var pair in this . othersBirthdays )
{
if ( pair . Value . BirthdaySeason ! = Game1 . currentSeason . ToLower ( ) ) continue ;
int index = pair . Value . BirthdayDay ;
2019-12-02 12:47:31 +08:00
string bdayDisplay = Game1 . content . LoadString ( "Strings\\UI:Billboard_Birthday" ) ;
2019-01-06 15:21:06 +08:00
Rectangle otherBirthdayRect = new Rectangle ( Game1 . activeClickableMenu . xPositionOnScreen + 152 + ( index - 1 ) % 7 * 32 * 4 , Game1 . activeClickableMenu . yPositionOnScreen + 200 + ( index - 1 ) / 7 * 32 * 4 , 124 , 124 ) ;
2019-12-02 12:47:31 +08:00
billboard . calendarDays . Add ( new ClickableTextureComponent ( "" , otherBirthdayRect , "" , string . Format ( bdayDisplay , Game1 . getFarmer ( pair . Key ) . Name ) , text , new Rectangle ( 0 , 0 , 124 , 124 ) , 1f , false ) ) ;
2019-01-06 15:21:06 +08:00
}
2019-07-08 08:09:28 +08:00
break ;
}
case DialogueBox dBox :
{
if ( Game1 . eventUp ) return ;
//Hijack the dialogue box and ensure that birthday dialogue gets spoken.
if ( Game1 . currentSpeaker ! = null )
{
this . lastSpeaker = Game1 . currentSpeaker ;
if ( Game1 . activeClickableMenu ! = null & & this . IsBirthday ( ) & & this . VillagerQueue . ContainsKey ( Game1 . currentSpeaker . Name ) )
{
if ( ( Game1 . player . getFriendshipHeartLevelForNPC ( Game1 . currentSpeaker . Name ) < Config . minimumFriendshipLevelForBirthdayWish ) ) return ;
if ( Game1 . activeClickableMenu is StardewValley . Menus . DialogueBox & & this . VillagerQueue [ Game1 . currentSpeaker . Name ] . hasGivenBirthdayWish = = false & & ( Game1 . player . getFriendshipHeartLevelForNPC ( Game1 . currentSpeaker . Name ) > = Config . minimumFriendshipLevelForBirthdayWish ) )
{
2019-12-14 08:00:06 +08:00
//IReflectedField < Dialogue > cDialogue= this.Helper.Reflection.GetField<Dialogue>((Game1.activeClickableMenu as DialogueBox), "characterDialogue", true);
//IReflectedField<List<string>> dialogues = this.Helper.Reflection.GetField<List<string>>((Game1.activeClickableMenu as DialogueBox), "dialogues", true);
2019-07-08 08:09:28 +08:00
Game1 . currentSpeaker . resetCurrentDialogue ( ) ;
Game1 . currentSpeaker . resetSeasonalDialogue ( ) ;
this . Helper . Reflection . GetMethod ( Game1 . currentSpeaker , "loadCurrentDialogue" , true ) . Invoke ( ) ;
Game1 . npcDialogues [ Game1 . currentSpeaker . Name ] = Game1 . currentSpeaker . CurrentDialogue ;
if ( this . IsBirthday ( ) & & this . VillagerQueue [ Game1 . currentSpeaker . Name ] . hasGivenBirthdayGift = = false & & Game1 . player . getFriendshipHeartLevelForNPC ( Game1 . currentSpeaker . Name ) > = Config . minNeutralFriendshipGiftLevel )
{
try
{
this . giftManager . SetNextBirthdayGift ( Game1 . currentSpeaker . Name ) ;
this . Monitor . Log ( "Setting next birthday gift. 1" ) ;
}
catch ( Exception ex )
{
this . Monitor . Log ( ex . ToString ( ) , LogLevel . Error ) ;
}
}
2019-12-14 08:00:06 +08:00
Game1 . activeClickableMenu = new DialogueBox ( new Dialogue ( this . messages . getBirthdayMessage ( Game1 . currentSpeaker . Name ) , Game1 . currentSpeaker ) ) ;
2019-07-08 08:09:28 +08:00
this . VillagerQueue [ Game1 . currentSpeaker . Name ] . hasGivenBirthdayWish = true ;
// Set birthday gift for the player to recieve from the npc they are currently talking with.
}
}
}
2019-01-06 15:21:06 +08:00
break ;
2018-12-10 13:04:41 +08:00
}
2018-09-19 09:04:38 +08:00
}
2019-07-08 08:09:28 +08:00
2017-02-22 15:29:00 +08:00
}
2019-01-06 15:21:06 +08:00
/// <summary>Raised after the game begins a new day (including when the player loads a save).</summary>
2017-07-30 06:02:49 +08:00
/// <param name="sender">The event sender.</param>
2019-01-06 15:21:06 +08:00
/// <param name="e">The event arguments.</param>
private void OnDayStarted ( object sender , DayStartedEventArgs e )
2016-10-20 15:01:51 +08:00
{
2019-07-08 08:09:28 +08:00
try
{
this . ResetVillagerQueue ( ) ;
}
catch ( Exception ex )
{
this . Monitor . Log ( ex . ToString ( ) , LogLevel . Error ) ;
}
2017-07-30 06:02:49 +08:00
this . CheckedForBirthday = false ;
2016-10-20 15:01:51 +08:00
}
2019-01-06 15:21:06 +08:00
/// <summary>Raised after the player presses a button on the keyboard, controller, or mouse.</summary>
2017-07-30 06:02:49 +08:00
/// <param name="sender">The event sender.</param>
2019-01-06 15:21:06 +08:00
/// <param name="e">The event arguments.</param>
private void OnButtonPressed ( object sender , ButtonPressedEventArgs e )
2016-10-20 15:01:51 +08:00
{
2017-07-30 06:02:49 +08:00
// show birthday selection menu
2018-06-26 12:13:40 +08:00
if ( Game1 . activeClickableMenu ! = null ) return ;
2019-01-06 15:21:06 +08:00
if ( Context . IsPlayerFree & & ! this . HasChosenBirthday & & e . Button = = Config . KeyBinding )
2017-08-06 03:51:44 +08:00
Game1 . activeClickableMenu = new BirthdayMenu ( this . PlayerData . BirthdaySeason , this . PlayerData . BirthdayDay , this . SetBirthday ) ;
2016-10-20 15:01:51 +08:00
}
2019-01-06 15:21:06 +08:00
/// <summary>Raised after the player loads a save slot and the world is initialised.</summary>
2017-07-30 06:02:49 +08:00
/// <param name="sender">The event sender.</param>
2019-01-06 15:21:06 +08:00
/// <param name="e">The event arguments.</param>
private void OnSaveLoaded ( object sender , SaveLoadedEventArgs e )
2016-10-20 15:01:51 +08:00
{
2019-01-06 15:21:06 +08:00
this . DataFilePath = Path . Combine ( "data" , $"{Game1.player.Name}_{Game1.player.UniqueMultiplayerID}.json" ) ;
2018-05-10 05:23:42 +08:00
2017-08-06 11:00:37 +08:00
// reset state
2019-07-08 08:09:28 +08:00
this . VillagerQueue = new Dictionary < string , VillagerInfo > ( ) ;
2017-08-06 11:00:37 +08:00
this . CheckedForBirthday = false ;
// load settings
2019-12-14 08:00:06 +08:00
/ /
//this.MigrateLegacyData();
2018-12-06 09:16:28 +08:00
this . PlayerData = this . Helper . Data . ReadJsonFile < PlayerData > ( this . DataFilePath ) ? ? new PlayerData ( ) ;
2018-09-19 09:04:38 +08:00
2019-12-11 09:16:25 +08:00
if ( HappyBirthday . Config . autoSetTranslation )
{
HappyBirthday . Config . translationInfo . setTranslationFromLanguageCode ( Game1 . content . GetCurrentLanguage ( ) ) ;
}
2018-12-10 13:04:41 +08:00
if ( PlayerBirthdayData ! = null )
{
2019-12-14 08:00:06 +08:00
//ModMonitor.Log("Send all birthday information from " + Game1.player.Name);
2018-12-10 13:04:41 +08:00
MultiplayerSupport . SendBirthdayInfoToOtherPlayers ( ) ;
}
2019-12-03 11:10:56 +08:00
2019-12-07 07:04:48 +08:00
if ( Game1 . player . mailReceived . Contains ( "birthdayMom" ) )
{
Game1 . player . mailReceived . Remove ( "birthdayMom" ) ;
}
if ( Game1 . player . mailReceived . Contains ( "birthdayDad" ) )
{
Game1 . player . mailReceived . Remove ( "birthdayDad" ) ;
}
if ( Game1 . player . mailReceived . Contains ( "birthdayJunimos" ) )
{
Game1 . player . mailReceived . Remove ( "birthdayJunimos" ) ;
}
2019-12-07 12:59:05 +08:00
if ( Game1 . player . mailReceived . Contains ( "birthdayDatingPenny" ) )
{
Game1 . player . mailReceived . Remove ( "birthdayDatingPenny" ) ;
}
2019-12-08 09:09:40 +08:00
if ( Game1 . player . mailReceived . Contains ( "birthdayDatingMaru" ) )
{
Game1 . player . mailReceived . Remove ( "birthdayDatingMaru" ) ;
}
if ( Game1 . player . mailReceived . Contains ( "birthdayDatingSebastian" ) )
{
Game1 . player . mailReceived . Remove ( "birthdayDatingSebastian" ) ;
}
2019-12-08 09:54:49 +08:00
if ( Game1 . player . mailReceived . Contains ( "birthdayDatingLeah" ) )
{
Game1 . player . mailReceived . Remove ( "birthdayDatingLeah" ) ;
}
2019-12-08 10:27:34 +08:00
if ( Game1 . player . mailReceived . Contains ( "birthdayDatingAbigail" ) )
{
Game1 . player . mailReceived . Remove ( "birthdayDatingAbigail" ) ;
}
2019-12-10 10:12:29 +08:00
if ( Game1 . player . mailReceived . Contains ( "birthdayDatingEmily" ) )
{
Game1 . player . mailReceived . Remove ( "birthdayDatingEmily" ) ;
}
2019-12-10 11:02:24 +08:00
if ( Game1 . player . mailReceived . Contains ( "birthdayDatingHaley" ) )
{
Game1 . player . mailReceived . Remove ( "birthdayDatingHaley" ) ;
}
if ( Game1 . player . mailReceived . Contains ( "birthdayDatingHarvey" ) )
{
Game1 . player . mailReceived . Remove ( "birthdayDatingHarvey" ) ;
}
2019-12-11 07:08:01 +08:00
if ( Game1 . player . mailReceived . Contains ( "birthdayDatingElliott" ) )
{
Game1 . player . mailReceived . Remove ( "birthdayDatingElliott" ) ;
}
2019-12-11 07:33:41 +08:00
if ( Game1 . player . mailReceived . Contains ( "birthdayDatingSam" ) )
{
Game1 . player . mailReceived . Remove ( "birthdayDatingSam" ) ;
}
2019-12-11 09:16:25 +08:00
if ( Game1 . player . mailReceived . Contains ( "birthdayDatingAlex" ) )
{
Game1 . player . mailReceived . Remove ( "birthdayDatingAlex" ) ;
}
if ( Game1 . player . mailReceived . Contains ( "birthdayDatingShane" ) )
{
Game1 . player . mailReceived . Remove ( "birthdayDatingShane" ) ;
}
2019-12-07 07:26:16 +08:00
EventHelper communityCenterJunimoBirthday = BirthdayEvents . CommunityCenterJunimoBirthday ( ) ;
2019-12-07 12:59:05 +08:00
EventHelper birthdayDating_Penny = BirthdayEvents . DatingBirthday_Penny ( ) ;
2019-12-11 09:16:25 +08:00
EventHelper birthdayDating_Penny_Big = BirthdayEvents . DatingBirthday_Penny_BigHome ( ) ;
2019-12-08 09:09:40 +08:00
EventHelper birthdayDating_Maru = BirthdayEvents . DatingBirthday_Maru ( ) ;
EventHelper birthdayDating_Sebastian = BirthdayEvents . DatingBirthday_Sebastian ( ) ;
2019-12-08 09:54:49 +08:00
EventHelper birthdayDating_Leah = BirthdayEvents . DatingBirthday_Leah ( ) ;
2019-12-08 10:27:34 +08:00
EventHelper birthdayDating_Abigail = BirthdayEvents . DatingBirthday_Abigail ( ) ;
2019-12-10 10:12:29 +08:00
EventHelper birthdayDating_Emily = BirthdayEvents . DatingBirthday_Emily ( ) ;
2019-12-10 11:02:24 +08:00
EventHelper birthdayDating_Haley = BirthdayEvents . DatingBirthday_Haley ( ) ;
EventHelper birthdayDating_Harvey = BirthdayEvents . DatingBirthday_Harvey ( ) ;
2019-12-11 07:08:01 +08:00
EventHelper birthdayDating_Elliott = BirthdayEvents . DatingBirthday_Elliott ( ) ;
2019-12-11 07:33:41 +08:00
EventHelper birthdayDating_Sam = BirthdayEvents . DatingBirthday_Sam ( ) ;
2019-12-11 09:16:25 +08:00
EventHelper birthdayDating_Alex = BirthdayEvents . DatingBirthday_Alex ( ) ;
EventHelper birthdayDating_Shane = BirthdayEvents . DatingBirthday_Shane ( ) ;
2019-12-08 09:54:49 +08:00
2019-12-07 07:26:16 +08:00
this . eventManager . addEvent ( communityCenterJunimoBirthday ) ;
2019-12-07 12:59:05 +08:00
this . eventManager . addEvent ( birthdayDating_Penny ) ;
2019-12-11 09:16:25 +08:00
this . eventManager . addEvent ( birthdayDating_Penny_Big ) ;
2019-12-08 09:09:40 +08:00
this . eventManager . addEvent ( birthdayDating_Maru ) ;
this . eventManager . addEvent ( birthdayDating_Sebastian ) ;
2019-12-08 09:54:49 +08:00
this . eventManager . addEvent ( birthdayDating_Leah ) ;
2019-12-08 10:27:34 +08:00
this . eventManager . addEvent ( birthdayDating_Abigail ) ;
2019-12-10 10:12:29 +08:00
this . eventManager . addEvent ( birthdayDating_Emily ) ;
2019-12-10 11:02:24 +08:00
this . eventManager . addEvent ( birthdayDating_Haley ) ;
this . eventManager . addEvent ( birthdayDating_Harvey ) ;
2019-12-11 07:08:01 +08:00
this . eventManager . addEvent ( birthdayDating_Elliott ) ;
2019-12-11 07:33:41 +08:00
this . eventManager . addEvent ( birthdayDating_Sam ) ;
2019-12-14 08:00:06 +08:00
this . eventManager . addEvent ( birthdayDating_Alex ) ;
2019-12-11 09:16:25 +08:00
this . eventManager . addEvent ( birthdayDating_Shane ) ;
2016-10-20 15:01:51 +08:00
}
2019-01-06 15:21:06 +08:00
/// <summary>Raised before the game begins writes data to the save file (except the initial save creation).</summary>
2017-08-06 03:51:44 +08:00
/// <param name="sender">The event sender.</param>
2019-01-06 15:21:06 +08:00
/// <param name="e">The event arguments.</param>
private void OnSaving ( object sender , SavingEventArgs e )
2017-08-06 03:51:44 +08:00
{
if ( this . HasChosenBirthday )
2018-12-06 09:16:28 +08:00
this . Helper . Data . WriteJsonFile ( this . DataFilePath , this . PlayerData ) ;
2017-08-06 03:51:44 +08:00
}
2019-01-06 15:21:06 +08:00
/// <summary>Raised after the game state is updated (≈60 times per second).</summary>
2017-07-30 06:02:49 +08:00
/// <param name="sender">The event sender.</param>
2019-01-06 15:21:06 +08:00
/// <param name="e">The event arguments.</param>
private void OnUpdateTicked ( object sender , UpdateTickedEventArgs e )
2016-10-20 15:01:51 +08:00
{
2019-04-12 08:25:54 +08:00
2019-12-05 17:25:46 +08:00
if ( ! Context . IsWorldReady | | Game1 . isFestival ( ) )
{
2017-07-30 06:02:49 +08:00
return ;
2019-12-05 17:25:46 +08:00
}
if ( Game1 . eventUp )
{
if ( this . eventManager ! = null )
{
this . eventManager . update ( ) ;
}
return ;
}
2019-12-31 13:37:42 +08:00
else
{
if ( this . eventManager ! = null )
{
this . eventManager . update ( ) ;
}
}
2019-07-08 08:09:28 +08:00
2018-12-30 18:00:05 +08:00
if ( ! this . HasChosenBirthday & & Game1 . activeClickableMenu = = null & & Game1 . player . Name . ToLower ( ) ! = "unnamed farmhand" )
2018-08-06 00:33:00 +08:00
{
Game1 . activeClickableMenu = new BirthdayMenu ( this . PlayerData . BirthdaySeason , this . PlayerData . BirthdayDay , this . SetBirthday ) ;
this . CheckedForBirthday = false ;
}
2017-02-22 15:29:00 +08:00
2018-12-30 18:00:05 +08:00
if ( ! this . CheckedForBirthday & & Game1 . activeClickableMenu = = null )
2016-10-20 15:01:51 +08:00
{
2017-07-30 06:02:49 +08:00
this . CheckedForBirthday = true ;
// set up birthday
if ( this . IsBirthday ( ) )
2016-10-20 15:01:51 +08:00
{
2019-01-15 04:26:36 +08:00
string starMessage = BirthdayMessages . GetTranslatedString ( "Happy Birthday: Star Message" ) ;
2019-04-12 08:25:54 +08:00
2019-12-14 08:00:06 +08:00
//ModMonitor.Log(starMessage);
2019-01-15 04:26:36 +08:00
Messages . ShowStarMessage ( starMessage ) ;
2018-12-10 11:57:12 +08:00
MultiplayerSupport . SendBirthdayMessageToOtherPlayers ( ) ;
2019-04-12 08:25:54 +08:00
2018-05-01 09:21:31 +08:00
Game1 . player . mailbox . Add ( "birthdayMom" ) ;
Game1 . player . mailbox . Add ( "birthdayDad" ) ;
2017-02-22 15:29:00 +08:00
2019-12-07 12:59:05 +08:00
if ( Game1 . player . friendshipData . ContainsKey ( "Penny" ) )
{
if ( Game1 . player . friendshipData [ "Penny" ] . IsDating ( ) ) {
Game1 . player . mailbox . Add ( "birthdayDatingPenny" ) ;
}
}
2019-12-08 09:09:40 +08:00
if ( Game1 . player . friendshipData . ContainsKey ( "Maru" ) )
{
if ( Game1 . player . friendshipData [ "Maru" ] . IsDating ( ) )
{
Game1 . player . mailbox . Add ( "birthdayDatingMaru" ) ;
}
}
2019-12-08 09:54:49 +08:00
if ( Game1 . player . friendshipData . ContainsKey ( "Leah" ) )
{
if ( Game1 . player . friendshipData [ "Leah" ] . IsDating ( ) )
{
Game1 . player . mailbox . Add ( "birthdayDatingLeah" ) ;
}
}
2019-12-08 10:27:34 +08:00
if ( Game1 . player . friendshipData . ContainsKey ( "Abigail" ) )
{
if ( Game1 . player . friendshipData [ "Abigail" ] . IsDating ( ) )
{
2019-12-10 10:12:29 +08:00
Game1 . player . mailbox . Add ( "birthdayDatingAbigail" ) ;
2019-12-08 10:27:34 +08:00
}
}
2019-12-08 09:54:49 +08:00
2019-12-10 10:12:29 +08:00
if ( Game1 . player . friendshipData . ContainsKey ( "Emily" ) )
{
if ( Game1 . player . friendshipData [ "Emily" ] . IsDating ( ) )
{
Game1 . player . mailbox . Add ( "birthdayDatingEmily" ) ;
}
}
2019-12-10 11:02:24 +08:00
if ( Game1 . player . friendshipData . ContainsKey ( "Haley" ) )
{
if ( Game1 . player . friendshipData [ "Haley" ] . IsDating ( ) )
{
Game1 . player . mailbox . Add ( "birthdayDatingHaley" ) ;
}
}
2019-12-08 09:09:40 +08:00
if ( Game1 . player . friendshipData . ContainsKey ( "Sebastian" ) )
{
if ( Game1 . player . friendshipData [ "Sebastian" ] . IsDating ( ) )
{
Game1 . player . mailbox . Add ( "birthdayDatingSebastian" ) ;
}
}
2019-12-10 11:02:24 +08:00
if ( Game1 . player . friendshipData . ContainsKey ( "Harvey" ) )
{
if ( Game1 . player . friendshipData [ "Harvey" ] . IsDating ( ) )
{
Game1 . player . mailbox . Add ( "birthdayDatingHarvey" ) ;
}
}
2019-12-11 07:08:01 +08:00
if ( Game1 . player . friendshipData . ContainsKey ( "Elliott" ) )
{
if ( Game1 . player . friendshipData [ "Elliott" ] . IsDating ( ) )
{
Game1 . player . mailbox . Add ( "birthdayDatingElliott" ) ;
}
}
2019-12-10 11:02:24 +08:00
2019-12-11 09:16:25 +08:00
if ( Game1 . player . friendshipData . ContainsKey ( "Sam" ) )
{
if ( Game1 . player . friendshipData [ "Sam" ] . IsDating ( ) )
{
Game1 . player . mailbox . Add ( "birthdayDatingSam" ) ;
}
}
if ( Game1 . player . friendshipData . ContainsKey ( "Alex" ) )
{
if ( Game1 . player . friendshipData [ "Alex" ] . IsDating ( ) )
{
Game1 . player . mailbox . Add ( "birthdayDatingAlex" ) ;
}
}
if ( Game1 . player . friendshipData . ContainsKey ( "Shane" ) )
{
if ( Game1 . player . friendshipData [ "Shane" ] . IsDating ( ) )
{
Game1 . player . mailbox . Add ( "birthdayDatingShane" ) ;
}
}
2019-12-07 07:04:48 +08:00
if ( Game1 . player . CanReadJunimo ( ) )
{
Game1 . player . mailbox . Add ( "birthdayJunimos" ) ;
}
2019-07-08 08:09:28 +08:00
2017-07-30 06:02:49 +08:00
foreach ( GameLocation location in Game1 . locations )
2016-10-20 15:01:51 +08:00
{
foreach ( NPC npc in location . characters )
{
2017-07-30 06:02:49 +08:00
if ( npc is Child | | npc is Horse | | npc is Junimo | | npc is Monster | | npc is Pet )
continue ;
2019-12-14 08:00:06 +08:00
string message = this . messages . getBirthdayMessage ( npc . Name ) ;
Dialogue d = new Dialogue ( message , npc ) ;
npc . CurrentDialogue . Push ( d ) ;
if ( npc . CurrentDialogue . ElementAt ( 0 ) ! = d ) npc . setNewDialogue ( message ) ;
2016-10-20 15:01:51 +08:00
}
}
}
2016-11-08 17:19:56 +08:00
2018-12-06 09:16:28 +08:00
//Don't constantly set the birthday menu.
2018-12-30 18:00:05 +08:00
if ( Game1 . activeClickableMenu ? . GetType ( ) = = typeof ( BirthdayMenu ) )
return ;
2017-07-30 06:02:49 +08:00
// ask for birthday date
2018-12-30 18:00:05 +08:00
if ( ! this . HasChosenBirthday & & Game1 . activeClickableMenu = = null )
2016-11-08 17:19:56 +08:00
{
2017-08-06 03:51:44 +08:00
Game1 . activeClickableMenu = new BirthdayMenu ( this . PlayerData . BirthdaySeason , this . PlayerData . BirthdayDay , this . SetBirthday ) ;
2017-07-30 06:02:49 +08:00
this . CheckedForBirthday = false ;
2016-11-08 17:19:56 +08:00
}
}
2018-12-06 09:16:28 +08:00
2016-10-20 15:01:51 +08:00
}
2018-12-06 09:16:28 +08:00
/// <summary>Set the player's birthday/</summary>
2017-07-30 06:02:49 +08:00
/// <param name="season">The birthday season.</param>
/// <param name="day">The birthday day.</param>
private void SetBirthday ( string season , int day )
2016-10-20 15:01:51 +08:00
{
2017-08-06 03:51:44 +08:00
this . PlayerData . BirthdaySeason = season ;
this . PlayerData . BirthdayDay = day ;
2017-02-22 15:29:00 +08:00
}
2017-07-30 06:02:49 +08:00
/// <summary>Reset the queue of villager names.</summary>
private void ResetVillagerQueue ( )
2017-02-22 15:29:00 +08:00
{
2017-07-30 06:02:49 +08:00
this . VillagerQueue . Clear ( ) ;
foreach ( GameLocation location in Game1 . locations )
2016-10-20 15:01:51 +08:00
{
2017-07-30 06:02:49 +08:00
foreach ( NPC npc in location . characters )
2016-10-20 15:01:51 +08:00
{
2017-07-30 06:02:49 +08:00
if ( npc is Child | | npc is Horse | | npc is Junimo | | npc is Monster | | npc is Pet )
2017-02-22 15:29:00 +08:00
continue ;
2019-07-08 08:09:28 +08:00
if ( this . VillagerQueue . ContainsKey ( npc . Name ) )
2017-07-30 06:02:49 +08:00
continue ;
2019-07-08 08:09:28 +08:00
this . VillagerQueue . Add ( npc . Name , new VillagerInfo ( ) ) ;
2017-02-22 15:29:00 +08:00
}
2016-10-20 15:01:51 +08:00
}
}
2017-07-30 06:02:49 +08:00
/// <summary>Get whether today is the player's birthday.</summary>
2019-12-05 05:24:21 +08:00
public bool IsBirthday ( )
2017-07-30 06:02:49 +08:00
{
return
2017-08-06 03:51:44 +08:00
this . PlayerData . BirthdayDay = = Game1 . dayOfMonth
2019-12-14 08:00:06 +08:00
& & this . PlayerData . BirthdaySeason . ToLower ( ) . Equals ( Game1 . currentSeason . ToLower ( ) ) ;
2017-07-30 06:02:49 +08:00
}
2016-10-20 15:01:51 +08:00
2019-12-14 08:00:06 +08:00
/ *
2017-08-06 03:51:44 +08:00
/// <summary>Migrate the legacy settings for the current player.</summary>
private void MigrateLegacyData ( )
2017-07-30 06:02:49 +08:00
{
2017-08-06 03:51:44 +08:00
// skip if no legacy data or new data already exists
try
2016-10-20 15:01:51 +08:00
{
2018-01-31 04:46:04 +08:00
if ( ! File . Exists ( this . LegacyDataFilePath ) | | File . Exists ( this . DataFilePath ) )
2018-12-30 18:00:05 +08:00
{
if ( this . PlayerData = = null )
this . PlayerData = new PlayerData ( ) ;
}
2016-10-20 15:01:51 +08:00
}
2018-12-30 18:00:05 +08:00
catch
2016-10-20 15:01:51 +08:00
{
2018-01-31 04:46:04 +08:00
// migrate to new file
try
{
string [ ] text = File . ReadAllLines ( this . LegacyDataFilePath ) ;
2018-12-06 09:16:28 +08:00
this . Helper . Data . WriteJsonFile ( this . DataFilePath , new PlayerData
2018-01-31 04:46:04 +08:00
{
BirthdaySeason = text [ 3 ] ,
BirthdayDay = Convert . ToInt32 ( text [ 5 ] )
} ) ;
FileInfo file = new FileInfo ( this . LegacyDataFilePath ) ;
file . Delete ( ) ;
if ( ! file . Directory . EnumerateFiles ( ) . Any ( ) )
file . Directory . Delete ( ) ;
}
catch ( Exception ex )
{
this . Monitor . Log ( $"Error migrating data from the legacy 'Player_Birthdays' folder for the current player. Technical details:\n {ex}" , LogLevel . Error ) ;
}
2016-10-20 15:01:51 +08:00
}
}
2019-12-14 08:00:06 +08:00
* /
2016-10-20 15:01:51 +08:00
}
}