Coding Help How to add secret_note?

Athos

Cowpoke
I try to add a object using the texture of original SecretNote, But I cant make the MAXstack to be 1. How can I resolve it? Please help me. Thanks
 

SomeoneEls

Farmer
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;)
 

SomeoneEls

Farmer
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;)

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.
 

Athos

Cowpoke
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.
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.
 

SomeoneEls

Farmer
Probably skip it since you usually dont carry them I think.

Here is a method for handling any amount of secret letters you want.

C#:
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.
                }
            }
        }
    }
}
Then in your entry method, you need

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.
(EDIT) forgot about community rules, just look it up on google (EDIT)
 
Last edited:

SomeoneEls

Farmer
OH YEAH

here is every location name in the game, ignore the number after.

FarmHouse1
FarmCave2
Town3
JoshHouse4
HaleyHouse5
SamHouse6
Blacksmith7
ManorHouse8
SeedShop9
Saloon10
Trailer11
Hospital12
HarveyRoom13
Beach14
BeachNightMarket15
ElliottHouse16
Mountain17
ScienceHouse18
SebastianRoom19
Tent20
Forest21
WizardHouse22
AnimalShop23
LeahHouse24
BusStop25
Mine26
Sewer27
BugLand28
Desert29
Club30
SandyHouse31
ArchaeologyHouse32
WizardHouseBasement33
AdventureGuild34
Woods35
Railroad36
WitchSwamp37
WitchHut38
WitchWarpCave39
Summit40
FishShop41
BathHouse_Entry42
BathHouse_MensLocker43
BathHouse_WomensLocker44
BathHouse_Pool45
CommunityCenter46
JojaMart47
Greenhouse48
SkullCave49
Backwoods50
Tunnel51
Trailer_Big52
Cellar53
MermaidHouse54
Submarine55
AbandonedJojaMart56
MovieTheater57
Sunroom58
BoatTunnel59
IslandSouth60
IslandSouthEast61
IslandSouthEastCave62
IslandEast63
IslandWest64
IslandNorth65
IslandHut66
IslandWestCave167
IslandNorthCave168
IslandFieldOffice69
IslandFarmHouse70
CaptainRoom71
IslandShrine72
IslandFarmCave73
Caldera74
LeoTreeHouse75
QiNutRoom76
MasteryCave77
DesertFestival78
LewisBasement79

For these ignore the second number.
Cellar2 80
Cellar3 81
Cellar4 82
Cellar5 83
Cellar6 84
Cellar7 85
Cellar8 86
 

SomeoneEls

Farmer
oop
Probably skip it since you usually dont carry them I think.

Here is a method for handling any amount of secret letters you want.

C#:
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.
                }
            }
        }
    }
}
Then in your entry method, you need

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.
oop. need to debug rq
 

SomeoneEls

Farmer
C#:
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
        }
    }
}

Done! This should work.
 
Top