Try modifying Content/Data/SecretNotes.json, you should just be able to add another entry to the dictionary there for secret notes you get via the hoe.. and other methods?
Are there other methods to finding randomly generated notes?
I dunno.
For secret notes that are behind bushes and stuff, I think those are hard coded, so you would prob have to do some c# shennanigans.
(If they arent, please correct me bc that would be so much easier ;u;)
Thank you ! You are the first one who reply to me on forum! And I do want to use C# to handle the item use event (pop up,attachments,and so on). But I am still thiking about the max stack. Maybe I need to skip it or (ugly code) add a function to implement it.If you do wanna make em via c#, the idea is that once the farmer clicks on a tile (you can just hard-code the tile location and check if the farmer clicks on it), you do a pop up of a note.
Oh yeah, if your just modifying the Content/Data/SecretNotes.json, it should be CP compatable.
private void SecretNoteEvents(object obj)
{
GameLocation[] LOCATIONS = { };
Vector2[] TILES = { };
String[] MESSAGES = { };
//treat locations[i], tiles[i], and messages[i] as the data of the ith secret letter
LOCATIONS.AddItem(Game1.getLocationFromName({your location name here}); //1st secret letter location
...
TILES.AddItem(new Vector2({ X val },{ y val}); //1st secret letter tile
...
MESSAGES.AddItem("your message here"); //1st secret letter message
...
while (dayFlag)
{
if (Game1.didPlayerJustLeftClick() && !Game1.isTimePaused) // checks if the player clicks (its outside as a guard clause), also checks if player is in menu
{
for (int i = 0; i < LOCATIONS.Length; i++) //assumes that the arrays are all equal length.
{
if (Game1.player.currentLocation.Equals(LOCATIONS[i]) && Game1.currentCursorTile.Equals(TILES[i])) //is player in location and cursor at tile?
{
//show the letter
Game1.drawLetterMessage(MESSAGES[i]);
Thread.sleep(1000); //for no dupe messages
break; //break because there cant be more than one letter at a tile.
}
}
}
}
}
oop. need to debug rqProbably skip it since you usually dont carry them I think.
Here is a method for handling any amount of secret letters you want.
Then in your entry method, you needC#:private void SecretNoteEvents(object obj) { GameLocation[] LOCATIONS = { }; Vector2[] TILES = { }; String[] MESSAGES = { }; //treat locations[i], tiles[i], and messages[i] as the data of the ith secret letter LOCATIONS.AddItem(Game1.getLocationFromName({your location name here}); //1st secret letter location ... TILES.AddItem(new Vector2({ X val },{ y val}); //1st secret letter tile ... MESSAGES.AddItem("your message here"); //1st secret letter message ... while (dayFlag) { if (Game1.didPlayerJustLeftClick() && !Game1.isTimePaused) // checks if the player clicks (its outside as a guard clause), also checks if player is in menu { for (int i = 0; i < LOCATIONS.Length; i++) //assumes that the arrays are all equal length. { if (Game1.player.currentLocation.Equals(LOCATIONS[i]) && Game1.currentCursorTile.Equals(TILES[i])) //is player in location and cursor at tile? { //show the letter Game1.drawLetterMessage(MESSAGES[i]); Thread.sleep(1000); //for no dupe messages break; //break because there cant be more than one letter at a tile. } } } } }
helper.Events.GameLoop.DayStarted += this.OnDayStarted;
helper.Events.GameLoop.DayEnding += this.OnDayEnding;
with the methods OnDayStarted being your day starting method and ondayending being your day ending method
The args and met look like this
private void OnDayStarted(object? sender, DayStartedEventArgs e)
private void OnDayEnding(object? sender, DayEndingEventArgs e)
After that, you want to add a thread to your global varibles, and a flag (outside the methods but in the class of ModEntry)
V
Thread secretLetterLoop;
bool dayFlag
For the day starting method you want to add this code to the method
secretLetterLoop = new Thread(SecretNoteEvents);
dayFlag = true;
secretLetterLoop.Start();
And the day ending..
dayFlag = false;
/// V Optional stuff if you wanna make sure no more than 1 thread will be existing at a time V
try
{
while ( secretLetterLoop.IsAlive)
{
}
break;
}
catch (NullReferenceException a)
{
break;
}
Whew. That was a lot. Im pretty sure ittl work... I think.
If you want to find out what tile needs to be used for a letter, use the DebugMode mod by Pathoschild.
private void SecretNoteEvents(object obj)
{
LinkedList<String> LOCATIONS = new LinkedList<String>();
LinkedList<Vector2> TILES = new LinkedList<Vector2>();
LinkedList<String> MESSAGES = new LinkedList<String>();
///LOCATIONS.AddLast("your location name here");
///...
//TILES.AddLast(new Vector2({ X val },{ y val});
//...
//MESSAGES.AddLast("your message here");
//EXAMPLE
//LOCATIONS.AddLast("FarmHouse");
//TILES.AddLast(new Vector2(10, 10));
//MESSAGES.AddLast("hello");
while (dayFlag)
{
if ( (Helper.Input.IsDown(SButton.MouseLeft) || Helper.Input.IsDown(SButton.MouseRight)) && !Game1.isTimePaused) // checks if the player clicks (its outside as a guard clause)
{
for (int i = 0; i < LOCATIONS.Count; i++) //assumes that the arrays are all equal length.
{
if (Game1.player.currentLocation.Name.Equals(LOCATIONS.ElementAt(i)) && (Game1.currentCursorTile.X == TILES.ElementAt(i).X) && (Game1.currentCursorTile.X == TILES.ElementAt(i).Y)) //is player in location and cursor at tile?
{
//show the letter
Game1.drawLetterMessage(MESSAGES.ElementAt(i));
break; //break because there cant be more than one letter at a tile.
}
}
Thread.Sleep(1000); //sleep for no dupes
}
}
}