From 1fb92f7cf7a1afed1db17d64bd8e231ed3d8c26c Mon Sep 17 00:00:00 2001 From: Date: Sat, 3 Feb 2018 11:50:56 -0800 Subject: [PATCH 01/18] Finally got XACT music packs to load in again. Next up is loading in WAV files. --- .../Framework/MusicHexProcessor.cs | 16 ++++-- .../Framework/MusicManager.cs | 21 ++++++- .../Framework/XACTMusicPack.cs | 24 ++++---- .../StardewSymphony.cs | 56 +++++++++++++++---- .../StardewSymphonyRemastered/manifest.json | 10 ++++ 5 files changed, 100 insertions(+), 27 deletions(-) create mode 100644 GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/manifest.json diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/MusicHexProcessor.cs b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/MusicHexProcessor.cs index a8ac41dc..d77c0d39 100644 --- a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/MusicHexProcessor.cs +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/MusicHexProcessor.cs @@ -49,6 +49,8 @@ namespace StardewSymphonyRemastered.Framework string rawName = FileName.Substring(0, FileName.Length - 4); string cueName = rawName + "CueList.txt"; + //Not used as the music pack can change between loads + /* if (File.Exists(cueName)) { string[] arr = File.ReadAllLines(cueName); @@ -59,6 +61,7 @@ namespace StardewSymphonyRemastered.Framework } return names; } + */ string hexDumpContents = HexDump(array); string rawHexName = rawName + "HexDump.txt"; @@ -89,20 +92,25 @@ namespace StardewSymphonyRemastered.Framework foreach (var split in splits) { if (split == "") continue; - try { Game1.waveBank = musicPack.WaveBank; Game1.soundBank = musicPack.SoundBank; - if (Game1.soundBank.GetCue(split) != null) - cleanCueNames.Add(split); + if (Game1.soundBank.GetCue(split) != null) + { + cleanCueNames.Add(split); + } reset.Invoke(); } - catch { } + catch(Exception err) + { + reset.Invoke(); + } } + return cleanCueNames; } diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/MusicManager.cs b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/MusicManager.cs index 39409b9e..d4aacddf 100644 --- a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/MusicManager.cs +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/MusicManager.cs @@ -223,8 +223,27 @@ namespace StardewSymphonyRemastered.Framework /// Adds a valid xwb music pack to the list of music packs available. /// /// - public void addMusicPack(XACTMusicPack xwbMusicPack) + /// Whether or not to display the process to the console. Will include information from the pack's metadata. Default:False + /// If displayLogInformation is also true this will display the name of all of the songs in the music pack when it is added in. + public void addMusicPack(XACTMusicPack xwbMusicPack,bool displayLogInformation=false,bool displaySongs=false) { + if (displayLogInformation == true) + { + StardewSymphony.ModMonitor.Log("Adding a new music pack!"); + StardewSymphony.ModMonitor.Log(" Name:" + xwbMusicPack.musicPackInformation.name); + StardewSymphony.ModMonitor.Log(" Author:" + xwbMusicPack.musicPackInformation.author); + StardewSymphony.ModMonitor.Log(" Description:" + xwbMusicPack.musicPackInformation.description); + StardewSymphony.ModMonitor.Log(" Version Info:" + xwbMusicPack.musicPackInformation.versionInfo); + StardewSymphony.ModMonitor.Log(" Song List:"); + + if (displaySongs == true) + { + foreach(var songname in xwbMusicPack.songInformation.listOfSongsWithoutTriggers) + { + StardewSymphony.ModMonitor.Log(" " + songname); + } + } + } this.musicPacks.Add(xwbMusicPack.musicPackInformation.name,xwbMusicPack); } } diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/XACTMusicPack.cs b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/XACTMusicPack.cs index 7e443a9d..20b89086 100644 --- a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/XACTMusicPack.cs +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/XACTMusicPack.cs @@ -17,25 +17,23 @@ namespace StardewSymphonyRemastered.Framework public Microsoft.Xna.Framework.Audio.WaveBank WaveBank; public Microsoft.Xna.Framework.Audio.SoundBank SoundBank; - - public Cue currentCue; - - //Make Music pack meta data. Includes author, version, description. - - public string XWBPath; + public string WaveBankPath; + public string SoundBankPath; /// /// Constructor. /// /// /// - /// - public XACTMusicPack(string directoryToXwb,string pathToXWB) + /// + /// + public XACTMusicPack(string directoryToXwb,string pathToWaveBank,string pathToSoundBank) { this.directory = directoryToXwb; - this.XWBPath = pathToXWB; + this.WaveBankPath = pathToWaveBank; + this.SoundBankPath = pathToSoundBank; this.songInformation = new SongSpecifics(); this.currentCue = null; this.musicPackInformation = MusicPackMetaData.readFromJson(Path.Combine(directoryToXwb, "MusicPackInformation.json")); @@ -44,6 +42,10 @@ namespace StardewSymphonyRemastered.Framework StardewSymphony.ModMonitor.Log("Error: MusicPackInformation.json not found at: " + directoryToXwb + ". Blank information will be put in place.",StardewModdingAPI.LogLevel.Warn); this.musicPackInformation = new MusicPackMetaData("???","???","","0.0.0"); } + + this.WaveBank = new WaveBank(Game1.audioEngine, this.WaveBankPath); + this.SoundBank = new SoundBank(Game1.audioEngine,this.SoundBankPath); + this.loadMusicFiles(); } /// @@ -51,7 +53,7 @@ namespace StardewSymphonyRemastered.Framework /// public override void loadMusicFiles() { - this.songInformation.listOfSongsWithoutTriggers=StardewSymphonyRemastered.Framework.MusicHexProcessor.ProcessSongNamesFromHex(this,StardewSymphony.Reset,this.XWBPath); + this.songInformation.listOfSongsWithoutTriggers=StardewSymphonyRemastered.Framework.MusicHexProcessor.ProcessSongNamesFromHex(this,StardewSymphony.Reset,this.SoundBankPath); } /// @@ -62,7 +64,7 @@ namespace StardewSymphonyRemastered.Framework private Cue getCue(string name) { if (this.songInformation.isSongInList(name) == false) { - StardewSymphony.ModMonitor.Log("Error! The song " + name + " could not be found in music pack " + this.musicPackInformation.name+". Please ensure that this song is part of this music pack located at: "+ this.XWBPath+ " or contact the music pack author: "+this.musicPackInformation.author,StardewModdingAPI.LogLevel.Error); + StardewSymphony.ModMonitor.Log("Error! The song " + name + " could not be found in music pack " + this.musicPackInformation.name+". Please ensure that this song is part of this music pack located at: "+ this.WaveBankPath+ " or contact the music pack author: "+this.musicPackInformation.author,StardewModdingAPI.LogLevel.Error); return null; } else diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphony.cs b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphony.cs index 84dc33ff..ac09e983 100644 --- a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphony.cs +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphony.cs @@ -42,6 +42,7 @@ namespace StardewSymphonyRemastered public static string XACTMusicDirectory; public static string TemplateMusicDirectory; + public bool musicPacksInitialized; public override void Entry(IModHelper helper) { @@ -52,7 +53,7 @@ namespace StardewSymphonyRemastered StardewModdingAPI.Events.SaveEvents.AfterLoad += SaveEvents_AfterLoad; StardewModdingAPI.Events.LocationEvents.CurrentLocationChanged += LocationEvents_CurrentLocationChanged; - + StardewModdingAPI.Events.GameEvents.UpdateTick += GameEvents_UpdateTick; musicManager = new MusicManager(); MusicPath = Path.Combine(ModHelper.DirectoryPath, "Content", "Music"); @@ -62,7 +63,24 @@ namespace StardewSymphonyRemastered this.createDirectories(); this.createBlankXACTTemplate(); + + musicPacksInitialized = false; + } + + private void GameEvents_UpdateTick(object sender, EventArgs e) + { + if (Game1.activeClickableMenu.GetType()!=typeof(StardewValley.Menus.TitleMenu)&& Game1.audioEngine.isNull()) return; + if (musicPacksInitialized == false) + { + initializeMusicPacks(); + musicPacksInitialized = true; + } + } + + public void initializeMusicPacks() + { //load in all packs here. + loadXACTMusicPacks(); } public void createDirectories() @@ -80,7 +98,7 @@ namespace StardewSymphonyRemastered Directory.CreateDirectory(path); } if(!File.Exists(Path.Combine(path, "MusicPackInformation.json"))){ - MusicPackMetaData blankMetaData = new MusicPackMetaData(); + MusicPackMetaData blankMetaData = new MusicPackMetaData("Omegas's Music Data Example","Omegasis","Just a simple example of how metadata is formated for music packs. Feel free to copy and edit this one!","1.0.0 CoolExample"); blankMetaData.writeToJson(Path.Combine(path, "MusicPackInformation.json")); } if (!File.Exists(Path.Combine(path, "readme.txt"))) @@ -96,27 +114,43 @@ namespace StardewSymphonyRemastered string[] listOfDirectories= Directory.GetDirectories(XACTMusicDirectory); foreach(string folder in listOfDirectories) { - string waveBank = Path.Combine(folder, "Wave Bank.xwb"); - string soundBank = Path.Combine(folder, "Sound Bank.xwb"); - string metaData = Path.Combine(folder, "MusicPackInformation.json"); - if (!File.Exists(waveBank)) + //This chunk essentially allows people to name .xwb and .xsb files whatever they want. + string[] xwb=Directory.GetFiles(folder, "*.xwb"); + string[] xsb = Directory.GetFiles(folder, "*.xsb"); + + string[] debug = Directory.GetFiles(folder); + if (xwb.Length == 0) { - ModMonitor.Log("Error loading in attempting to load music pack from: " + folder + ". There is no file Wave Bank.xwb located in this directory. AKA there is no valid music here.", LogLevel.Error); + ModMonitor.Log("Error loading in attempting to load music pack from: " + folder + ". There is no wave bank music file: .xwb located in this directory. AKA there is no valid music here.", LogLevel.Error); + return; + } + if (xwb.Length >= 2) + { + ModMonitor.Log("Error loading in attempting to load music pack from: " + folder + ". There are too many wave bank music files or .xwbs located in this directory. Please ensure that there is only one music pack in this folder. You can make another music pack but putting a wave bank file in a different folder.", LogLevel.Error); return; } - if (!File.Exists(soundBank)) + if (xsb.Length == 0) { - ModMonitor.Log("Error loading in attempting to load music pack from: " + folder + ". There is no file Sound Bank.xwb located in this directory. This is needed to play the music from Wave Bank.xwb", LogLevel.Error); + ModMonitor.Log("Error loading in attempting to load music pack from: " + folder + ". There is no sound bank music file: .xsb located in this directory. AKA there is no valid music here.", LogLevel.Error); return; } + if (xsb.Length >= 2) + { + ModMonitor.Log("Error loading in attempting to load music pack from: " + folder + ". There are too many sound bank music files or .xsbs located in this directory. Please ensure that there is only one sound reference file in this folder. You can make another music pack but putting a sound file in a different folder.", LogLevel.Error); + return; + } + + string waveBank = xwb[0]; + string soundBank = xsb[0]; + string metaData = Path.Combine(folder, "MusicPackInformation.json"); if (!File.Exists(metaData)) { ModMonitor.Log("WARNING! Loading in a music pack from: " + folder + ". There is no MusicPackInformation.json associated with this music pack meaning that while songs can be played from this pack, no information about it will be displayed.", LogLevel.Error); } - StardewSymphonyRemastered.Framework.XACTMusicPack musicPack = new XACTMusicPack(folder, waveBank); - musicManager.addMusicPack(musicPack); + StardewSymphonyRemastered.Framework.XACTMusicPack musicPack = new XACTMusicPack(folder, waveBank,soundBank); + musicManager.addMusicPack(musicPack,true,true); } } diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/manifest.json b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/manifest.json new file mode 100644 index 00000000..d9b57173 --- /dev/null +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/manifest.json @@ -0,0 +1,10 @@ +{ + "Name": "Stardew Symphony", + "Author": "Alpha_Omegasis", + "Version": "2.0.0", + "Description": "Adding more music to the game one beep at a time. Now with streaming!", + "UniqueID": "Omegasis.StardewSymphony", + "EntryDll": "StardewSymphonyRemastered.dll", + "MinimumApiVersion": "2.0", + "UpdateKeys": [ "Nexus:425" ] +} From b5b6c2083095cb33c81b0db8c0b89fc8b4e108bd Mon Sep 17 00:00:00 2001 From: Date: Sat, 3 Feb 2018 20:40:03 -0800 Subject: [PATCH 02/18] Sucessfully loaded in songs with the WAV music packs. Just need to implement functionality in the WAV "packs" --- .../Framework/MusicManager.cs | 36 ++++--- .../Framework/MusicPack.cs | 5 + .../Framework/Song.cs | 84 +++++++++++++++++ .../Framework/SongSpecifics.cs | 92 ++++++++++-------- .../Framework/WavMusicPack.cs | 93 +++++++++++++++++++ .../Framework/XACTMusicPack.cs | 37 +++++++- .../StardewSymphony.cs | 51 ++++++++-- .../StardewSymphonyRemastered.csproj | 1 + 8 files changed, 335 insertions(+), 64 deletions(-) create mode 100644 GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/Song.cs diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/MusicManager.cs b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/MusicManager.cs index d4aacddf..4a4ff992 100644 --- a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/MusicManager.cs +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/MusicManager.cs @@ -5,6 +5,7 @@ using System.Text; using System.Threading.Tasks; using StardewSymphonyRemastered; using StardewValley; +using System.IO; namespace StardewSymphonyRemastered.Framework { @@ -168,9 +169,9 @@ namespace StardewSymphonyRemastered.Framework /// /// /// - public Dictionary> getListOfApplicableMusicPacks(string songListKey) + public Dictionary> getListOfApplicableMusicPacks(string songListKey) { - Dictionary> listOfValidDictionaries = new Dictionary>(); + Dictionary> listOfValidDictionaries = new Dictionary>(); foreach(var v in this.musicPacks) { var songList= v.Value.songInformation.getSongList(songListKey).Value; @@ -207,44 +208,39 @@ namespace StardewSymphonyRemastered.Framework var songName = musicPackPair.Value.ElementAt(randInt2); - this.currentMusicPack.playSong(songName); + this.currentMusicPack.playSong(songName.name); } - /// - /// TODO: Make WAV MUSIC PACKS - /// - /// - public void addMusicPack(WavMusicPack wavMusicPack) - { - - } /// /// Adds a valid xwb music pack to the list of music packs available. /// - /// + /// /// Whether or not to display the process to the console. Will include information from the pack's metadata. Default:False /// If displayLogInformation is also true this will display the name of all of the songs in the music pack when it is added in. - public void addMusicPack(XACTMusicPack xwbMusicPack,bool displayLogInformation=false,bool displaySongs=false) + public void addMusicPack(MusicPack musicPack,bool displayLogInformation=false,bool displaySongs=false) { if (displayLogInformation == true) { StardewSymphony.ModMonitor.Log("Adding a new music pack!"); - StardewSymphony.ModMonitor.Log(" Name:" + xwbMusicPack.musicPackInformation.name); - StardewSymphony.ModMonitor.Log(" Author:" + xwbMusicPack.musicPackInformation.author); - StardewSymphony.ModMonitor.Log(" Description:" + xwbMusicPack.musicPackInformation.description); - StardewSymphony.ModMonitor.Log(" Version Info:" + xwbMusicPack.musicPackInformation.versionInfo); + + + StardewSymphony.ModMonitor.Log(" Location:" + musicPack.shortenedDirectory); + StardewSymphony.ModMonitor.Log(" Name:" + musicPack.musicPackInformation.name); + StardewSymphony.ModMonitor.Log(" Author:" + musicPack.musicPackInformation.author); + StardewSymphony.ModMonitor.Log(" Description:" + musicPack.musicPackInformation.description); + StardewSymphony.ModMonitor.Log(" Version Info:" + musicPack.musicPackInformation.versionInfo); StardewSymphony.ModMonitor.Log(" Song List:"); if (displaySongs == true) { - foreach(var songname in xwbMusicPack.songInformation.listOfSongsWithoutTriggers) + foreach(var song in musicPack.songInformation.listOfSongsWithoutTriggers) { - StardewSymphony.ModMonitor.Log(" " + songname); + StardewSymphony.ModMonitor.Log(" " + song.name); } } } - this.musicPacks.Add(xwbMusicPack.musicPackInformation.name,xwbMusicPack); + this.musicPacks.Add(musicPack.musicPackInformation.name,musicPack); } } } diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/MusicPack.cs b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/MusicPack.cs index a39b1e0a..4bbad6d1 100644 --- a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/MusicPack.cs +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/MusicPack.cs @@ -13,6 +13,7 @@ namespace StardewSymphonyRemastered.Framework public class MusicPack { public string directory; + public string shortenedDirectory; public StardewSymphonyRemastered.Framework.SongSpecifics songInformation; public MusicPackMetaData musicPackInformation; @@ -52,5 +53,9 @@ namespace StardewSymphonyRemastered.Framework return ""; } + public virtual void setModDirectoryFromFullDirectory() + { + + } } } diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/Song.cs b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/Song.cs new file mode 100644 index 00000000..f01f386b --- /dev/null +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/Song.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.IO; + +namespace StardewSymphonyRemastered.Framework +{ + /// + /// The class to be used to manage individual songs. + /// + public class Song + { + /// + /// The path to the song. In the case of XACT songs this points to the .xwb file. For WAV files this points directly to the WAV file itself. + /// + public string pathToSong; + + /// + /// The name of the song itself. + /// + public string name; + + /// + /// Blank Constructor; + /// + public Song() + { + + } + + /// + /// Constructor to be used for WAV files. + /// + /// + public Song(string PathToSong) + { + this.pathToSong=PathToSong; + this.name = getNameFromPath(this.pathToSong); + } + + /// + /// Constructor to be used for XACT music packs. + /// + /// + /// + public Song(string PathToSong,string Name) + { + this.pathToSong = PathToSong; + this.name = Name; + } + + /// + /// Parse the name of the file from the path provided. + /// + /// + /// + public string getNameFromPath(string path) + { + return Path.GetFileNameWithoutExtension(path); + } + + /// + /// Read the info from a .json file. + /// + /// + /// + public static Song ReadFromJson(string path) + { + return StardewSymphony.ModHelper.ReadJsonFile(path); + } + + /// + /// Write the information of the instance to a .json file. + /// + /// The path to which the json file is written to. + public void writeToJson(string path) + { + StardewSymphony.ModHelper.WriteJsonFile(path, this); + } + + } +} diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/SongSpecifics.cs b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/SongSpecifics.cs index f4822747..dbb7965d 100644 --- a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/SongSpecifics.cs +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/SongSpecifics.cs @@ -14,13 +14,13 @@ namespace StardewSymphonyRemastered.Framework /// public class SongSpecifics { - Dictionary> listOfSongsWithTriggers; //triggerName, + Dictionary> listOfSongsWithTriggers; //triggerName, - Dictionary> eventSongs; + Dictionary> eventSongs; - Dictionary> festivalSongs; + Dictionary> festivalSongs; - public List listOfSongsWithoutTriggers; + public List listOfSongsWithoutTriggers; public static List locations = new List(); public static List festivals = new List(); @@ -71,11 +71,11 @@ namespace StardewSymphonyRemastered.Framework "night" }; - listOfSongsWithTriggers = new Dictionary>(); - eventSongs = new Dictionary>(); - festivalSongs = new Dictionary>(); + listOfSongsWithTriggers = new Dictionary>(); + eventSongs = new Dictionary>(); + festivalSongs = new Dictionary>(); - this.listOfSongsWithoutTriggers = new List(); + this.listOfSongsWithoutTriggers = new List(); this.addSongLists(); @@ -263,9 +263,9 @@ namespace StardewSymphonyRemastered.Framework /// Adds the song's reference to a music pack. /// /// - public void addSongToMusicPack(string songName) + public void addSongToMusicPack(Song song) { - this.listOfSongsWithoutTriggers.Add(songName); + this.listOfSongsWithoutTriggers.Add(song); } /// @@ -275,7 +275,8 @@ namespace StardewSymphonyRemastered.Framework /// public bool isSongInList(string songName) { - return listOfSongsWithoutTriggers.Contains(songName); + Song s = getSongFromList(listOfSongsWithoutTriggers, songName); + return listOfSongsWithoutTriggers.Contains(s); } /// @@ -287,16 +288,16 @@ namespace StardewSymphonyRemastered.Framework { foreach (var season in seasons) { - listOfSongsWithTriggers.Add(loc + seperator + season, new List()); + listOfSongsWithTriggers.Add(loc + seperator + season, new List()); foreach(var Weather in weather) { - listOfSongsWithTriggers.Add(loc + seperator + season + seperator + Weather, new List()); + listOfSongsWithTriggers.Add(loc + seperator + season + seperator + Weather, new List()); foreach(var day in daysOfWeek) { - listOfSongsWithTriggers.Add(loc + seperator + season + seperator + Weather + seperator + day, new List()); + listOfSongsWithTriggers.Add(loc + seperator + season + seperator + Weather + seperator + day, new List()); foreach(var time in timesOfDay) { - listOfSongsWithTriggers.Add(loc + seperator + season + seperator + Weather + seperator + day + seperator + time, new List()); + listOfSongsWithTriggers.Add(loc + seperator + season + seperator + Weather + seperator + day + seperator + time, new List()); } } } @@ -306,16 +307,16 @@ namespace StardewSymphonyRemastered.Framework //Add in some default seasonal music because maybe a location doesn't have some music? foreach (var season in seasons) { - listOfSongsWithTriggers.Add(season, new List()); + listOfSongsWithTriggers.Add(season, new List()); foreach (var Weather in weather) { - listOfSongsWithTriggers.Add( season + seperator + Weather, new List()); + listOfSongsWithTriggers.Add( season + seperator + Weather, new List()); foreach (var day in daysOfWeek) { - listOfSongsWithTriggers.Add(season + seperator + Weather + seperator + day, new List()); + listOfSongsWithTriggers.Add(season + seperator + Weather + seperator + day, new List()); foreach (var time in timesOfDay) { - listOfSongsWithTriggers.Add(season + seperator + Weather + seperator + day + seperator + time, new List()); + listOfSongsWithTriggers.Add(season + seperator + Weather + seperator + day + seperator + time, new List()); } } } @@ -328,40 +329,41 @@ namespace StardewSymphonyRemastered.Framework /// /// /// - public KeyValuePair>getSongList(string key) + public KeyValuePair>getSongList(string key) { string keyPhrase = key.Split(seperator).ElementAt(0); if (keyPhrase == "event") { - /* - foreach (KeyValuePair> pair in eventSongs) + + foreach (KeyValuePair> pair in eventSongs) { if (pair.Key == key) return pair; } - */ - return new KeyValuePair>(key, eventSongs[key]); + + //return new KeyValuePair>(key, eventSongs[key]); } else if (keyPhrase == "festival") { - /* - foreach (KeyValuePair> pair in festivalSongs) + + foreach (KeyValuePair> pair in festivalSongs) { if (pair.Key == key) return pair; } - */ - return new KeyValuePair>(key, festivalSongs[key]); + + //return new KeyValuePair>(key, festivalSongs[key]); } else { - /* - foreach(KeyValuePair> pair in listOfSongsWithTriggers) + + foreach(KeyValuePair> pair in listOfSongsWithTriggers) { if (pair.Key == key) return pair; } - */ - return new KeyValuePair>(key, listOfSongsWithTriggers[key]); + + //return new KeyValuePair>(key, listOfSongsWithTriggers[key]); } + return new KeyValuePair>("",null); } /// @@ -371,9 +373,9 @@ namespace StardewSymphonyRemastered.Framework /// public void addSongToList(string songListKey,string songName) { - var songList = getSongList(songListKey); - - songList.Value.Add(songName); + var songKeyPair = getSongList(songListKey); + var song = getSongFromList(songKeyPair.Value, songName); + songKeyPair.Value.Add(song); } /// @@ -383,8 +385,24 @@ namespace StardewSymphonyRemastered.Framework /// public void removeSongFromList(string songListKey,string songName) { - var songList = getSongList(songListKey); - songList.Value.Remove(songName); + var songKeyPair = getSongList(songListKey); + var song = getSongFromList(songKeyPair.Value, songName); + songKeyPair.Value.Remove(song); + } + + /// + /// Get the Song instance that is referenced with the song's name. + /// + /// + /// + /// + public Song getSongFromList(List songList,string songName) + { + foreach(var song in songList) + { + if (song.name == songName) return song; + } + return null; } #endregion } diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/WavMusicPack.cs b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/WavMusicPack.cs index 061e07bb..eb311178 100644 --- a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/WavMusicPack.cs +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/WavMusicPack.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -11,5 +12,97 @@ namespace StardewSymphonyRemastered.Framework /// public class WavMusicPack : MusicPack { + public Song currentSong; + public string songsDirectory; + + /// + /// Constructor. + /// + /// + public WavMusicPack(string directoryToMusicPack) + { + this.directory = directoryToMusicPack; + this.setModDirectoryFromFullDirectory(); + this.songsDirectory = Path.Combine(this.directory, "Songs"); + this.songInformation = new SongSpecifics(); + this.musicPackInformation = MusicPackMetaData.readFromJson(Path.Combine(directoryToMusicPack, "MusicPackInformation.json")); + + if (this.musicPackInformation == null) + { + StardewSymphony.ModMonitor.Log("Error: MusicPackInformation.json not found at: " + directoryToMusicPack + ". Blank information will be put in place.", StardewModdingAPI.LogLevel.Warn); + this.musicPackInformation = new MusicPackMetaData("???", "???", "", "0.0.0"); + } + this.loadMusicFiles(); + } + + /// + /// A shortened directory name for display purposes. + /// + /// + public override void setModDirectoryFromFullDirectory() + { + string[] spliter = this.directory.Split(Path.DirectorySeparatorChar); + string directoryLocation = ""; + for (int i = spliter.Length - 6; i < spliter.Length; i++) + { + directoryLocation += spliter[i]; + + if (i != spliter.Length - 1) + { + directoryLocation += Path.DirectorySeparatorChar; + } + } + this.shortenedDirectory = directoryLocation; + } + + /// + /// Returns the name of the currently playing song. + /// + /// + public override string getNameOfCurrentSong() + { + return this.currentSong.name; + } + + /// + /// Load in the music files from the pack's respective Directory/Songs folder. Typically Content/Music/Wav/FolderName/Songs + /// + public override void loadMusicFiles() + { + string[] wavFiles = Directory.GetFiles(this.songsDirectory, "*.wav"); + List listOfSongs = new List(); + foreach(var wav in wavFiles) + { + Song song = new Song(wav); + listOfSongs.Add(song); + } + this.songInformation.listOfSongsWithoutTriggers = listOfSongs; + } + + public override void pauseSong() + { + throw new NotImplementedException(); + } + + public override void playSong(string name) + { + throw new NotImplementedException(); + } + + public override void resumeSong() + { + throw new NotImplementedException(); + } + + public override void stopSong() + { + throw new NotImplementedException(); + } + + public override void swapSong(string songName) + { + throw new NotImplementedException(); + } + } } diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/XACTMusicPack.cs b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/XACTMusicPack.cs index 20b89086..e5ed9a5f 100644 --- a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/XACTMusicPack.cs +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/XACTMusicPack.cs @@ -34,6 +34,7 @@ namespace StardewSymphonyRemastered.Framework this.directory = directoryToXwb; this.WaveBankPath = pathToWaveBank; this.SoundBankPath = pathToSoundBank; + this.setModDirectoryFromFullDirectory(); this.songInformation = new SongSpecifics(); this.currentCue = null; this.musicPackInformation = MusicPackMetaData.readFromJson(Path.Combine(directoryToXwb, "MusicPackInformation.json")); @@ -53,7 +54,21 @@ namespace StardewSymphonyRemastered.Framework /// public override void loadMusicFiles() { - this.songInformation.listOfSongsWithoutTriggers=StardewSymphonyRemastered.Framework.MusicHexProcessor.ProcessSongNamesFromHex(this,StardewSymphony.Reset,this.SoundBankPath); + + var listOfSongStrings = StardewSymphonyRemastered.Framework.MusicHexProcessor.ProcessSongNamesFromHex(this, StardewSymphony.Reset, this.SoundBankPath); + + List listofSongs = new List(); + foreach(var songname in listOfSongStrings) + { + Song song = new Song(this.WaveBankPath, songname); + listofSongs.Add(song); + } + + this.songInformation.listOfSongsWithoutTriggers = listofSongs; + + + + } /// @@ -158,5 +173,25 @@ namespace StardewSymphonyRemastered.Framework return this.currentCue.Name; } + /// + /// Returns a shortened directory name for display purposes. + /// + /// + public override void setModDirectoryFromFullDirectory() + { + string[] spliter = this.WaveBankPath.Split(Path.DirectorySeparatorChar); + string directoryLocation=""; + for (int i = spliter.Length - 5; i < spliter.Length; i++) + { + directoryLocation += spliter[i]; + + if (i != spliter.Length - 1) + { + directoryLocation += Path.DirectorySeparatorChar; + } + } + this.shortenedDirectory = directoryLocation; + } + } } diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphony.cs b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphony.cs index ac09e983..4824ea15 100644 --- a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphony.cs +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphony.cs @@ -63,13 +63,12 @@ namespace StardewSymphonyRemastered this.createDirectories(); this.createBlankXACTTemplate(); - + this.createBlankWAVTemplate(); musicPacksInitialized = false; } private void GameEvents_UpdateTick(object sender, EventArgs e) { - if (Game1.activeClickableMenu.GetType()!=typeof(StardewValley.Menus.TitleMenu)&& Game1.audioEngine.isNull()) return; if (musicPacksInitialized == false) { initializeMusicPacks(); @@ -81,6 +80,7 @@ namespace StardewSymphonyRemastered { //load in all packs here. loadXACTMusicPacks(); + loadWAVMusicPacks(); } public void createDirectories() @@ -90,6 +90,7 @@ namespace StardewSymphonyRemastered if (!Directory.Exists(XACTMusicDirectory)) Directory.CreateDirectory(XACTMusicDirectory); if (!Directory.Exists(TemplateMusicDirectory)) Directory.CreateDirectory(TemplateMusicDirectory); } + public void createBlankXACTTemplate() { string path= Path.Combine(TemplateMusicDirectory, "XACT"); @@ -103,11 +104,35 @@ namespace StardewSymphonyRemastered } if (!File.Exists(Path.Combine(path, "readme.txt"))) { - string info = "Place the Wave Bank.xwb file and Sound Bank.xsb file you created in XACT in a similar directory in Content/Music/XACT/SoundPackName with a new meta data to load it!"; + string info = "Place the Wave Bank.xwb file and Sound Bank.xsb file you created in XACT in a similar directory in Content/Music/XACT/SoundPackName.\nModify MusicPackInformation.json as desire!\nRun the mod!"; File.WriteAllText(Path.Combine(path, "readme.txt"),info); } } + public void createBlankWAVTemplate() + { + string path = Path.Combine(TemplateMusicDirectory, "WAV"); + string pathSongs = Path.Combine(path, "Songs"); + if (!Directory.Exists(path)) + { + Directory.CreateDirectory(path); + } + if (!Directory.Exists(pathSongs)) + { + Directory.CreateDirectory(pathSongs); + } + if (!File.Exists(Path.Combine(path, "MusicPackInformation.json"))) + { + MusicPackMetaData blankMetaData = new MusicPackMetaData("Omegas's Music Data Example", "Omegasis", "Just a simple example of how metadata is formated for music packs. Feel free to copy and edit this one!", "1.0.0 CoolExample"); + blankMetaData.writeToJson(Path.Combine(path, "MusicPackInformation.json")); + } + if (!File.Exists(Path.Combine(path, "readme.txt"))) + { + string info = "Place the .wav song files in the Songs folder, modify the MusicPackInformation.json as desired, and then run!"; + File.WriteAllText(Path.Combine(path, "readme.txt"), info); + } + } + public static void loadXACTMusicPacks() { @@ -155,6 +180,23 @@ namespace StardewSymphonyRemastered } + public static void loadWAVMusicPacks() + { + string[] listOfDirectories = Directory.GetDirectories(WavMusicDirectory); + foreach (string folder in listOfDirectories) + { + string metaData = Path.Combine(folder, "MusicPackInformation.json"); + + if (!File.Exists(metaData)) + { + ModMonitor.Log("WARNING! Loading in a music pack from: " + folder + ". There is no MusicPackInformation.json associated with this music pack meaning that while songs can be played from this pack, no information about it will be displayed.", LogLevel.Error); + } + + StardewSymphonyRemastered.Framework.WavMusicPack musicPack = new WavMusicPack(folder); + musicManager.addMusicPack(musicPack,true,true); + } + } + /// /// Raised when the player changes locations. This should determine the next song to play. /// @@ -175,9 +217,6 @@ namespace StardewSymphonyRemastered StardewSymphonyRemastered.Framework.SongSpecifics.addLocations(); StardewSymphonyRemastered.Framework.SongSpecifics.addFestivals(); StardewSymphonyRemastered.Framework.SongSpecifics.addEvents(); - - - } diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphonyRemastered.csproj b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphonyRemastered.csproj index c90fa29f..65480488 100644 --- a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphonyRemastered.csproj +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphonyRemastered.csproj @@ -43,6 +43,7 @@ + From aed71ac4db43297582da31528f4c35e8b18f6674 Mon Sep 17 00:00:00 2001 From: Date: Sat, 3 Feb 2018 21:11:38 -0800 Subject: [PATCH 03/18] Just some summary tags to explain some functions. --- .../StardewSymphony.cs | 32 ++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphony.cs b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphony.cs index 4824ea15..dd73bdb3 100644 --- a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphony.cs +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphony.cs @@ -17,9 +17,7 @@ namespace StardewSymphonyRemastered /// BIG WIP. Don't use this at all because it does nothing right now. /// TODO: /// 1.Make Xwb packs work - /// 1.5. Make way to load in music packs. /// 2.Make stream files work - /// 2.5. Make Music Manager /// 3.Make interface. /// 4.Make sure stuff doesn't blow up. /// 5.Release @@ -44,6 +42,10 @@ namespace StardewSymphonyRemastered public bool musicPacksInitialized; + /// + /// Entry point for the mod. + /// + /// public override void Entry(IModHelper helper) { DefaultSoundBank = Game1.soundBank; @@ -67,6 +69,11 @@ namespace StardewSymphonyRemastered musicPacksInitialized = false; } + /// + /// Raised every frame. Mainly used just to initiate the music packs. Probably not needed. + /// + /// + /// private void GameEvents_UpdateTick(object sender, EventArgs e) { if (musicPacksInitialized == false) @@ -76,6 +83,9 @@ namespace StardewSymphonyRemastered } } + /// + /// Load in the music packs to the music manager. + /// public void initializeMusicPacks() { //load in all packs here. @@ -83,6 +93,9 @@ namespace StardewSymphonyRemastered loadWAVMusicPacks(); } + /// + /// Create the core directories needed by the mod. + /// public void createDirectories() { if (!Directory.Exists(MusicPath)) Directory.CreateDirectory(MusicPath); @@ -91,6 +104,10 @@ namespace StardewSymphonyRemastered if (!Directory.Exists(TemplateMusicDirectory)) Directory.CreateDirectory(TemplateMusicDirectory); } + + /// + /// Used to create a blank XACT music pack example. + /// public void createBlankXACTTemplate() { string path= Path.Combine(TemplateMusicDirectory, "XACT"); @@ -109,6 +126,9 @@ namespace StardewSymphonyRemastered } } + /// + /// USed to create a blank WAV music pack example. + /// public void createBlankWAVTemplate() { string path = Path.Combine(TemplateMusicDirectory, "WAV"); @@ -133,7 +153,9 @@ namespace StardewSymphonyRemastered } } - + /// + /// Load in the XACT music packs. + /// public static void loadXACTMusicPacks() { string[] listOfDirectories= Directory.GetDirectories(XACTMusicDirectory); @@ -179,7 +201,9 @@ namespace StardewSymphonyRemastered } } - + /// + /// Load in WAV music packs. + /// public static void loadWAVMusicPacks() { string[] listOfDirectories = Directory.GetDirectories(WavMusicDirectory); From 45bfa5731f8b59ab9fbcbf20192b78ab97bb68b1 Mon Sep 17 00:00:00 2001 From: Date: Mon, 5 Feb 2018 17:31:59 -0800 Subject: [PATCH 04/18] Finished writing functionality for WAV music packs. fixed issue when loading in songs, made sure initial sound keys are propperly loaded, and have implemented support for custom title screen music. --- .../Framework/Menus/MusicManagerMenu.cs | 22 +++ .../Framework/MusicManager.cs | 122 ++++++++++++++- .../Framework/Song.cs | 36 +++++ .../Framework/SongSpecifics.cs | 53 ++++++- .../Framework/WavMusicPack.cs | 144 +++++++++++++++++- .../StardewSymphony.cs | 13 ++ .../StardewSymphonyRemastered.csproj | 1 + 7 files changed, 374 insertions(+), 17 deletions(-) create mode 100644 GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/Menus/MusicManagerMenu.cs diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/Menus/MusicManagerMenu.cs b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/Menus/MusicManagerMenu.cs new file mode 100644 index 00000000..1348761c --- /dev/null +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/Menus/MusicManagerMenu.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Microsoft.Xna.Framework.Graphics; + +namespace StardewSymphonyRemastered.Framework.Menus +{ + class MusicManagerMenu : StardewValley.Menus.IClickableMenu + { + public override void receiveRightClick(int x, int y, bool playSound = true) + { + throw new NotImplementedException(); + } + + public override void drawBackground(SpriteBatch b) + { + base.drawBackground(b); + } + } +} diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/MusicManager.cs b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/MusicManager.cs index 4a4ff992..88897ea4 100644 --- a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/MusicManager.cs +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/MusicManager.cs @@ -174,10 +174,17 @@ namespace StardewSymphonyRemastered.Framework Dictionary> listOfValidDictionaries = new Dictionary>(); foreach(var v in this.musicPacks) { - var songList= v.Value.songInformation.getSongList(songListKey).Value; - if (songList.Count > 0) + try { - listOfValidDictionaries.Add(v.Value, songList); + var songList = v.Value.songInformation.getSongList(songListKey).Value; + if (songList.Count > 0) + { + listOfValidDictionaries.Add(v.Value, songList); + } + } + catch(Exception err) + { + } } return listOfValidDictionaries; @@ -189,14 +196,101 @@ namespace StardewSymphonyRemastered.Framework /// public void selectMusic(string songListKey) { + var listOfValidMusicPacks = getListOfApplicableMusicPacks(songListKey); + + string subKey = songListKey; + //Try to get more specific. + + //This chunk is to determine song specifics for location. + while (listOfValidMusicPacks.Count == 0) + { + if (subKey.Length == 0) break; + string[] subList= subKey.Split(SongSpecifics.seperator); + if (subList.Length == 0) break; //Because things would go bad otherwise. + subKey = ""; + for(int i = 0; i < subList.Length-1; i++) + { + subKey += subList[i]; + if (i != subList.Length - 2) + { + subKey += SongSpecifics.seperator; + } + } + if (subKey == "") break; + StardewSymphony.ModMonitor.Log(subKey,StardewModdingAPI.LogLevel.Alert); + listOfValidMusicPacks = getListOfApplicableMusicPacks(subKey); + if (listOfValidMusicPacks.Count == 0) + { + //No valid songs to play at this time. + StardewSymphony.ModMonitor.Log("Error: There are no songs to play across any music pack for the song key: " + subKey + ". Are you sure you did this properly?"); + //return; + } + } + + if (listOfValidMusicPacks.Count == 0) + { + //This chunk is used to determine more general seasonal specifics if song specifics couldn't be found. + subKey = songListKey; + string[] season = subKey.Split(SongSpecifics.seperator); + subKey = ""; + for (int i = 1; i < season.Length; i++) + { + subKey += season[i]; + if (i != season.Length - 1) + { + subKey += SongSpecifics.seperator; + } + } + if (string.IsNullOrEmpty(subKey)) + { + StardewSymphony.ModMonitor.Log("Error: There are no songs to play across any music pack for the song key: " + songListKey + ". Are you sure you did this properly?"); + return; + } + StardewSymphony.ModMonitor.Log(subKey, StardewModdingAPI.LogLevel.Alert); + listOfValidMusicPacks = getListOfApplicableMusicPacks(subKey); + if (listOfValidMusicPacks.Count == 0) + { + //No valid songs to play at this time. + StardewSymphony.ModMonitor.Log("Error: There are no songs to play across any music pack for the song key: " + subKey + ". Are you sure you did this properly?"); + //return; + } + //Try to get more specific. + + while (listOfValidMusicPacks.Count == 0) + { + if (subKey.Length == 0) break; + string[] subList = subKey.Split(SongSpecifics.seperator); + if (subList.Length == 0) break; //Because things would go bad otherwise. + subKey = ""; + for (int i = 0; i < subList.Length - 1; i++) + { + subKey += subList[i]; + if (i != subList.Length - 2) + { + subKey += SongSpecifics.seperator; + } + } + if (subKey == "") break; + StardewSymphony.ModMonitor.Log(subKey, StardewModdingAPI.LogLevel.Alert); + listOfValidMusicPacks = getListOfApplicableMusicPacks(subKey); + if (listOfValidMusicPacks.Count == 0) + { + //No valid songs to play at this time. + StardewSymphony.ModMonitor.Log("Error: There are no songs to play across any music pack for the song key: " + subKey + ". Are you sure you did this properly?"); + //return; + } + } + } + if (listOfValidMusicPacks.Count == 0) { //No valid songs to play at this time. - StardewSymphony.ModMonitor.Log("Error: There are no songs to play across any music pack. Are you sure you did this properly?"); + StardewSymphony.ModMonitor.Log("Error: There are no songs to play across any music pack for the song key: " + songListKey + ". Are you sure you did this properly?"); return; } - + + int randInt = packSelector.Next(0, listOfValidMusicPacks.Count-1); var musicPackPair = listOfValidMusicPacks.ElementAt(randInt); @@ -240,7 +334,25 @@ namespace StardewSymphonyRemastered.Framework } } } + /* + if(musicPack.GetType()==typeof(WavMusicPack)){ + foreach (var song in musicPack.songInformation.listOfSongsWithoutTriggers) + { + (musicPack as WavMusicPack).LoadWavFromFileToStream(song.pathToSong); + } + } + */ + this.musicPacks.Add(musicPack.musicPackInformation.name,musicPack); } + + + public void initializeSeasonalMusic() + { + foreach(var pack in this.musicPacks) + { + pack.Value.songInformation.initializeSeasonalMusic(); + } + } } } diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/Song.cs b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/Song.cs index f01f386b..ada048b5 100644 --- a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/Song.cs +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/Song.cs @@ -9,6 +9,10 @@ namespace StardewSymphonyRemastered.Framework { /// /// The class to be used to manage individual songs. + /// + /// + /// + /// TODO: MAKE SMALL RELATIVE PATH TO SONG. /CONTENT/MUSIC/SONG /// public class Song { @@ -22,6 +26,11 @@ namespace StardewSymphonyRemastered.Framework /// public string name; + /// + /// The relative path to the song. + /// + public string relativePath; + /// /// Blank Constructor; /// @@ -38,6 +47,7 @@ namespace StardewSymphonyRemastered.Framework { this.pathToSong=PathToSong; this.name = getNameFromPath(this.pathToSong); + this.relativePath = this.getRelativePathFromFullPath(); } /// @@ -49,6 +59,7 @@ namespace StardewSymphonyRemastered.Framework { this.pathToSong = PathToSong; this.name = Name; + this.relativePath = this.getRelativePathFromFullPath(); } /// @@ -61,6 +72,31 @@ namespace StardewSymphonyRemastered.Framework return Path.GetFileNameWithoutExtension(path); } + public string getRelativePathFromFullPath() + { + string[] spliter = this.pathToSong.Split(Path.DirectorySeparatorChar); + string relative = ""; + int index = 0; + foreach(var str in spliter) //iterate across all of the strings until Content is found. + { + + if (str == "Content") + { + //Once content is found add it to the relative string and append a newline character. + for(int i = index; i < spliter.Length; i++) + { + relative += spliter[i]; + if (i != spliter.Length - 1) + { + relative += Path.DirectorySeparatorChar; + } + } + } + index++; + } + return relative; //Return the relative path string + } + /// /// Read the info from a .json file. /// diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/SongSpecifics.cs b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/SongSpecifics.cs index dbb7965d..253c8e17 100644 --- a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/SongSpecifics.cs +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/SongSpecifics.cs @@ -30,6 +30,7 @@ namespace StardewSymphonyRemastered.Framework string[] weather; string[] daysOfWeek; string[] timesOfDay; + List menus; public static char seperator = '_'; /// @@ -70,15 +71,16 @@ namespace StardewSymphonyRemastered.Framework "day", "night" }; + menus = new List(); + menus.Add(typeof(StardewValley.Menus.TitleMenu).ToString()); + listOfSongsWithTriggers = new Dictionary>(); eventSongs = new Dictionary>(); festivalSongs = new Dictionary>(); this.listOfSongsWithoutTriggers = new List(); - - this.addSongLists(); - + this.addMenuMusic(); } @@ -96,6 +98,7 @@ namespace StardewSymphonyRemastered.Framework public static string getCurrentConditionalString() { string key = ""; + bool foundMenuString = false; if (Game1.eventUp == true) { //Get the event id an hijack it with some different music @@ -106,10 +109,25 @@ namespace StardewSymphonyRemastered.Framework //hijack the name of the festival and load some different songs // string s="Festival_FestivalName"; } + else if (Game1.activeClickableMenu!=null) + { + if (Game1.activeClickableMenu.GetType() == typeof(StardewValley.Menus.TitleMenu)) + { + key = Game1.activeClickableMenu.GetType().ToString(); + foundMenuString = true; + } + + } else { key = getLocationString() + seperator + getSeasonNameString() + seperator + getWeatherString() + seperator + getDayOfWeekString() + seperator + getTimeOfDayString(); } + + if(foundMenuString==false && key == "") + { + key = getLocationString() + seperator + getSeasonNameString() + seperator + getWeatherString() + seperator + getDayOfWeekString() + seperator + getTimeOfDayString(); + } + return key; } @@ -123,6 +141,7 @@ namespace StardewSymphonyRemastered.Framework foreach (var v in Game1.locations) { locations.Add(v.name); + StardewSymphony.ModMonitor.Log("Adding in song triggers for location: " + v.name); } } @@ -252,6 +271,12 @@ namespace StardewSymphonyRemastered.Framework { return Game1.currentLocation.name; } + + public static string getCurrentMenuString() + { + if (Game1.activeClickableMenu == null) return ""; + else return Game1.activeClickableMenu.GetType().ToString(); + } #endregion //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~// @@ -268,6 +293,14 @@ namespace StardewSymphonyRemastered.Framework this.listOfSongsWithoutTriggers.Add(song); } + public void addMenuMusic() + { + foreach(var v in menus) + { + this.listOfSongsWithTriggers.Add(v, new List()); + } + } + /// /// Checks if the song exists at all in this music pack. /// @@ -282,7 +315,7 @@ namespace StardewSymphonyRemastered.Framework /// /// A pretty big function to add in all of the specific songs that play at certain locations_seasons_weather_dayOfWeek_times. /// - public void addSongLists() + public void initializeSeasonalMusic() { foreach (var loc in locations) { @@ -331,8 +364,15 @@ namespace StardewSymphonyRemastered.Framework /// public KeyValuePair>getSongList(string key) { - string keyPhrase = key.Split(seperator).ElementAt(0); - + string keyPhrase = ""; + try + { + keyPhrase= key.Split(seperator).ElementAt(0); + } + catch(Exception err) + { + keyPhrase = key; + } if (keyPhrase == "event") { @@ -358,6 +398,7 @@ namespace StardewSymphonyRemastered.Framework foreach(KeyValuePair> pair in listOfSongsWithTriggers) { + //StardewSymphony.ModMonitor.Log(pair.Key); if (pair.Key == key) return pair; } diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/WavMusicPack.cs b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/WavMusicPack.cs index eb311178..4c3d9bb3 100644 --- a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/WavMusicPack.cs +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/WavMusicPack.cs @@ -1,4 +1,6 @@ -using System; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Audio; +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -15,6 +17,23 @@ namespace StardewSymphonyRemastered.Framework public Song currentSong; public string songsDirectory; + /// + /// Used to actually play the song. + /// + DynamicSoundEffectInstance dynamicSound; + /// + /// Used to keep track of where in the song we are. + /// + int position; + /// + /// ??? + /// + int count; + /// + /// Used to store the info for the song. + /// + byte[] byteArray; + /// /// Constructor. /// @@ -55,12 +74,69 @@ namespace StardewSymphonyRemastered.Framework this.shortenedDirectory = directoryLocation; } + /// + /// Load a wav file into the stream to be played. + /// + public void LoadWavFromFileToStream(string p) + { + // Create a new SpriteBatch, which can be used to draw textures. + + string file =p; + System.IO.Stream waveFileStream = File.OpenRead(file); //TitleContainer.OpenStream(file); + + BinaryReader reader = new BinaryReader(waveFileStream); + + int chunkID = reader.ReadInt32(); + int fileSize = reader.ReadInt32(); + int riffType = reader.ReadInt32(); + int fmtID = reader.ReadInt32(); + int fmtSize = reader.ReadInt32(); + int fmtCode = reader.ReadInt16(); + int channels = reader.ReadInt16(); + int sampleRate = reader.ReadInt32(); + int fmtAvgBPS = reader.ReadInt32(); + int fmtBlockAlign = reader.ReadInt16(); + int bitDepth = reader.ReadInt16(); + + if (fmtSize == 18) + { + // Read any extra values + int fmtExtraSize = reader.ReadInt16(); + reader.ReadBytes(fmtExtraSize); + } + + int dataID = reader.ReadInt32(); + int dataSize = reader.ReadInt32(); + + byteArray = reader.ReadBytes(dataSize); + + dynamicSound = new DynamicSoundEffectInstance(sampleRate, (AudioChannels)channels); + count = dynamicSound.GetSampleSizeInBytes(TimeSpan.FromMilliseconds(100)); + + dynamicSound.BufferNeeded += new EventHandler(DynamicSound_BufferNeeded); + this.currentSong = new Song(p); + } + + void DynamicSound_BufferNeeded(object sender, EventArgs e) + { + dynamicSound.SubmitBuffer(byteArray, position, count / 2); + dynamicSound.SubmitBuffer(byteArray, position + count / 2, count / 2); + + position += count; + if (position + count > byteArray.Length) + { + position = 0; + } + } + + /// /// Returns the name of the currently playing song. /// /// public override string getNameOfCurrentSong() { + if (this.currentSong == null) return ""; return this.currentSong.name; } @@ -79,30 +155,86 @@ namespace StardewSymphonyRemastered.Framework this.songInformation.listOfSongsWithoutTriggers = listOfSongs; } + /// + /// Used to pause the current song. + /// public override void pauseSong() { - throw new NotImplementedException(); + if (dynamicSound != null) dynamicSound.Pause(); } + /// + /// Used to play a song. + /// + /// public override void playSong(string name) { - throw new NotImplementedException(); + string pathToSong = getSongPathFromName(name); + LoadWavFromFileToStream(pathToSong); + dynamicSound.Play(); } + /// + /// Used to resume the currently playing song. + /// public override void resumeSong() { - throw new NotImplementedException(); + if (dynamicSound == null) return; + dynamicSound.Resume(); } + /// + /// Used to stop the currently playing song. + /// public override void stopSong() { - throw new NotImplementedException(); + if (dynamicSound != null) + { + dynamicSound.Stop(); + dynamicSound = null; + this.currentSong = null; + } } + /// + /// Used to change from one playing song to another; + /// + /// public override void swapSong(string songName) { - throw new NotImplementedException(); + this.stopSong(); + this.playSong(songName); } + /// + /// Get the son's name from the path. + /// + /// + /// + public string getSongNameFromPath(string path) + { + foreach(var song in this.songInformation.listOfSongsWithoutTriggers) + { + if (song.pathToSong == path) return song.name; + } + return ""; + } + + /// + /// Gets the song's path that shares the same name. + /// + /// + /// + public string getSongPathFromName(string name) + { + foreach (var song in this.songInformation.listOfSongsWithoutTriggers) + { + if (song.name == name) return song.pathToSong; + } + return ""; + } + + + } } diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphony.cs b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphony.cs index dd73bdb3..02c31a83 100644 --- a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphony.cs +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphony.cs @@ -56,6 +56,7 @@ namespace StardewSymphonyRemastered StardewModdingAPI.Events.SaveEvents.AfterLoad += SaveEvents_AfterLoad; StardewModdingAPI.Events.LocationEvents.CurrentLocationChanged += LocationEvents_CurrentLocationChanged; StardewModdingAPI.Events.GameEvents.UpdateTick += GameEvents_UpdateTick; + StardewModdingAPI.Events.ControlEvents.KeyPressed += ControlEvents_KeyPressed; musicManager = new MusicManager(); MusicPath = Path.Combine(ModHelper.DirectoryPath, "Content", "Music"); @@ -66,9 +67,19 @@ namespace StardewSymphonyRemastered this.createDirectories(); this.createBlankXACTTemplate(); this.createBlankWAVTemplate(); + musicPacksInitialized = false; } + private void ControlEvents_KeyPressed(object sender, StardewModdingAPI.Events.EventArgsKeyPressed e) + { + if (e.KeyPressed == Microsoft.Xna.Framework.Input.Keys.O) + { + Game1.activeClickableMenu = new StardewSymphonyRemastered.Framework.Menus.MusicManagerMenu(); + } + } + + /// /// Raised every frame. Mainly used just to initiate the music packs. Probably not needed. /// @@ -80,6 +91,7 @@ namespace StardewSymphonyRemastered { initializeMusicPacks(); musicPacksInitialized = true; + musicManager.selectMusic(SongSpecifics.getCurrentConditionalString()); } } @@ -241,6 +253,7 @@ namespace StardewSymphonyRemastered StardewSymphonyRemastered.Framework.SongSpecifics.addLocations(); StardewSymphonyRemastered.Framework.SongSpecifics.addFestivals(); StardewSymphonyRemastered.Framework.SongSpecifics.addEvents(); + musicManager.initializeSeasonalMusic(); } diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphonyRemastered.csproj b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphonyRemastered.csproj index 65480488..0e523462 100644 --- a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphonyRemastered.csproj +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphonyRemastered.csproj @@ -42,6 +42,7 @@ + From ff6456d9ec52c37c8f823e80513259c8662782c5 Mon Sep 17 00:00:00 2001 From: Date: Mon, 5 Feb 2018 19:07:29 -0800 Subject: [PATCH 05/18] Added in ability to save and load music packs. Needs lots of work. Next step, menus. --- .../Framework/MusicPack.cs | 39 +++++++++++++++++++ .../Framework/SongListNode.cs | 36 +++++++++++++++++ .../Framework/SongSpecifics.cs | 11 +++--- .../Framework/WavMusicPack.cs | 3 -- .../StardewSymphony.cs | 17 ++++++++ .../StardewSymphonyRemastered.csproj | 1 + 6 files changed, 99 insertions(+), 8 deletions(-) create mode 100644 GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/SongListNode.cs diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/MusicPack.cs b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/MusicPack.cs index 4bbad6d1..b4f954da 100644 --- a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/MusicPack.cs +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/MusicPack.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -57,5 +58,43 @@ namespace StardewSymphonyRemastered.Framework { } + + + public virtual void writeToJson() + { + StardewSymphony.ModMonitor.Log("Loading in music for this pack:"+this.musicPackInformation.name+". Please wait."); + string data = Path.Combine(this.directory, "data"); + if (!Directory.Exists(data)) + { + Directory.CreateDirectory(data); + } + foreach (var list in this.songInformation.listOfSongsWithTriggers) + { + if (list.Value.Count == 0) continue; + SongListNode node = new SongListNode(list.Key, list.Value); + node.WriteToJson(Path.Combine(data, node.trigger+".json")); + } + } + + public virtual void readFromJson() + { + StardewSymphony.ModMonitor.Log("Saving music for this pack:" + this.musicPackInformation.name + ". Please wait as this will take quite soem time."); + string data = Path.Combine(this.directory, "data"); + if (!Directory.Exists(data)) + { + Directory.CreateDirectory(data); + } + string[] files = Directory.GetFiles(data); + foreach (var file in files) + { + SongListNode node = SongListNode.ReadFromJson(Path.Combine(data,file)); + var pair = this.songInformation.getSongList(node.trigger+".json"); + foreach (var v in node.songList) + { + this.songInformation.addSongToList(node.trigger, v.name); + } + } + + } } } diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/SongListNode.cs b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/SongListNode.cs new file mode 100644 index 00000000..524ee58f --- /dev/null +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/SongListNode.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StardewSymphonyRemastered.Framework +{ + class SongListNode + { + public string trigger; + public List songList; + + public SongListNode() + { + + } + + public SongListNode(string Trigger, List SongList) + { + this.trigger = Trigger; + this.songList = SongList; + } + + public void WriteToJson(string path) + { + StardewSymphony.ModHelper.WriteJsonFile(path, this); + } + + public static SongListNode ReadFromJson(string path) + { + return StardewSymphony.ModHelper.ReadJsonFile(path); + } + + } +} diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/SongSpecifics.cs b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/SongSpecifics.cs index 253c8e17..689cc377 100644 --- a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/SongSpecifics.cs +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/SongSpecifics.cs @@ -14,11 +14,11 @@ namespace StardewSymphonyRemastered.Framework /// public class SongSpecifics { - Dictionary> listOfSongsWithTriggers; //triggerName, + public Dictionary> listOfSongsWithTriggers; //triggerName, - Dictionary> eventSongs; + public Dictionary> eventSongs; - Dictionary> festivalSongs; + public Dictionary> festivalSongs; public List listOfSongsWithoutTriggers; @@ -72,7 +72,8 @@ namespace StardewSymphonyRemastered.Framework "night" }; menus = new List(); - menus.Add(typeof(StardewValley.Menus.TitleMenu).ToString()); + + menus.Add(typeof(StardewValley.Menus.TitleMenu).ToString().Replace('.', seperator)); listOfSongsWithTriggers = new Dictionary>(); @@ -113,7 +114,7 @@ namespace StardewSymphonyRemastered.Framework { if (Game1.activeClickableMenu.GetType() == typeof(StardewValley.Menus.TitleMenu)) { - key = Game1.activeClickableMenu.GetType().ToString(); + key = Game1.activeClickableMenu.GetType().ToString().Replace('.',seperator); foundMenuString = true; } diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/WavMusicPack.cs b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/WavMusicPack.cs index 4c3d9bb3..1c3ee009 100644 --- a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/WavMusicPack.cs +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/WavMusicPack.cs @@ -233,8 +233,5 @@ namespace StardewSymphonyRemastered.Framework } return ""; } - - - } } diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphony.cs b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphony.cs index 02c31a83..5f080d7d 100644 --- a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphony.cs +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphony.cs @@ -57,6 +57,7 @@ namespace StardewSymphonyRemastered StardewModdingAPI.Events.LocationEvents.CurrentLocationChanged += LocationEvents_CurrentLocationChanged; StardewModdingAPI.Events.GameEvents.UpdateTick += GameEvents_UpdateTick; StardewModdingAPI.Events.ControlEvents.KeyPressed += ControlEvents_KeyPressed; + StardewModdingAPI.Events.SaveEvents.BeforeSave += SaveEvents_BeforeSave; musicManager = new MusicManager(); MusicPath = Path.Combine(ModHelper.DirectoryPath, "Content", "Music"); @@ -71,6 +72,16 @@ namespace StardewSymphonyRemastered musicPacksInitialized = false; } + private void SaveEvents_BeforeSave(object sender, EventArgs e) + { + /* THIS IS WAY TO LONG to run. Better make it save individual lists when I am editing songs. + foreach(var musicPack in musicManager.musicPacks) + { + musicPack.Value.writeToJson(); + } + */ + } + private void ControlEvents_KeyPressed(object sender, StardewModdingAPI.Events.EventArgsKeyPressed e) { if (e.KeyPressed == Microsoft.Xna.Framework.Input.Keys.O) @@ -210,6 +221,9 @@ namespace StardewSymphonyRemastered } StardewSymphonyRemastered.Framework.XACTMusicPack musicPack = new XACTMusicPack(folder, waveBank,soundBank); musicManager.addMusicPack(musicPack,true,true); + + musicPack.readFromJson(); + } } @@ -230,6 +244,9 @@ namespace StardewSymphonyRemastered StardewSymphonyRemastered.Framework.WavMusicPack musicPack = new WavMusicPack(folder); musicManager.addMusicPack(musicPack,true,true); + + musicPack.readFromJson(); + } } diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphonyRemastered.csproj b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphonyRemastered.csproj index 0e523462..fd6de3f7 100644 --- a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphonyRemastered.csproj +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphonyRemastered.csproj @@ -45,6 +45,7 @@ + From 13e1d9591ad414f53e15605b37b19d2153fa154c Mon Sep 17 00:00:00 2001 From: Date: Tue, 6 Feb 2018 01:27:28 -0800 Subject: [PATCH 06/18] Integrated StardustCore with UIUtilities a new framework that makes making menus easier. It adds buttons and TexturedFonts that are loaded in as individual images for each character. Colors can be applied to these chararacters for some nice graphical effects. --- GeneralMods/StardewMods.sln | 3 + .../Framework/Menus/MusicManagerMenu.cs | 23 +- .../Framework/MusicPackMetaData.cs | 18 +- .../Framework/WavMusicPack.cs | 2 +- .../Framework/XACTMusicPack.cs | 2 +- .../StardewSymphony.cs | 6 +- .../StardewSymphonyRemastered.csproj | 3 + .../Animations/AnimationManager.cs | 7 + .../IlluminateFramework/Colors.cs | 4 +- GeneralMods/StardustCore/ModCore.cs | 12 +- GeneralMods/StardustCore/StardustCore.csproj | 10 + .../UIUtilities/MenuComponents/Button.cs | 108 ++++++++ .../CharacterSheets/GenericCharacterSheets.cs | 20 ++ .../CharacterSheets/VanillaCharacterSheet.cs | 239 ++++++++++++++++++ .../Fonts/Components/CharacterSpacing.cs | 73 ++++++ .../Fonts/Components/TexturedCharacter.cs | 61 +++++ .../Fonts/Components/TexturedString.cs | 129 ++++++++++ .../SpriteFonts/Fonts/GenericFont.cs | 15 ++ .../SpriteFonts/Fonts/VanillaFont.cs | 102 ++++++++ .../UIUtilities/SpriteFonts/SpriteFont.cs | 28 ++ GeneralMods/StardustCore/Utilities.cs | 12 +- GeneralMods/UIUtilities/UIUtilities.sln | 22 ++ GeneralMods/UIUtilities/UIUtilities/Class1.cs | 12 + .../UIUtilities/MenuComponents/Button.cs | 12 + .../UIUtilities/Properties/AssemblyInfo.cs | 36 +++ .../UIUtilities/UIUtilities.csproj | 67 +++++ .../UIUtilities/UIUtilities/packages.config | 4 + 27 files changed, 1013 insertions(+), 17 deletions(-) create mode 100644 GeneralMods/StardustCore/UIUtilities/MenuComponents/Button.cs create mode 100644 GeneralMods/StardustCore/UIUtilities/SpriteFonts/CharacterSheets/GenericCharacterSheets.cs create mode 100644 GeneralMods/StardustCore/UIUtilities/SpriteFonts/CharacterSheets/VanillaCharacterSheet.cs create mode 100644 GeneralMods/StardustCore/UIUtilities/SpriteFonts/Fonts/Components/CharacterSpacing.cs create mode 100644 GeneralMods/StardustCore/UIUtilities/SpriteFonts/Fonts/Components/TexturedCharacter.cs create mode 100644 GeneralMods/StardustCore/UIUtilities/SpriteFonts/Fonts/Components/TexturedString.cs create mode 100644 GeneralMods/StardustCore/UIUtilities/SpriteFonts/Fonts/GenericFont.cs create mode 100644 GeneralMods/StardustCore/UIUtilities/SpriteFonts/Fonts/VanillaFont.cs create mode 100644 GeneralMods/StardustCore/UIUtilities/SpriteFonts/SpriteFont.cs create mode 100644 GeneralMods/UIUtilities/UIUtilities.sln create mode 100644 GeneralMods/UIUtilities/UIUtilities/Class1.cs create mode 100644 GeneralMods/UIUtilities/UIUtilities/MenuComponents/Button.cs create mode 100644 GeneralMods/UIUtilities/UIUtilities/Properties/AssemblyInfo.cs create mode 100644 GeneralMods/UIUtilities/UIUtilities/UIUtilities.csproj create mode 100644 GeneralMods/UIUtilities/UIUtilities/packages.config diff --git a/GeneralMods/StardewMods.sln b/GeneralMods/StardewMods.sln index 3230c825..f5e56d43 100644 --- a/GeneralMods/StardewMods.sln +++ b/GeneralMods/StardewMods.sln @@ -67,6 +67,9 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StarAI", "..\StarAI\StarAI\ EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StardewSymphonyRemastered", "StardewSymphonyRemastered\StardewSymphonyRemastered\StardewSymphonyRemastered.csproj", "{19F64B03-6A9B-49E1-854A-C05D5A014646}" + ProjectSection(ProjectDependencies) = postProject + {0756D36A-95C8-480D-8EA6-4584C03010C6} = {0756D36A-95C8-480D-8EA6-4584C03010C6} + EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/Menus/MusicManagerMenu.cs b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/Menus/MusicManagerMenu.cs index 1348761c..f4d9d61c 100644 --- a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/Menus/MusicManagerMenu.cs +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/Menus/MusicManagerMenu.cs @@ -4,11 +4,21 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using Microsoft.Xna.Framework.Graphics; +using StardewValley; namespace StardewSymphonyRemastered.Framework.Menus { class MusicManagerMenu : StardewValley.Menus.IClickableMenu { + public List texturedStrings; + public MusicManagerMenu(float width, float height) + { + this.width = (int)width; + this.height = (int)height; + this.texturedStrings = new List(); + this.texturedStrings.Add(StardustCore.UIUtilities.SpriteFonts.SpriteFont.vanillaFont.ParseString("Hello", new Microsoft.Xna.Framework.Vector2(100, 100),StardustCore.IlluminateFramework.Colors.invertColor(StardustCore.IlluminateFramework.LightColorsList.Blue))); + } + public override void receiveRightClick(int x, int y, bool playSound = true) { throw new NotImplementedException(); @@ -16,7 +26,18 @@ namespace StardewSymphonyRemastered.Framework.Menus public override void drawBackground(SpriteBatch b) { - base.drawBackground(b); + Game1.drawDialogueBox(this.xPositionOnScreen, this.yPositionOnScreen, this.width, this.height, false, true); + //base.drawBackground(b); + } + + public override void draw(SpriteBatch b) + { + this.drawBackground(b); + + foreach(var v in texturedStrings) + { + v.draw(b); + } } } } diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/MusicPackMetaData.cs b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/MusicPackMetaData.cs index bb0bb2b9..73f0966a 100644 --- a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/MusicPackMetaData.cs +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/MusicPackMetaData.cs @@ -1,4 +1,5 @@ -using System; +using Microsoft.Xna.Framework.Graphics; +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -16,7 +17,8 @@ namespace StardewSymphonyRemastered.Framework public string author; public string description; public string versionInfo; - + public string pathToMusicPackIcon; + public Texture2D Icon; /// /// Constrctor /// @@ -24,12 +26,22 @@ namespace StardewSymphonyRemastered.Framework /// The author who compiled ths music pack. /// The description of /// - public MusicPackMetaData(string Name,string Author,string Description,string VersionInfo) + public MusicPackMetaData(string Name,string Author,string Description,string VersionInfo,string PathToMusicPackIcon) { this.name = Name; this.author = Author; this.description = Description; this.versionInfo = VersionInfo; + this.pathToMusicPackIcon = PathToMusicPackIcon; + try + { + this.Icon = StardewSymphony.ModHelper.Content.Load(this.pathToMusicPackIcon); + } + catch(Exception err) + { + this.Icon = null; + StardewSymphony.ModMonitor.Log(err.ToString()); + } } /// /// Blank Constructor diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/WavMusicPack.cs b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/WavMusicPack.cs index 1c3ee009..d9449ede 100644 --- a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/WavMusicPack.cs +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/WavMusicPack.cs @@ -49,7 +49,7 @@ namespace StardewSymphonyRemastered.Framework if (this.musicPackInformation == null) { StardewSymphony.ModMonitor.Log("Error: MusicPackInformation.json not found at: " + directoryToMusicPack + ". Blank information will be put in place.", StardewModdingAPI.LogLevel.Warn); - this.musicPackInformation = new MusicPackMetaData("???", "???", "", "0.0.0"); + this.musicPackInformation = new MusicPackMetaData("???", "???", "", "0.0.0",""); } this.loadMusicFiles(); } diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/XACTMusicPack.cs b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/XACTMusicPack.cs index e5ed9a5f..de56a22e 100644 --- a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/XACTMusicPack.cs +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/Framework/XACTMusicPack.cs @@ -41,7 +41,7 @@ namespace StardewSymphonyRemastered.Framework if (this.musicPackInformation == null) { StardewSymphony.ModMonitor.Log("Error: MusicPackInformation.json not found at: " + directoryToXwb + ". Blank information will be put in place.",StardewModdingAPI.LogLevel.Warn); - this.musicPackInformation = new MusicPackMetaData("???","???","","0.0.0"); + this.musicPackInformation = new MusicPackMetaData("???","???","","0.0.0",""); } this.WaveBank = new WaveBank(Game1.audioEngine, this.WaveBankPath); diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphony.cs b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphony.cs index 5f080d7d..5f761eb0 100644 --- a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphony.cs +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphony.cs @@ -86,7 +86,7 @@ namespace StardewSymphonyRemastered { if (e.KeyPressed == Microsoft.Xna.Framework.Input.Keys.O) { - Game1.activeClickableMenu = new StardewSymphonyRemastered.Framework.Menus.MusicManagerMenu(); + Game1.activeClickableMenu = new StardewSymphonyRemastered.Framework.Menus.MusicManagerMenu(Game1.viewport.Width,Game1.viewport.Height); } } @@ -139,7 +139,7 @@ namespace StardewSymphonyRemastered Directory.CreateDirectory(path); } if(!File.Exists(Path.Combine(path, "MusicPackInformation.json"))){ - MusicPackMetaData blankMetaData = new MusicPackMetaData("Omegas's Music Data Example","Omegasis","Just a simple example of how metadata is formated for music packs. Feel free to copy and edit this one!","1.0.0 CoolExample"); + MusicPackMetaData blankMetaData = new MusicPackMetaData("Omegas's Music Data Example","Omegasis","Just a simple example of how metadata is formated for music packs. Feel free to copy and edit this one!","1.0.0 CoolExample","Icon.png"); blankMetaData.writeToJson(Path.Combine(path, "MusicPackInformation.json")); } if (!File.Exists(Path.Combine(path, "readme.txt"))) @@ -166,7 +166,7 @@ namespace StardewSymphonyRemastered } if (!File.Exists(Path.Combine(path, "MusicPackInformation.json"))) { - MusicPackMetaData blankMetaData = new MusicPackMetaData("Omegas's Music Data Example", "Omegasis", "Just a simple example of how metadata is formated for music packs. Feel free to copy and edit this one!", "1.0.0 CoolExample"); + MusicPackMetaData blankMetaData = new MusicPackMetaData("Omegas's Music Data Example", "Omegasis", "Just a simple example of how metadata is formated for music packs. Feel free to copy and edit this one!", "1.0.0 CoolExample","Icon"); blankMetaData.writeToJson(Path.Combine(path, "MusicPackInformation.json")); } if (!File.Exists(Path.Combine(path, "readme.txt"))) diff --git a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphonyRemastered.csproj b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphonyRemastered.csproj index fd6de3f7..da8dd107 100644 --- a/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphonyRemastered.csproj +++ b/GeneralMods/StardewSymphonyRemastered/StardewSymphonyRemastered/StardewSymphonyRemastered.csproj @@ -32,6 +32,9 @@ 4 + + ..\..\StardustCore\bin\Release\StardustCore.dll + diff --git a/GeneralMods/StardustCore/Animations/AnimationManager.cs b/GeneralMods/StardustCore/Animations/AnimationManager.cs index 4e3d7328..ec94a8c1 100644 --- a/GeneralMods/StardustCore/Animations/AnimationManager.cs +++ b/GeneralMods/StardustCore/Animations/AnimationManager.cs @@ -120,10 +120,17 @@ namespace StardustCore.Animations } } + /// + /// Sets the animation manager to an on state, meaning that this animation will update on the draw frame. + /// public void enableAnimation() { this.enabled = true; } + + /// + /// Sets the animation manager to an off state, meaning that this animation will no longer update on the draw frame. + /// public void disableAnimation() { this.enabled = false; diff --git a/GeneralMods/StardustCore/IlluminateFramework/Colors.cs b/GeneralMods/StardustCore/IlluminateFramework/Colors.cs index 63ebae48..d89f33b0 100644 --- a/GeneralMods/StardustCore/IlluminateFramework/Colors.cs +++ b/GeneralMods/StardustCore/IlluminateFramework/Colors.cs @@ -12,7 +12,7 @@ namespace StardustCore.IlluminateFramework /// /// Make sure all colors are inverted. /// - public class ColorsList + public class LightColorsList { public static Color AliceBlue = new Color(15, 7, 0, 255); @@ -639,7 +639,7 @@ namespace StardustCore.IlluminateFramework } - public Color getColorFromList(string s) + public static Color getColorFromList(string s) { Color color; bool f = ColorDictionary.TryGetValue(s, out color); diff --git a/GeneralMods/StardustCore/ModCore.cs b/GeneralMods/StardustCore/ModCore.cs index 706bbd23..be88c1da 100644 --- a/GeneralMods/StardustCore/ModCore.cs +++ b/GeneralMods/StardustCore/ModCore.cs @@ -18,14 +18,16 @@ namespace StardustCore public static IModHelper ModHelper; public static IMonitor ModMonitor; public static Serialization.SerializationManager SerializationManager; + + public static string ContentDirectory; public override void Entry(IModHelper helper) { ModHelper = helper; - ModMonitor = this.Monitor; + ModMonitor = Monitor; //Unused MetaData information. Works in player inventory but not in chests. Besides who really care where an object is from anyways. Also doesn't work 100% like I intended since it only gets base mod object that this runs from, not extensions? // StardewModdingAPI.Events.GraphicsEvents.OnPostRenderGuiEvent += Metadata.GameEvents_UpdateTick; - StardewModdingAPI.Events.ControlEvents.MouseChanged += ControlEvents_MouseChanged; + //StardewModdingAPI.Events.ControlEvents.MouseChanged += ControlEvents_MouseChanged; string invPath = Path.Combine(ModCore.ModHelper.DirectoryPath, "PlayerData", Game1.player.name, "PlayerInventory"); string worldPath = Path.Combine(ModCore.ModHelper.DirectoryPath, Game1.player.name, "ObjectsInWorld"); ; string trashPath = Path.Combine(ModCore.ModHelper.DirectoryPath, "ModTrashFolder"); @@ -36,9 +38,11 @@ namespace StardustCore StardewModdingAPI.Events.SaveEvents.BeforeSave += SaveEvents_BeforeSave; StardewModdingAPI.Events.SaveEvents.AfterLoad += SaveEvents_AfterLoad; - IlluminateFramework.Colors.initializeColors(); - + ContentDirectory = Path.Combine(ModHelper.DirectoryPath, "Content"); + if (!Directory.Exists(ContentDirectory)) Directory.CreateDirectory(ContentDirectory); + UIUtilities.SpriteFonts.SpriteFont.initialize(); + } diff --git a/GeneralMods/StardustCore/StardustCore.csproj b/GeneralMods/StardustCore/StardustCore.csproj index f6afd46d..137361de 100644 --- a/GeneralMods/StardustCore/StardustCore.csproj +++ b/GeneralMods/StardustCore/StardustCore.csproj @@ -45,6 +45,12 @@ + + + + + + @@ -52,12 +58,16 @@ + + + + diff --git a/GeneralMods/StardustCore/UIUtilities/MenuComponents/Button.cs b/GeneralMods/StardustCore/UIUtilities/MenuComponents/Button.cs new file mode 100644 index 00000000..65ec9f73 --- /dev/null +++ b/GeneralMods/StardustCore/UIUtilities/MenuComponents/Button.cs @@ -0,0 +1,108 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using StardewValley; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StardustCore.UIUtilities.MenuComponents +{ + public class Button : StardewValley.Menus.ClickableTextureComponent + { + public Animations.AnimationManager animationManager; + public Color textureColor; + public Color textColor; + /// + /// Basic Button constructor. + /// + /// + /// + /// + /// + /// + /// + public Button(string Name,Rectangle Bounds,Texture2D Texture,string displayText,Rectangle sourceRect,float Scale,Animations.Animation defaultAnimation, Color DrawColor,Color TextColor, bool AnimationEnabled=true) : base(Bounds,Texture,sourceRect,Scale) + { + this.animationManager = new Animations.AnimationManager(Texture, defaultAnimation,AnimationEnabled); + this.label = displayText; + this.name = Name; + this.textureColor = DrawColor; + if (this.textureColor == null) + { + this.textureColor = StardustCore.IlluminateFramework.Colors.getColorFromList("White"); + } + this.textColor = DrawColor; + if (this.textColor == null) + { + this.textColor = StardustCore.IlluminateFramework.Colors.getColorFromList("White"); + } + } + + /// + /// A more advanced Button constructor that deals with an animation manager. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public Button(string Name,Rectangle Bounds,Texture2D Texture, string displayText, Rectangle sourceRect,float Scale, Animations.Animation defaultAnimation,Dictionary> animationsToPlay,string startingAnimationKey,Color DrawColor,Color TextColor,int startingAnimationFrame=0,bool AnimationEnabled=true) : base(Bounds, Texture, sourceRect, Scale) + { + this.animationManager = new Animations.AnimationManager(Texture, defaultAnimation, animationsToPlay, startingAnimationKey, startingAnimationFrame, AnimationEnabled); + this.label = displayText; + this.name = Name; + this.textureColor = DrawColor; + if (this.textureColor == null) + { + this.textureColor = StardustCore.IlluminateFramework.Colors.getColorFromList("White"); + } + this.textColor = DrawColor; + if (this.textColor == null) + { + this.textColor = StardustCore.IlluminateFramework.Colors.getColorFromList("White"); + } + } + + /// + /// Draws the button and all of it's components. + /// + /// + /// + /// + public void draw(SpriteBatch b, float layerDepth) + { + + this.animationManager.tickAnimation(); + if (!this.visible) + return; + if (this.drawShadow) + Utility.drawWithShadow(b, this.texture, new Vector2((float)this.bounds.X + (float)(this.sourceRect.Width / 2) * this.baseScale, (float)this.bounds.Y + (float)(this.sourceRect.Height / 2) * this.baseScale), this.sourceRect, this.textureColor, 0.0f, new Vector2((float)(this.sourceRect.Width / 2), (float)(this.sourceRect.Height / 2)), this.scale, false, layerDepth, -1, -1, 0.35f); + else + b.Draw(this.texture, new Vector2((float)this.bounds.X + (float)(this.sourceRect.Width / 2) * this.baseScale, (float)this.bounds.Y + (float)(this.sourceRect.Height / 2) * this.baseScale), new Rectangle?(this.sourceRect), this.textureColor, 0.0f, new Vector2((float)(this.sourceRect.Width / 2), (float)(this.sourceRect.Height / 2)), this.scale, SpriteEffects.None, layerDepth); + if (string.IsNullOrEmpty(this.label)) + return; + b.DrawString(Game1.smallFont, this.label, new Vector2((float)(this.bounds.X + this.bounds.Width), (float)this.bounds.Y + ((float)(this.bounds.Height / 2) - Game1.smallFont.MeasureString(this.label).Y / 2f)), this.textColor); + } + + /// + /// Swaps if the button is visible or not. Also toggles the animation manager appropriately. + /// + public void swapVisibility() + { + if (this.visible == true) + { + this.visible = false; + this.animationManager.disableAnimation(); + } + } + + } +} diff --git a/GeneralMods/StardustCore/UIUtilities/SpriteFonts/CharacterSheets/GenericCharacterSheets.cs b/GeneralMods/StardustCore/UIUtilities/SpriteFonts/CharacterSheets/GenericCharacterSheets.cs new file mode 100644 index 00000000..86558587 --- /dev/null +++ b/GeneralMods/StardustCore/UIUtilities/SpriteFonts/CharacterSheets/GenericCharacterSheets.cs @@ -0,0 +1,20 @@ +using Microsoft.Xna.Framework.Graphics; +using StardustCore.UIUtilities.SpriteFonts.Components; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StardustCore.UIUtilities.SpriteFonts.CharacterSheets +{ + public class GenericCharacterSheets + { + public Dictionary CharacterAtlus; + + public virtual TexturedCharacter getTexturedCharacter(char c) + { + return new TexturedCharacter(); + } + } +} diff --git a/GeneralMods/StardustCore/UIUtilities/SpriteFonts/CharacterSheets/VanillaCharacterSheet.cs b/GeneralMods/StardustCore/UIUtilities/SpriteFonts/CharacterSheets/VanillaCharacterSheet.cs new file mode 100644 index 00000000..2843e426 --- /dev/null +++ b/GeneralMods/StardustCore/UIUtilities/SpriteFonts/CharacterSheets/VanillaCharacterSheet.cs @@ -0,0 +1,239 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.IO; +using Microsoft.Xna.Framework.Graphics; +using Microsoft.Xna.Framework; +using StardustCore.UIUtilities.SpriteFonts.Components; + +namespace StardustCore.UIUtilities.SpriteFonts.CharacterSheets +{ + public class VanillaCharacterSheet :GenericCharacterSheets + { + + public VanillaCharacterSheet(string directoryToFonts) + { + Color fontColor = StardustCore.IlluminateFramework.Colors.getColorFromList("Black"); + this.CharacterAtlus = new Dictionary(); + this.CharacterAtlus.Add('0', new TexturedCharacter('0', Path.Combine(Utilities.getRelativePath(directoryToFonts), "0"), fontColor)); + this.CharacterAtlus.Add('1', new TexturedCharacter('1', Path.Combine(Utilities.getRelativePath(directoryToFonts), "1"), fontColor)); + this.CharacterAtlus.Add('2', new TexturedCharacter('2', Path.Combine(Utilities.getRelativePath(directoryToFonts), "2"), fontColor)); + this.CharacterAtlus.Add('3', new TexturedCharacter('3', Path.Combine(Utilities.getRelativePath(directoryToFonts), "3"), fontColor)); + this.CharacterAtlus.Add('4', new TexturedCharacter('4', Path.Combine(Utilities.getRelativePath(directoryToFonts), "4"), fontColor)); + this.CharacterAtlus.Add('5', new TexturedCharacter('5', Path.Combine(Utilities.getRelativePath(directoryToFonts), "5"), fontColor)); + this.CharacterAtlus.Add('6', new TexturedCharacter('6', Path.Combine(Utilities.getRelativePath(directoryToFonts), "6"), fontColor)); + this.CharacterAtlus.Add('7', new TexturedCharacter('7', Path.Combine(Utilities.getRelativePath(directoryToFonts), "7"), fontColor)); + this.CharacterAtlus.Add('8', new TexturedCharacter('8', Path.Combine(Utilities.getRelativePath(directoryToFonts), "8"), fontColor)); + this.CharacterAtlus.Add('9', new TexturedCharacter('9', Path.Combine(Utilities.getRelativePath(directoryToFonts), "9"), fontColor)); + + this.CharacterAtlus.Add('&', new TexturedCharacter('&', Path.Combine(Utilities.getRelativePath(directoryToFonts), "ampersand"), fontColor)); + this.CharacterAtlus.Add('*', new TexturedCharacter('*', Path.Combine(Utilities.getRelativePath(directoryToFonts), "asterisk"), fontColor)); + this.CharacterAtlus.Add('\\', new TexturedCharacter('\\', Path.Combine(Utilities.getRelativePath(directoryToFonts), "backSlash"), fontColor)); + + this.CharacterAtlus.Add('A', new TexturedCharacter('A', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalA"), fontColor)); + this.CharacterAtlus.Add('B', new TexturedCharacter('B', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalB"), fontColor)); + this.CharacterAtlus.Add('C', new TexturedCharacter('C', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalC"), fontColor)); + this.CharacterAtlus.Add('D', new TexturedCharacter('D', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalD"), fontColor)); + this.CharacterAtlus.Add('E', new TexturedCharacter('E', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalE"), fontColor)); + this.CharacterAtlus.Add('F', new TexturedCharacter('F', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalF"), fontColor)); + this.CharacterAtlus.Add('G', new TexturedCharacter('G', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalG"), fontColor)); + this.CharacterAtlus.Add('H', new TexturedCharacter('H', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalH"), fontColor)); + this.CharacterAtlus.Add('I', new TexturedCharacter('I', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalI"), fontColor)); + this.CharacterAtlus.Add('J', new TexturedCharacter('J', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalJ"), fontColor)); + this.CharacterAtlus.Add('K', new TexturedCharacter('K', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalK"), fontColor)); + this.CharacterAtlus.Add('L', new TexturedCharacter('L', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalL"), fontColor)); + this.CharacterAtlus.Add('M', new TexturedCharacter('M', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalM"), fontColor)); + this.CharacterAtlus.Add('N', new TexturedCharacter('N', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalN"), fontColor)); + this.CharacterAtlus.Add('O', new TexturedCharacter('O', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalO"), fontColor)); + this.CharacterAtlus.Add('P', new TexturedCharacter('P', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalP"), fontColor)); + this.CharacterAtlus.Add('Q', new TexturedCharacter('Q', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalQ"), fontColor)); + this.CharacterAtlus.Add('R', new TexturedCharacter('R', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalR"), fontColor)); + this.CharacterAtlus.Add('S', new TexturedCharacter('S', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalS"), fontColor)); + this.CharacterAtlus.Add('T', new TexturedCharacter('T', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalT"), fontColor)); + this.CharacterAtlus.Add('U', new TexturedCharacter('U', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalU"), fontColor)); + this.CharacterAtlus.Add('V', new TexturedCharacter('V', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalV"), fontColor)); + this.CharacterAtlus.Add('W', new TexturedCharacter('W', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalW"), fontColor)); + this.CharacterAtlus.Add('X', new TexturedCharacter('X', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalX"), fontColor)); + this.CharacterAtlus.Add('Y', new TexturedCharacter('Y', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalY"), fontColor)); + this.CharacterAtlus.Add('Z', new TexturedCharacter('Z', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalZ"), fontColor)); + + this.CharacterAtlus.Add('^', new TexturedCharacter('^', Path.Combine(Utilities.getRelativePath(directoryToFonts), "caret"), fontColor)); + this.CharacterAtlus.Add(':', new TexturedCharacter(':', Path.Combine(Utilities.getRelativePath(directoryToFonts), "colon"), fontColor)); + this.CharacterAtlus.Add(',', new TexturedCharacter(',', Path.Combine(Utilities.getRelativePath(directoryToFonts), "comma"), fontColor)); + this.CharacterAtlus.Add('\"', new TexturedCharacter('\"', Path.Combine(Utilities.getRelativePath(directoryToFonts), "doubleQuotes"), fontColor)); + this.CharacterAtlus.Add('!', new TexturedCharacter('!', Path.Combine(Utilities.getRelativePath(directoryToFonts), "exclamationMark"), fontColor)); + this.CharacterAtlus.Add('/', new TexturedCharacter('/', Path.Combine(Utilities.getRelativePath(directoryToFonts), "forwardSlash"), fontColor)); + this.CharacterAtlus.Add('`', new TexturedCharacter('`', Path.Combine(Utilities.getRelativePath(directoryToFonts), "grave"), fontColor)); + this.CharacterAtlus.Add('[', new TexturedCharacter('[', Path.Combine(Utilities.getRelativePath(directoryToFonts), "leftBracket"), fontColor)); + this.CharacterAtlus.Add('{', new TexturedCharacter('{', Path.Combine(Utilities.getRelativePath(directoryToFonts), "leftCurlyBracket"), fontColor)); + this.CharacterAtlus.Add('(', new TexturedCharacter('(', Path.Combine(Utilities.getRelativePath(directoryToFonts), "leftParenthesis"), fontColor)); + + this.CharacterAtlus.Add('a', new TexturedCharacter('a', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseA"), fontColor)); + this.CharacterAtlus.Add('b', new TexturedCharacter('b', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseB"), fontColor)); + this.CharacterAtlus.Add('c', new TexturedCharacter('c', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseC"), fontColor)); + this.CharacterAtlus.Add('d', new TexturedCharacter('d', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseD"), fontColor)); + this.CharacterAtlus.Add('e', new TexturedCharacter('e', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseE"), fontColor)); + this.CharacterAtlus.Add('f', new TexturedCharacter('f', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseF"), fontColor)); + this.CharacterAtlus.Add('g', new TexturedCharacter('g', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseG"), fontColor)); + this.CharacterAtlus.Add('h', new TexturedCharacter('h', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseH"), fontColor)); + this.CharacterAtlus.Add('i', new TexturedCharacter('i', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseI"), fontColor)); + this.CharacterAtlus.Add('j', new TexturedCharacter('j', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseJ"), fontColor)); + this.CharacterAtlus.Add('k', new TexturedCharacter('k', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseK"), fontColor)); + this.CharacterAtlus.Add('l', new TexturedCharacter('l', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseL"), fontColor)); + this.CharacterAtlus.Add('m', new TexturedCharacter('m', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseM"), fontColor)); + this.CharacterAtlus.Add('n', new TexturedCharacter('n', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseN"), fontColor)); + this.CharacterAtlus.Add('o', new TexturedCharacter('o', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseO"), fontColor)); + this.CharacterAtlus.Add('p', new TexturedCharacter('p', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseP"), fontColor)); + this.CharacterAtlus.Add('q', new TexturedCharacter('q', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseQ"), fontColor)); + this.CharacterAtlus.Add('r', new TexturedCharacter('r', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseR"), fontColor)); + this.CharacterAtlus.Add('s', new TexturedCharacter('s', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseS"), fontColor)); + this.CharacterAtlus.Add('t', new TexturedCharacter('t', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseT"), fontColor)); + this.CharacterAtlus.Add('u', new TexturedCharacter('u', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseU"), fontColor)); + this.CharacterAtlus.Add('v', new TexturedCharacter('v', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseV"), fontColor)); + this.CharacterAtlus.Add('w', new TexturedCharacter('w', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseW"), fontColor)); + this.CharacterAtlus.Add('x', new TexturedCharacter('x', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseX"), fontColor)); + this.CharacterAtlus.Add('y', new TexturedCharacter('y', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseY"), fontColor)); + this.CharacterAtlus.Add('z', new TexturedCharacter('z', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseZ"), fontColor)); + + this.CharacterAtlus.Add('-', new TexturedCharacter('-', Path.Combine(Utilities.getRelativePath(directoryToFonts), "minus"), fontColor)); + this.CharacterAtlus.Add('%', new TexturedCharacter('%', Path.Combine(Utilities.getRelativePath(directoryToFonts), "percent"), fontColor)); + this.CharacterAtlus.Add('.', new TexturedCharacter('.', Path.Combine(Utilities.getRelativePath(directoryToFonts), "period"), fontColor)); + this.CharacterAtlus.Add('+', new TexturedCharacter('+', Path.Combine(Utilities.getRelativePath(directoryToFonts), "plus"), fontColor)); + this.CharacterAtlus.Add('#', new TexturedCharacter('#', Path.Combine(Utilities.getRelativePath(directoryToFonts), "pound"), fontColor)); + + this.CharacterAtlus.Add('?', new TexturedCharacter('?', Path.Combine(Utilities.getRelativePath(directoryToFonts), "questionMark"), fontColor)); + this.CharacterAtlus.Add(']', new TexturedCharacter(']', Path.Combine(Utilities.getRelativePath(directoryToFonts), "rightBracket"), fontColor)); + this.CharacterAtlus.Add('}', new TexturedCharacter('}', Path.Combine(Utilities.getRelativePath(directoryToFonts), "rightCurlyBracket"), fontColor)); + + this.CharacterAtlus.Add(')', new TexturedCharacter(')', Path.Combine(Utilities.getRelativePath(directoryToFonts), "rightParenthesis"), fontColor)); + + this.CharacterAtlus.Add(';', new TexturedCharacter(';', Path.Combine(Utilities.getRelativePath(directoryToFonts), "semicolon"), fontColor)); + + this.CharacterAtlus.Add('\'', new TexturedCharacter('\'', Path.Combine(Utilities.getRelativePath(directoryToFonts), "singleQuote"), fontColor)); + this.CharacterAtlus.Add(' ', new TexturedCharacter(' ', Path.Combine(Utilities.getRelativePath(directoryToFonts), "space"), fontColor)); + this.CharacterAtlus.Add('~', new TexturedCharacter('~', Path.Combine(Utilities.getRelativePath(directoryToFonts), "tilde"), fontColor)); + this.CharacterAtlus.Add('_', new TexturedCharacter('_', Path.Combine(Utilities.getRelativePath(directoryToFonts), "underScore"), fontColor)); + this.CharacterAtlus.Add('|', new TexturedCharacter('|', Path.Combine(Utilities.getRelativePath(directoryToFonts), "verticalLine"), fontColor)); + + this.CharacterAtlus.Add('$', new TexturedCharacter('$', Path.Combine(Utilities.getRelativePath(directoryToFonts), "coin"), fontColor)); + this.CharacterAtlus.Add('=', new TexturedCharacter('=', Path.Combine(Utilities.getRelativePath(directoryToFonts), "star"), fontColor)); + this.CharacterAtlus.Add('@', new TexturedCharacter('@', Path.Combine(Utilities.getRelativePath(directoryToFonts), "heart"), fontColor)); + } + + public VanillaCharacterSheet(string directoryToFonts, Color fontColor) + { + this.CharacterAtlus = new Dictionary(); + this.CharacterAtlus.Add('0', new TexturedCharacter('0', Path.Combine(Utilities.getRelativePath(directoryToFonts), "0"), fontColor)); + this.CharacterAtlus.Add('1', new TexturedCharacter('1', Path.Combine(Utilities.getRelativePath(directoryToFonts), "1"), fontColor)); + this.CharacterAtlus.Add('2', new TexturedCharacter('2', Path.Combine(Utilities.getRelativePath(directoryToFonts), "2"), fontColor)); + this.CharacterAtlus.Add('3', new TexturedCharacter('3', Path.Combine(Utilities.getRelativePath(directoryToFonts), "3"), fontColor)); + this.CharacterAtlus.Add('4', new TexturedCharacter('4', Path.Combine(Utilities.getRelativePath(directoryToFonts), "4"), fontColor)); + this.CharacterAtlus.Add('5', new TexturedCharacter('5', Path.Combine(Utilities.getRelativePath(directoryToFonts), "5"), fontColor)); + this.CharacterAtlus.Add('6', new TexturedCharacter('6', Path.Combine(Utilities.getRelativePath(directoryToFonts), "6"), fontColor)); + this.CharacterAtlus.Add('7', new TexturedCharacter('7', Path.Combine(Utilities.getRelativePath(directoryToFonts), "7"), fontColor)); + this.CharacterAtlus.Add('8', new TexturedCharacter('8', Path.Combine(Utilities.getRelativePath(directoryToFonts), "8"), fontColor)); + this.CharacterAtlus.Add('9', new TexturedCharacter('9', Path.Combine(Utilities.getRelativePath(directoryToFonts), "9"), fontColor)); + + this.CharacterAtlus.Add('&', new TexturedCharacter('&', Path.Combine(Utilities.getRelativePath(directoryToFonts), "ampersand"), fontColor)); + this.CharacterAtlus.Add('*', new TexturedCharacter('*', Path.Combine(Utilities.getRelativePath(directoryToFonts), "asterisk"), fontColor)); + this.CharacterAtlus.Add('\\', new TexturedCharacter('\\', Path.Combine(Utilities.getRelativePath(directoryToFonts), "backSlash"), fontColor)); + + this.CharacterAtlus.Add('A', new TexturedCharacter('A', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalA"), fontColor)); + this.CharacterAtlus.Add('B', new TexturedCharacter('B', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalB"), fontColor)); + this.CharacterAtlus.Add('C', new TexturedCharacter('C', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalC"), fontColor)); + this.CharacterAtlus.Add('D', new TexturedCharacter('D', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalD"), fontColor)); + this.CharacterAtlus.Add('E', new TexturedCharacter('E', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalE"), fontColor)); + this.CharacterAtlus.Add('F', new TexturedCharacter('F', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalF"), fontColor)); + this.CharacterAtlus.Add('G', new TexturedCharacter('G', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalG"), fontColor)); + this.CharacterAtlus.Add('H', new TexturedCharacter('H', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalH"), fontColor)); + this.CharacterAtlus.Add('I', new TexturedCharacter('I', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalI"), fontColor)); + this.CharacterAtlus.Add('J', new TexturedCharacter('J', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalJ"), fontColor)); + this.CharacterAtlus.Add('K', new TexturedCharacter('K', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalK"), fontColor)); + this.CharacterAtlus.Add('L', new TexturedCharacter('L', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalL"), fontColor)); + this.CharacterAtlus.Add('M', new TexturedCharacter('M', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalM"), fontColor)); + this.CharacterAtlus.Add('N', new TexturedCharacter('N', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalN"), fontColor)); + this.CharacterAtlus.Add('O', new TexturedCharacter('O', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalO"), fontColor)); + this.CharacterAtlus.Add('P', new TexturedCharacter('P', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalP"), fontColor)); + this.CharacterAtlus.Add('Q', new TexturedCharacter('Q', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalQ"), fontColor)); + this.CharacterAtlus.Add('R', new TexturedCharacter('R', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalR"), fontColor)); + this.CharacterAtlus.Add('S', new TexturedCharacter('S', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalS"), fontColor)); + this.CharacterAtlus.Add('T', new TexturedCharacter('T', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalT"), fontColor)); + this.CharacterAtlus.Add('U', new TexturedCharacter('U', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalU"), fontColor)); + this.CharacterAtlus.Add('V', new TexturedCharacter('V', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalV"), fontColor)); + this.CharacterAtlus.Add('W', new TexturedCharacter('W', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalW"), fontColor)); + this.CharacterAtlus.Add('X', new TexturedCharacter('X', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalX"), fontColor)); + this.CharacterAtlus.Add('Y', new TexturedCharacter('Y', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalY"), fontColor)); + this.CharacterAtlus.Add('Z', new TexturedCharacter('Z', Path.Combine(Utilities.getRelativePath(directoryToFonts), "capitalZ"), fontColor)); + + this.CharacterAtlus.Add('^', new TexturedCharacter('^', Path.Combine(Utilities.getRelativePath(directoryToFonts), "caret"), fontColor)); + this.CharacterAtlus.Add(':', new TexturedCharacter(':', Path.Combine(Utilities.getRelativePath(directoryToFonts), "colon"), fontColor)); + this.CharacterAtlus.Add(',', new TexturedCharacter(',', Path.Combine(Utilities.getRelativePath(directoryToFonts), "comma"), fontColor)); + this.CharacterAtlus.Add('\"', new TexturedCharacter('\"', Path.Combine(Utilities.getRelativePath(directoryToFonts), "doubleQuotes"), fontColor)); + this.CharacterAtlus.Add('!', new TexturedCharacter('!', Path.Combine(Utilities.getRelativePath(directoryToFonts), "exclamationMark"), fontColor)); + this.CharacterAtlus.Add('/', new TexturedCharacter('/', Path.Combine(Utilities.getRelativePath(directoryToFonts), "forwardSlash"), fontColor)); + this.CharacterAtlus.Add('`', new TexturedCharacter('`', Path.Combine(Utilities.getRelativePath(directoryToFonts), "grave"), fontColor)); + this.CharacterAtlus.Add('[', new TexturedCharacter('[', Path.Combine(Utilities.getRelativePath(directoryToFonts), "leftBracket"), fontColor)); + this.CharacterAtlus.Add('{', new TexturedCharacter('{', Path.Combine(Utilities.getRelativePath(directoryToFonts), "leftCurlyBracket"), fontColor)); + this.CharacterAtlus.Add('(', new TexturedCharacter('(', Path.Combine(Utilities.getRelativePath(directoryToFonts), "leftParenthesis"), fontColor)); + + this.CharacterAtlus.Add('a', new TexturedCharacter('a', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseA"), fontColor)); + this.CharacterAtlus.Add('b', new TexturedCharacter('b', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseB"), fontColor)); + this.CharacterAtlus.Add('c', new TexturedCharacter('c', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseC"), fontColor)); + this.CharacterAtlus.Add('d', new TexturedCharacter('d', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseD"), fontColor)); + this.CharacterAtlus.Add('e', new TexturedCharacter('e', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseE"), fontColor)); + this.CharacterAtlus.Add('f', new TexturedCharacter('f', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseF"), fontColor)); + this.CharacterAtlus.Add('g', new TexturedCharacter('g', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseG"), fontColor)); + this.CharacterAtlus.Add('h', new TexturedCharacter('h', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseH"), fontColor)); + this.CharacterAtlus.Add('i', new TexturedCharacter('i', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseI"), fontColor)); + this.CharacterAtlus.Add('j', new TexturedCharacter('j', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseJ"), fontColor)); + this.CharacterAtlus.Add('k', new TexturedCharacter('k', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseK"), fontColor)); + this.CharacterAtlus.Add('l', new TexturedCharacter('l', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseL"), fontColor)); + this.CharacterAtlus.Add('m', new TexturedCharacter('m', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseM"), fontColor)); + this.CharacterAtlus.Add('n', new TexturedCharacter('n', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseN"), fontColor)); + this.CharacterAtlus.Add('o', new TexturedCharacter('o', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseO"), fontColor)); + this.CharacterAtlus.Add('p', new TexturedCharacter('p', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseP"), fontColor)); + this.CharacterAtlus.Add('q', new TexturedCharacter('q', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseQ"), fontColor)); + this.CharacterAtlus.Add('r', new TexturedCharacter('r', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseR"), fontColor)); + this.CharacterAtlus.Add('s', new TexturedCharacter('s', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseS"), fontColor)); + this.CharacterAtlus.Add('t', new TexturedCharacter('t', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseT"), fontColor)); + this.CharacterAtlus.Add('u', new TexturedCharacter('u', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseU"), fontColor)); + this.CharacterAtlus.Add('v', new TexturedCharacter('v', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseV"), fontColor)); + this.CharacterAtlus.Add('w', new TexturedCharacter('w', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseW"), fontColor)); + this.CharacterAtlus.Add('x', new TexturedCharacter('x', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseX"), fontColor)); + this.CharacterAtlus.Add('y', new TexturedCharacter('y', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseY"), fontColor)); + this.CharacterAtlus.Add('z', new TexturedCharacter('z', Path.Combine(Utilities.getRelativePath(directoryToFonts), "lowercaseZ"), fontColor)); + + this.CharacterAtlus.Add('-', new TexturedCharacter('-', Path.Combine(Utilities.getRelativePath(directoryToFonts), "minus"), fontColor)); + this.CharacterAtlus.Add('%', new TexturedCharacter('%', Path.Combine(Utilities.getRelativePath(directoryToFonts), "percent"), fontColor)); + this.CharacterAtlus.Add('.', new TexturedCharacter('.', Path.Combine(Utilities.getRelativePath(directoryToFonts), "period"), fontColor)); + this.CharacterAtlus.Add('+', new TexturedCharacter('+', Path.Combine(Utilities.getRelativePath(directoryToFonts), "plus"), fontColor)); + this.CharacterAtlus.Add('#', new TexturedCharacter('#', Path.Combine(Utilities.getRelativePath(directoryToFonts), "pound"), fontColor)); + + this.CharacterAtlus.Add('?', new TexturedCharacter('?', Path.Combine(Utilities.getRelativePath(directoryToFonts), "questionMark"), fontColor)); + this.CharacterAtlus.Add(']', new TexturedCharacter(']', Path.Combine(Utilities.getRelativePath(directoryToFonts), "rightBracket"), fontColor)); + this.CharacterAtlus.Add('}', new TexturedCharacter('}', Path.Combine(Utilities.getRelativePath(directoryToFonts), "rightCurlyBracket"), fontColor)); + + this.CharacterAtlus.Add(')', new TexturedCharacter(')', Path.Combine(Utilities.getRelativePath(directoryToFonts), "rightParenthesis"), fontColor)); + + this.CharacterAtlus.Add(';', new TexturedCharacter(';', Path.Combine(Utilities.getRelativePath(directoryToFonts), "semicolon"), fontColor)); + + this.CharacterAtlus.Add('\'', new TexturedCharacter('\'', Path.Combine(Utilities.getRelativePath(directoryToFonts), "singleQuote"), fontColor)); + this.CharacterAtlus.Add(' ', new TexturedCharacter(' ', Path.Combine(Utilities.getRelativePath(directoryToFonts), "space"), fontColor)); + this.CharacterAtlus.Add('~', new TexturedCharacter('~', Path.Combine(Utilities.getRelativePath(directoryToFonts), "tilde"), fontColor)); + this.CharacterAtlus.Add('_', new TexturedCharacter('_', Path.Combine(Utilities.getRelativePath(directoryToFonts), "underScore"), fontColor)); + this.CharacterAtlus.Add('|', new TexturedCharacter('|', Path.Combine(Utilities.getRelativePath(directoryToFonts), "verticalLine"), fontColor)); + + this.CharacterAtlus.Add('$', new TexturedCharacter('$', Path.Combine(Utilities.getRelativePath(directoryToFonts), "coin"), fontColor)); + this.CharacterAtlus.Add('=', new TexturedCharacter('=', Path.Combine(Utilities.getRelativePath(directoryToFonts), "star"), fontColor)); + this.CharacterAtlus.Add('@', new TexturedCharacter('@', Path.Combine(Utilities.getRelativePath(directoryToFonts), "heart"), fontColor)); + } + + public override TexturedCharacter getTexturedCharacter(char c) + { + var original = this.CharacterAtlus[c]; + return TexturedCharacter.Copy(original); + } + } +} diff --git a/GeneralMods/StardustCore/UIUtilities/SpriteFonts/Fonts/Components/CharacterSpacing.cs b/GeneralMods/StardustCore/UIUtilities/SpriteFonts/Fonts/Components/CharacterSpacing.cs new file mode 100644 index 00000000..34205001 --- /dev/null +++ b/GeneralMods/StardustCore/UIUtilities/SpriteFonts/Fonts/Components/CharacterSpacing.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StardustCore.UIUtilities.SpriteFonts.Components +{ + /// + /// Used to determine spacing between TexturedCharacters. + /// + public class CharacterSpacing + { + /// + /// Padding to offset this chaarcter by the previous character; + /// + public int LeftPadding; + /// + /// Padding to offset the following character by. + /// + public int RightPadding; + /// + /// Padding to offset the top character by. Not sure if this will be used. + /// + public int TopPadding; + /// + /// Padding to offset the bottom character by. Not sure if this will be used. + /// + public int BottomPadding; + + /// + /// Empty constructor; + /// + public CharacterSpacing() + { + + } + + /// + /// Constructor. + /// + /// + /// + /// + /// + public CharacterSpacing(int left, int right, int top, int bottom) + { + this.LeftPadding = left; + this.RightPadding = right; + this.TopPadding = top; + this.BottomPadding = bottom; + } + + /// + /// Save this to a .json file. + /// + /// + public void WriteToJson(string path) + { + StardustCore.ModCore.ModHelper.WriteJsonFile(path, this); + } + + /// + /// Read the data from the .json file. + /// + /// + /// + public static CharacterSpacing ReadFromJson(string path) + { + return StardustCore.ModCore.ModHelper.ReadJsonFile(path); + } + } +} diff --git a/GeneralMods/StardustCore/UIUtilities/SpriteFonts/Fonts/Components/TexturedCharacter.cs b/GeneralMods/StardustCore/UIUtilities/SpriteFonts/Fonts/Components/TexturedCharacter.cs new file mode 100644 index 00000000..c5f89a46 --- /dev/null +++ b/GeneralMods/StardustCore/UIUtilities/SpriteFonts/Fonts/Components/TexturedCharacter.cs @@ -0,0 +1,61 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StardustCore.UIUtilities.SpriteFonts.Components +{ + public class TexturedCharacter + { + public char character; + public string pathToTexture; + public Texture2D texture; + public CharacterSpacing spacing; + public Color drawColor; + public Vector2 position; + + public TexturedCharacter() + { + + } + + public TexturedCharacter(char Character,string PathToTexture,Color color) + { + this.character = Character; + this.pathToTexture = PathToTexture; + string text = this.pathToTexture.Remove(0, 1); + this.texture = StardustCore.ModCore.ModHelper.Content.Load(text+".png"); + this.spacing = new CharacterSpacing(); + this.drawColor = color; + this.position = new Vector2(); + } + + public TexturedCharacter(char Character, string PathToTexture,Color color,int left, int right,int top, int bottom) + { + this.character = Character; + this.pathToTexture = PathToTexture; + string text = this.pathToTexture.Remove(0, 1); + this.texture = StardustCore.ModCore.ModHelper.Content.Load(text + ".png"); + this.spacing = new CharacterSpacing(left,right,top,bottom); + this.drawColor = color; + this.position = new Vector2(); + } + + public static TexturedCharacter Copy(TexturedCharacter original) + { + TexturedCharacter copy = new TexturedCharacter(original.character,original.pathToTexture,original.drawColor); + copy.spacing = new CharacterSpacing(original.spacing.LeftPadding, original.spacing.RightPadding, original.spacing.TopPadding, original.spacing.BottomPadding); + return copy; + } + + + public void draw(SpriteBatch b) + { + b.Draw(this.texture, this.position, this.drawColor); + } + } +} diff --git a/GeneralMods/StardustCore/UIUtilities/SpriteFonts/Fonts/Components/TexturedString.cs b/GeneralMods/StardustCore/UIUtilities/SpriteFonts/Fonts/Components/TexturedString.cs new file mode 100644 index 00000000..878407b3 --- /dev/null +++ b/GeneralMods/StardustCore/UIUtilities/SpriteFonts/Fonts/Components/TexturedString.cs @@ -0,0 +1,129 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StardustCore.UIUtilities.SpriteFonts.Components +{ + public class TexturedString + { + List characters; + Vector2 position; + + public TexturedString(Vector2 Position,List Characters) + { + this.characters = Characters; + this.position = Position; + setCharacterPositions(); + } + + /// + /// Sets the character positions relative to the string's position on screen. + /// + public void setCharacterPositions() + { + int index = 0; + TexturedCharacter lastSeenChar=new TexturedCharacter(); + foreach(var c in characters) + { + if (index == 0) + { + c.position = new Vector2(this.position.X + c.spacing.LeftPadding,this.position.Y); + } + else + { + c.position = new Vector2(this.position.X + c.spacing.LeftPadding + lastSeenChar.spacing.RightPadding+lastSeenChar.texture.Width*index, this.position.Y); + } + StardustCore.ModCore.ModMonitor.Log(c.character.ToString()); + StardustCore.ModCore.ModMonitor.Log(c.position.ToString()); + lastSeenChar = c; + index++; + } + } + + /// + /// Adds a textured character to a textured string. + /// + /// + public void addCharacterToEnd(TexturedCharacter ch) + { + this.characters.Add(ch); + this.setCharacterPositions(); + } + + /// + /// Adds a list of textured characters to a textured string. + /// + /// + public void addCharactersToEnd(List chList) + { + foreach(var ch in chList) + { + this.characters.Add(ch); + } + this.setCharacterPositions(); + } + + /// + /// Adds the strings together and allows the position to be set. + /// + /// + /// + /// + /// + public TexturedString addStrings(TexturedString first,TexturedString second,Vector2 NewPosition) + { + var newString = first + second; + newString.position = NewPosition; + newString.setCharacterPositions(); + return newString; + } + + /// + /// Operator overload of +. Adds the two strings together and sets a new 0,0 position. + /// + /// + /// + /// + public static TexturedString operator+(TexturedString first, TexturedString second) + { + List characterList = new List(); + foreach(var v in first.characters) + { + characterList.Add(v); + } + foreach (var v in second.characters) + { + characterList.Add(v); + } + TexturedString newString = new TexturedString(new Vector2(0, 0), characterList); + return newString; + } + + + /// + /// Removes the characters from the textured word. + /// + /// + /// + public void removeCharactersFromEnd(int index,int howMany) + { + this.characters.RemoveRange(index, howMany); + } + + /// + /// Draw the textured string. + /// + /// + public void draw(SpriteBatch b) + { + foreach(var v in this.characters) + { + v.draw(b); + } + } + } +} diff --git a/GeneralMods/StardustCore/UIUtilities/SpriteFonts/Fonts/GenericFont.cs b/GeneralMods/StardustCore/UIUtilities/SpriteFonts/Fonts/GenericFont.cs new file mode 100644 index 00000000..f5aed4e1 --- /dev/null +++ b/GeneralMods/StardustCore/UIUtilities/SpriteFonts/Fonts/GenericFont.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StardustCore.UIUtilities.SpriteFonts.Fonts +{ + public class GenericFont + { + + public CharacterSheets.GenericCharacterSheets characterSheet; + public string path; + } +} diff --git a/GeneralMods/StardustCore/UIUtilities/SpriteFonts/Fonts/VanillaFont.cs b/GeneralMods/StardustCore/UIUtilities/SpriteFonts/Fonts/VanillaFont.cs new file mode 100644 index 00000000..7e33c682 --- /dev/null +++ b/GeneralMods/StardustCore/UIUtilities/SpriteFonts/Fonts/VanillaFont.cs @@ -0,0 +1,102 @@ +using Microsoft.Xna.Framework; +using StardustCore.UIUtilities.SpriteFonts.CharacterSheets; +using StardustCore.UIUtilities.SpriteFonts.Components; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StardustCore.UIUtilities.SpriteFonts.Fonts +{ + public class VanillaFont :GenericFont + { + /// + /// Constructor; + /// + public VanillaFont() + { + this.path = Path.Combine(StardustCore.UIUtilities.SpriteFonts.SpriteFont.FontDirectory, "Vanilla"); + if (!Directory.Exists(path)) Directory.CreateDirectory(path); + this.characterSheet = new VanillaCharacterSheet(path); + } + + /// + /// Takes a string and returns a textured string in it's place. + /// + /// + /// + public TexturedString voidParseString(string str) + { + List characters=new List(); + foreach(var chr in str) + { + characters.Add(characterSheet.getTexturedCharacter(chr)); + } + var tStr = new TexturedString(new Microsoft.Xna.Framework.Vector2(0, 0), characters); + return tStr; + } + + /// + /// Takes a string and returns a textured string in it's place. Also sets the new position. + /// + /// + /// + /// + public TexturedString ParseString(string str,Vector2 Position) + { + List characters = new List(); + foreach (var chr in str) + { + characters.Add(characterSheet.getTexturedCharacter(chr)); + } + var tStr = new TexturedString(Position, characters); + return tStr; + } + + /// + /// Takes a string and returns a textured string in it's place. Also sets the new position and string color. + /// + /// + /// + /// + /// + public TexturedString ParseString(string str, Vector2 Position, Color stringColor) + { + List characters = new List(); + foreach (var chr in str) + { + var c = characterSheet.getTexturedCharacter(chr); + c.drawColor = stringColor; + characters.Add(c); + } + var tStr = new TexturedString(Position, characters); + return tStr; + } + + /// + /// Takes a string and returns a textured string in it's place. Also sets the new position and string color. + /// + /// + /// + /// The color for the individual characters. + /// + public TexturedString ParseString(string str, Vector2 Position, List stringColor) + { + List characters = new List(); + int index = 0; + foreach (var chr in str) + { + var c = characterSheet.getTexturedCharacter(chr); + c.drawColor = stringColor.ElementAt(index); + characters.Add(c); + index++; + } + var tStr = new TexturedString(Position, characters); + return tStr; + } + + + } +} diff --git a/GeneralMods/StardustCore/UIUtilities/SpriteFonts/SpriteFont.cs b/GeneralMods/StardustCore/UIUtilities/SpriteFonts/SpriteFont.cs new file mode 100644 index 00000000..201f0f1b --- /dev/null +++ b/GeneralMods/StardustCore/UIUtilities/SpriteFonts/SpriteFont.cs @@ -0,0 +1,28 @@ +using StardustCore.UIUtilities.SpriteFonts.Fonts; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StardustCore.UIUtilities.SpriteFonts +{ + /// + /// Manages Fonts for Stardust core. While all fonts variables can be accessed from their classes, they can also hold a reference here. + /// + public class SpriteFont + { + public static string FontDirectory; + + public static VanillaFont vanillaFont; + + public static void initialize() + { + StardustCore.ModCore.ModMonitor.Log("HEY THERE!!"); + FontDirectory = Path.Combine(StardustCore.ModCore.ContentDirectory, "Fonts"); + if (!Directory.Exists(FontDirectory)) Directory.CreateDirectory(FontDirectory); + vanillaFont = new VanillaFont(); + } + } +} diff --git a/GeneralMods/StardustCore/Utilities.cs b/GeneralMods/StardustCore/Utilities.cs index 9703e5d9..9d1595c7 100644 --- a/GeneralMods/StardustCore/Utilities.cs +++ b/GeneralMods/StardustCore/Utilities.cs @@ -30,8 +30,16 @@ namespace StardustCore return (int)((double)c.price * (1.0 + (double)c.quality * 0.25)); } - - + /// + /// Returns an absolute path past the mod's directory. + /// + /// + /// + public static string getRelativePath(string absolutePath) + { + var ok= absolutePath.Split(new string[] { "StardustCore" }, StringSplitOptions.None); + return ok.ElementAt(1); + } public static void createObjectDebris(Item I, int xTileOrigin, int yTileOrigin, int xTileTarget, int yTileTarget, int groundLevel = -1, int itemQuality = 0, float velocityMultiplyer = 1f, GameLocation location = null) diff --git a/GeneralMods/UIUtilities/UIUtilities.sln b/GeneralMods/UIUtilities/UIUtilities.sln new file mode 100644 index 00000000..9249205d --- /dev/null +++ b/GeneralMods/UIUtilities/UIUtilities.sln @@ -0,0 +1,22 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Express 14 for Windows Desktop +VisualStudioVersion = 14.0.25420.1 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "UIUtilities", "UIUtilities\UIUtilities.csproj", "{ABA29468-BAC9-47E9-983A-393FC5489124}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {ABA29468-BAC9-47E9-983A-393FC5489124}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {ABA29468-BAC9-47E9-983A-393FC5489124}.Debug|Any CPU.Build.0 = Debug|Any CPU + {ABA29468-BAC9-47E9-983A-393FC5489124}.Release|Any CPU.ActiveCfg = Release|Any CPU + {ABA29468-BAC9-47E9-983A-393FC5489124}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/GeneralMods/UIUtilities/UIUtilities/Class1.cs b/GeneralMods/UIUtilities/UIUtilities/Class1.cs new file mode 100644 index 00000000..aa318fee --- /dev/null +++ b/GeneralMods/UIUtilities/UIUtilities/Class1.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace UIUtilities +{ + public class Class1 + { + } +} diff --git a/GeneralMods/UIUtilities/UIUtilities/MenuComponents/Button.cs b/GeneralMods/UIUtilities/UIUtilities/MenuComponents/Button.cs new file mode 100644 index 00000000..71eb3c9d --- /dev/null +++ b/GeneralMods/UIUtilities/UIUtilities/MenuComponents/Button.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace UIUtilities.MenuComponents +{ + class Button : StardewValley.Menus.ClickableComponent + { + } +} diff --git a/GeneralMods/UIUtilities/UIUtilities/Properties/AssemblyInfo.cs b/GeneralMods/UIUtilities/UIUtilities/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..a20bd801 --- /dev/null +++ b/GeneralMods/UIUtilities/UIUtilities/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("UIUtilities")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("UIUtilities")] +[assembly: AssemblyCopyright("Copyright © 2018")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("aba29468-bac9-47e9-983a-393fc5489124")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/GeneralMods/UIUtilities/UIUtilities/UIUtilities.csproj b/GeneralMods/UIUtilities/UIUtilities/UIUtilities.csproj new file mode 100644 index 00000000..057f4cef --- /dev/null +++ b/GeneralMods/UIUtilities/UIUtilities/UIUtilities.csproj @@ -0,0 +1,67 @@ + + + + + Debug + AnyCPU + {ABA29468-BAC9-47E9-983A-393FC5489124} + Library + Properties + UIUtilities + UIUtilities + v4.5 + 512 + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + \ No newline at end of file diff --git a/GeneralMods/UIUtilities/UIUtilities/packages.config b/GeneralMods/UIUtilities/UIUtilities/packages.config new file mode 100644 index 00000000..028670c6 --- /dev/null +++ b/GeneralMods/UIUtilities/UIUtilities/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file From 1b41fc47e92d2a4a9456e705fc419263a2c380cc Mon Sep 17 00:00:00 2001 From: Date: Tue, 6 Feb 2018 02:13:21 -0800 Subject: [PATCH 07/18] Made layered texture to be able to have textures on textures. Might be used in the near future. --- GeneralMods/StardustCore/StardustCore.csproj | 2 + .../UIUtilities/LayeredTexture.cs | 44 +++++++++++++++++++ .../UIUtilities/Texture2DExtended.cs | 29 ++++++++++++ 3 files changed, 75 insertions(+) create mode 100644 GeneralMods/StardustCore/UIUtilities/LayeredTexture.cs create mode 100644 GeneralMods/StardustCore/UIUtilities/Texture2DExtended.cs diff --git a/GeneralMods/StardustCore/StardustCore.csproj b/GeneralMods/StardustCore/StardustCore.csproj index 137361de..a599906b 100644 --- a/GeneralMods/StardustCore/StardustCore.csproj +++ b/GeneralMods/StardustCore/StardustCore.csproj @@ -45,6 +45,7 @@ + @@ -61,6 +62,7 @@ + diff --git a/GeneralMods/StardustCore/UIUtilities/LayeredTexture.cs b/GeneralMods/StardustCore/UIUtilities/LayeredTexture.cs new file mode 100644 index 00000000..af7972df --- /dev/null +++ b/GeneralMods/StardustCore/UIUtilities/LayeredTexture.cs @@ -0,0 +1,44 @@ +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StardustCore.UIUtilities +{ + public class LayeredTexture + { + public List textureLayers; + + public LayeredTexture(List textures) + { + this.textureLayers = textures; + } + + /// + /// Adds a new texture as the top layer. + /// + /// + public void addTexture(Texture2DExtended texture) + { + this.textureLayers.Add(texture); + } + + /// + /// Adds a new texture at a specific layer depth. + /// + /// + /// + public void addTexture(Texture2DExtended texture, int index) + { + this.textureLayers.Insert(index, texture); + } + + public LayeredTexture Copy() + { + return new LayeredTexture(this.textureLayers); + } + + } +} diff --git a/GeneralMods/StardustCore/UIUtilities/Texture2DExtended.cs b/GeneralMods/StardustCore/UIUtilities/Texture2DExtended.cs new file mode 100644 index 00000000..134d3608 --- /dev/null +++ b/GeneralMods/StardustCore/UIUtilities/Texture2DExtended.cs @@ -0,0 +1,29 @@ +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StardustCore.UIUtilities +{ + public class Texture2DExtended + { + public string Name; + public Texture2D texture; + public string path; + + public Texture2DExtended(string path) + { + this.Name = Path.GetFileName(path); + this.path = path; + this.texture = StardustCore.ModCore.ModHelper.Content.Load(path); + } + + public Texture2DExtended Copy() + { + return new Texture2DExtended(this.path); + } + } +} From aa71ab8ec4562bec8889ad8de1986950f83c368e Mon Sep 17 00:00:00 2001 From: Date: Wed, 21 Feb 2018 13:41:43 -0800 Subject: [PATCH 08/18] Started work on Hex32 class for color conversion because why not. --- GeneralMods/StardustCore/Math/Hex.cs | 106 +++++++++++++++++++++++++ GeneralMods/StardustCore/Math/Hex32.cs | 90 +++++++++++++++++++++ 2 files changed, 196 insertions(+) create mode 100644 GeneralMods/StardustCore/Math/Hex.cs create mode 100644 GeneralMods/StardustCore/Math/Hex32.cs diff --git a/GeneralMods/StardustCore/Math/Hex.cs b/GeneralMods/StardustCore/Math/Hex.cs new file mode 100644 index 00000000..03d4ae35 --- /dev/null +++ b/GeneralMods/StardustCore/Math/Hex.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StardustCore.Math +{ + /// + /// Base class for hex representation. + /// + public class Hex + { + /// + /// The hex value represented as a string. + /// + public string hexValue; + + /// + /// Default constructor. + /// + public Hex() + { + + } + /// + /// Empty Constructor; + /// + /// + public Hex(string HexValue) + { + + } + + /// + /// Verifies that the hex is of the specified length. + /// + /// + public virtual bool verifyHexLength() + { + return true; + } + + /// + /// Trims the hex value by removing the leading 0x; + /// + /// + public virtual string trimHex() + { + return this.hexValue.Split('x')[1]; + } + + /// + /// A virtual function to be overriden. + /// + /// + public virtual List getBytes() + { + return new List(); + } + + /// + /// Converts a Hex byte (represented as a length two string) to an int equal or less than 255. Ex ff=255; + /// + /// The length two value to be converted. + /// + public virtual int convertHexByteTo255Int(string value) + { + int val1 = convertHexValueToInt(value[0]); + int val2 = convertHexValueToInt(value[1]); + val1 *= 16; + val2 *= 16; + return val1 + val2; + } + + /// + /// Converts a hex char to an int. + /// + /// + /// + public virtual int convertHexValueToInt(char c) + { + if (c == 'a') return 10; + else if (c == 'b') return 11; + else if (c == 'c') return 12; + else if (c == 'd') return 13; + else if (c == 'e') return 14; + else if (c == 'f') return 15; + else return Convert.ToInt32(c); + } + + /// + /// Gets the associated byte from the hex positioning. + /// + /// + /// + public virtual string getByte(int index) + { + string hex = this.trimHex(); + int val = index * 2 + 1; + char str1 = hex[index * 2]; + char str2 = hex[val]; + return (str1.ToString() + str2.ToString()); + } + } +} diff --git a/GeneralMods/StardustCore/Math/Hex32.cs b/GeneralMods/StardustCore/Math/Hex32.cs new file mode 100644 index 00000000..25da9ed0 --- /dev/null +++ b/GeneralMods/StardustCore/Math/Hex32.cs @@ -0,0 +1,90 @@ +using Microsoft.Xna.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace StardustCore.Math +{ + /// + /// A Class that helps represents 32 bit hex. + /// + class Hex32 : Hex + { + /// + /// A default constructor. + /// + public Hex32() + { + this.hexValue = "0x00000000"; + } + + /// + /// Constructor. + /// + /// A string in hex representation. Ex) 0x00000000 + public Hex32(string hexValue) + { + this.hexValue = hexValue; + if (verifyHexLength() == false) this.hexValue = "0x00000000"; + } + /// + /// Constructor. + /// + /// An int to be converted into Hex. + public Hex32(int value) + { + this.hexValue= value.ToString("X"); + if (verifyHexLength() == false) this.hexValue = "0x00000000"; + } + + + /// + /// Makes sure the hex value is the appropriate length. + /// + /// + public override bool verifyHexLength() + { + if (this.hexValue.Length != 10) return false; + else return true; + } + + /// + /// Trims the hex to get rid of the leading 0x; + /// + /// + public override string trimHex() + { + return base.trimHex(); + } + + /// + /// Converts a hex value to a string. + /// + /// + public Color toColor() + { + var bytes = getBytes(); + int red = convertHexByteTo255Int(bytes[0]); + int green = convertHexByteTo255Int(bytes[1]); + int blue = convertHexByteTo255Int(bytes[2]); + int alpha = convertHexByteTo255Int(bytes[3]); + return new Color(red, green, blue, alpha); + } + + /// + /// Get the individual byte strings associated with this hex value. + /// + /// + public override List getBytes() + { + List bytes = new List(); + bytes.Add(getByte(0)); + bytes.Add(getByte(1)); + bytes.Add(getByte(2)); + bytes.Add(getByte(3)); + return bytes; + } + } +} From bebcefa76517daa7778275af2df2f27f1657815a Mon Sep 17 00:00:00 2001 From: Date: Thu, 22 Feb 2018 11:43:18 -0800 Subject: [PATCH 09/18] Started work on new mod to add map events with code. --- GeneralMods/MapEvents/Class1.cs | 17 ++ GeneralMods/MapEvents/Framework/Delegates.cs | 15 ++ .../FunctionEvents/MouseButtonEvents.cs | 62 ++++++ .../FunctionEvents/MouseEntryLeaveEvent.cs | 34 ++++ .../Framework/FunctionEvents/PlayerEvents.cs | 34 ++++ .../Framework/FunctionEvents/functionEvent.cs | 47 +++++ GeneralMods/MapEvents/Framework/MapEvent.cs | 187 ++++++++++++++++++ GeneralMods/MapEvents/MapEvents.csproj | 61 ++++++ .../MapEvents/Properties/AssemblyInfo.cs | 36 ++++ GeneralMods/MapEvents/packages.config | 4 + GeneralMods/StardustCore/StardustCore.csproj | 2 + 11 files changed, 499 insertions(+) create mode 100644 GeneralMods/MapEvents/Class1.cs create mode 100644 GeneralMods/MapEvents/Framework/Delegates.cs create mode 100644 GeneralMods/MapEvents/Framework/FunctionEvents/MouseButtonEvents.cs create mode 100644 GeneralMods/MapEvents/Framework/FunctionEvents/MouseEntryLeaveEvent.cs create mode 100644 GeneralMods/MapEvents/Framework/FunctionEvents/PlayerEvents.cs create mode 100644 GeneralMods/MapEvents/Framework/FunctionEvents/functionEvent.cs create mode 100644 GeneralMods/MapEvents/Framework/MapEvent.cs create mode 100644 GeneralMods/MapEvents/MapEvents.csproj create mode 100644 GeneralMods/MapEvents/Properties/AssemblyInfo.cs create mode 100644 GeneralMods/MapEvents/packages.config diff --git a/GeneralMods/MapEvents/Class1.cs b/GeneralMods/MapEvents/Class1.cs new file mode 100644 index 00000000..7dadf81e --- /dev/null +++ b/GeneralMods/MapEvents/Class1.cs @@ -0,0 +1,17 @@ +using StardewModdingAPI; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MapEvents +{ + public class MapEvents: Mod + { + public override void Entry(IModHelper helper) + { + + } + } +} diff --git a/GeneralMods/MapEvents/Framework/Delegates.cs b/GeneralMods/MapEvents/Framework/Delegates.cs new file mode 100644 index 00000000..206d1294 --- /dev/null +++ b/GeneralMods/MapEvents/Framework/Delegates.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MapEvents.Framework +{ + class Delegates + { + public delegate void voidDel(); + public delegate void strDel(string s); + public delegate void paramFunction(List parameters); + } +} diff --git a/GeneralMods/MapEvents/Framework/FunctionEvents/MouseButtonEvents.cs b/GeneralMods/MapEvents/Framework/FunctionEvents/MouseButtonEvents.cs new file mode 100644 index 00000000..e44ae354 --- /dev/null +++ b/GeneralMods/MapEvents/Framework/FunctionEvents/MouseButtonEvents.cs @@ -0,0 +1,62 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MapEvents.Framework.FunctionEvents +{ + /// + /// Used to handle mouse interactions with button clicks and scrolling the mouse wheel. + /// + class MouseButtonEvents + { + /// + /// Function that runs when the user left clicks. + /// + public functionEvent onLeftClick; + /// + /// Function that runs when the user right clicks. + /// + public functionEvent onRightClick; + /// + /// Function that runs when the user scrolls the mouse wheel. + /// + public functionEvent onMouseScroll; + + /// + /// A constructor used to set a single function to a mouse button. + /// + /// + /// If true the function is set to the left click. If false the function is set to the right click. + public MouseButtonEvents(functionEvent clickFunction, bool leftClick) + { + if (leftClick == true) this.onLeftClick = clickFunction; + else this.onRightClick = clickFunction; + } + + /// + /// A constructor used to map functions to mouse clicks. + /// + /// A function to be ran when the mouse left clicks this position. + /// A function to be ran when the mouse right clicks this position. + public MouseButtonEvents(functionEvent OnLeftClick, functionEvent OnRightClick) + { + this.onLeftClick = OnLeftClick; + this.onRightClick = OnRightClick; + } + + /// + /// A constructor used to map functions to mouse clicks and scrolling the mouse wheel. + /// + /// A function to be ran when the mouse left clicks this position. + /// A function to be ran when the mouse right clicks this position. + /// A function to be ran when the user scrolls the mouse + public MouseButtonEvents(functionEvent OnLeftClick,functionEvent OnRightClick, functionEvent OnMouseScroll) + { + this.onLeftClick = OnLeftClick; + this.onRightClick = OnRightClick; + this.onMouseScroll = OnMouseScroll; + } + } +} diff --git a/GeneralMods/MapEvents/Framework/FunctionEvents/MouseEntryLeaveEvent.cs b/GeneralMods/MapEvents/Framework/FunctionEvents/MouseEntryLeaveEvent.cs new file mode 100644 index 00000000..dd8487f7 --- /dev/null +++ b/GeneralMods/MapEvents/Framework/FunctionEvents/MouseEntryLeaveEvent.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MapEvents.Framework.FunctionEvents +{ + /// + /// Used to handle events that happens when a mouse enters/leaves a specified position. + /// + class MouseEntryLeaveEvent + { + /// + /// A function that is called when a mouse enters a certain position. + /// + public functionEvent onMouseEnter; + /// + /// A function that is called when a mouse leaves a certain position. + /// + public functionEvent onMouseLeave; + + /// + /// Constructor. + /// + /// The function that occurs when the mouse enters a certain position. + /// The function that occurs when the mouse leaves a certain position. + public MouseEntryLeaveEvent(functionEvent OnMouseEnter, functionEvent OnMouseLeave) + { + this.onMouseEnter = OnMouseEnter; + this.onMouseLeave = OnMouseLeave; + } + } +} diff --git a/GeneralMods/MapEvents/Framework/FunctionEvents/PlayerEvents.cs b/GeneralMods/MapEvents/Framework/FunctionEvents/PlayerEvents.cs new file mode 100644 index 00000000..382e7bc0 --- /dev/null +++ b/GeneralMods/MapEvents/Framework/FunctionEvents/PlayerEvents.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace MapEvents.Framework.FunctionEvents +{ + /// + /// Used to handle various functions that occur on player interaction. + /// + class PlayerEvents + { + /// + /// Occurs when the player enters the same tile as this event. + /// + public functionEvent onPlayerEnter; + /// + /// Occurs when the player leaves the same tile as this event. + /// + public functionEvent onPlayerLeave; + + /// + /// Constructor. + /// + /// + /// + public PlayerEvents(functionEvent OnPlayerEnter, functionEvent OnPlayerLeave) + { + this.onPlayerEnter = OnPlayerEnter; + this.onPlayerLeave = OnPlayerLeave; + } + } +} diff --git a/GeneralMods/MapEvents/Framework/FunctionEvents/functionEvent.cs b/GeneralMods/MapEvents/Framework/FunctionEvents/functionEvent.cs new file mode 100644 index 00000000..d1487719 --- /dev/null +++ b/GeneralMods/MapEvents/Framework/FunctionEvents/functionEvent.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static MapEvents.Framework.Delegates; + +namespace MapEvents.Framework +{ + /// + /// Used to pair a function and a parameter list using the super object class to run virtually any function for map events. + /// + class functionEvent + { + public paramFunction function; + public List parameters; + + /// + /// Constructor. + /// + /// The function to be called when running an event. + /// The list of system.objects to be used in the function. Can include objects,strings, ints, etc. Anything can be passed in as a parameter or can be passed in as empty. Passing in null will just create an empty list. + public functionEvent(paramFunction Function, List Parameters) + { + if (this.parameters == null) this.parameters = new List(); + this.function = Function; + this.parameters = Parameters; + } + + /// + /// Runs the function with the passed in parameters. + /// + public void run() + { + this.function.Invoke(this.parameters); + } + + /// + /// Simply swaps out the old parameters list for a new one. + /// + /// + public void updateParameters(List newParameters) + { + this.parameters = newParameters; + } + } +} diff --git a/GeneralMods/MapEvents/Framework/MapEvent.cs b/GeneralMods/MapEvents/Framework/MapEvent.cs new file mode 100644 index 00000000..38f549a2 --- /dev/null +++ b/GeneralMods/MapEvents/Framework/MapEvent.cs @@ -0,0 +1,187 @@ +using MapEvents.Framework.FunctionEvents; +using Microsoft.Xna.Framework; +using StardewValley; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using static MapEvents.Framework.Delegates; + +namespace MapEvents.Framework +{ + class MapEvent + { + /// + /// Make constructor that takes all parameters for a function. + /// Make an update function that runs associated functions to check which events need to be ran. + /// + /// //MAKE A MAP EVENT MANAGER TO HOLD GAME LOCATIONS AND A LIST OF MAP EVENTS!!!!!! Dic> + /// + + + public Vector2 tilePosition; + public GameLocation location; + + public PlayerEvents playerEvents; + + public bool playerOnTile; + + + public MouseButtonEvents mouseButtonEvents; + public MouseEntryLeaveEvent mouseEntryLeaveEvents; + public bool mouseOnTile; + + + + public bool doesInteractionNeedToRun; + public bool loopInteraction; + + /// + /// A simple map event that doesn't do anything. + /// + /// + /// + public MapEvent(GameLocation Location,Vector2 Position) + { + this.location = Location; + this.tilePosition = Position; + } + + /// + /// Empty Constructor + /// + public MapEvent() + { + + } + + + /// + /// A simple map function that runs when the player enters and leaves a tile. Set values to null for nothing to happen. + /// + /// The game location where the event is. I.E Farm, Town, Mine etc. + /// The x,y position on the map the event is. + /// Handles various events that runs when the player enters/leaves a tile, etc. + + public MapEvent(GameLocation Location,Vector2 position, PlayerEvents PlayerEvents) + { + this.location = Location; + this.tilePosition = position; + this.playerEvents = PlayerEvents; + } + + /// + /// A constructor that handles when the mouse leaves and enters a tile. + /// + /// The game location where the event is. + /// The x,y position of the tile at the game location. + /// A class used to handle mouse entry/leave events. + public MapEvent(GameLocation Location, Vector2 Position, MouseEntryLeaveEvent mouseEvents) + { + this.location = Location; + this.tilePosition = Position; + this.mouseEntryLeaveEvents = mouseEvents; + } + + /// + /// A constructor that handles when the mouse leaves and enters a tile. + /// + /// The game location where the event is. + /// The x,y position of the tile at the game location. + /// A class used to handle mouse click/scroll events. + public MapEvent(GameLocation Location, Vector2 Position, MouseButtonEvents mouseEvents) + { + this.location = Location; + this.tilePosition = Position; + this.mouseButtonEvents = mouseEvents; + } + + /// + /// Occurs when the player enters the same tile as this event. The function associated with this event is then ran. + /// + public void OnPlayerEnter() + { + this.playerOnTile = true; + if (this.playerEvents.onPlayerEnter != null) this.playerEvents.onPlayerEnter.run(); + } + + /// + /// Occurs when the player leaves the same tile that this event is on. The function associated with thie event is then ran. + /// + public void OnPlayerLeave() + { + this.playerOnTile = false; + if (this.playerEvents.onPlayerLeave != null) this.playerEvents.onPlayerEnter.run(); + } + + /// + /// Occurs when the player left clicks the same tile that this event is on. + /// + public void OnLeftClick() + { + if (this.mouseButtonEvents.onLeftClick != null) this.mouseButtonEvents.onLeftClick.run(); + } + + /// + /// Occurs when the player right clicks the same tile that this event is on. + /// + public void OnRightClick() + { + if (this.mouseButtonEvents.onRightClick != null) this.mouseButtonEvents.onRightClick.run(); + } + + /// + /// Occurs when the mouse tile position is the same as this event's x,y position. + /// + public void OnMouseEnter() + { + this.mouseOnTile = true; + if (this.mouseEntryLeaveEvents.onMouseEnter != null) this.mouseEntryLeaveEvents.onMouseEnter.run(); + } + + /// + /// Occurs when the mouse tile position leaves the the same x,y position as this event. + /// + public void OnMouseLeave() + { + this.mouseOnTile = false; + if (this.mouseEntryLeaveEvents.onMouseLeave != null) this.mouseEntryLeaveEvents.onMouseLeave.run(); + } + + /// + /// Occurs when the mouse is on the same position as the tile AND the user scrolls the mouse wheel. + /// + public void OnMouseScroll() + { + if (this.mouseButtonEvents.onMouseScroll != null) this.mouseButtonEvents.onMouseScroll.run(); + } + + /// + /// Checks if the player is on the same tile as this event. + /// + /// + public bool isPlayerOnTile() + { + if (Game1.player.getTileX() == this.tilePosition.X && Game1.player.getTileY() == this.tilePosition.Y) return true; + else return false; + } + + /// + /// Checks if the player is on the same tile as the event and then runs the associated event. + /// + public void isPlayerOnTileRunEvent() + { + if (isPlayerOnTile() == true) OnPlayerEnter(); + } + + /// + /// If the player recently entered the tile and the player is no longer on this tile then the player left the tile. If that is true then run the leaving function. + /// + public void didPlayerLeaveTileRunEvent() + { + if (this.playerOnTile == true && isPlayerOnTile() == false) this.OnPlayerLeave(); + } + + } +} diff --git a/GeneralMods/MapEvents/MapEvents.csproj b/GeneralMods/MapEvents/MapEvents.csproj new file mode 100644 index 00000000..f01a7780 --- /dev/null +++ b/GeneralMods/MapEvents/MapEvents.csproj @@ -0,0 +1,61 @@ + + + + + Debug + AnyCPU + {BB737337-2D82-4245-AA46-F3B82FC6F228} + Library + Properties + MapEvents + MapEvents + v4.5 + 512 + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + \ No newline at end of file diff --git a/GeneralMods/MapEvents/Properties/AssemblyInfo.cs b/GeneralMods/MapEvents/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..374e3112 --- /dev/null +++ b/GeneralMods/MapEvents/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("MapEvents")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("MapEvents")] +[assembly: AssemblyCopyright("Copyright © 2018")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("bb737337-2d82-4245-aa46-f3b82fc6f228")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/GeneralMods/MapEvents/packages.config b/GeneralMods/MapEvents/packages.config new file mode 100644 index 00000000..028670c6 --- /dev/null +++ b/GeneralMods/MapEvents/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/GeneralMods/StardustCore/StardustCore.csproj b/GeneralMods/StardustCore/StardustCore.csproj index a599906b..9d1d2321 100644 --- a/GeneralMods/StardustCore/StardustCore.csproj +++ b/GeneralMods/StardustCore/StardustCore.csproj @@ -45,6 +45,8 @@ + + From 44a5887e1b933a34a4165bafb17343b06c8da799 Mon Sep 17 00:00:00 2001 From: Date: Thu, 22 Feb 2018 15:30:35 -0800 Subject: [PATCH 10/18] Working on mouse button events. --- GeneralMods/MapEvents/Framework/MapEvent.cs | 54 ++++++++++++++++++--- 1 file changed, 46 insertions(+), 8 deletions(-) diff --git a/GeneralMods/MapEvents/Framework/MapEvent.cs b/GeneralMods/MapEvents/Framework/MapEvent.cs index 38f549a2..fe89b7b4 100644 --- a/GeneralMods/MapEvents/Framework/MapEvent.cs +++ b/GeneralMods/MapEvents/Framework/MapEvent.cs @@ -13,9 +13,8 @@ namespace MapEvents.Framework class MapEvent { /// - /// Make constructor that takes all parameters for a function. /// Make an update function that runs associated functions to check which events need to be ran. - /// + /// make way to detect which button is clicked when on this tile. /// //MAKE A MAP EVENT MANAGER TO HOLD GAME LOCATIONS AND A LIST OF MAP EVENTS!!!!!! Dic> /// @@ -97,10 +96,27 @@ namespace MapEvents.Framework this.mouseButtonEvents = mouseEvents; } + /// + /// A constructor encapsulating player, mouse button, and mouse entry events. + /// + /// The game location for which the event is located. I.E Town, Farm, etc. + /// The x,y cordinates for this event to be located at. + /// The events that occur associated with the player. I.E player entry, etc. + /// The events associated with clicking a mouse button while on this tile. + /// The events that occur when the mouse enters or leaves the same tile position as this event. + public MapEvent(GameLocation Location, Vector2 Position, PlayerEvents playerEvents, MouseButtonEvents mouseButtonEvents, MouseEntryLeaveEvent mouseEntryLeaveEvents) + { + this.location = Location; + this.tilePosition = Position; + this.playerEvents = playerEvents; + this.mouseButtonEvents = mouseButtonEvents; + this.mouseEntryLeaveEvents = mouseEntryLeaveEvents; + } + /// /// Occurs when the player enters the same tile as this event. The function associated with this event is then ran. /// - public void OnPlayerEnter() + private void OnPlayerEnter() { this.playerOnTile = true; if (this.playerEvents.onPlayerEnter != null) this.playerEvents.onPlayerEnter.run(); @@ -109,7 +125,7 @@ namespace MapEvents.Framework /// /// Occurs when the player leaves the same tile that this event is on. The function associated with thie event is then ran. /// - public void OnPlayerLeave() + private void OnPlayerLeave() { this.playerOnTile = false; if (this.playerEvents.onPlayerLeave != null) this.playerEvents.onPlayerEnter.run(); @@ -120,6 +136,7 @@ namespace MapEvents.Framework /// public void OnLeftClick() { + if (this.mouseOnTile==false) return; if (this.mouseButtonEvents.onLeftClick != null) this.mouseButtonEvents.onLeftClick.run(); } @@ -128,6 +145,7 @@ namespace MapEvents.Framework /// public void OnRightClick() { + if (this.mouseOnTile == false) return; if (this.mouseButtonEvents.onRightClick != null) this.mouseButtonEvents.onRightClick.run(); } @@ -136,8 +154,11 @@ namespace MapEvents.Framework /// public void OnMouseEnter() { - this.mouseOnTile = true; - if (this.mouseEntryLeaveEvents.onMouseEnter != null) this.mouseEntryLeaveEvents.onMouseEnter.run(); + if (isMouseOnTile()) + { + this.mouseOnTile = true; + if (this.mouseEntryLeaveEvents.onMouseEnter != null) this.mouseEntryLeaveEvents.onMouseEnter.run(); + } } /// @@ -145,8 +166,11 @@ namespace MapEvents.Framework /// public void OnMouseLeave() { - this.mouseOnTile = false; - if (this.mouseEntryLeaveEvents.onMouseLeave != null) this.mouseEntryLeaveEvents.onMouseLeave.run(); + if (isMouseOnTile() == false && this.mouseOnTile == true) + { + this.mouseOnTile = false; + if (this.mouseEntryLeaveEvents.onMouseLeave != null) this.mouseEntryLeaveEvents.onMouseLeave.run(); + } } /// @@ -154,6 +178,7 @@ namespace MapEvents.Framework /// public void OnMouseScroll() { + if (isMouseOnTile() == false) return; if (this.mouseButtonEvents.onMouseScroll != null) this.mouseButtonEvents.onMouseScroll.run(); } @@ -183,5 +208,18 @@ namespace MapEvents.Framework if (this.playerOnTile == true && isPlayerOnTile() == false) this.OnPlayerLeave(); } + /// + /// Checks if the mouse is on the tile. + /// + /// + public bool isMouseOnTile() + { + Vector2 mousePosition = new Vector2(Game1.getMouseX(), Game1.getMouseY()); + if (mousePosition.X == this.tilePosition.X && mousePosition.Y == this.tilePosition.Y) return true; + return false; + } + + + } } From 534eda1414c93ab51952cccc3bda3a52fde06ff3 Mon Sep 17 00:00:00 2001 From: Date: Fri, 23 Feb 2018 13:55:51 -0800 Subject: [PATCH 11/18] finished work on warp events --- .../AdditionalCropsFramework/packages.config | 2 +- GeneralMods/MapEvents/Class1.cs | 17 -- GeneralMods/MapEvents/EventSystem.cs | 37 ++++ GeneralMods/MapEvents/EventSystem.csproj | 75 ++++++++ GeneralMods/MapEvents/Framework/Delegates.cs | 4 +- .../MapEvents/Framework/EventManager.cs | 122 +++++++++++++ .../MapEvents/Framework/Events/WarpEvent.cs | 77 ++++++++ .../FunctionEvents/MouseButtonEvents.cs | 4 +- .../FunctionEvents/MouseEntryLeaveEvent.cs | 4 +- .../Framework/FunctionEvents/PlayerEvents.cs | 4 +- .../Framework/FunctionEvents/functionEvent.cs | 6 +- .../Framework/Information/WarpInformation.cs | 37 ++++ GeneralMods/MapEvents/Framework/MapEvent.cs | 168 +++++++++++------- GeneralMods/MapEvents/manifest.json | 10 ++ GeneralMods/StardewMods.sln | 22 +++ GeneralMods/StardustCore/Math/Hex.cs | 2 +- GeneralMods/StardustCore/Math/Hex32.cs | 2 +- GeneralMods/StardustCore/packages.config | 2 +- GeneralMods/SundropMapEvents/Class1.cs | 32 ++++ .../Properties/AssemblyInfo.cs | 36 ++++ .../SundropMapEvents.csproj} | 9 +- GeneralMods/SundropMapEvents/manifest.json | 16 ++ GeneralMods/SundropMapEvents/packages.config | 5 + 23 files changed, 593 insertions(+), 100 deletions(-) delete mode 100644 GeneralMods/MapEvents/Class1.cs create mode 100644 GeneralMods/MapEvents/EventSystem.cs create mode 100644 GeneralMods/MapEvents/EventSystem.csproj create mode 100644 GeneralMods/MapEvents/Framework/EventManager.cs create mode 100644 GeneralMods/MapEvents/Framework/Events/WarpEvent.cs create mode 100644 GeneralMods/MapEvents/Framework/Information/WarpInformation.cs create mode 100644 GeneralMods/MapEvents/manifest.json create mode 100644 GeneralMods/SundropMapEvents/Class1.cs create mode 100644 GeneralMods/SundropMapEvents/Properties/AssemblyInfo.cs rename GeneralMods/{MapEvents/MapEvents.csproj => SundropMapEvents/SundropMapEvents.csproj} (91%) create mode 100644 GeneralMods/SundropMapEvents/manifest.json create mode 100644 GeneralMods/SundropMapEvents/packages.config diff --git a/GeneralMods/AdditionalCropsFramework/packages.config b/GeneralMods/AdditionalCropsFramework/packages.config index ffa27b4a..0dfc12f8 100644 --- a/GeneralMods/AdditionalCropsFramework/packages.config +++ b/GeneralMods/AdditionalCropsFramework/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/GeneralMods/MapEvents/Class1.cs b/GeneralMods/MapEvents/Class1.cs deleted file mode 100644 index 7dadf81e..00000000 --- a/GeneralMods/MapEvents/Class1.cs +++ /dev/null @@ -1,17 +0,0 @@ -using StardewModdingAPI; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace MapEvents -{ - public class MapEvents: Mod - { - public override void Entry(IModHelper helper) - { - - } - } -} diff --git a/GeneralMods/MapEvents/EventSystem.cs b/GeneralMods/MapEvents/EventSystem.cs new file mode 100644 index 00000000..f396aab4 --- /dev/null +++ b/GeneralMods/MapEvents/EventSystem.cs @@ -0,0 +1,37 @@ +using EventSystem.Framework; +using StardewModdingAPI; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EventSystem +{ + public class EventSystem: Mod + { + public static IModHelper ModHelper; + public static IMonitor ModMonitor; + + public static EventManager eventManager; + public override void Entry(IModHelper helper) + { + + ModHelper = this.Helper; + ModMonitor = this.Monitor; + StardewModdingAPI.Events.GameEvents.UpdateTick += GameEvents_UpdateTick; + StardewModdingAPI.Events.SaveEvents.AfterLoad += SaveEvents_AfterLoad; + } + + private void SaveEvents_AfterLoad(object sender, EventArgs e) + { + eventManager = new EventManager(); + } + + private void GameEvents_UpdateTick(object sender, EventArgs e) + { + if (eventManager == null) return; + eventManager.update(); + } + } +} diff --git a/GeneralMods/MapEvents/EventSystem.csproj b/GeneralMods/MapEvents/EventSystem.csproj new file mode 100644 index 00000000..6b437ff4 --- /dev/null +++ b/GeneralMods/MapEvents/EventSystem.csproj @@ -0,0 +1,75 @@ + + + + + Debug + AnyCPU + {BB737337-2D82-4245-AA46-F3B82FC6F228} + Library + Properties + EventSystem + EventSystem + v4.5 + 512 + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + \ No newline at end of file diff --git a/GeneralMods/MapEvents/Framework/Delegates.cs b/GeneralMods/MapEvents/Framework/Delegates.cs index 206d1294..617d0080 100644 --- a/GeneralMods/MapEvents/Framework/Delegates.cs +++ b/GeneralMods/MapEvents/Framework/Delegates.cs @@ -4,9 +4,9 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace MapEvents.Framework +namespace EventSystem.Framework { - class Delegates + public class Delegates { public delegate void voidDel(); public delegate void strDel(string s); diff --git a/GeneralMods/MapEvents/Framework/EventManager.cs b/GeneralMods/MapEvents/Framework/EventManager.cs new file mode 100644 index 00000000..79c68a15 --- /dev/null +++ b/GeneralMods/MapEvents/Framework/EventManager.cs @@ -0,0 +1,122 @@ +using StardewValley; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EventSystem.Framework +{ + public class EventManager + { + public Dictionary> mapEvents; + + /// + /// Constructor. + /// + public EventManager() + { + this.mapEvents = new Dictionary>(); + foreach(var v in Game1.locations) + { + addLocation(v.name, false); + } + } + + /// + /// Adds an event to the map given the name of the map. + /// + /// + /// + public virtual void addEvent(string mapName,MapEvent mapEvent) + { + foreach(var pair in this.mapEvents) + { + if (pair.Key.name == mapName) + { + pair.Value.Add(mapEvent); + } + } + } + + /// + /// Adds an event to a map. + /// + /// + /// + public virtual void addEvent(GameLocation Location, MapEvent mapEvent) + { + foreach (var pair in this.mapEvents) + { + if (pair.Key == Location) + { + + pair.Value.Add(mapEvent); + } + } + } + + /// + /// Adds a location to have events handled. + /// + /// The location to handle events. + public virtual void addLocation(GameLocation Location) + { + EventSystem.ModMonitor.Log("Adding event processing for location: " + Location.name); + this.mapEvents.Add(Location, new List()); + } + + /// + /// Adds a location to have events handled. + /// + /// + /// + public virtual void addLocation(GameLocation Location,List Events) + { + EventSystem.ModMonitor.Log("Adding event processing for location: " + Location.name); + this.mapEvents.Add(Location, Events); + } + + /// + /// Adds a location to handle events. + /// + /// The name of the location. Can include farm buildings. + /// Used if the building is a stucture. True=building. + public virtual void addLocation(string Location,bool isStructure) + { + EventSystem.ModMonitor.Log("Adding event processing for location: " + Location); + this.mapEvents.Add(Game1.getLocationFromName(Location,isStructure), new List()); + } + + /// + /// Adds a location to have events handled. + /// + /// The name of the location. Can include farm buildings. + /// Used if the building is a stucture. True=building. + /// A list of pre-initialized events. + public virtual void addLocation(string Location, bool isStructure, List Events) + { + EventSystem.ModMonitor.Log("Adding event processing for location: " + Location); + this.mapEvents.Add(Game1.getLocationFromName(Location,isStructure), Events); + } + + /// + /// Updates all events associated with the event manager. + /// + public virtual void update() + { + List events = new List(); + if (Game1.player == null) return; + if (Game1.hasLoadedGame == false) return; + bool ok=this.mapEvents.TryGetValue(Game1.player.currentLocation, out events); + if (ok == false) return; + else + { + foreach(var v in events) + { + v.update(); + } + } + } + } +} diff --git a/GeneralMods/MapEvents/Framework/Events/WarpEvent.cs b/GeneralMods/MapEvents/Framework/Events/WarpEvent.cs new file mode 100644 index 00000000..68ae3f3b --- /dev/null +++ b/GeneralMods/MapEvents/Framework/Events/WarpEvent.cs @@ -0,0 +1,77 @@ +using EventSystem.Framework.FunctionEvents; +using EventSystem.Framework.Information; +using Microsoft.Xna.Framework; +using StardewValley; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EventSystem.Framework.Events +{ + /// + /// Used to handle warp events on the map. + /// + public class WarpEvent :MapEvent + { + WarpInformation warpInfo; + + /// + /// Constructor for handling warp events. + /// + /// The name of the event. + /// The game location that this event is located at. + /// The x,y tile position of the event. + /// The events to occur when the player enters the warp tile before the warp. + /// The information for warping the farmer. + public WarpEvent(string Name, GameLocation Location, Vector2 Position, PlayerEvents playerEvents,WarpInformation WarpInfo) : base(Name, Location, Position, playerEvents) + { + this.name = Name; + this.location = Location; + this.tilePosition = Position; + this.playerEvents = playerEvents; + this.warpInfo = WarpInfo; + + this.doesInteractionNeedToRun = true; + } + + /// + /// Occurs when the player enters the warp tile event position. + /// + public override void OnPlayerEnter() + { + if (isPlayerOnTile() == true&& this.doesInteractionNeedToRun==true) + { + this.doesInteractionNeedToRun = false; + this.playerOnTile = true; + if (this.playerEvents.onPlayerEnter != null) this.playerEvents.onPlayerEnter.run(); //used to run a function before the warp. + Game1.warpFarmer(Game1.getLocationFromName(this.warpInfo.targetMapName),this.warpInfo.targetX,this.warpInfo.targetY,this.warpInfo.facingDirection,this.warpInfo.isStructure); + } + } + + /// + /// Runs when the player is not on the tile and resets player interaction. + /// + public override void OnPlayerLeave() + { + if (isPlayerOnTile() == false && this.playerOnTile == true) + { + this.playerOnTile = false; + this.doesInteractionNeedToRun = true; + if (this.playerEvents.onPlayerLeave != null) this.playerEvents.onPlayerLeave.run(); + } + } + + /// + /// Used to update the event and check for interaction. + /// + public override void update() + { + this.OnPlayerEnter(); + this.OnPlayerLeave(); + } + + + } +} diff --git a/GeneralMods/MapEvents/Framework/FunctionEvents/MouseButtonEvents.cs b/GeneralMods/MapEvents/Framework/FunctionEvents/MouseButtonEvents.cs index e44ae354..634f9086 100644 --- a/GeneralMods/MapEvents/Framework/FunctionEvents/MouseButtonEvents.cs +++ b/GeneralMods/MapEvents/Framework/FunctionEvents/MouseButtonEvents.cs @@ -4,12 +4,12 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace MapEvents.Framework.FunctionEvents +namespace EventSystem.Framework.FunctionEvents { /// /// Used to handle mouse interactions with button clicks and scrolling the mouse wheel. /// - class MouseButtonEvents + public class MouseButtonEvents { /// /// Function that runs when the user left clicks. diff --git a/GeneralMods/MapEvents/Framework/FunctionEvents/MouseEntryLeaveEvent.cs b/GeneralMods/MapEvents/Framework/FunctionEvents/MouseEntryLeaveEvent.cs index dd8487f7..7ae55635 100644 --- a/GeneralMods/MapEvents/Framework/FunctionEvents/MouseEntryLeaveEvent.cs +++ b/GeneralMods/MapEvents/Framework/FunctionEvents/MouseEntryLeaveEvent.cs @@ -4,12 +4,12 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace MapEvents.Framework.FunctionEvents +namespace EventSystem.Framework.FunctionEvents { /// /// Used to handle events that happens when a mouse enters/leaves a specified position. /// - class MouseEntryLeaveEvent + public class MouseEntryLeaveEvent { /// /// A function that is called when a mouse enters a certain position. diff --git a/GeneralMods/MapEvents/Framework/FunctionEvents/PlayerEvents.cs b/GeneralMods/MapEvents/Framework/FunctionEvents/PlayerEvents.cs index 382e7bc0..e29d55ae 100644 --- a/GeneralMods/MapEvents/Framework/FunctionEvents/PlayerEvents.cs +++ b/GeneralMods/MapEvents/Framework/FunctionEvents/PlayerEvents.cs @@ -4,12 +4,12 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace MapEvents.Framework.FunctionEvents +namespace EventSystem.Framework.FunctionEvents { /// /// Used to handle various functions that occur on player interaction. /// - class PlayerEvents + public class PlayerEvents { /// /// Occurs when the player enters the same tile as this event. diff --git a/GeneralMods/MapEvents/Framework/FunctionEvents/functionEvent.cs b/GeneralMods/MapEvents/Framework/FunctionEvents/functionEvent.cs index d1487719..896c2050 100644 --- a/GeneralMods/MapEvents/Framework/FunctionEvents/functionEvent.cs +++ b/GeneralMods/MapEvents/Framework/FunctionEvents/functionEvent.cs @@ -3,14 +3,14 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -using static MapEvents.Framework.Delegates; +using static EventSystem.Framework.Delegates; -namespace MapEvents.Framework +namespace EventSystem.Framework { /// /// Used to pair a function and a parameter list using the super object class to run virtually any function for map events. /// - class functionEvent + public class functionEvent { public paramFunction function; public List parameters; diff --git a/GeneralMods/MapEvents/Framework/Information/WarpInformation.cs b/GeneralMods/MapEvents/Framework/Information/WarpInformation.cs new file mode 100644 index 00000000..7cda2745 --- /dev/null +++ b/GeneralMods/MapEvents/Framework/Information/WarpInformation.cs @@ -0,0 +1,37 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace EventSystem.Framework.Information +{ + /// + /// Used to store all of the information necessary to warp the farmer. + /// + public class WarpInformation + { + public string targetMapName; + public int targetX; + public int targetY; + public int facingDirection; + public bool isStructure; + + /// + /// Constructor used to bundle together necessary information to warp the player character. + /// + /// The target map name to warp the farmer to. + /// The target X location on the map to warp the farmer to. + /// The target Y location on the map to warp the farmer to. + /// The facing direction for the farmer to be facing after the warp. + /// Used to determine the position to be warped to when leaving a structure. + public WarpInformation(string MapName, int TargetX,int TargetY, int FacingDirection, bool IsStructure) + { + this.targetMapName = MapName; + this.targetX = TargetX; + this.targetY = TargetY; + this.facingDirection = FacingDirection; + this.isStructure = IsStructure; + } + } +} diff --git a/GeneralMods/MapEvents/Framework/MapEvent.cs b/GeneralMods/MapEvents/Framework/MapEvent.cs index fe89b7b4..d07d213e 100644 --- a/GeneralMods/MapEvents/Framework/MapEvent.cs +++ b/GeneralMods/MapEvents/Framework/MapEvent.cs @@ -1,51 +1,47 @@ -using MapEvents.Framework.FunctionEvents; +using EventSystem.Framework.FunctionEvents; using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Input; using StardewValley; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; -using static MapEvents.Framework.Delegates; -namespace MapEvents.Framework +namespace EventSystem.Framework { - class MapEvent + + /// + /// Base class used to handle map tile events. + /// + public class MapEvent { /// - /// Make an update function that runs associated functions to check which events need to be ran. - /// make way to detect which button is clicked when on this tile. - /// //MAKE A MAP EVENT MANAGER TO HOLD GAME LOCATIONS AND A LIST OF MAP EVENTS!!!!!! Dic> + /// //MAKE NAME FOR EVENTS /// - + public string name; + public Vector2 tilePosition; public GameLocation location; public PlayerEvents playerEvents; - public bool playerOnTile; - public MouseButtonEvents mouseButtonEvents; public MouseEntryLeaveEvent mouseEntryLeaveEvents; public bool mouseOnTile; - - public bool doesInteractionNeedToRun; public bool loopInteraction; - /// - /// A simple map event that doesn't do anything. - /// - /// - /// - public MapEvent(GameLocation Location,Vector2 Position) - { - this.location = Location; - this.tilePosition = Position; - } + /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Constructors + + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + #region + /// /// Empty Constructor @@ -55,6 +51,17 @@ namespace MapEvents.Framework } + /// + /// A simple map event that doesn't do anything. + /// + /// + /// + public MapEvent(string name,GameLocation Location,Vector2 Position) + { + this.name = name; + this.location = Location; + this.tilePosition = Position; + } /// /// A simple map function that runs when the player enters and leaves a tile. Set values to null for nothing to happen. @@ -63,8 +70,9 @@ namespace MapEvents.Framework /// The x,y position on the map the event is. /// Handles various events that runs when the player enters/leaves a tile, etc. - public MapEvent(GameLocation Location,Vector2 position, PlayerEvents PlayerEvents) + public MapEvent(string name,GameLocation Location,Vector2 position, PlayerEvents PlayerEvents) { + this.name = name; this.location = Location; this.tilePosition = position; this.playerEvents = PlayerEvents; @@ -76,8 +84,9 @@ namespace MapEvents.Framework /// The game location where the event is. /// The x,y position of the tile at the game location. /// A class used to handle mouse entry/leave events. - public MapEvent(GameLocation Location, Vector2 Position, MouseEntryLeaveEvent mouseEvents) + public MapEvent(string name,GameLocation Location, Vector2 Position, MouseEntryLeaveEvent mouseEvents) { + this.name = name; this.location = Location; this.tilePosition = Position; this.mouseEntryLeaveEvents = mouseEvents; @@ -89,8 +98,9 @@ namespace MapEvents.Framework /// The game location where the event is. /// The x,y position of the tile at the game location. /// A class used to handle mouse click/scroll events. - public MapEvent(GameLocation Location, Vector2 Position, MouseButtonEvents mouseEvents) + public MapEvent(string name,GameLocation Location, Vector2 Position, MouseButtonEvents mouseEvents) { + this.name = name; this.location = Location; this.tilePosition = Position; this.mouseButtonEvents = mouseEvents; @@ -104,37 +114,68 @@ namespace MapEvents.Framework /// The events that occur associated with the player. I.E player entry, etc. /// The events associated with clicking a mouse button while on this tile. /// The events that occur when the mouse enters or leaves the same tile position as this event. - public MapEvent(GameLocation Location, Vector2 Position, PlayerEvents playerEvents, MouseButtonEvents mouseButtonEvents, MouseEntryLeaveEvent mouseEntryLeaveEvents) + public MapEvent(string name,GameLocation Location, Vector2 Position, PlayerEvents playerEvents, MouseButtonEvents mouseButtonEvents, MouseEntryLeaveEvent mouseEntryLeaveEvents) { + this.name = name; this.location = Location; this.tilePosition = Position; this.playerEvents = playerEvents; this.mouseButtonEvents = mouseButtonEvents; this.mouseEntryLeaveEvents = mouseEntryLeaveEvents; } + #endregion + + /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Player related functions + + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + #region /// /// Occurs when the player enters the same tile as this event. The function associated with this event is then ran. /// - private void OnPlayerEnter() + public virtual void OnPlayerEnter() { - this.playerOnTile = true; - if (this.playerEvents.onPlayerEnter != null) this.playerEvents.onPlayerEnter.run(); + if (isPlayerOnTile() == true) + { + this.playerOnTile = true; + if (this.playerEvents.onPlayerEnter != null) this.playerEvents.onPlayerEnter.run(); + } } /// /// Occurs when the player leaves the same tile that this event is on. The function associated with thie event is then ran. /// - private void OnPlayerLeave() + public virtual void OnPlayerLeave() { - this.playerOnTile = false; - if (this.playerEvents.onPlayerLeave != null) this.playerEvents.onPlayerEnter.run(); + if(isPlayerOnTile() == false && this.playerOnTile==true){ + this.playerOnTile = false; + if (this.playerEvents.onPlayerLeave != null) this.playerEvents.onPlayerLeave.run(); + } } + /// + /// Checks if the player is on the same tile as this event. + /// + /// + public virtual bool isPlayerOnTile() + { + if (Game1.player.getTileX() == this.tilePosition.X && Game1.player.getTileY() == this.tilePosition.Y) return true; + else return false; + } + #endregion + + /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + Mouse related functions + + *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + */ + #region /// /// Occurs when the player left clicks the same tile that this event is on. /// - public void OnLeftClick() + public virtual void OnLeftClick() { if (this.mouseOnTile==false) return; if (this.mouseButtonEvents.onLeftClick != null) this.mouseButtonEvents.onLeftClick.run(); @@ -143,7 +184,7 @@ namespace MapEvents.Framework /// /// Occurs when the player right clicks the same tile that this event is on. /// - public void OnRightClick() + public virtual void OnRightClick() { if (this.mouseOnTile == false) return; if (this.mouseButtonEvents.onRightClick != null) this.mouseButtonEvents.onRightClick.run(); @@ -152,7 +193,7 @@ namespace MapEvents.Framework /// /// Occurs when the mouse tile position is the same as this event's x,y position. /// - public void OnMouseEnter() + public virtual void OnMouseEnter() { if (isMouseOnTile()) { @@ -164,7 +205,7 @@ namespace MapEvents.Framework /// /// Occurs when the mouse tile position leaves the the same x,y position as this event. /// - public void OnMouseLeave() + public virtual void OnMouseLeave() { if (isMouseOnTile() == false && this.mouseOnTile == true) { @@ -174,52 +215,49 @@ namespace MapEvents.Framework } /// + /// UNUSED!!!! /// Occurs when the mouse is on the same position as the tile AND the user scrolls the mouse wheel. /// - public void OnMouseScroll() + public virtual void OnMouseScroll() { if (isMouseOnTile() == false) return; if (this.mouseButtonEvents.onMouseScroll != null) this.mouseButtonEvents.onMouseScroll.run(); } - /// - /// Checks if the player is on the same tile as this event. - /// - /// - public bool isPlayerOnTile() - { - if (Game1.player.getTileX() == this.tilePosition.X && Game1.player.getTileY() == this.tilePosition.Y) return true; - else return false; - } - - /// - /// Checks if the player is on the same tile as the event and then runs the associated event. - /// - public void isPlayerOnTileRunEvent() - { - if (isPlayerOnTile() == true) OnPlayerEnter(); - } - - /// - /// If the player recently entered the tile and the player is no longer on this tile then the player left the tile. If that is true then run the leaving function. - /// - public void didPlayerLeaveTileRunEvent() - { - if (this.playerOnTile == true && isPlayerOnTile() == false) this.OnPlayerLeave(); - } - /// /// Checks if the mouse is on the tile. /// /// - public bool isMouseOnTile() + public virtual bool isMouseOnTile() { Vector2 mousePosition = new Vector2(Game1.getMouseX(), Game1.getMouseY()); if (mousePosition.X == this.tilePosition.X && mousePosition.Y == this.tilePosition.Y) return true; return false; } - + /// + /// Occurs when the tile is clicked. Runs the appropriate event. + /// + public virtual void eventClickEvent() + { + if (this.mouseOnTile == false) return; + var mouseState=Mouse.GetState(); + if (mouseState.LeftButton == ButtonState.Pressed) OnLeftClick(); + if (mouseState.RightButton == ButtonState.Pressed) OnRightClick(); + } +#endregion + + /// + /// Used to check if any sort of events need to run on this tile right now. + /// + public virtual void update() + { + eventClickEvent(); //click events + OnPlayerEnter(); //player enter events + OnPlayerLeave(); //player leave events + OnMouseEnter(); //on mouse enter events + OnMouseLeave(); //on mouse leave events. + } } } diff --git a/GeneralMods/MapEvents/manifest.json b/GeneralMods/MapEvents/manifest.json new file mode 100644 index 00000000..4579d6f3 --- /dev/null +++ b/GeneralMods/MapEvents/manifest.json @@ -0,0 +1,10 @@ +{ + "Name": "EventSystem", + "Author": "Alpha_Omegasis", + "Version": "0.1.0", + "Description": "A system to manage different events that can happen on the map.", + "UniqueID": "Omegasis.EventSystem", + "EntryDll": "EventSystem.dll", + "MinimumApiVersion": "2.0", + "UpdateKeys": [ ] +} diff --git a/GeneralMods/StardewMods.sln b/GeneralMods/StardewMods.sln index f5e56d43..076cb9cb 100644 --- a/GeneralMods/StardewMods.sln +++ b/GeneralMods/StardewMods.sln @@ -71,6 +71,17 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StardewSymphonyRemastered", {0756D36A-95C8-480D-8EA6-4584C03010C6} = {0756D36A-95C8-480D-8EA6-4584C03010C6} EndProjectSection EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Sundrop", "Sundrop", "{3EE26DA0-0337-4991-8B02-BCB8D408008C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EventSystem", "MapEvents\EventSystem.csproj", "{BB737337-2D82-4245-AA46-F3B82FC6F228}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "EventSystemMods", "EventSystemMods", "{BAAC8F21-C12F-42B0-A51C-0C5F33B52575}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SundropMapEvents", "SundropMapEvents\SundropMapEvents.csproj", "{29A68F94-B23C-442B-8867-8B8F3502E64F}" + ProjectSection(ProjectDependencies) = postProject + {BB737337-2D82-4245-AA46-F3B82FC6F228} = {BB737337-2D82-4245-AA46-F3B82FC6F228} + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -169,11 +180,22 @@ Global {19F64B03-6A9B-49E1-854A-C05D5A014646}.Debug|Any CPU.Build.0 = Debug|Any CPU {19F64B03-6A9B-49E1-854A-C05D5A014646}.Release|Any CPU.ActiveCfg = Release|Any CPU {19F64B03-6A9B-49E1-854A-C05D5A014646}.Release|Any CPU.Build.0 = Release|Any CPU + {BB737337-2D82-4245-AA46-F3B82FC6F228}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {BB737337-2D82-4245-AA46-F3B82FC6F228}.Debug|Any CPU.Build.0 = Debug|Any CPU + {BB737337-2D82-4245-AA46-F3B82FC6F228}.Release|Any CPU.ActiveCfg = Release|Any CPU + {BB737337-2D82-4245-AA46-F3B82FC6F228}.Release|Any CPU.Build.0 = Release|Any CPU + {29A68F94-B23C-442B-8867-8B8F3502E64F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {29A68F94-B23C-442B-8867-8B8F3502E64F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {29A68F94-B23C-442B-8867-8B8F3502E64F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {29A68F94-B23C-442B-8867-8B8F3502E64F}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {8415BB0C-94A7-4E11-B6D5-C31649C3A95D} = {953CD0A4-8529-45E6-87C2-31837940D62C} + {BB737337-2D82-4245-AA46-F3B82FC6F228} = {3EE26DA0-0337-4991-8B02-BCB8D408008C} + {BAAC8F21-C12F-42B0-A51C-0C5F33B52575} = {3EE26DA0-0337-4991-8B02-BCB8D408008C} + {29A68F94-B23C-442B-8867-8B8F3502E64F} = {BAAC8F21-C12F-42B0-A51C-0C5F33B52575} EndGlobalSection EndGlobal diff --git a/GeneralMods/StardustCore/Math/Hex.cs b/GeneralMods/StardustCore/Math/Hex.cs index 03d4ae35..01ba3dd3 100644 --- a/GeneralMods/StardustCore/Math/Hex.cs +++ b/GeneralMods/StardustCore/Math/Hex.cs @@ -4,7 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace StardustCore.Math +namespace StardustCore.StardustMath { /// /// Base class for hex representation. diff --git a/GeneralMods/StardustCore/Math/Hex32.cs b/GeneralMods/StardustCore/Math/Hex32.cs index 25da9ed0..b3065b0c 100644 --- a/GeneralMods/StardustCore/Math/Hex32.cs +++ b/GeneralMods/StardustCore/Math/Hex32.cs @@ -5,7 +5,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace StardustCore.Math +namespace StardustCore.StardustMath { /// /// A Class that helps represents 32 bit hex. diff --git a/GeneralMods/StardustCore/packages.config b/GeneralMods/StardustCore/packages.config index ffa27b4a..0dfc12f8 100644 --- a/GeneralMods/StardustCore/packages.config +++ b/GeneralMods/StardustCore/packages.config @@ -1,5 +1,5 @@  - + \ No newline at end of file diff --git a/GeneralMods/SundropMapEvents/Class1.cs b/GeneralMods/SundropMapEvents/Class1.cs new file mode 100644 index 00000000..62ad006a --- /dev/null +++ b/GeneralMods/SundropMapEvents/Class1.cs @@ -0,0 +1,32 @@ +using StardewModdingAPI; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using EventSystem; +using StardewValley; +using EventSystem.Framework.FunctionEvents; +using EventSystem.Framework.Information; +using Microsoft.Xna.Framework; + +namespace SundropMapEvents +{ + public class Class1 :Mod + { + + public static IModHelper ModHelper; + public static IMonitor ModMonitor; + public override void Entry(IModHelper helper) + { + ModHelper = this.Helper; + ModMonitor = this.Monitor; + StardewModdingAPI.Events.SaveEvents.AfterLoad += SaveEvents_AfterLoad; + } + + private void SaveEvents_AfterLoad(object sender, EventArgs e) + { + EventSystem.EventSystem.eventManager.addEvent(Game1.getLocationFromName("BusStop"), new EventSystem.Framework.Events.WarpEvent("toRR", Game1.getLocationFromName("BusStop"), new Vector2(6, 11), new PlayerEvents(null, null), new WarpInformation("BusStop", 10, 12, 2, false))); + } + } +} diff --git a/GeneralMods/SundropMapEvents/Properties/AssemblyInfo.cs b/GeneralMods/SundropMapEvents/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..b394cc6c --- /dev/null +++ b/GeneralMods/SundropMapEvents/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("SundropMapEvents")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("SundropMapEvents")] +[assembly: AssemblyCopyright("Copyright © 2018")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("29a68f94-b23c-442b-8867-8b8f3502e64f")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/GeneralMods/MapEvents/MapEvents.csproj b/GeneralMods/SundropMapEvents/SundropMapEvents.csproj similarity index 91% rename from GeneralMods/MapEvents/MapEvents.csproj rename to GeneralMods/SundropMapEvents/SundropMapEvents.csproj index f01a7780..95c10476 100644 --- a/GeneralMods/MapEvents/MapEvents.csproj +++ b/GeneralMods/SundropMapEvents/SundropMapEvents.csproj @@ -4,11 +4,11 @@ Debug AnyCPU - {BB737337-2D82-4245-AA46-F3B82FC6F228} + {29A68F94-B23C-442B-8867-8B8F3502E64F} Library Properties - MapEvents - MapEvents + SundropMapEvents + SundropMapEvents v4.5 512 @@ -30,6 +30,9 @@ 4 + + ..\MapEvents\bin\Release\EventSystem.dll + diff --git a/GeneralMods/SundropMapEvents/manifest.json b/GeneralMods/SundropMapEvents/manifest.json new file mode 100644 index 00000000..9f2ab67d --- /dev/null +++ b/GeneralMods/SundropMapEvents/manifest.json @@ -0,0 +1,16 @@ +{ + "Name": "SunDropMapEvents", + "Author": "Alpha_Omegasis", + "Version": "0.1.0", + "Description": "A system to add events to the SunDropMod", + "UniqueID": "SunDrop.MapEvents", + "EntryDll": "SunDropMapEvents.dll", + "MinimumApiVersion": "2.0", + "UpdateKeys": [ ], + "Dependencies": [ + { + "UniqueID": "Omegasis.EventSystem", + "IsRequired": true + } +] +} diff --git a/GeneralMods/SundropMapEvents/packages.config b/GeneralMods/SundropMapEvents/packages.config new file mode 100644 index 00000000..ffa27b4a --- /dev/null +++ b/GeneralMods/SundropMapEvents/packages.config @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file From 1fc38b964c3ccc8db2d692313f2b6b8707c95fd8 Mon Sep 17 00:00:00 2001 From: Date: Fri, 23 Feb 2018 19:10:56 -0800 Subject: [PATCH 12/18] Started work on custom npcs. Can load in new npcs from graphics. They don't do anything but stand there... --- GeneralMods/CustomNPCFramework/Class1.cs | 84 +++++ .../CustomNPCFramework.csproj | 70 ++++ .../Framework/Graphics/AssetInfo.cs | 47 +++ .../Framework/Graphics/AssetManager.cs | 98 +++++ .../Framework/Graphics/AssetSheet.cs | 140 +++++++ .../Framework/NPCS/ExtendedNPC.cs | 341 ++++++++++++++++++ .../Properties/AssemblyInfo.cs | 36 ++ GeneralMods/CustomNPCFramework/manifest.json | 10 + .../CustomNPCFramework/packages.config | 4 + GeneralMods/StardewMods.sln | 7 + 10 files changed, 837 insertions(+) create mode 100644 GeneralMods/CustomNPCFramework/Class1.cs create mode 100644 GeneralMods/CustomNPCFramework/CustomNPCFramework.csproj create mode 100644 GeneralMods/CustomNPCFramework/Framework/Graphics/AssetInfo.cs create mode 100644 GeneralMods/CustomNPCFramework/Framework/Graphics/AssetManager.cs create mode 100644 GeneralMods/CustomNPCFramework/Framework/Graphics/AssetSheet.cs create mode 100644 GeneralMods/CustomNPCFramework/Framework/NPCS/ExtendedNPC.cs create mode 100644 GeneralMods/CustomNPCFramework/Properties/AssemblyInfo.cs create mode 100644 GeneralMods/CustomNPCFramework/manifest.json create mode 100644 GeneralMods/CustomNPCFramework/packages.config diff --git a/GeneralMods/CustomNPCFramework/Class1.cs b/GeneralMods/CustomNPCFramework/Class1.cs new file mode 100644 index 00000000..e0801aea --- /dev/null +++ b/GeneralMods/CustomNPCFramework/Class1.cs @@ -0,0 +1,84 @@ +using CustomNPCFramework.Framework.Graphics; +using CustomNPCFramework.Framework.NPCS; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using StardewModdingAPI; +using StardewValley; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CustomNPCFramework +{ + public class Class1 : Mod + { + public static IModHelper ModHelper; + public static IMonitor ModMonitor; + public static AssetManager assetManager; + public override void Entry(IModHelper helper) + { + ModHelper = this.Helper; + ModMonitor = this.Monitor; + assetManager = new AssetManager(); + initializeExamples(); + assetManager.loadAssets(); + StardewModdingAPI.Events.SaveEvents.AfterLoad += SaveEvents_LoadChar; + StardewModdingAPI.Events.LocationEvents.CurrentLocationChanged += LocationEvents_CurrentLocationChanged; + StardewModdingAPI.Events.GameEvents.UpdateTick += GameEvents_UpdateTick; + } + + private void GameEvents_UpdateTick(object sender, EventArgs e) + { + if (Game1.player.currentLocation == null) return; + foreach (var v in Game1.player.currentLocation.characters) + { + v.speed = 5; + v.MovePosition(Game1.currentGameTime, Game1.viewport, Game1.player.currentLocation); + ModMonitor.Log(v.name); + } + } + + private void LocationEvents_CurrentLocationChanged(object sender, StardewModdingAPI.Events.EventArgsCurrentLocationChanged e) + { + + } + + private void SaveEvents_LoadChar(object sender, EventArgs e) + { + string path = Path.Combine(ModHelper.DirectoryPath, "Content", "Graphics", "NPCS", "Characters", "RainMan"); + assetManager.addPathCreateDirectory(new KeyValuePair("characters", path)); + Texture2D tex=ModHelper.Content.Load(Path.Combine(getShortenedDirectory(path).Remove(0,1), "character.png")); + ExtendedNPC myNpc3 = new ExtendedNPC(new StardewValley.AnimatedSprite(tex, 0, 16, 32), new Vector2(14, 14)*Game1.tileSize, 2, "b2"); + Game1.getLocationFromName("BusStop").addCharacter(myNpc3); + myNpc3.SetMovingDown(true); + } + + public void initializeExamples() + { + string dirPath = Path.Combine(ModHelper.DirectoryPath, "Content", "Templates"); + assetManager.addPathCreateDirectory(new KeyValuePair("templates", dirPath)); + string filePath =Path.Combine(dirPath, "Example.json"); + if (File.Exists(filePath)) return; + string getRelativePath = getShortenedDirectory(filePath); + ModMonitor.Log("THIS IS THE PATH::: " + getRelativePath); + AssetInfo info = new AssetInfo("Example", new Vector2(16, 16), false); + info.writeToJson(filePath); + } + + public static string getShortenedDirectory(string path) + { + + string[] spliter = path.Split(new string[] { ModHelper.DirectoryPath },StringSplitOptions.None); + return spliter[1]; + } + + public static string getRelativeDirectory(string path) + { + string s = getShortenedDirectory(path); + return s.Remove(0, 1); + } + } +} diff --git a/GeneralMods/CustomNPCFramework/CustomNPCFramework.csproj b/GeneralMods/CustomNPCFramework/CustomNPCFramework.csproj new file mode 100644 index 00000000..8fd07e7e --- /dev/null +++ b/GeneralMods/CustomNPCFramework/CustomNPCFramework.csproj @@ -0,0 +1,70 @@ + + + + + Debug + AnyCPU + {89C7DF45-8AE5-49AC-ADA9-6312E9590829} + Library + Properties + CustomNPCFramework + CustomNPCFramework + v4.5 + 512 + + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + + + + + + + + + + + + + + + + + + + + + + + + + This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + + + + \ No newline at end of file diff --git a/GeneralMods/CustomNPCFramework/Framework/Graphics/AssetInfo.cs b/GeneralMods/CustomNPCFramework/Framework/Graphics/AssetInfo.cs new file mode 100644 index 00000000..0ed38ff3 --- /dev/null +++ b/GeneralMods/CustomNPCFramework/Framework/Graphics/AssetInfo.cs @@ -0,0 +1,47 @@ +using Microsoft.Xna.Framework; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CustomNPCFramework.Framework.Graphics +{ + public class AssetInfo + { + public string name; + public Vector2 assetSize; + public bool randomizeUponLoad; + /// + /// A constructor use to create asset info which can then be used to create asset sheets. + /// + /// The name of the texture sheet. Can be different than the actual file name. + /// The size of the individual sprites on the texture sheet. Ex 16x16 pixels. + /// If true, the index for the asset will be randomized. Good for getting variation from a texture. + public AssetInfo(string name, Vector2 assetSize, bool randomizeUponLoad) + { + this.name = name; + this.assetSize = assetSize; + this.randomizeUponLoad = randomizeUponLoad; + } + + /// + /// Save the json to a certain location. + /// + /// + public void writeToJson(string path) + { + Class1.ModHelper.WriteJsonFile(path, this); + } + + /// + /// Read the json from a certain location. + /// + /// + /// + public static AssetInfo readFromJson(string path) + { + return Class1.ModHelper.ReadJsonFile(path); + } + } +} diff --git a/GeneralMods/CustomNPCFramework/Framework/Graphics/AssetManager.cs b/GeneralMods/CustomNPCFramework/Framework/Graphics/AssetManager.cs new file mode 100644 index 00000000..d430ee19 --- /dev/null +++ b/GeneralMods/CustomNPCFramework/Framework/Graphics/AssetManager.cs @@ -0,0 +1,98 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CustomNPCFramework.Framework.Graphics +{ + public class AssetManager + { + public List assets; + public Dictionary paths; + + /// + /// Basic constructor. + /// + public AssetManager() + { + this.assets = new List(); + this.paths = new Dictionary(); + } + + /// + /// Default loading function from paths. + /// + public void loadAssets() + { + foreach(var path in this.paths) + { + string[] files= Directory.GetFiles(path.Value, "*.json"); + foreach(var file in files) + { + AssetInfo info = AssetInfo.readFromJson(file); + AssetSheet sheet = new AssetSheet(info,path.Value); + this.assets.Add(sheet); + } + } + } + + /// + /// Add an asset to be handled from the asset manager. + /// + /// + public void addAsset(AssetSheet asset) + { + this.assets.Add(asset); + } + + /// + /// Get an individual asset by its name. + /// + /// + /// + public AssetSheet getAssetByName(string s) + { + foreach(var v in assets) + { + if (v.assetInfo.name == s) return v; + } + return null; + } + + /// + /// Add a new path to the asset manager and create the directory for it. + /// + /// + public void addPathCreateDirectory(KeyValuePair path) + { + this.addPath(path); + string dir = Path.Combine(Class1.ModHelper.DirectoryPath, path.Value); + if (!Directory.Exists(dir)) + { + Directory.CreateDirectory(Path.Combine(Class1.ModHelper.DirectoryPath, path.Value)); + } + } + + /// + /// Add a path to the dictionary. + /// + /// + private void addPath(KeyValuePair path) + { + this.paths.Add(path.Key, path.Value); + } + + /// + /// Create appropriate directories for the path. + /// + private void createDirectoriesFromPaths() + { + foreach(var v in paths) + { + Directory.CreateDirectory(Path.Combine(Class1.ModHelper.DirectoryPath,v.Value)); + } + } + } +} diff --git a/GeneralMods/CustomNPCFramework/Framework/Graphics/AssetSheet.cs b/GeneralMods/CustomNPCFramework/Framework/Graphics/AssetSheet.cs new file mode 100644 index 00000000..d07ccdef --- /dev/null +++ b/GeneralMods/CustomNPCFramework/Framework/Graphics/AssetSheet.cs @@ -0,0 +1,140 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CustomNPCFramework.Framework.Graphics +{ + /// + /// Used to handle loading different textures and handling opperations on those textures. + /// + public class AssetSheet + { + public Texture2D texture; + public AssetInfo assetInfo; + public string path; + + public int index; + + private int widthIndex; + private int heightIndex; + private int widthIndexMax; + private int heightIndexMax; + + public Rectangle currentAsset; + + public AssetSheet(AssetInfo info,string path) + { + this.assetInfo = info; + this.texture = Class1.ModHelper.Content.Load(Class1.getShortenedDirectory(Path.Combine(path,info.name+".png")).Remove(0,1)); + + this.widthIndexMax = this.texture.Width / (int)this.assetInfo.assetSize.X; + this.heightIndexMax = this.texture.Width / (int)this.assetInfo.assetSize.Y; + this.index = 0; + if (this.assetInfo.randomizeUponLoad == false) + { + this.widthIndex = 0; + this.heightIndex = 0; + } + else + { + getRandomAssetIndicies(); + setIndex(); + } + this.currentAsset = new Rectangle(widthIndex * (int)this.assetInfo.assetSize.X, heightIndex * (int)this.assetInfo.assetSize.Y, (int)this.assetInfo.assetSize.X, (int)this.assetInfo.assetSize.Y); + } + + /// + /// Get the next graphic from the texture. + /// + public void getNext() + { + //If I can still iterate through my list but my width is maxed, increment height. + if (this.widthIndex == this.widthIndexMax - 1 && this.heightIndex != this.heightIndexMax) + { + this.widthIndex -= 0; + this.heightIndex++; + } + //If I reached the end of my image loop to 0; + else if (this.heightIndex == this.heightIndexMax && this.widthIndex == this.widthIndexMax - 1) + { + this.heightIndex = 0; + this.widthIndex = 0; + } + else + { + //If I can still iterate through my list do so. + widthIndex++; + } + this.setIndex(); + this.setAsset(); + } + + /// + /// Get the last graphic from my texture. + /// + public void getPrevious() + { + //If my width index is 0 and my height index isn't decrement my height index and set the width index to the far right. + if (this.widthIndex == 0 && this.heightIndex != 0) + { + this.heightIndex--; + this.widthIndex = this.widthIndexMax - 1; + } + //If both my height and width indicies are 0, loop to the bottom right of the texture. + else if (this.widthIndex == 0 && this.heightIndex == 0) + { + this.widthIndex = this.widthIndexMax - 1; + this.heightIndex = this.heightIndexMax - 1; + } + else + { + //Just decrement my width index by 1. + this.widthIndex--; + } + this.setIndex(); + this.setAsset(); + } + + /// + /// sets the current positioning for the rectangle index; + /// + private void setAsset() + { + this.currentAsset.X = widthIndex * (int)this.assetInfo.assetSize.X; + this.currentAsset.Y = heightIndex * (int)this.assetInfo.assetSize.Y; + } + + /// + /// Used mainly for display purposes and length purposes. + /// + public void setIndex() + { + this.index = heightIndex * widthIndexMax + widthIndex; + } + + /// + /// Sets the asset index to a random value. + /// + public void getRandomAssetIndicies() + { + Random r = new Random(DateTime.Now.Millisecond); + this.widthIndex = r.Next(0, this.widthIndexMax); + this.widthIndex = r.Next(0, this.heightIndexMax); + setIndex(); + setAsset(); + } + + /// + /// Used just to get a copy of this asset sheet. + /// + public void clone() + { + var asset = new AssetSheet(this.assetInfo,(string)this.path.Clone()); + } + } +} diff --git a/GeneralMods/CustomNPCFramework/Framework/NPCS/ExtendedNPC.cs b/GeneralMods/CustomNPCFramework/Framework/NPCS/ExtendedNPC.cs new file mode 100644 index 00000000..6c68eada --- /dev/null +++ b/GeneralMods/CustomNPCFramework/Framework/NPCS/ExtendedNPC.cs @@ -0,0 +1,341 @@ +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using StardewValley; +using StardewValley.Characters; +using StardewValley.Locations; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using xTile.Dimensions; +using xTile.ObjectModel; +using xTile.Tiles; + +namespace CustomNPCFramework.Framework.NPCS +{ + class ExtendedNPC :StardewValley.NPC + { + public ExtendedNPC() :base() + { + + } + public ExtendedNPC(StardewValley.AnimatedSprite sprite,Vector2 position,int facingDirection,string name): base(sprite, position, facingDirection, name, null) + { + + } + + + public override void MovePosition(GameTime time, xTile.Dimensions.Rectangle viewport, GameLocation currentLocation) + { + if (this.GetType() == typeof(FarmAnimal)) + this.willDestroyObjectsUnderfoot = false; + if ((double)this.xVelocity != 0.0 || (double)this.yVelocity != 0.0) + { + Microsoft.Xna.Framework.Rectangle boundingBox = this.GetBoundingBox(); + boundingBox.X += (int)this.xVelocity; + boundingBox.Y -= (int)this.yVelocity; + if (currentLocation == null || !currentLocation.isCollidingPosition(boundingBox, viewport, false, 0, false, this)) + { + this.position.X += this.xVelocity; + this.position.Y -= this.yVelocity; + } + this.xVelocity = (float)(int)((double)this.xVelocity - (double)this.xVelocity / 2.0); + this.yVelocity = (float)(int)((double)this.yVelocity - (double)this.yVelocity / 2.0); + } + else if (this.moveUp) + { + if (currentLocation == null || !currentLocation.isCollidingPosition(this.nextPosition(0), viewport, false, 0, false, this) || this.isCharging) + { + this.position.Y -= (float)(this.speed + this.addedSpeed); + if (!this.ignoreMovementAnimation) + { + this.sprite.AnimateUp(time, (this.speed - 2 + this.addedSpeed) * -25, Utility.isOnScreen(this.getTileLocationPoint(), 1, currentLocation) ? "Cowboy_Footstep" : ""); + this.faceDirection(0); + } + } + else if (!currentLocation.isTilePassable(this.nextPosition(0), viewport) || !this.willDestroyObjectsUnderfoot) + this.Halt(); + else if (this.willDestroyObjectsUnderfoot) + { + Vector2 vector2 = new Vector2((float)(this.getStandingX() / Game1.tileSize), (float)(this.getStandingY() / Game1.tileSize - 1)); + if (currentLocation.characterDestroyObjectWithinRectangle(this.nextPosition(0), true)) + { + this.doEmote(12, true); + this.position.Y -= (float)(this.speed + this.addedSpeed); + } + else + this.blockedInterval = this.blockedInterval + time.ElapsedGameTime.Milliseconds; + } + } + else if (this.moveRight) + { + if (currentLocation == null || !currentLocation.isCollidingPosition(this.nextPosition(1), viewport, false, 0, false, this) || this.isCharging) + { + this.position.X += (float)(this.speed + this.addedSpeed); + if (!this.ignoreMovementAnimation) + { + this.sprite.AnimateRight(time, (this.speed - 2 + this.addedSpeed) * -25, Utility.isOnScreen(this.getTileLocationPoint(), 1, currentLocation) ? "Cowboy_Footstep" : ""); + this.faceDirection(1); + } + } + else if (!currentLocation.isTilePassable(this.nextPosition(1), viewport) || !this.willDestroyObjectsUnderfoot) + this.Halt(); + else if (this.willDestroyObjectsUnderfoot) + { + Vector2 vector2 = new Vector2((float)(this.getStandingX() / Game1.tileSize + 1), (float)(this.getStandingY() / Game1.tileSize)); + if (currentLocation.characterDestroyObjectWithinRectangle(this.nextPosition(1), true)) + { + this.doEmote(12, true); + this.position.X += (float)(this.speed + this.addedSpeed); + } + else + this.blockedInterval = this.blockedInterval + time.ElapsedGameTime.Milliseconds; + } + } + else if (this.moveDown) + { + if (currentLocation == null || !currentLocation.isCollidingPosition(this.nextPosition(2), viewport, false, 0, false, this) || this.isCharging) + { + this.position.Y += (float)(this.speed + this.addedSpeed); + if (!this.ignoreMovementAnimation) + { + this.sprite.AnimateDown(time, (this.speed - 2 + this.addedSpeed) * -25, Utility.isOnScreen(this.getTileLocationPoint(), 1, currentLocation) ? "Cowboy_Footstep" : ""); + this.faceDirection(2); + } + } + else if (!currentLocation.isTilePassable(this.nextPosition(2), viewport) || !this.willDestroyObjectsUnderfoot) + this.Halt(); + else if (this.willDestroyObjectsUnderfoot) + { + Vector2 vector2 = new Vector2((float)(this.getStandingX() / Game1.tileSize), (float)(this.getStandingY() / Game1.tileSize + 1)); + if (currentLocation.characterDestroyObjectWithinRectangle(this.nextPosition(2), true)) + { + this.doEmote(12, true); + this.position.Y += (float)(this.speed + this.addedSpeed); + } + else + this.blockedInterval = this.blockedInterval + time.ElapsedGameTime.Milliseconds; + } + } + else if (this.moveLeft) + { + if (currentLocation == null || !currentLocation.isCollidingPosition(this.nextPosition(3), viewport, false, 0, false, this) || this.isCharging) + { + this.position.X -= (float)(this.speed + this.addedSpeed); + if (!this.ignoreMovementAnimation) + { + this.sprite.AnimateLeft(time, (this.speed - 2 + this.addedSpeed) * -25, Utility.isOnScreen(this.getTileLocationPoint(), 1, currentLocation) ? "Cowboy_Footstep" : ""); + this.faceDirection(3); + } + } + else if (!currentLocation.isTilePassable(this.nextPosition(3), viewport) || !this.willDestroyObjectsUnderfoot) + this.Halt(); + else if (this.willDestroyObjectsUnderfoot) + { + Vector2 vector2 = new Vector2((float)(this.getStandingX() / Game1.tileSize - 1), (float)(this.getStandingY() / Game1.tileSize)); + if (currentLocation.characterDestroyObjectWithinRectangle(this.nextPosition(3), true)) + { + this.doEmote(12, true); + this.position.X -= (float)(this.speed + this.addedSpeed); + } + else + this.blockedInterval = this.blockedInterval + time.ElapsedGameTime.Milliseconds; + } + } + if (this.blockedInterval >= 3000 && (double)this.blockedInterval <= 3750.0 && !Game1.eventUp) + { + this.doEmote(Game1.random.NextDouble() < 0.5 ? 8 : 40, true); + this.blockedInterval = 3750; + } + else + { + if (this.blockedInterval < 5000) + return; + this.speed = 4; + this.isCharging = true; + this.blockedInterval = 0; + } + } + + public override void draw(SpriteBatch b, float alpha = 1f) + { + if (this.sprite == null || this.isInvisible || !Utility.isOnScreen(this.position, 2 * Game1.tileSize)) + return; + //Checks if the npc is swimming. If not draw it's default graphic. Do characters aside from Farmer and Penny Swim??? + if (this.swimming) + { + b.Draw(this.Sprite.Texture, this.getLocalPosition(Game1.viewport) + new Vector2((float)(Game1.tileSize / 2), (float)(Game1.tileSize + Game1.tileSize / 4 + this.yJumpOffset * 2)) + (this.shakeTimer > 0 ? new Vector2((float)Game1.random.Next(-1, 2), (float)Game1.random.Next(-1, 2)) : Vector2.Zero) - new Vector2(0.0f, this.yOffset), new Microsoft.Xna.Framework.Rectangle?(new Microsoft.Xna.Framework.Rectangle(this.sprite.SourceRect.X, this.sprite.SourceRect.Y, this.sprite.SourceRect.Width, this.sprite.SourceRect.Height / 2 - (int)((double)this.yOffset / (double)Game1.pixelZoom))), Color.White, this.rotation, new Vector2((float)(Game1.tileSize / 2), (float)(Game1.tileSize * 3 / 2)) / 4f, Math.Max(0.2f, this.scale) * (float)Game1.pixelZoom, this.flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, Math.Max(0.0f, this.drawOnTop ? 0.991f : (float)this.getStandingY() / 10000f)); + Vector2 localPosition = this.getLocalPosition(Game1.viewport); + b.Draw(Game1.staminaRect, new Microsoft.Xna.Framework.Rectangle((int)localPosition.X + (int)this.yOffset + Game1.pixelZoom * 2, (int)localPosition.Y - 32 * Game1.pixelZoom + this.sprite.SourceRect.Height * Game1.pixelZoom + Game1.tileSize * 3 / 4 + this.yJumpOffset * 2 - (int)this.yOffset, this.sprite.SourceRect.Width * Game1.pixelZoom - (int)this.yOffset * 2 - Game1.pixelZoom * 4, Game1.pixelZoom), new Microsoft.Xna.Framework.Rectangle?(Game1.staminaRect.Bounds), Color.White * 0.75f, 0.0f, Vector2.Zero, SpriteEffects.None, (float)((double)this.getStandingY() / 10000.0 + 1.0 / 1000.0)); + } + else + { + b.Draw(this.Sprite.Texture, this.getLocalPosition(Game1.viewport) + new Vector2((float)(this.sprite.spriteWidth * Game1.pixelZoom / 2), (float)(this.GetBoundingBox().Height / 2)) + (this.shakeTimer > 0 ? new Vector2((float)Game1.random.Next(-1, 2), (float)Game1.random.Next(-1, 2)) : Vector2.Zero), new Microsoft.Xna.Framework.Rectangle?(this.Sprite.SourceRect), Color.White * alpha, this.rotation, new Vector2((float)(this.sprite.spriteWidth / 2), (float)((double)this.sprite.spriteHeight * 3.0 / 4.0)), Math.Max(0.2f, this.scale) * (float)Game1.pixelZoom, this.flip || this.sprite.currentAnimation != null && this.sprite.currentAnimation[this.sprite.currentAnimationIndex].flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, Math.Max(0.0f, this.drawOnTop ? 0.991f : (float)this.getStandingY() / 10000f)); + } + //If the npc breathes then this code is ran. + if (this.breather && this.shakeTimer <= 0 && (!this.swimming && this.sprite.CurrentFrame < 16) && !this.farmerPassesThrough) + { + Microsoft.Xna.Framework.Rectangle sourceRect = this.sprite.SourceRect; + sourceRect.Y += this.sprite.spriteHeight / 2 + this.sprite.spriteHeight / 32; + sourceRect.Height = this.sprite.spriteHeight / 4; + sourceRect.X += this.sprite.spriteWidth / 4; + sourceRect.Width = this.sprite.spriteWidth / 2; + Vector2 vector2 = new Vector2((float)(this.sprite.spriteWidth * Game1.pixelZoom / 2), (float)(Game1.tileSize / 8)); + if (this.age == 2) + { + sourceRect.Y += this.sprite.spriteHeight / 6 + 1; + sourceRect.Height /= 2; + vector2.Y += (float)(this.sprite.spriteHeight / 8 * Game1.pixelZoom); + } + else if (this.gender == 1) + { + ++sourceRect.Y; + vector2.Y -= (float)Game1.pixelZoom; + sourceRect.Height /= 2; + } + float num = Math.Max(0.0f, (float)(Math.Ceiling(Math.Sin(Game1.currentGameTime.TotalGameTime.TotalMilliseconds / 600.0 + (double)this.DefaultPosition.X * 20.0)) / 4.0)); + b.Draw(this.Sprite.Texture, this.getLocalPosition(Game1.viewport) + vector2 + (this.shakeTimer > 0 ? new Vector2((float)Game1.random.Next(-1, 2), (float)Game1.random.Next(-1, 2)) : Vector2.Zero), new Microsoft.Xna.Framework.Rectangle?(sourceRect), Color.White * alpha, this.rotation, new Vector2((float)(sourceRect.Width / 2), (float)(sourceRect.Height / 2 + 1)), Math.Max(0.2f, this.scale) * (float)Game1.pixelZoom + num, this.flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, Math.Max(0.0f, this.drawOnTop ? 0.992f : (float)((double)this.getStandingY() / 10000.0 + 1.0 / 1000.0))); + } + + //Checks if the npc is glowing. + if (this.isGlowing) + b.Draw(this.Sprite.Texture, this.getLocalPosition(Game1.viewport) + new Vector2((float)(this.sprite.spriteWidth * Game1.pixelZoom / 2), (float)(this.GetBoundingBox().Height / 2)) + (this.shakeTimer > 0 ? new Vector2((float)Game1.random.Next(-1, 2), (float)Game1.random.Next(-1, 2)) : Vector2.Zero), new Microsoft.Xna.Framework.Rectangle?(this.Sprite.SourceRect), this.glowingColor * this.glowingTransparency, this.rotation, new Vector2((float)(this.sprite.spriteWidth / 2), (float)((double)this.sprite.spriteHeight * 3.0 / 4.0)), Math.Max(0.2f, this.scale) * 4f, this.flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, Math.Max(0.0f, this.drawOnTop ? 0.99f : (float)((double)this.getStandingY() / 10000.0 + 1.0 / 1000.0))); + + //This code runs if the npc is emoting. + if (!this.IsEmoting || Game1.eventUp) + return; + Vector2 localPosition1 = this.getLocalPosition(Game1.viewport); + localPosition1.Y -= (float)(Game1.tileSize / 2 + this.sprite.spriteHeight * Game1.pixelZoom); + b.Draw(Game1.emoteSpriteSheet, localPosition1, new Microsoft.Xna.Framework.Rectangle?(new Microsoft.Xna.Framework.Rectangle(this.CurrentEmoteIndex * 16 % Game1.emoteSpriteSheet.Width, this.CurrentEmoteIndex * 16 / Game1.emoteSpriteSheet.Width * 16, 16, 16)), Color.White, 0.0f, Vector2.Zero, (float)Game1.pixelZoom, SpriteEffects.None, (float)this.getStandingY() / 10000f); + } + + + public override void updateMovement(GameLocation location, GameTime time) + { + this.lastPosition = this.position; + if (this.DirectionsToNewLocation != null && !Game1.newDay) + { + if (this.getStandingX() < -Game1.tileSize || this.getStandingX() > location.map.DisplayWidth + Game1.tileSize || (this.getStandingY() < -Game1.tileSize || this.getStandingY() > location.map.DisplayHeight + Game1.tileSize)) + { + this.IsWalkingInSquare = false; + Game1.warpCharacter(this, this.DefaultMap, this.DefaultPosition, true, true); + location.characters.Remove(this); + } + else if (this.IsWalkingInSquare) + { + this.returnToEndPoint(); + this.MovePosition(time, Game1.viewport, location); + } + else + { + if (!this.followSchedule) + return; + this.MovePosition(time, Game1.viewport, location); + Warp warp = location.isCollidingWithWarp(this.GetBoundingBox()); + PropertyValue propertyValue = (PropertyValue)null; + Tile tile1 = location.map.GetLayer("Buildings").PickTile(this.nextPositionPoint(), Game1.viewport.Size); + if (tile1 != null) + tile1.Properties.TryGetValue("Action", out propertyValue); + string[] strArray1; + if (propertyValue != null) + strArray1 = propertyValue.ToString().Split(' '); + else + strArray1 = (string[])null; + string[] strArray2 = strArray1; + if (warp != null) + { + if (location is BusStop && warp.TargetName.Equals("Farm")) + { + Point entryLocation = ((this.isMarried() ? (GameLocation)(this.getHome() as FarmHouse) : Game1.getLocationFromName("FarmHouse")) as FarmHouse).getEntryLocation(); + warp = new Warp(warp.X, warp.Y, "FarmHouse", entryLocation.X, entryLocation.Y, false); + } + else if (location is FarmHouse && warp.TargetName.Equals("Farm")) + warp = new Warp(warp.X, warp.Y, "BusStop", 0, 23, false); + Game1.warpCharacter(this, warp.TargetName, new Vector2((float)(warp.TargetX * Game1.tileSize), (float)(warp.TargetY * Game1.tileSize - this.Sprite.getHeight() / 2 - Game1.tileSize / 4)), false, location.IsOutdoors); + location.characters.Remove(this); + } + else if (strArray2 != null && strArray2.Length >= 1 && strArray2[0].Contains("Warp")) + { + Game1.warpCharacter(this, strArray2[3], new Vector2((float)Convert.ToInt32(strArray2[1]), (float)Convert.ToInt32(strArray2[2])), false, location.IsOutdoors); + if (Game1.currentLocation.name.Equals(location.name) && Utility.isOnScreen(this.getStandingPosition(), Game1.tileSize * 3)) + Game1.playSound("doorClose"); + location.characters.Remove(this); + } + else if (strArray2 != null && strArray2.Length >= 1 && strArray2[0].Contains("Door")) + { + location.openDoor(new Location(this.nextPositionPoint().X / Game1.tileSize, this.nextPositionPoint().Y / Game1.tileSize), Game1.player.currentLocation.Equals((object)location)); + } + else + { + if (location.map.GetLayer("Paths") == null) + return; + Tile tile2 = location.map.GetLayer("Paths").PickTile(new Location(this.getStandingX(), this.getStandingY()), Game1.viewport.Size); + Microsoft.Xna.Framework.Rectangle boundingBox = this.GetBoundingBox(); + boundingBox.Inflate(2, 2); + if (tile2 == null || !new Microsoft.Xna.Framework.Rectangle(this.getStandingX() - this.getStandingX() % Game1.tileSize, this.getStandingY() - this.getStandingY() % Game1.tileSize, Game1.tileSize, Game1.tileSize).Contains(boundingBox)) + return; + switch (tile2.TileIndex) + { + case 0: + if (this.getDirection() == 3) + { + this.SetMovingOnlyUp(); + break; + } + if (this.getDirection() != 2) + break; + this.SetMovingOnlyRight(); + break; + case 1: + if (this.getDirection() == 3) + { + this.SetMovingOnlyDown(); + break; + } + if (this.getDirection() != 0) + break; + this.SetMovingOnlyRight(); + break; + case 2: + if (this.getDirection() == 1) + { + this.SetMovingOnlyDown(); + break; + } + if (this.getDirection() != 0) + break; + this.SetMovingOnlyLeft(); + break; + case 3: + if (this.getDirection() == 1) + { + this.SetMovingOnlyUp(); + break; + } + if (this.getDirection() != 2) + break; + this.SetMovingOnlyLeft(); + break; + case 4: + this.changeSchedulePathDirection(); + this.moveCharacterOnSchedulePath(); + break; + case 7: + this.ReachedEndPoint(); + break; + } + } + } + } + else + { + if (!this.IsWalkingInSquare) + return; + this.randomSquareMovement(time); + this.MovePosition(time, Game1.viewport, location); + } + } + + } +} diff --git a/GeneralMods/CustomNPCFramework/Properties/AssemblyInfo.cs b/GeneralMods/CustomNPCFramework/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..db3fa352 --- /dev/null +++ b/GeneralMods/CustomNPCFramework/Properties/AssemblyInfo.cs @@ -0,0 +1,36 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; + +// General Information about an assembly is controlled through the following +// set of attributes. Change these attribute values to modify the information +// associated with an assembly. +[assembly: AssemblyTitle("CustomNPCFramework")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("CustomNPCFramework")] +[assembly: AssemblyCopyright("Copyright © 2018")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("89c7df45-8ae5-49ac-ada9-6312e9590829")] + +// Version information for an assembly consists of the following four values: +// +// Major Version +// Minor Version +// Build Number +// Revision +// +// You can specify all the values or you can default the Build and Revision Numbers +// by using the '*' as shown below: +// [assembly: AssemblyVersion("1.0.*")] +[assembly: AssemblyVersion("1.0.0.0")] +[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/GeneralMods/CustomNPCFramework/manifest.json b/GeneralMods/CustomNPCFramework/manifest.json new file mode 100644 index 00000000..56346973 --- /dev/null +++ b/GeneralMods/CustomNPCFramework/manifest.json @@ -0,0 +1,10 @@ +{ + "Name": "CustomNPCFramework", + "Author": "Alpha_Omegasis", + "Version": "0.1.0", + "Description": "A system to add custom npcs to Stardew.", + "UniqueID": "Omegasis.CustomNPCFramework", + "EntryDll": "CustomNPCFramework.dll", + "MinimumApiVersion": "2.0", + "UpdateKeys": [ ] +} diff --git a/GeneralMods/CustomNPCFramework/packages.config b/GeneralMods/CustomNPCFramework/packages.config new file mode 100644 index 00000000..028670c6 --- /dev/null +++ b/GeneralMods/CustomNPCFramework/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/GeneralMods/StardewMods.sln b/GeneralMods/StardewMods.sln index 076cb9cb..d346b575 100644 --- a/GeneralMods/StardewMods.sln +++ b/GeneralMods/StardewMods.sln @@ -82,6 +82,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SundropMapEvents", "Sundrop {BB737337-2D82-4245-AA46-F3B82FC6F228} = {BB737337-2D82-4245-AA46-F3B82FC6F228} EndProjectSection EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CustomNPCFramework", "CustomNPCFramework\CustomNPCFramework.csproj", "{89C7DF45-8AE5-49AC-ADA9-6312E9590829}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -188,6 +190,10 @@ Global {29A68F94-B23C-442B-8867-8B8F3502E64F}.Debug|Any CPU.Build.0 = Debug|Any CPU {29A68F94-B23C-442B-8867-8B8F3502E64F}.Release|Any CPU.ActiveCfg = Release|Any CPU {29A68F94-B23C-442B-8867-8B8F3502E64F}.Release|Any CPU.Build.0 = Release|Any CPU + {89C7DF45-8AE5-49AC-ADA9-6312E9590829}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {89C7DF45-8AE5-49AC-ADA9-6312E9590829}.Debug|Any CPU.Build.0 = Debug|Any CPU + {89C7DF45-8AE5-49AC-ADA9-6312E9590829}.Release|Any CPU.ActiveCfg = Release|Any CPU + {89C7DF45-8AE5-49AC-ADA9-6312E9590829}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -197,5 +203,6 @@ Global {BB737337-2D82-4245-AA46-F3B82FC6F228} = {3EE26DA0-0337-4991-8B02-BCB8D408008C} {BAAC8F21-C12F-42B0-A51C-0C5F33B52575} = {3EE26DA0-0337-4991-8B02-BCB8D408008C} {29A68F94-B23C-442B-8867-8B8F3502E64F} = {BAAC8F21-C12F-42B0-A51C-0C5F33B52575} + {89C7DF45-8AE5-49AC-ADA9-6312E9590829} = {3EE26DA0-0337-4991-8B02-BCB8D408008C} EndGlobalSection EndGlobal From b57a5f506fe9fa9e3bf0b6cd58766ace75d0662f Mon Sep 17 00:00:00 2001 From: Date: Fri, 23 Feb 2018 23:16:10 -0800 Subject: [PATCH 13/18] Finished base code for basic renderer. Now all I have to do is create the character renderer and AssetManager... --- .../ModularNPCS/AnimatedSpriteCollection.cs | 134 +++++++++++++ .../ModularNPCS/CharacterAnimation.cs | 184 ++++++++++++++++++ .../Framework/ModularNPCS/Direction.cs | 16 ++ .../ModularRenderers/AnimationKeys.cs | 16 ++ .../ModularRenderers/BasicRenderer.cs | 136 +++++++++++++ .../Framework/NPCS/ExtendedNPC.cs | 23 ++- 6 files changed, 502 insertions(+), 7 deletions(-) create mode 100644 GeneralMods/CustomNPCFramework/Framework/ModularNPCS/AnimatedSpriteCollection.cs create mode 100644 GeneralMods/CustomNPCFramework/Framework/ModularNPCS/CharacterAnimation.cs create mode 100644 GeneralMods/CustomNPCFramework/Framework/ModularNPCS/Direction.cs create mode 100644 GeneralMods/CustomNPCFramework/Framework/ModularNPCS/ModularRenderers/AnimationKeys.cs create mode 100644 GeneralMods/CustomNPCFramework/Framework/ModularNPCS/ModularRenderers/BasicRenderer.cs diff --git a/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/AnimatedSpriteCollection.cs b/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/AnimatedSpriteCollection.cs new file mode 100644 index 00000000..625dc23c --- /dev/null +++ b/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/AnimatedSpriteCollection.cs @@ -0,0 +1,134 @@ +using CustomNPCFramework.Framework.NPCS; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using StardewValley; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CustomNPCFramework.Framework.ModularNPCS +{ + public class AnimatedSpriteCollection + { + AnimatedSprite leftSprite; + AnimatedSprite rightSprite; + AnimatedSprite upSprite; + AnimatedSprite downSprite; + + public AnimatedSprite currentSprite; + + /// + /// Constructor. + /// + /// Left animated sprite for this piece. + /// Right animated sprite for this piece. + /// Up animated sprite for this piece. + /// Down animated sprite for this piece. + /// + public AnimatedSpriteCollection(AnimatedSprite LeftSprite,AnimatedSprite RightSprite,AnimatedSprite UpSprite,AnimatedSprite DownSprite,Direction startingSpriteDirection) + { + this.leftSprite = LeftSprite; + this.rightSprite = RightSprite; + this.upSprite = UpSprite; + this.downSprite = DownSprite; + if (startingSpriteDirection == Direction.down) + { + setDown(); + } + if (startingSpriteDirection == Direction.left) + { + setLeft(); + } + if (startingSpriteDirection == Direction.right) + { + setRight(); + } + if (startingSpriteDirection == Direction.up) + { + setUp(); + } + } + + /// + /// Sets the current + /// + public void setLeft() + { + this.currentSprite = leftSprite; + } + + public void setRight() + { + this.currentSprite = rightSprite; + } + + public void setDown() + { + this.currentSprite = downSprite; + } + + public void setUp() + { + this.currentSprite = upSprite; + } + + /// + /// Used to draw the sprite to the screen. + /// + /// + /// + /// + public void draw(SpriteBatch b, Vector2 screenPosition, float layerDepth) + { + b.Draw(this.currentSprite.Texture, screenPosition, new Rectangle?(this.currentSprite.sourceRect), Color.White, 0.0f, Vector2.Zero, (float)Game1.pixelZoom, this.currentSprite.currentAnimation == null || !this.currentSprite.currentAnimation[this.currentSprite.currentAnimationIndex].flip ? SpriteEffects.None : SpriteEffects.FlipHorizontally, layerDepth); + } + + /// + /// Used to draw the sprite to the screen. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public void draw(SpriteBatch b, Vector2 screenPosition, float layerDepth, int xOffset, int yOffset, Color c, bool flip = false, float scale = 1f, float rotation = 0.0f, bool characterSourceRectOffset = false) + { + b.Draw(this.currentSprite.Texture, screenPosition, new Rectangle?(new Rectangle(this.currentSprite.sourceRect.X + xOffset, this.currentSprite.sourceRect.Y + yOffset, this.currentSprite.sourceRect.Width, this.currentSprite.sourceRect.Height)), c, rotation, characterSourceRectOffset ? new Vector2((float)(this.currentSprite.spriteWidth / 2), (float)((double)this.currentSprite.spriteHeight * 3.0 / 4.0)) : Vector2.Zero, scale, flip || this.currentSprite.currentAnimation != null && this.currentSprite.currentAnimation[this.currentSprite.currentAnimationIndex].flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, layerDepth); + } + + /// + /// A very verbose asset drawer. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public void draw(SpriteBatch b, ExtendedNPC npc, Vector2 position, Rectangle sourceRectangle,Color color, float alpha,Vector2 origin,float scale,SpriteEffects effects,float layerDepth) + { + b.Draw(this.currentSprite.Texture,position,sourceRectangle, color* alpha, npc.rotation, origin,scale,effects,layerDepth); + //b.Draw(this.Sprite.Texture, npc.getLocalPosition(Game1.viewport) + new Vector2((float)(this.sprite.spriteWidth * Game1.pixelZoom / 2), (float)(this.GetBoundingBox().Height / 2)) + (this.shakeTimer > 0 ? new Vector2((float)Game1.random.Next(-1, 2), (float)Game1.random.Next(-1, 2)) : Vector2.Zero), new Microsoft.Xna.Framework.Rectangle?(this.Sprite.SourceRect), Color.White * alpha, this.rotation, new Vector2((float)(this.sprite.spriteWidth / 2), (float)((double)this.sprite.spriteHeight * 3.0 / 4.0)), Math.Max(0.2f, this.scale) * (float)Game1.pixelZoom, this.flip || this.sprite.currentAnimation != null && this.sprite.currentAnimation[this.sprite.currentAnimationIndex].flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, Math.Max(0.0f, this.drawOnTop ? 0.991f : (float)this.getStandingY() / 10000f)); + } + + /// + /// Animate the current sprite. Theoreticlly works from index offset to how many frames + /// + /// + public void Animate(float intervalFromCharacter) + { + this.currentSprite.Animate(Game1.currentGameTime, 0, 3, intervalFromCharacter); + } + } +} diff --git a/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/CharacterAnimation.cs b/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/CharacterAnimation.cs new file mode 100644 index 00000000..1eeb06b3 --- /dev/null +++ b/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/CharacterAnimation.cs @@ -0,0 +1,184 @@ +using CustomNPCFramework.Framework.NPCS; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CustomNPCFramework.Framework.ModularNPCS +{ + public class CharacterAnimation + { + public AnimatedSpriteCollection hair; + public AnimatedSpriteCollection body; + public AnimatedSpriteCollection eyes; + public AnimatedSpriteCollection shirt; + public AnimatedSpriteCollection pants; + public AnimatedSpriteCollection shoes; + public List accessories; + + public CharacterAnimation(AnimatedSpriteCollection bodyAnimation, AnimatedSpriteCollection eyeAnimation, AnimatedSpriteCollection hairAnimation, AnimatedSpriteCollection shirtAnimation, AnimatedSpriteCollection pantsAnimation, AnimatedSpriteCollection shoesAnimation,List accessoriesWithAnimations) + { + this.body = bodyAnimation; + this.hair = hairAnimation; + this.eyes = eyeAnimation; + this.shirt = shirtAnimation; + this.pants = pantsAnimation; + this.shoes = shoesAnimation; + this.accessories = accessoriesWithAnimations; + } + + public void setLeft() + { + this.body.setLeft(); + this.hair.setLeft(); + this.eyes.setLeft(); + this.shirt.setLeft(); + this.pants.setLeft(); + this.shoes.setLeft(); + + foreach(var accessory in this.accessories) + { + accessory.setLeft(); + } + } + public void setRight() + { + this.body.setRight(); + this.hair.setRight(); + this.eyes.setRight(); + this.shirt.setRight(); + this.pants.setRight(); + this.shoes.setRight(); + + foreach (var accessory in this.accessories) + { + accessory.setRight(); + } + } + public void setUp() + { + this.body.setUp(); + this.hair.setUp(); + this.eyes.setUp(); + this.shirt.setUp(); + this.pants.setUp(); + this.shoes.setUp(); + + foreach (var accessory in this.accessories) + { + accessory.setUp(); + } + } + public void setDown() + { + this.body.setDown(); + this.hair.setDown(); + this.eyes.setDown(); + this.shirt.setDown(); + this.pants.setDown(); + this.shoes.setDown(); + + foreach (var accessory in this.accessories) + { + accessory.setDown(); + } + } + + public void Animate(float animationInterval) + { + this.body.Animate(animationInterval); + this.hair.Animate(animationInterval); + this.eyes.Animate(animationInterval); + this.shirt.Animate(animationInterval); + this.pants.Animate(animationInterval); + this.shoes.Animate(animationInterval); + foreach(var accessory in this.accessories) + { + accessory.Animate(animationInterval); + } + + } + + /// + /// Used to draw the sprite to the screen. + /// + /// + /// + /// + public void draw(SpriteBatch b, Vector2 screenPosition, float layerDepth) + { + this.body.draw(b,screenPosition,layerDepth); + this.hair.draw(b, screenPosition, layerDepth); + this.eyes.draw(b, screenPosition, layerDepth); + this.shirt.draw(b, screenPosition, layerDepth); + this.pants.draw(b, screenPosition, layerDepth); + this.shoes.draw(b, screenPosition, layerDepth); + foreach (var accessory in this.accessories) + { + accessory.draw(b, screenPosition, layerDepth); + } + //b.Draw(this.currentSprite.Texture, screenPosition, new Rectangle?(this.currentSprite.sourceRect), Color.White, 0.0f, Vector2.Zero, (float)Game1.pixelZoom, this.currentSprite.currentAnimation == null || !this.currentSprite.currentAnimation[this.currentSprite.currentAnimationIndex].flip ? SpriteEffects.None : SpriteEffects.FlipHorizontally, layerDepth); + } + + + + /// + /// Used to draw the sprite to the screen. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public void draw(SpriteBatch b, Vector2 screenPosition, float layerDepth, int xOffset, int yOffset, Color c, bool flip = false, float scale = 1f, float rotation = 0.0f, bool characterSourceRectOffset = false) + { + // b.Draw(this.currentSprite.Texture, screenPosition, new Rectangle?(new Rectangle(this.currentSprite.sourceRect.X + xOffset, this.currentSprite.sourceRect.Y + yOffset, this.currentSprite.sourceRect.Width, this.currentSprite.sourceRect.Height)), c, rotation, characterSourceRectOffset ? new Vector2((float)(this.currentSprite.spriteWidth / 2), (float)((double)this.currentSprite.spriteHeight * 3.0 / 4.0)) : Vector2.Zero, scale, flip || this.currentSprite.currentAnimation != null && this.currentSprite.currentAnimation[this.currentSprite.currentAnimationIndex].flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, layerDepth); + this.body.draw(b, screenPosition, layerDepth, xOffset, yOffset, c, flip, scale, rotation, characterSourceRectOffset); + this.hair.draw(b, screenPosition, layerDepth, xOffset, yOffset, c, flip, scale, rotation, characterSourceRectOffset); + this.eyes.draw(b, screenPosition, layerDepth, xOffset, yOffset, c, flip, scale, rotation, characterSourceRectOffset); + this.shirt.draw(b, screenPosition, layerDepth, xOffset, yOffset, c, flip, scale, rotation, characterSourceRectOffset); + this.pants.draw(b, screenPosition, layerDepth, xOffset, yOffset, c, flip, scale, rotation, characterSourceRectOffset); + this.shoes.draw(b, screenPosition, layerDepth, xOffset, yOffset, c, flip, scale, rotation, characterSourceRectOffset); + foreach(var accessory in this.accessories) + { + accessory.draw(b, screenPosition, layerDepth, xOffset, yOffset, c, flip, scale, rotation, characterSourceRectOffset); + } + } + + /// + /// A very verbose asset drawer. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public void draw(SpriteBatch b, ExtendedNPC npc, Vector2 position, Rectangle sourceRectangle, Color color, float alpha, Vector2 origin, float scale, SpriteEffects effects, float layerDepth) + { + this.body.draw(b, npc, position, sourceRectangle, color, alpha, origin, scale, effects, layerDepth); + this.hair.draw(b, npc, position, sourceRectangle, color, alpha, origin, scale, effects, layerDepth); + this.eyes.draw(b, npc, position, sourceRectangle, color, alpha, origin, scale, effects, layerDepth); + this.shirt.draw(b, npc, position, sourceRectangle, color, alpha, origin, scale, effects, layerDepth); + this.pants.draw(b, npc, position, sourceRectangle, color, alpha, origin, scale, effects, layerDepth); + this.shoes.draw(b, npc, position, sourceRectangle, color, alpha, origin, scale, effects, layerDepth); + foreach(var accessory in this.accessories) + { + accessory.draw(b, npc, position, sourceRectangle, color, alpha, origin, scale, effects, layerDepth); + } + } + + } +} diff --git a/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/Direction.cs b/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/Direction.cs new file mode 100644 index 00000000..e34d3623 --- /dev/null +++ b/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/Direction.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CustomNPCFramework.Framework.ModularNPCS +{ + public enum Direction + { + up, + right, + down, + left + } +} diff --git a/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/ModularRenderers/AnimationKeys.cs b/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/ModularRenderers/AnimationKeys.cs new file mode 100644 index 00000000..502b540a --- /dev/null +++ b/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/ModularRenderers/AnimationKeys.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CustomNPCFramework.Framework.ModularNPCS.ModularRenderers +{ + class AnimationKeys + { + public static string standingKey = "standing"; + public static string walkingKey = "walking"; + public static string sittingKey = "sitting"; + public static string swimmingKey = "swimming"; + } +} diff --git a/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/ModularRenderers/BasicRenderer.cs b/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/ModularRenderers/BasicRenderer.cs new file mode 100644 index 00000000..7a6c7733 --- /dev/null +++ b/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/ModularRenderers/BasicRenderer.cs @@ -0,0 +1,136 @@ +using CustomNPCFramework.Framework.NPCS; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CustomNPCFramework.Framework.ModularNPCS.ModularRenderers +{ + public class BasicRenderer + { + public Dictionary animationList; + public CharacterAnimation currentAnimation; + + public BasicRenderer(CharacterAnimation standingAnimation,CharacterAnimation walkingAnimation, CharacterAnimation swimmingAnimation) + { + animationList = new Dictionary(); + animationList.Add(AnimationKeys.standingKey, standingAnimation); + animationList.Add(AnimationKeys.walkingKey, walkingAnimation); + animationList.Add(AnimationKeys.swimmingKey, swimmingAnimation); + setAnimation(AnimationKeys.standingKey); + } + + /// + /// Sets the animation associated with the key name; If it fails the npc will just default to standing. + /// + /// + public virtual void setAnimation(string key) + { + this.currentAnimation = animationList[key]; + if (this.currentAnimation == null) this.setAnimation(AnimationKeys.standingKey); + } + + public virtual void setDirection(int facingDirection) + { + if (facingDirection == 0) setUp(); + if (facingDirection == 1) setRight(); + if (facingDirection == 2) setDown(); + if (facingDirection == 2) setLeft(); + } + + public virtual void setLeft() + { + this.currentAnimation.setLeft(); + } + + public virtual void setRight() + { + this.currentAnimation.setRight(); + } + + public virtual void setUp() + { + this.currentAnimation.setUp(); + } + + public virtual void setDown() + { + this.currentAnimation.setDown(); + } + + /// + /// Used to draw the sprite to the screen. + /// + /// + /// + /// + public virtual void draw(SpriteBatch b, Vector2 screenPosition, float layerDepth) + { + this.currentAnimation.draw(b, screenPosition, layerDepth); + } + + /// + /// Used to draw the sprite to the screen. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public virtual void draw(SpriteBatch b, Vector2 screenPosition, float layerDepth, int xOffset, int yOffset, Color c, bool flip = false, float scale = 1f, float rotation = 0.0f, bool characterSourceRectOffset = false) + { + this.currentAnimation.draw(b, screenPosition, layerDepth, xOffset, yOffset, c, flip, scale, rotation, characterSourceRectOffset); + } + + /// + /// A very verbose asset drawer. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public void draw(SpriteBatch b, ExtendedNPC npc, Vector2 position, Rectangle sourceRectangle, Color color, float alpha, Vector2 origin, float scale, SpriteEffects effects, float layerDepth) + { + this.currentAnimation.draw(b, npc, position, sourceRectangle, color, alpha, origin, scale, effects, layerDepth); + } + + + public virtual void Animate(float interval) + { + this.currentAnimation.Animate(interval); + } + + + /// + /// Wrapper for a draw function that accepts rectangles to be null. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public void draw(SpriteBatch b, ExtendedNPC extendedNPC, Vector2 vector21, Rectangle? v1, Color white, float rotation, Vector2 vector22, float v2, SpriteEffects spriteEffects, float v3) + { + this.draw(b, extendedNPC, vector21, v1, white, rotation, vector22, v2, spriteEffects, v3); + } + } +} diff --git a/GeneralMods/CustomNPCFramework/Framework/NPCS/ExtendedNPC.cs b/GeneralMods/CustomNPCFramework/Framework/NPCS/ExtendedNPC.cs index 6c68eada..1899871f 100644 --- a/GeneralMods/CustomNPCFramework/Framework/NPCS/ExtendedNPC.cs +++ b/GeneralMods/CustomNPCFramework/Framework/NPCS/ExtendedNPC.cs @@ -1,4 +1,5 @@ -using Microsoft.Xna.Framework; +using CustomNPCFramework.Framework.ModularNPCS.ModularRenderers; +using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using StardewValley; using StardewValley.Characters; @@ -14,8 +15,9 @@ using xTile.Tiles; namespace CustomNPCFramework.Framework.NPCS { - class ExtendedNPC :StardewValley.NPC + public class ExtendedNPC :StardewValley.NPC { + public BasicRenderer characterRenderer; public ExtendedNPC() :base() { @@ -158,6 +160,11 @@ namespace CustomNPCFramework.Framework.NPCS } } + /// + /// Used to draw the npc with the custom renderer. + /// + /// + /// public override void draw(SpriteBatch b, float alpha = 1f) { if (this.sprite == null || this.isInvisible || !Utility.isOnScreen(this.position, 2 * Game1.tileSize)) @@ -165,13 +172,15 @@ namespace CustomNPCFramework.Framework.NPCS //Checks if the npc is swimming. If not draw it's default graphic. Do characters aside from Farmer and Penny Swim??? if (this.swimming) { - b.Draw(this.Sprite.Texture, this.getLocalPosition(Game1.viewport) + new Vector2((float)(Game1.tileSize / 2), (float)(Game1.tileSize + Game1.tileSize / 4 + this.yJumpOffset * 2)) + (this.shakeTimer > 0 ? new Vector2((float)Game1.random.Next(-1, 2), (float)Game1.random.Next(-1, 2)) : Vector2.Zero) - new Vector2(0.0f, this.yOffset), new Microsoft.Xna.Framework.Rectangle?(new Microsoft.Xna.Framework.Rectangle(this.sprite.SourceRect.X, this.sprite.SourceRect.Y, this.sprite.SourceRect.Width, this.sprite.SourceRect.Height / 2 - (int)((double)this.yOffset / (double)Game1.pixelZoom))), Color.White, this.rotation, new Vector2((float)(Game1.tileSize / 2), (float)(Game1.tileSize * 3 / 2)) / 4f, Math.Max(0.2f, this.scale) * (float)Game1.pixelZoom, this.flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, Math.Max(0.0f, this.drawOnTop ? 0.991f : (float)this.getStandingY() / 10000f)); - Vector2 localPosition = this.getLocalPosition(Game1.viewport); - b.Draw(Game1.staminaRect, new Microsoft.Xna.Framework.Rectangle((int)localPosition.X + (int)this.yOffset + Game1.pixelZoom * 2, (int)localPosition.Y - 32 * Game1.pixelZoom + this.sprite.SourceRect.Height * Game1.pixelZoom + Game1.tileSize * 3 / 4 + this.yJumpOffset * 2 - (int)this.yOffset, this.sprite.SourceRect.Width * Game1.pixelZoom - (int)this.yOffset * 2 - Game1.pixelZoom * 4, Game1.pixelZoom), new Microsoft.Xna.Framework.Rectangle?(Game1.staminaRect.Bounds), Color.White * 0.75f, 0.0f, Vector2.Zero, SpriteEffects.None, (float)((double)this.getStandingY() / 10000.0 + 1.0 / 1000.0)); + this.characterRenderer.setAnimation(AnimationKeys.swimmingKey); + this.characterRenderer.setDirection(this.facingDirection); + this.characterRenderer.draw(b,this,this.getLocalPosition(Game1.viewport) + new Vector2((float)(Game1.tileSize / 2), (float)(Game1.tileSize + Game1.tileSize / 4 + this.yJumpOffset * 2)) + (this.shakeTimer > 0 ? new Vector2((float)Game1.random.Next(-1, 2), (float)Game1.random.Next(-1, 2)) : Vector2.Zero) - new Vector2(0.0f, this.yOffset), new Microsoft.Xna.Framework.Rectangle?(new Microsoft.Xna.Framework.Rectangle(this.sprite.SourceRect.X, this.sprite.SourceRect.Y, this.sprite.SourceRect.Width, this.sprite.SourceRect.Height / 2 - (int)((double)this.yOffset / (double)Game1.pixelZoom))), Color.White, this.rotation, new Vector2((float)(Game1.tileSize / 2), (float)(Game1.tileSize * 3 / 2)) / 4f, Math.Max(0.2f, this.scale) * (float)Game1.pixelZoom, this.flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, Math.Max(0.0f, this.drawOnTop ? 0.991f : (float)this.getStandingY() / 10000f)); + //Vector2 localPosition = this.getLocalPosition(Game1.viewport); + //b.Draw(Game1.staminaRect, new Microsoft.Xna.Framework.Rectangle((int)localPosition.X + (int)this.yOffset + Game1.pixelZoom * 2, (int)localPosition.Y - 32 * Game1.pixelZoom + this.sprite.SourceRect.Height * Game1.pixelZoom + Game1.tileSize * 3 / 4 + this.yJumpOffset * 2 - (int)this.yOffset, this.sprite.SourceRect.Width * Game1.pixelZoom - (int)this.yOffset * 2 - Game1.pixelZoom * 4, Game1.pixelZoom), new Microsoft.Xna.Framework.Rectangle?(Game1.staminaRect.Bounds), Color.White * 0.75f, 0.0f, Vector2.Zero, SpriteEffects.None, (float)((double)this.getStandingY() / 10000.0 + 1.0 / 1000.0)); } else { - b.Draw(this.Sprite.Texture, this.getLocalPosition(Game1.viewport) + new Vector2((float)(this.sprite.spriteWidth * Game1.pixelZoom / 2), (float)(this.GetBoundingBox().Height / 2)) + (this.shakeTimer > 0 ? new Vector2((float)Game1.random.Next(-1, 2), (float)Game1.random.Next(-1, 2)) : Vector2.Zero), new Microsoft.Xna.Framework.Rectangle?(this.Sprite.SourceRect), Color.White * alpha, this.rotation, new Vector2((float)(this.sprite.spriteWidth / 2), (float)((double)this.sprite.spriteHeight * 3.0 / 4.0)), Math.Max(0.2f, this.scale) * (float)Game1.pixelZoom, this.flip || this.sprite.currentAnimation != null && this.sprite.currentAnimation[this.sprite.currentAnimationIndex].flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, Math.Max(0.0f, this.drawOnTop ? 0.991f : (float)this.getStandingY() / 10000f)); + this.characterRenderer.draw(b,this, this.getLocalPosition(Game1.viewport) + new Vector2((float)(this.sprite.spriteWidth * Game1.pixelZoom / 2), (float)(this.GetBoundingBox().Height / 2)) + (this.shakeTimer > 0 ? new Vector2((float)Game1.random.Next(-1, 2), (float)Game1.random.Next(-1, 2)) : Vector2.Zero), new Microsoft.Xna.Framework.Rectangle?(this.Sprite.SourceRect), Color.White * alpha, this.rotation, new Vector2((float)(this.sprite.spriteWidth / 2), (float)((double)this.sprite.spriteHeight * 3.0 / 4.0)), Math.Max(0.2f, this.scale) * (float)Game1.pixelZoom, this.flip || this.sprite.currentAnimation != null && this.sprite.currentAnimation[this.sprite.currentAnimationIndex].flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, Math.Max(0.0f, this.drawOnTop ? 0.991f : (float)this.getStandingY() / 10000f)); } //If the npc breathes then this code is ran. if (this.breather && this.shakeTimer <= 0 && (!this.swimming && this.sprite.CurrentFrame < 16) && !this.farmerPassesThrough) @@ -195,7 +204,7 @@ namespace CustomNPCFramework.Framework.NPCS sourceRect.Height /= 2; } float num = Math.Max(0.0f, (float)(Math.Ceiling(Math.Sin(Game1.currentGameTime.TotalGameTime.TotalMilliseconds / 600.0 + (double)this.DefaultPosition.X * 20.0)) / 4.0)); - b.Draw(this.Sprite.Texture, this.getLocalPosition(Game1.viewport) + vector2 + (this.shakeTimer > 0 ? new Vector2((float)Game1.random.Next(-1, 2), (float)Game1.random.Next(-1, 2)) : Vector2.Zero), new Microsoft.Xna.Framework.Rectangle?(sourceRect), Color.White * alpha, this.rotation, new Vector2((float)(sourceRect.Width / 2), (float)(sourceRect.Height / 2 + 1)), Math.Max(0.2f, this.scale) * (float)Game1.pixelZoom + num, this.flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, Math.Max(0.0f, this.drawOnTop ? 0.992f : (float)((double)this.getStandingY() / 10000.0 + 1.0 / 1000.0))); + this.characterRenderer.draw(b,this, this.getLocalPosition(Game1.viewport) + vector2 + (this.shakeTimer > 0 ? new Vector2((float)Game1.random.Next(-1, 2), (float)Game1.random.Next(-1, 2)) : Vector2.Zero), new Microsoft.Xna.Framework.Rectangle?(sourceRect), Color.White * alpha, this.rotation, new Vector2((float)(sourceRect.Width / 2), (float)(sourceRect.Height / 2 + 1)), Math.Max(0.2f, this.scale) * (float)Game1.pixelZoom + num, this.flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, Math.Max(0.0f, this.drawOnTop ? 0.992f : (float)((double)this.getStandingY() / 10000.0 + 1.0 / 1000.0))); } //Checks if the npc is glowing. From b19de2348741455d4f128b83e04c3c83ef2d4e0c Mon Sep 17 00:00:00 2001 From: Date: Fri, 23 Feb 2018 23:40:34 -0800 Subject: [PATCH 14/18] integrated code to ExtendedNPC that needs to be overwritten to fix the this.sprite issue. --- .../ModularRenderers/BasicRenderer.cs | 4 +- .../Framework/NPCS/ExtendedNPC.cs | 1354 +++++++++++++++-- 2 files changed, 1224 insertions(+), 134 deletions(-) diff --git a/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/ModularRenderers/BasicRenderer.cs b/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/ModularRenderers/BasicRenderer.cs index 7a6c7733..46d9c9f6 100644 --- a/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/ModularRenderers/BasicRenderer.cs +++ b/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/ModularRenderers/BasicRenderer.cs @@ -103,7 +103,7 @@ namespace CustomNPCFramework.Framework.ModularNPCS.ModularRenderers /// /// /// - public void draw(SpriteBatch b, ExtendedNPC npc, Vector2 position, Rectangle sourceRectangle, Color color, float alpha, Vector2 origin, float scale, SpriteEffects effects, float layerDepth) + public virtual void draw(SpriteBatch b, ExtendedNPC npc, Vector2 position, Rectangle sourceRectangle, Color color, float alpha, Vector2 origin, float scale, SpriteEffects effects, float layerDepth) { this.currentAnimation.draw(b, npc, position, sourceRectangle, color, alpha, origin, scale, effects, layerDepth); } @@ -128,7 +128,7 @@ namespace CustomNPCFramework.Framework.ModularNPCS.ModularRenderers /// /// /// - public void draw(SpriteBatch b, ExtendedNPC extendedNPC, Vector2 vector21, Rectangle? v1, Color white, float rotation, Vector2 vector22, float v2, SpriteEffects spriteEffects, float v3) + public virtual void draw(SpriteBatch b, ExtendedNPC extendedNPC, Vector2 vector21, Rectangle? v1, Color white, float rotation, Vector2 vector22, float v2, SpriteEffects spriteEffects, float v3) { this.draw(b, extendedNPC, vector21, v1, white, rotation, vector22, v2, spriteEffects, v3); } diff --git a/GeneralMods/CustomNPCFramework/Framework/NPCS/ExtendedNPC.cs b/GeneralMods/CustomNPCFramework/Framework/NPCS/ExtendedNPC.cs index 1899871f..43d1130c 100644 --- a/GeneralMods/CustomNPCFramework/Framework/NPCS/ExtendedNPC.cs +++ b/GeneralMods/CustomNPCFramework/Framework/NPCS/ExtendedNPC.cs @@ -18,16 +18,614 @@ namespace CustomNPCFramework.Framework.NPCS public class ExtendedNPC :StardewValley.NPC { public BasicRenderer characterRenderer; + + public ExtendedNPC() :base() { - } - public ExtendedNPC(StardewValley.AnimatedSprite sprite,Vector2 position,int facingDirection,string name): base(sprite, position, facingDirection, name, null) + public ExtendedNPC(BasicRenderer renderer,Vector2 position,int facingDirection,string name): base(null, position, facingDirection, name, null) { - + this.characterRenderer = renderer; } + public ExtendedNPC(BasicRenderer renderer,Texture2D portrait, Vector2 position, int facingDirection, string name) : base(null, position, facingDirection, name, null) + { + this.characterRenderer = renderer; + this.Portrait = portrait; + } + //ERROR NEED FIXING + public override void reloadSprite() + { + string name = this.name; + string str = name == "Old Mariner" ? "Mariner" : (name == "Dwarf King" ? "DwarfKing" : (name == "Mister Qi" ? "MrQi" : (name == "???" ? "Monsters\\Shadow Guy" : this.name))); + if (this.name.Equals(Utility.getOtherFarmerNames()[0])) + str = Game1.player.isMale ? "maleRival" : "femaleRival"; + if (!this.IsMonster) + { + this.sprite = new AnimatedSprite(Game1.content.Load("Characters\\" + str)); + if (!this.name.Contains("Dwarf")) + this.sprite.spriteHeight = 32; + } + else + this.sprite = new AnimatedSprite(Game1.content.Load("Monsters\\" + str)); + try + { + this.portrait = Game1.content.Load("Portraits\\" + str); + } + catch (Exception ex) + { + this.portrait = (Texture2D)null; + } + int num = this.isInvisible ? 1 : 0; + if (!Game1.newDay && (int)Game1.gameMode != 6) + return; + this.faceDirection(this.DefaultFacingDirection); + this.scheduleTimeToTry = 9999999; + this.previousEndPoint = new Point((int)this.defaultPosition.X / Game1.tileSize, (int)this.defaultPosition.Y / Game1.tileSize); + this.Schedule = this.getSchedule(Game1.dayOfMonth); + this.faceDirection(this.defaultFacingDirection); + this.sprite.standAndFaceDirection(this.defaultFacingDirection); + this.loadSeasonalDialogue(); + this.updateDialogue(); + if (this.isMarried()) + this.marriageDuties(); + bool flag = Utility.isFestivalDay(Game1.dayOfMonth, Game1.currentSeason); + if (this.name.Equals("Robin") && Game1.player.daysUntilHouseUpgrade > 0 && !flag) + { + this.setTilePosition(68, 14); + this.ignoreMultiplayerUpdates = true; + this.sprite.setCurrentAnimation(new List() + { + new FarmerSprite.AnimationFrame(24, 75), + new FarmerSprite.AnimationFrame(25, 75), + new FarmerSprite.AnimationFrame(26, 300, false, false, new AnimatedSprite.endOfAnimationBehavior(this.robinHammerSound), false), + new FarmerSprite.AnimationFrame(27, 1000, false, false, new AnimatedSprite.endOfAnimationBehavior(this.robinVariablePause), false) + }); + this.ignoreScheduleToday = true; + this.CurrentDialogue.Clear(); + this.currentDialogue.Push(new StardewValley.Dialogue(Game1.player.daysUntilHouseUpgrade == 2 ? Game1.content.LoadString("Strings\\StringsFromCSFiles:NPC.cs.3926") : Game1.content.LoadString("Strings\\StringsFromCSFiles:NPC.cs.3927"), this)); + } + else if (this.name.Equals("Robin") && Game1.getFarm().isThereABuildingUnderConstruction() && !flag) + { + this.ignoreMultiplayerUpdates = true; + this.sprite.setCurrentAnimation(new List() + { + new FarmerSprite.AnimationFrame(24, 75), + new FarmerSprite.AnimationFrame(25, 75), + new FarmerSprite.AnimationFrame(26, 300, false, false, new AnimatedSprite.endOfAnimationBehavior(this.robinHammerSound), false), + new FarmerSprite.AnimationFrame(27, 1000, false, false, new AnimatedSprite.endOfAnimationBehavior(this.robinVariablePause), false) + }); + this.ignoreScheduleToday = true; + Building underConstruction = Game1.getFarm().getBuildingUnderConstruction(); + if (underConstruction.daysUntilUpgrade > 0) + { + if (!underConstruction.indoors.characters.Contains(this)) + underConstruction.indoors.addCharacter(this); + if (this.currentLocation != null) + this.currentLocation.characters.Remove(this); + this.currentLocation = underConstruction.indoors; + this.setTilePosition(1, 5); + } + else + { + Game1.warpCharacter(this, "Farm", new Vector2((float)(underConstruction.tileX + underConstruction.tilesWide / 2), (float)(underConstruction.tileY + underConstruction.tilesHigh / 2)), false, false); + this.position.X += (float)(Game1.tileSize / 4); + this.position.Y -= (float)(Game1.tileSize / 2); + } + this.CurrentDialogue.Clear(); + this.currentDialogue.Push(new StardewValley.Dialogue(Game1.content.LoadString("Strings\\StringsFromCSFiles:NPC.cs.3926"), this)); + } + if (this.name.Equals("Shane") || this.name.Equals("Emily")) + this.datable = true; + try + { + this.displayName = Game1.content.Load>("Data\\NPCDispositions")[this.name].Split('/')[11]; + } + catch (Exception ex) + { + } + } + + //ERROR NEED FIXING + public virtual bool checkAction(Farmer who, GameLocation l) + { + if (this.isInvisible) + return false; + if (who.isRidingHorse()) + who.Halt(); + if (this.name.Equals("Henchman") && l.name.Equals("WitchSwamp")) + { + if (!Game1.player.mailReceived.Contains("Henchman1")) + { + Game1.player.mailReceived.Add("Henchman1"); + this.CurrentDialogue.Push(new StardewValley.Dialogue(Game1.content.LoadString("Strings\\Characters:Henchman1"), this)); + Game1.drawDialogue(this); + Game1.player.addQuest(27); + Game1.player.friendships.Add("Henchman", new int[6]); + } + else + { + if (who.ActiveObject != null && who.ActiveObject.canBeGivenAsGift()) + { + this.tryToReceiveActiveObject(who); + return true; + } + if (this.controller == null) + { + this.CurrentDialogue.Push(new StardewValley.Dialogue(Game1.content.LoadString("Strings\\Characters:Henchman2"), this)); + Game1.drawDialogue(this); + } + } + return true; + } + if (Game1.NPCGiftTastes.ContainsKey(this.name) && !Game1.player.friendships.ContainsKey(this.name)) + { + Game1.player.friendships.Add(this.name, new int[6]); + if (this.name.Equals("Krobus")) + { + this.currentDialogue.Push(new StardewValley.Dialogue(Game1.content.LoadString("Strings\\StringsFromCSFiles:NPC.cs.3990"), this)); + Game1.drawDialogue(this); + return true; + } + } + if (who.checkForQuestComplete(this, -1, -1, (Item)who.ActiveObject, (string)null, -1, 5)) + { + this.faceTowardFarmerForPeriod(6000, 3, false, who); + return true; + } + if (this.name.Equals("Dwarf") && this.currentDialogue.Count <= 0 && (who.canUnderstandDwarves && l.name.Equals("Mine"))) + Game1.activeClickableMenu = (IClickableMenu)new ShopMenu(Utility.getDwarfShopStock(), 0, "Dwarf"); + if (this.name.Equals("Krobus")) + { + if (who.hasQuest(28)) + { + this.CurrentDialogue.Push(new StardewValley.Dialogue(Game1.content.LoadString("Strings\\Characters:KrobusDarkTalisman"), this)); + Game1.drawDialogue(this); + who.removeQuest(28); + who.mailReceived.Add("krobusUnseal"); + TemporaryAnimatedSprite t1 = new TemporaryAnimatedSprite(Projectile.projectileSheet, new Microsoft.Xna.Framework.Rectangle(0, 0, 16, 16), 3000f, 1, 0, new Vector2(31f, 17f) * (float)Game1.tileSize, false, false); + t1.scale = (float)Game1.pixelZoom; + t1.delayBeforeAnimationStart = 1; + t1.startSound = "debuffSpell"; + t1.motion = new Vector2(-9f, 1f); + t1.rotationChange = (float)Math.PI / 64f; + int num1 = 1; + t1.light = num1 != 0; + double num2 = 1.0; + t1.lightRadius = (float)num2; + Color color1 = new Color(150, 0, 50); + t1.lightcolor = color1; + double num3 = 1.0; + t1.layerDepth = (float)num3; + double num4 = 3.0 / 1000.0; + t1.alphaFade = (float)num4; + GameLocation l1 = l; + int timer1 = 200; + int num5 = 1; + DelayedAction.addTemporarySpriteAfterDelay(t1, l1, timer1, num5 != 0); + TemporaryAnimatedSprite t2 = new TemporaryAnimatedSprite(Projectile.projectileSheet, new Microsoft.Xna.Framework.Rectangle(0, 0, 16, 16), 3000f, 1, 0, new Vector2(31f, 17f) * (float)Game1.tileSize, false, false); + t2.startSound = "debuffSpell"; + t2.delayBeforeAnimationStart = 1; + double pixelZoom = (double)Game1.pixelZoom; + t2.scale = (float)pixelZoom; + Vector2 vector2 = new Vector2(-9f, 1f); + t2.motion = vector2; + double num6 = 0.0490873865783215; + t2.rotationChange = (float)num6; + int num7 = 1; + t2.light = num7 != 0; + double num8 = 1.0; + t2.lightRadius = (float)num8; + Color color2 = new Color(150, 0, 50); + t2.lightcolor = color2; + double num9 = 1.0; + t2.layerDepth = (float)num9; + double num10 = 3.0 / 1000.0; + t2.alphaFade = (float)num10; + GameLocation l2 = l; + int timer2 = 700; + int num11 = 1; + DelayedAction.addTemporarySpriteAfterDelay(t2, l2, timer2, num11 != 0); + return true; + } + if (this.currentDialogue.Count <= 0 && l is Sewer) + Game1.activeClickableMenu = (IClickableMenu)new ShopMenu((l as Sewer).getShadowShopStock(), 0, "Krobus"); + } + if (this.name.Equals(who.spouse) && who.IsMainPlayer) + { + int timeOfDay = Game1.timeOfDay; + if (this.sprite.currentAnimation == null) + this.faceDirection(-3); + if (this.sprite.currentAnimation == null && who.friendships.ContainsKey(this.name) && (who.friendships[this.name][0] >= 3375 && !who.mailReceived.Contains("CF_Spouse"))) + { + this.CurrentDialogue.Push(new StardewValley.Dialogue(Game1.content.LoadString("Strings\\StringsFromCSFiles:NPC.cs.4001"), this)); + Game1.player.addItemByMenuIfNecessary((Item)new Object(Vector2.Zero, 434, "Cosmic Fruit", false, false, false, false), (ItemGrabMenu.behaviorOnItemSelect)null); + who.mailReceived.Add("CF_Spouse"); + return true; + } + if (this.sprite.currentAnimation == null && !this.hasTemporaryMessageAvailable() && (this.CurrentDialogue.Count == 0 && Game1.timeOfDay < 2200) && (this.controller == null && who.ActiveObject == null)) + { + this.faceGeneralDirection(who.getStandingPosition(), 0); + who.faceGeneralDirection(this.getStandingPosition(), 0); + if (this.facingDirection == 3 || this.facingDirection == 1) + { + int frame = 28; + bool flag = true; + string name = this.name; + // ISSUE: reference to a compiler-generated method + uint stringHash = \u003CPrivateImplementationDetails\u003E.ComputeStringHash(name); + if (stringHash <= 1708213605U) + { + if (stringHash <= 587846041U) + { + if ((int)stringHash != 161540545) + { + if ((int)stringHash == 587846041 && name == "Penny") + { + frame = 35; + flag = true; + } + } + else if (name == "Sebastian") + { + frame = 40; + flag = false; + } + } + else if ((int)stringHash != 1067922812) + { + if ((int)stringHash != 1281010426) + { + if ((int)stringHash == 1708213605 && name == "Alex") + { + frame = 42; + flag = true; + } + } + else if (name == "Maru") + { + frame = 28; + flag = false; + } + } + else if (name == "Sam") + { + frame = 36; + flag = true; + } + } + else if (stringHash <= 2571828641U) + { + if ((int)stringHash != 1866496948) + { + if ((int)stringHash != 2010304804) + { + if ((int)stringHash == -1723138655 && name == "Emily") + { + frame = 33; + flag = false; + } + } + else if (name == "Harvey") + { + frame = 31; + flag = false; + } + } + else if (name == "Shane") + { + frame = 34; + flag = false; + } + } + else if ((int)stringHash != -1562053956) + { + if ((int)stringHash != -1468719973) + { + if ((int)stringHash == -1228790996 && name == "Elliott") + { + frame = 35; + flag = false; + } + } + else if (name == "Leah") + { + frame = 25; + flag = true; + } + } + else if (name == "Abigail") + { + frame = 33; + flag = false; + } + bool flip = flag && this.facingDirection == 3 || !flag && this.facingDirection == 1; + if (who.getFriendshipHeartLevelForNPC(this.name) > 9) + { + this.sprite.setCurrentAnimation(new List() + { + new FarmerSprite.AnimationFrame(frame, Game1.IsMultiplayer ? 1000 : 10, false, flip, new AnimatedSprite.endOfAnimationBehavior(this.haltMe), true) + }); + if (!this.hasBeenKissedToday) + { + who.changeFriendship(10, this); + who.currentLocation.TemporarySprites.Add(new TemporaryAnimatedSprite(Game1.mouseCursors, new Microsoft.Xna.Framework.Rectangle(211, 428, 7, 6), 2000f, 1, 0, new Vector2((float)this.getTileX(), (float)this.getTileY()) * (float)Game1.tileSize + new Vector2((float)(Game1.tileSize / 4), (float)-Game1.tileSize), false, false, 1f, 0.0f, Color.White, (float)Game1.pixelZoom, 0.0f, 0.0f, 0.0f, false) + { + motion = new Vector2(0.0f, -0.5f), + alphaFade = 0.01f + }); + Game1.playSound("dwop"); + who.exhausted = false; + } + this.hasBeenKissedToday = true; + } + else + { + this.faceDirection(Game1.random.NextDouble() < 0.5 ? 2 : 0); + this.doEmote(12, true); + } + who.CanMove = false; + who.FarmerSprite.pauseForSingleAnimation = false; + if (flag && !flip || !flag & flip) + who.faceDirection(3); + else + who.faceDirection(1); + who.FarmerSprite.animateOnce(new List() + { + new FarmerSprite.AnimationFrame(101, 1000, 0, false, who.facingDirection == 3, (AnimatedSprite.endOfAnimationBehavior) null, false, 0), + new FarmerSprite.AnimationFrame(6, 1, false, who.facingDirection == 3, new AnimatedSprite.endOfAnimationBehavior(Farmer.completelyStopAnimating), false) + }.ToArray()); + return true; + } + } + } + bool flag1 = false; + if (who.friendships.ContainsKey(this.name)) + { + flag1 = this.checkForNewCurrentDialogue(who.friendships[this.name][0], false); + if (!flag1) + flag1 = this.checkForNewCurrentDialogue(who.friendships[this.name][0], true); + } + if (who.IsMainPlayer && who.friendships.ContainsKey(this.name) && this.endOfRouteMessage != null | flag1) + { + if (!flag1 && this.setTemporaryMessages(who)) + { + Game1.player.checkForQuestComplete(this, -1, -1, (Item)null, (string)null, 5, -1); + return false; + } + if (this.sprite.Texture.Bounds.Height > 32) + this.faceTowardFarmerForPeriod(5000, 4, false, who); + if (who.ActiveObject != null && who.ActiveObject.canBeGivenAsGift()) + { + this.tryToReceiveActiveObject(who); + Game1.stats.checkForFriendshipAchievements(); + this.faceTowardFarmerForPeriod(3000, 4, false, who); + return true; + } + if (!this.name.Contains("King") && !who.hasPlayerTalkedToNPC(this.name) && who.friendships.ContainsKey(this.name)) + { + who.friendships[this.name][2] = 1; + who.changeFriendship(10, this); + Game1.stats.checkForFriendshipAchievements(); + Game1.player.checkForQuestComplete(this, -1, -1, (Item)null, (string)null, 5, -1); + } + Game1.drawDialogue(this); + } + else if (this.CurrentDialogue.Count > 0) + { + if (!this.name.Contains("King") && who.ActiveObject != null && who.ActiveObject.canBeGivenAsGift()) + { + if (who.IsMainPlayer) + { + this.tryToReceiveActiveObject(who); + Game1.stats.checkForFriendshipAchievements(); + } + else + this.faceTowardFarmerForPeriod(3000, 4, false, who); + } + else if (who.hasClubCard && this.name.Equals("Bouncer") && who.IsMainPlayer) + { + Response[] answerChoices = new Response[2] + { + new Response("Yes.", Game1.content.LoadString("Strings\\StringsFromCSFiles:NPC.cs.4018")), + new Response("That's", Game1.content.LoadString("Strings\\StringsFromCSFiles:NPC.cs.4020")) + }; + l.createQuestionDialogue(Game1.content.LoadString("Strings\\StringsFromCSFiles:NPC.cs.4021"), answerChoices, "ClubCard"); + } + else if (this.CurrentDialogue.Count >= 1 || this.endOfRouteMessage != null) + { + if (this.setTemporaryMessages(who)) + { + Game1.player.checkForQuestComplete(this, -1, -1, (Item)null, (string)null, 5, -1); + return false; + } + if (this.sprite.Texture.Bounds.Height > 32) + this.faceTowardFarmerForPeriod(5000, 4, false, who); + if (who.IsMainPlayer) + { + if (!this.name.Contains("King") && !who.hasPlayerTalkedToNPC(this.name) && who.friendships.ContainsKey(this.name)) + { + who.friendships[this.name][2] = 1; + Game1.player.checkForQuestComplete(this, -1, -1, (Item)null, (string)null, 5, -1); + who.changeFriendship(20, this); + Game1.stats.checkForFriendshipAchievements(); + } + Game1.drawDialogue(this); + } + } + else if (!this.doingEndOfRouteAnimation) + { + try + { + if (who.friendships.ContainsKey(this.name)) + this.faceTowardFarmerForPeriod(who.friendships[this.name][0] / 125 * 1000 + 1000, 4, false, who); + } + catch (Exception ex) + { + } + if (Game1.random.NextDouble() < 0.1) + this.doEmote(8, true); + } + } + else if (this.name.Equals("Cat") && !(this as StardewValley.Monsters.Cat).wasPet) + { + (this as StardewValley.Monsters.Cat).wasPet = true; + (this as StardewValley.Monsters.Cat).loveForMaster += 10; + this.doEmote(20, true); + Game1.playSound("purr"); + } + else if (who.ActiveObject != null && who.ActiveObject.canBeGivenAsGift()) + { + this.tryToReceiveActiveObject(who); + Game1.stats.checkForFriendshipAchievements(); + this.faceTowardFarmerForPeriod(3000, 4, false, who); + return true; + } + if (this.setTemporaryMessages(who) || !this.doingEndOfRouteAnimation && this.goingToDoEndOfRouteAnimation || this.endOfRouteMessage == null) + return false; + Game1.drawDialogue(this); + return false; + } + + //ERROR NEED FIXING + public virtual void behaviorOnFarmerLocationEntry(GameLocation location, Farmer who) + { + if (this.sprite == null || this.sprite.currentAnimation != null || this.sprite.sourceRect.Height <= 32) + return; + this.sprite.spriteWidth = 16; + this.sprite.spriteHeight = 16; + this.sprite.CurrentFrame = 0; + } + + //ERROR NEED FIXING + public override void updateMovement(GameLocation location, GameTime time) + { + this.lastPosition = this.position; + if (this.DirectionsToNewLocation != null && !Game1.newDay) + { + if (this.getStandingX() < -Game1.tileSize || this.getStandingX() > location.map.DisplayWidth + Game1.tileSize || (this.getStandingY() < -Game1.tileSize || this.getStandingY() > location.map.DisplayHeight + Game1.tileSize)) + { + this.IsWalkingInSquare = false; + Game1.warpCharacter(this, this.DefaultMap, this.DefaultPosition, true, true); + location.characters.Remove(this); + } + else if (this.IsWalkingInSquare) + { + this.returnToEndPoint(); + this.MovePosition(time, Game1.viewport, location); + } + else + { + if (!this.followSchedule) + return; + this.MovePosition(time, Game1.viewport, location); + Warp warp = location.isCollidingWithWarp(this.GetBoundingBox()); + PropertyValue propertyValue = (PropertyValue)null; + Tile tile1 = location.map.GetLayer("Buildings").PickTile(this.nextPositionPoint(), Game1.viewport.Size); + if (tile1 != null) + tile1.Properties.TryGetValue("Action", out propertyValue); + string[] strArray1; + if (propertyValue != null) + strArray1 = propertyValue.ToString().Split(' '); + else + strArray1 = (string[])null; + string[] strArray2 = strArray1; + if (warp != null) + { + if (location is BusStop && warp.TargetName.Equals("Farm")) + { + Point entryLocation = ((this.isMarried() ? (GameLocation)(this.getHome() as FarmHouse) : Game1.getLocationFromName("FarmHouse")) as FarmHouse).getEntryLocation(); + warp = new Warp(warp.X, warp.Y, "FarmHouse", entryLocation.X, entryLocation.Y, false); + } + else if (location is FarmHouse && warp.TargetName.Equals("Farm")) + warp = new Warp(warp.X, warp.Y, "BusStop", 0, 23, false); + Game1.warpCharacter(this, warp.TargetName, new Vector2((float)(warp.TargetX * Game1.tileSize), (float)(warp.TargetY * Game1.tileSize - this.Sprite.getHeight() / 2 - Game1.tileSize / 4)), false, location.IsOutdoors); + location.characters.Remove(this); + } + else if (strArray2 != null && strArray2.Length >= 1 && strArray2[0].Contains("Warp")) + { + Game1.warpCharacter(this, strArray2[3], new Vector2((float)Convert.ToInt32(strArray2[1]), (float)Convert.ToInt32(strArray2[2])), false, location.IsOutdoors); + if (Game1.currentLocation.name.Equals(location.name) && Utility.isOnScreen(this.getStandingPosition(), Game1.tileSize * 3)) + Game1.playSound("doorClose"); + location.characters.Remove(this); + } + else if (strArray2 != null && strArray2.Length >= 1 && strArray2[0].Contains("Door")) + { + location.openDoor(new Location(this.nextPositionPoint().X / Game1.tileSize, this.nextPositionPoint().Y / Game1.tileSize), Game1.player.currentLocation.Equals((object)location)); + } + else + { + if (location.map.GetLayer("Paths") == null) + return; + Tile tile2 = location.map.GetLayer("Paths").PickTile(new Location(this.getStandingX(), this.getStandingY()), Game1.viewport.Size); + Microsoft.Xna.Framework.Rectangle boundingBox = this.GetBoundingBox(); + boundingBox.Inflate(2, 2); + if (tile2 == null || !new Microsoft.Xna.Framework.Rectangle(this.getStandingX() - this.getStandingX() % Game1.tileSize, this.getStandingY() - this.getStandingY() % Game1.tileSize, Game1.tileSize, Game1.tileSize).Contains(boundingBox)) + return; + switch (tile2.TileIndex) + { + case 0: + if (this.getDirection() == 3) + { + this.SetMovingOnlyUp(); + break; + } + if (this.getDirection() != 2) + break; + this.SetMovingOnlyRight(); + break; + case 1: + if (this.getDirection() == 3) + { + this.SetMovingOnlyDown(); + break; + } + if (this.getDirection() != 0) + break; + this.SetMovingOnlyRight(); + break; + case 2: + if (this.getDirection() == 1) + { + this.SetMovingOnlyDown(); + break; + } + if (this.getDirection() != 0) + break; + this.SetMovingOnlyLeft(); + break; + case 3: + if (this.getDirection() == 1) + { + this.SetMovingOnlyUp(); + break; + } + if (this.getDirection() != 2) + break; + this.SetMovingOnlyLeft(); + break; + case 4: + this.changeSchedulePathDirection(); + this.moveCharacterOnSchedulePath(); + break; + case 7: + this.ReachedEndPoint(); + break; + } + } + } + } + else + { + if (!this.IsWalkingInSquare) + return; + this.randomSquareMovement(time); + this.MovePosition(time, Game1.viewport, location); + } + } + + //ERROR NEED FIXING public override void MovePosition(GameTime time, xTile.Dimensions.Rectangle viewport, GameLocation currentLocation) { if (this.GetType() == typeof(FarmAnimal)) @@ -160,6 +758,626 @@ namespace CustomNPCFramework.Framework.NPCS } } + //ERROR NEED FIXING + public override void update(GameTime time, GameLocation location) + { + if (this.returningToEndPoint) + { + this.returnToEndPoint(); + this.MovePosition(time, Game1.viewport, location); + } + else if (this.temporaryController != null) + { + if (this.temporaryController.update(time)) + this.temporaryController = (PathFindController)null; + this.updateEmote(time); + } + else + base.update(time, location); + if (this.textAboveHeadTimer > 0) + { + if (this.textAboveHeadPreTimer > 0) + { + this.textAboveHeadPreTimer = this.textAboveHeadPreTimer - time.ElapsedGameTime.Milliseconds; + } + else + { + this.textAboveHeadTimer = this.textAboveHeadTimer - time.ElapsedGameTime.Milliseconds; + this.textAboveHeadAlpha = this.textAboveHeadTimer <= 500 ? Math.Max(0.0f, this.textAboveHeadAlpha - 0.04f) : Math.Min(1f, this.textAboveHeadAlpha + 0.1f); + } + } + if (this.isWalkingInSquare && !this.returningToEndPoint) + this.randomSquareMovement(time); + if (this.Sprite != null && this.Sprite.currentAnimation != null && (!Game1.eventUp && this.Sprite.animateOnce(time))) + this.Sprite.currentAnimation = (List)null; + TimeSpan timeSpan; + if (this.movementPause > 0 && (!Game1.dialogueUp || this.controller != null)) + { + this.freezeMotion = true; + int movementPause = this.movementPause; + timeSpan = time.ElapsedGameTime; + int milliseconds = timeSpan.Milliseconds; + this.movementPause = movementPause - milliseconds; + if (this.movementPause <= 0) + this.freezeMotion = false; + } + if (this.shakeTimer > 0) + { + int shakeTimer = this.shakeTimer; + timeSpan = time.ElapsedGameTime; + int milliseconds = timeSpan.Milliseconds; + this.shakeTimer = shakeTimer - milliseconds; + } + if (this.lastPosition.Equals(this.position)) + { + double sinceLastMovement = (double)this.timerSinceLastMovement; + timeSpan = time.ElapsedGameTime; + double milliseconds = (double)timeSpan.Milliseconds; + this.timerSinceLastMovement = (float)(sinceLastMovement + milliseconds); + } + else + this.timerSinceLastMovement = 0.0f; + if (!this.swimming) + return; + timeSpan = time.TotalGameTime; + this.yOffset = (float)Math.Cos(timeSpan.TotalMilliseconds / 2000.0) * (float)Game1.pixelZoom; + float swimTimer1 = this.swimTimer; + double swimTimer2 = (double)this.swimTimer; + timeSpan = time.ElapsedGameTime; + double milliseconds1 = (double)timeSpan.Milliseconds; + this.swimTimer = (float)(swimTimer2 - milliseconds1); + if ((double)this.timerSinceLastMovement == 0.0) + { + if ((double)swimTimer1 > 400.0 && (double)this.swimTimer <= 400.0 && location.Equals((object)Game1.currentLocation)) + { + location.temporarySprites.Add(new TemporaryAnimatedSprite(Game1.animations, new Microsoft.Xna.Framework.Rectangle(0, 0, Game1.tileSize, Game1.tileSize), (float)(150.0 - ((double)Math.Abs(this.xVelocity) + (double)Math.Abs(this.yVelocity)) * 3.0), 8, 0, new Vector2(this.position.X, (float)(this.getStandingY() - Game1.tileSize / 2)), false, Game1.random.NextDouble() < 0.5, 0.01f, 0.01f, Color.White, 1f, 3f / 1000f, 0.0f, 0.0f, false)); + Game1.playSound("slosh"); + } + if ((double)this.swimTimer >= 0.0) + return; + this.swimTimer = 800f; + if (!location.Equals((object)Game1.currentLocation)) + return; + Game1.playSound("slosh"); + location.temporarySprites.Add(new TemporaryAnimatedSprite(Game1.animations, new Microsoft.Xna.Framework.Rectangle(0, 0, Game1.tileSize, Game1.tileSize), (float)(150.0 - ((double)Math.Abs(this.xVelocity) + (double)Math.Abs(this.yVelocity)) * 3.0), 8, 0, new Vector2(this.position.X, (float)(this.getStandingY() - Game1.tileSize / 2)), false, Game1.random.NextDouble() < 0.5, 0.01f, 0.01f, Color.White, 1f, 3f / 1000f, 0.0f, 0.0f, false)); + } + else + { + if ((double)this.swimTimer >= 0.0) + return; + this.swimTimer = 100f; + } + } + + //ERROR NEED FIXING + public virtual void prepareToDisembarkOnNewSchedulePath() + { + while (this.CurrentDialogue.Count > 0 && this.CurrentDialogue.Peek().removeOnNextMove) + this.CurrentDialogue.Pop(); + this.nextEndOfRouteMessage = (string)null; + this.endOfRouteMessage = (string)null; + if (this.doingEndOfRouteAnimation) + { + List animation = new List(); + for (int index = 0; index < this.routeEndOutro.Length; ++index) + { + if (index == this.routeEndOutro.Length - 1) + animation.Add(new FarmerSprite.AnimationFrame(this.routeEndOutro[index], 100, 0, false, false, new AnimatedSprite.endOfAnimationBehavior(this.routeEndAnimationFinished), true, 0)); + else + animation.Add(new FarmerSprite.AnimationFrame(this.routeEndOutro[index], 100, 0, false, false, (AnimatedSprite.endOfAnimationBehavior)null, false, 0)); + } + if (animation.Count > 0) + this.sprite.setCurrentAnimation(animation); + else + this.routeEndAnimationFinished((Farmer)null); + if (this.endOfRouteBehaviorName != null) + this.finishRouteBehavior(this.endOfRouteBehaviorName); + } + else + this.routeEndAnimationFinished((Farmer)null); + if (!this.isMarried()) + return; + if (this.temporaryController == null && Utility.getGameLocationOfCharacter(this) is FarmHouse) + { + this.temporaryController = new PathFindController((Character)this, this.getHome(), new Point(this.getHome().warps[0].X, this.getHome().warps[0].Y), 2, true) + { + NPCSchedule = true + }; + if (this.temporaryController.pathToEndPoint == null || this.temporaryController.pathToEndPoint.Count <= 0) + { + this.temporaryController = (PathFindController)null; + this.schedule = (Dictionary)null; + } + else + this.followSchedule = true; + } + else + { + if (!(Utility.getGameLocationOfCharacter(this) is Farm)) + return; + this.temporaryController = (PathFindController)null; + this.schedule = (Dictionary)null; + } + } + + //ERROR NEED FIXING + public virtual void routeEndAnimationFinished(Farmer who) + { + this.doingEndOfRouteAnimation = false; + this.freezeMotion = false; + this.sprite.spriteHeight = 32; + this.sprite.StopAnimation(); + this.endOfRouteMessage = (string)null; + this.isCharging = false; + this.speed = 2; + this.addedSpeed = 0; + this.goingToDoEndOfRouteAnimation = false; + if (!this.isWalkingInSquare) + return; + this.returningToEndPoint = true; + this.timeAfterSquare = Game1.timeOfDay; + } + + ///ERROR NEED FIXING + public virtual void doAnimationAtEndOfScheduleRoute(Character c, GameLocation l) + { + List animation = new List(); + for (int index = 0; index < this.routeEndIntro.Length; ++index) + { + if (index == this.routeEndIntro.Length - 1) + animation.Add(new FarmerSprite.AnimationFrame(this.routeEndIntro[index], 100, 0, false, false, new AnimatedSprite.endOfAnimationBehavior(this.doMiddleAnimation), true, 0)); + else + animation.Add(new FarmerSprite.AnimationFrame(this.routeEndIntro[index], 100, 0, false, false, (AnimatedSprite.endOfAnimationBehavior)null, false, 0)); + } + this.doingEndOfRouteAnimation = true; + this.freezeMotion = true; + this.sprite.setCurrentAnimation(animation); + } + + ///ERROR NEED FIXING + public virtual void doMiddleAnimation(Farmer who) + { + List animation = new List(); + for (int index = 0; index < this.routeEndAnimation.Length; ++index) + animation.Add(new FarmerSprite.AnimationFrame(this.routeEndAnimation[index], 100, 0, false, false, (AnimatedSprite.endOfAnimationBehavior)null, false, 0)); + this.sprite.setCurrentAnimation(animation); + this.sprite.loop = true; + if (this.endOfRouteBehaviorName == null) + return; + this.startRouteBehavior(this.endOfRouteBehaviorName); + } + + //ERROR NEED FIXING + public virtual void startRouteBehavior(string behaviorName) + { + if (behaviorName.Length > 0 && (int)behaviorName[0] == 34) + { + this.endOfRouteMessage = behaviorName.Replace("\"", ""); + } + else + { + if (behaviorName.Contains("square_")) + { + this.lastCrossroad = new Microsoft.Xna.Framework.Rectangle(this.getTileX() * Game1.tileSize, this.getTileY() * Game1.tileSize, Game1.tileSize, Game1.tileSize); + string[] strArray = behaviorName.Split('_'); + this.walkInSquare(Convert.ToInt32(strArray[1]), Convert.ToInt32(strArray[2]), 6000); + this.squareMovementFacingPreference = strArray.Length <= 3 ? -1 : Convert.ToInt32(strArray[3]); + } + if (!(behaviorName == "abigail_videogames")) + { + if (!(behaviorName == "dick_fish")) + { + if (!(behaviorName == "clint_hammer")) + return; + this.extendSourceRect(16, 0, true); + this.sprite.spriteWidth = 32; + this.sprite.ignoreSourceRectUpdates = false; + this.sprite.CurrentFrame = 8; + this.sprite.currentAnimation[14] = new FarmerSprite.AnimationFrame(9, 100, 0, false, false, new AnimatedSprite.endOfAnimationBehavior(this.clintHammerSound), false, 0); + } + else + { + this.extendSourceRect(0, 32, true); + if (!Utility.isOnScreen(Utility.Vector2ToPoint(this.position), Game1.tileSize, this.currentLocation)) + return; + Game1.playSound("slosh"); + } + } + else + { + Utility.getGameLocationOfCharacter(this).temporarySprites.Add(new TemporaryAnimatedSprite(Game1.mouseCursors, new Microsoft.Xna.Framework.Rectangle(167, 1714, 19, 14), 100f, 3, 999999, new Vector2(2f, 3f) * (float)Game1.tileSize + new Vector2(7f, 12f) * (float)Game1.pixelZoom, false, false, 0.0002f, 0.0f, Color.White, (float)Game1.pixelZoom, 0.0f, 0.0f, 0.0f, false) + { + id = 688f + }); + this.doEmote(52, true); + } + } + } + + //ERROR NEED FIXING + public void finishRouteBehavior(string behaviorName) + { + if (!(behaviorName == "abigail_videogames")) + { + if (!(behaviorName == "clint_hammer") && !(behaviorName == "dick_fish")) + return; + this.reloadSprite(); + this.sprite.spriteWidth = 16; + this.sprite.spriteHeight = 32; + this.sprite.UpdateSourceRect(); + this.Halt(); + this.movementPause = 1; + } + else + Utility.getGameLocationOfCharacter(this).removeTemporarySpritesWithID(688); + } + //ERROR NEED FIXING + public virtual void getHitByPlayer(Farmer who, GameLocation location) + { + this.doEmote(12, true); + if (who == null) + { + if (Game1.IsMultiplayer) + return; + who = Game1.player; + } + if (who.friendships.ContainsKey(this.name)) + { + who.friendships[this.name][0] -= 30; + if (who.IsMainPlayer) + { + this.CurrentDialogue.Clear(); + this.CurrentDialogue.Push(new StardewValley.Dialogue(Game1.random.NextDouble() < 0.5 ? Game1.LoadStringByGender(this.gender, "Strings\\StringsFromCSFiles:NPC.cs.4293") : Game1.content.LoadString("Strings\\StringsFromCSFiles:NPC.cs.4294"), this)); + } + location.debris.Add(new Debris(this.sprite.Texture, Game1.random.Next(3, 8), new Vector2((float)this.GetBoundingBox().Center.X, (float)this.GetBoundingBox().Center.Y))); + } + if (this.name.Equals("Bouncer")) + Game1.playSound("crafting"); + else + Game1.playSound("hitEnemy"); + } + + //ERROR NEED FIXING + public override void dayUpdate(int dayOfMonth) + { + if (this.currentLocation != null) + Game1.warpCharacter(this, this.defaultMap, this.defaultPosition / (float)Game1.tileSize, true, false); + if (this.name.Equals("Maru") || this.name.Equals("Shane")) + this.sprite.Texture = Game1.content.Load("Characters\\" + this.name); + if (this.name.Equals("Willy") || this.name.Equals("Clint")) + { + this.sprite.spriteWidth = 16; + this.sprite.spriteHeight = 32; + this.sprite.ignoreSourceRectUpdates = false; + this.sprite.UpdateSourceRect(); + this.isInvisible = false; + } + Game1.player.mailReceived.Remove(this.name); + Game1.player.mailReceived.Remove(this.name + "Cooking"); + this.doingEndOfRouteAnimation = false; + this.Halt(); + this.hasBeenKissedToday = false; + this.faceTowardFarmer = false; + this.faceTowardFarmerTimer = 0; + this.drawOffset = Vector2.Zero; + this.hasSaidAfternoonDialogue = false; + this.ignoreScheduleToday = false; + this.Halt(); + this.controller = (PathFindController)null; + this.temporaryController = (PathFindController)null; + this.directionsToNewLocation = (SchedulePathDescription)null; + this.faceDirection(this.DefaultFacingDirection); + this.scheduleTimeToTry = 9999999; + this.previousEndPoint = new Point((int)this.defaultPosition.X / Game1.tileSize, (int)this.defaultPosition.Y / Game1.tileSize); + this.isWalkingInSquare = false; + this.returningToEndPoint = false; + this.lastCrossroad = Microsoft.Xna.Framework.Rectangle.Empty; + if (this.isVillager()) + this.Schedule = this.getSchedule(dayOfMonth); + this.endOfRouteMessage = (string)null; + bool flag = Utility.isFestivalDay(dayOfMonth, Game1.currentSeason); + if (this.name.Equals("Robin") && Game1.player.daysUntilHouseUpgrade > 0 && !flag) + { + this.ignoreMultiplayerUpdates = true; + Game1.warpCharacter(this, "Farm", new Vector2(68f, 14f), false, false); + this.sprite.setCurrentAnimation(new List() + { + new FarmerSprite.AnimationFrame(24, 75), + new FarmerSprite.AnimationFrame(25, 75), + new FarmerSprite.AnimationFrame(26, 300, false, false, new AnimatedSprite.endOfAnimationBehavior(this.robinHammerSound), false), + new FarmerSprite.AnimationFrame(27, 1000, false, false, new AnimatedSprite.endOfAnimationBehavior(this.robinVariablePause), false) + }); + this.ignoreScheduleToday = true; + this.CurrentDialogue.Clear(); + this.currentDialogue.Push(new StardewValley.Dialogue(Game1.player.daysUntilHouseUpgrade == 2 ? Game1.content.LoadString("Strings\\StringsFromCSFiles:NPC.cs.3926") : Game1.content.LoadString("Strings\\StringsFromCSFiles:NPC.cs.3927"), this)); + } + else if (this.name.Equals("Robin") && Game1.getFarm().isThereABuildingUnderConstruction() && !flag) + { + Building underConstruction = Game1.getFarm().getBuildingUnderConstruction(); + if (underConstruction.daysUntilUpgrade > 0) + { + if (!underConstruction.indoors.characters.Contains(this)) + underConstruction.indoors.addCharacter(this); + if (this.currentLocation != null) + this.currentLocation.characters.Remove(this); + this.currentLocation = underConstruction.indoors; + this.setTilePosition(1, 5); + } + else + { + Game1.warpCharacter(this, "Farm", new Vector2((float)(underConstruction.tileX + underConstruction.tilesWide / 2), (float)(underConstruction.tileY + underConstruction.tilesHigh / 2)), false, false); + this.position.X += (float)(Game1.tileSize / 4); + this.position.Y -= (float)(Game1.tileSize / 2); + } + this.ignoreMultiplayerUpdates = true; + this.sprite.setCurrentAnimation(new List() + { + new FarmerSprite.AnimationFrame(24, 75), + new FarmerSprite.AnimationFrame(25, 75), + new FarmerSprite.AnimationFrame(26, 300, false, false, new AnimatedSprite.endOfAnimationBehavior(this.robinHammerSound), false), + new FarmerSprite.AnimationFrame(27, 1000, false, false, new AnimatedSprite.endOfAnimationBehavior(this.robinVariablePause), false) + }); + this.ignoreScheduleToday = true; + this.CurrentDialogue.Clear(); + this.currentDialogue.Push(new StardewValley.Dialogue(Game1.content.LoadString("Strings\\StringsFromCSFiles:NPC.cs.3926"), this)); + } + if (!this.isMarried()) + return; + this.marriageDuties(); + this.daysMarried = this.daysMarried + 1; + } + + //ERROR NEED FIXING + public virtual void setUpForOutdoorPatioActivity() + { + Game1.warpCharacter(this, "Farm", new Vector2(71f, 10f), false, false); + this.setNewDialogue("MarriageDialogue", "patio_", -1, false, true); + string name = this.name; + // ISSUE: reference to a compiler-generated method + uint stringHash = \u003CPrivateImplementationDetails\u003E.ComputeStringHash(name); + if (stringHash <= 1866496948U) + { + if (stringHash <= 1067922812U) + { + if ((int)stringHash != 161540545) + { + if ((int)stringHash != 587846041) + { + if ((int)stringHash != 1067922812 || !(name == "Sam")) + return; + this.setTilePosition(71, 8); + this.sprite.setCurrentAnimation(new List() + { + new FarmerSprite.AnimationFrame(25, 3000), + new FarmerSprite.AnimationFrame(27, 500), + new FarmerSprite.AnimationFrame(26, 100), + new FarmerSprite.AnimationFrame(28, 100), + new FarmerSprite.AnimationFrame(27, 500), + new FarmerSprite.AnimationFrame(25, 2000), + new FarmerSprite.AnimationFrame(27, 500), + new FarmerSprite.AnimationFrame(26, 100), + new FarmerSprite.AnimationFrame(29, 100), + new FarmerSprite.AnimationFrame(30, 100), + new FarmerSprite.AnimationFrame(32, 500), + new FarmerSprite.AnimationFrame(31, 1000), + new FarmerSprite.AnimationFrame(30, 100), + new FarmerSprite.AnimationFrame(29, 100) + }); + } + else + { + if (!(name == "Penny")) + return; + this.setTilePosition(71, 8); + this.sprite.setCurrentAnimation(new List() + { + new FarmerSprite.AnimationFrame(18, 6000), + new FarmerSprite.AnimationFrame(19, 500) + }); + } + } + else + { + if (!(name == "Sebastian")) + return; + this.setTilePosition(71, 9); + this.drawOffset = new Vector2((float)(Game1.tileSize / 4), (float)(Game1.tileSize / 2 + Game1.pixelZoom * 2)); + this.sprite.setCurrentAnimation(new List() + { + new FarmerSprite.AnimationFrame(32, 500, Game1.tileSize, false, false, (AnimatedSprite.endOfAnimationBehavior) null, false, 0), + new FarmerSprite.AnimationFrame(36, 500, Game1.tileSize, false, false, (AnimatedSprite.endOfAnimationBehavior) null, false, 0), + new FarmerSprite.AnimationFrame(32, 500, Game1.tileSize, false, false, (AnimatedSprite.endOfAnimationBehavior) null, false, 0), + new FarmerSprite.AnimationFrame(36, 500, Game1.tileSize, false, false, (AnimatedSprite.endOfAnimationBehavior) null, false, 0), + new FarmerSprite.AnimationFrame(32, 500, Game1.tileSize, false, false, (AnimatedSprite.endOfAnimationBehavior) null, false, 0), + new FarmerSprite.AnimationFrame(36, 500, Game1.tileSize, false, false, (AnimatedSprite.endOfAnimationBehavior) null, false, 0), + new FarmerSprite.AnimationFrame(32, 500, Game1.tileSize, false, false, (AnimatedSprite.endOfAnimationBehavior) null, false, 0), + new FarmerSprite.AnimationFrame(36, 2000, Game1.tileSize, false, false, (AnimatedSprite.endOfAnimationBehavior) null, false, 0), + new FarmerSprite.AnimationFrame(33, 100, Game1.tileSize, false, false, (AnimatedSprite.endOfAnimationBehavior) null, false, 0), + new FarmerSprite.AnimationFrame(34, 100, Game1.tileSize, false, false, (AnimatedSprite.endOfAnimationBehavior) null, false, 0), + new FarmerSprite.AnimationFrame(35, 3000, Game1.tileSize, false, false, (AnimatedSprite.endOfAnimationBehavior) null, false, 0), + new FarmerSprite.AnimationFrame(34, 100, Game1.tileSize, false, false, (AnimatedSprite.endOfAnimationBehavior) null, false, 0), + new FarmerSprite.AnimationFrame(33, 100, Game1.tileSize, false, false, (AnimatedSprite.endOfAnimationBehavior) null, false, 0), + new FarmerSprite.AnimationFrame(32, 1500, Game1.tileSize, false, false, (AnimatedSprite.endOfAnimationBehavior) null, false, 0) + }); + } + } + else if ((int)stringHash != 1281010426) + { + if ((int)stringHash != 1708213605) + { + if ((int)stringHash != 1866496948 || !(name == "Shane")) + return; + this.setTilePosition(69, 9); + this.sprite.setCurrentAnimation(new List() + { + new FarmerSprite.AnimationFrame(28, 4000, Game1.tileSize, false, false, (AnimatedSprite.endOfAnimationBehavior) null, false, 0), + new FarmerSprite.AnimationFrame(29, 800, Game1.tileSize, false, false, (AnimatedSprite.endOfAnimationBehavior) null, false, 0) + }); + } + else + { + if (!(name == "Alex")) + return; + this.setTilePosition(71, 8); + this.sprite.setCurrentAnimation(new List() + { + new FarmerSprite.AnimationFrame(34, 4000), + new FarmerSprite.AnimationFrame(33, 300), + new FarmerSprite.AnimationFrame(28, 200), + new FarmerSprite.AnimationFrame(29, 100), + new FarmerSprite.AnimationFrame(30, 100), + new FarmerSprite.AnimationFrame(31, 100), + new FarmerSprite.AnimationFrame(32, 100), + new FarmerSprite.AnimationFrame(31, 100), + new FarmerSprite.AnimationFrame(30, 100), + new FarmerSprite.AnimationFrame(29, 100), + new FarmerSprite.AnimationFrame(28, 800), + new FarmerSprite.AnimationFrame(29, 100), + new FarmerSprite.AnimationFrame(30, 100), + new FarmerSprite.AnimationFrame(31, 100), + new FarmerSprite.AnimationFrame(32, 100), + new FarmerSprite.AnimationFrame(31, 100), + new FarmerSprite.AnimationFrame(30, 100), + new FarmerSprite.AnimationFrame(29, 100), + new FarmerSprite.AnimationFrame(28, 800), + new FarmerSprite.AnimationFrame(33, 200) + }); + } + } + else + { + if (!(name == "Maru")) + return; + this.setTilePosition(70, 8); + this.sprite.setCurrentAnimation(new List() + { + new FarmerSprite.AnimationFrame(16, 4000), + new FarmerSprite.AnimationFrame(17, 200), + new FarmerSprite.AnimationFrame(18, 200), + new FarmerSprite.AnimationFrame(19, 200), + new FarmerSprite.AnimationFrame(20, 200), + new FarmerSprite.AnimationFrame(21, 200), + new FarmerSprite.AnimationFrame(22, 200), + new FarmerSprite.AnimationFrame(23, 200) + }); + } + } + else if (stringHash <= 2571828641U) + { + if ((int)stringHash != 2010304804) + { + if ((int)stringHash != -1860673204) + { + if ((int)stringHash != -1723138655 || !(name == "Emily")) + return; + this.setTilePosition(70, 9); + this.sprite.setCurrentAnimation(new List() + { + new FarmerSprite.AnimationFrame(54, 4000, Game1.tileSize, false, false, (AnimatedSprite.endOfAnimationBehavior) null, false, 0) + }); + } + else + { + if (!(name == "Haley")) + return; + this.setTilePosition(70, 8); + this.sprite.setCurrentAnimation(new List() + { + new FarmerSprite.AnimationFrame(30, 2000), + new FarmerSprite.AnimationFrame(31, 200), + new FarmerSprite.AnimationFrame(24, 2000), + new FarmerSprite.AnimationFrame(25, 1000), + new FarmerSprite.AnimationFrame(32, 200), + new FarmerSprite.AnimationFrame(33, 2000), + new FarmerSprite.AnimationFrame(32, 200), + new FarmerSprite.AnimationFrame(25, 2000), + new FarmerSprite.AnimationFrame(32, 200), + new FarmerSprite.AnimationFrame(33, 2000) + }); + } + } + else + { + if (!(name == "Harvey")) + return; + this.setTilePosition(71, 8); + this.sprite.setCurrentAnimation(new List() + { + new FarmerSprite.AnimationFrame(42, 6000), + new FarmerSprite.AnimationFrame(43, 1000), + new FarmerSprite.AnimationFrame(39, 100), + new FarmerSprite.AnimationFrame(43, 500), + new FarmerSprite.AnimationFrame(39, 100), + new FarmerSprite.AnimationFrame(43, 1000), + new FarmerSprite.AnimationFrame(42, 5000), + new FarmerSprite.AnimationFrame(43, 3000) + }); + } + } + else if ((int)stringHash != -1562053956) + { + if ((int)stringHash != -1468719973) + { + if ((int)stringHash != -1228790996 || !(name == "Elliott")) + return; + this.setTilePosition(71, 8); + this.sprite.setCurrentAnimation(new List() + { + new FarmerSprite.AnimationFrame(33, 3000), + new FarmerSprite.AnimationFrame(32, 500), + new FarmerSprite.AnimationFrame(33, 3000), + new FarmerSprite.AnimationFrame(32, 500), + new FarmerSprite.AnimationFrame(33, 2000), + new FarmerSprite.AnimationFrame(34, 1500) + }); + } + else + { + if (!(name == "Leah")) + return; + this.setTilePosition(71, 8); + this.sprite.setCurrentAnimation(new List() + { + new FarmerSprite.AnimationFrame(16, 100), + new FarmerSprite.AnimationFrame(17, 100), + new FarmerSprite.AnimationFrame(18, 100), + new FarmerSprite.AnimationFrame(19, 300), + new FarmerSprite.AnimationFrame(16, 100), + new FarmerSprite.AnimationFrame(17, 100), + new FarmerSprite.AnimationFrame(18, 100), + new FarmerSprite.AnimationFrame(19, 1000), + new FarmerSprite.AnimationFrame(16, 100), + new FarmerSprite.AnimationFrame(17, 100), + new FarmerSprite.AnimationFrame(18, 100), + new FarmerSprite.AnimationFrame(19, 300), + new FarmerSprite.AnimationFrame(16, 100), + new FarmerSprite.AnimationFrame(17, 100), + new FarmerSprite.AnimationFrame(18, 100), + new FarmerSprite.AnimationFrame(19, 300), + new FarmerSprite.AnimationFrame(16, 100), + new FarmerSprite.AnimationFrame(17, 100), + new FarmerSprite.AnimationFrame(18, 100), + new FarmerSprite.AnimationFrame(19, 2000) + }); + } + } + else + { + if (!(name == "Abigail")) + return; + this.setTilePosition(71, 8); + this.sprite.setCurrentAnimation(new List() + { + new FarmerSprite.AnimationFrame(16, 500), + new FarmerSprite.AnimationFrame(17, 500), + new FarmerSprite.AnimationFrame(18, 500), + new FarmerSprite.AnimationFrame(19, 500) + }); + } + } + + + //ERROR NEED FIXING!!!!!!!!!!!!!!!!!! /// /// Used to draw the npc with the custom renderer. /// @@ -167,7 +1385,7 @@ namespace CustomNPCFramework.Framework.NPCS /// public override void draw(SpriteBatch b, float alpha = 1f) { - if (this.sprite == null || this.isInvisible || !Utility.isOnScreen(this.position, 2 * Game1.tileSize)) + if (this.characterRenderer == null || this.isInvisible || !Utility.isOnScreen(this.position, 2 * Game1.tileSize)) return; //Checks if the npc is swimming. If not draw it's default graphic. Do characters aside from Farmer and Penny Swim??? if (this.swimming) @@ -218,133 +1436,5 @@ namespace CustomNPCFramework.Framework.NPCS localPosition1.Y -= (float)(Game1.tileSize / 2 + this.sprite.spriteHeight * Game1.pixelZoom); b.Draw(Game1.emoteSpriteSheet, localPosition1, new Microsoft.Xna.Framework.Rectangle?(new Microsoft.Xna.Framework.Rectangle(this.CurrentEmoteIndex * 16 % Game1.emoteSpriteSheet.Width, this.CurrentEmoteIndex * 16 / Game1.emoteSpriteSheet.Width * 16, 16, 16)), Color.White, 0.0f, Vector2.Zero, (float)Game1.pixelZoom, SpriteEffects.None, (float)this.getStandingY() / 10000f); } - - - public override void updateMovement(GameLocation location, GameTime time) - { - this.lastPosition = this.position; - if (this.DirectionsToNewLocation != null && !Game1.newDay) - { - if (this.getStandingX() < -Game1.tileSize || this.getStandingX() > location.map.DisplayWidth + Game1.tileSize || (this.getStandingY() < -Game1.tileSize || this.getStandingY() > location.map.DisplayHeight + Game1.tileSize)) - { - this.IsWalkingInSquare = false; - Game1.warpCharacter(this, this.DefaultMap, this.DefaultPosition, true, true); - location.characters.Remove(this); - } - else if (this.IsWalkingInSquare) - { - this.returnToEndPoint(); - this.MovePosition(time, Game1.viewport, location); - } - else - { - if (!this.followSchedule) - return; - this.MovePosition(time, Game1.viewport, location); - Warp warp = location.isCollidingWithWarp(this.GetBoundingBox()); - PropertyValue propertyValue = (PropertyValue)null; - Tile tile1 = location.map.GetLayer("Buildings").PickTile(this.nextPositionPoint(), Game1.viewport.Size); - if (tile1 != null) - tile1.Properties.TryGetValue("Action", out propertyValue); - string[] strArray1; - if (propertyValue != null) - strArray1 = propertyValue.ToString().Split(' '); - else - strArray1 = (string[])null; - string[] strArray2 = strArray1; - if (warp != null) - { - if (location is BusStop && warp.TargetName.Equals("Farm")) - { - Point entryLocation = ((this.isMarried() ? (GameLocation)(this.getHome() as FarmHouse) : Game1.getLocationFromName("FarmHouse")) as FarmHouse).getEntryLocation(); - warp = new Warp(warp.X, warp.Y, "FarmHouse", entryLocation.X, entryLocation.Y, false); - } - else if (location is FarmHouse && warp.TargetName.Equals("Farm")) - warp = new Warp(warp.X, warp.Y, "BusStop", 0, 23, false); - Game1.warpCharacter(this, warp.TargetName, new Vector2((float)(warp.TargetX * Game1.tileSize), (float)(warp.TargetY * Game1.tileSize - this.Sprite.getHeight() / 2 - Game1.tileSize / 4)), false, location.IsOutdoors); - location.characters.Remove(this); - } - else if (strArray2 != null && strArray2.Length >= 1 && strArray2[0].Contains("Warp")) - { - Game1.warpCharacter(this, strArray2[3], new Vector2((float)Convert.ToInt32(strArray2[1]), (float)Convert.ToInt32(strArray2[2])), false, location.IsOutdoors); - if (Game1.currentLocation.name.Equals(location.name) && Utility.isOnScreen(this.getStandingPosition(), Game1.tileSize * 3)) - Game1.playSound("doorClose"); - location.characters.Remove(this); - } - else if (strArray2 != null && strArray2.Length >= 1 && strArray2[0].Contains("Door")) - { - location.openDoor(new Location(this.nextPositionPoint().X / Game1.tileSize, this.nextPositionPoint().Y / Game1.tileSize), Game1.player.currentLocation.Equals((object)location)); - } - else - { - if (location.map.GetLayer("Paths") == null) - return; - Tile tile2 = location.map.GetLayer("Paths").PickTile(new Location(this.getStandingX(), this.getStandingY()), Game1.viewport.Size); - Microsoft.Xna.Framework.Rectangle boundingBox = this.GetBoundingBox(); - boundingBox.Inflate(2, 2); - if (tile2 == null || !new Microsoft.Xna.Framework.Rectangle(this.getStandingX() - this.getStandingX() % Game1.tileSize, this.getStandingY() - this.getStandingY() % Game1.tileSize, Game1.tileSize, Game1.tileSize).Contains(boundingBox)) - return; - switch (tile2.TileIndex) - { - case 0: - if (this.getDirection() == 3) - { - this.SetMovingOnlyUp(); - break; - } - if (this.getDirection() != 2) - break; - this.SetMovingOnlyRight(); - break; - case 1: - if (this.getDirection() == 3) - { - this.SetMovingOnlyDown(); - break; - } - if (this.getDirection() != 0) - break; - this.SetMovingOnlyRight(); - break; - case 2: - if (this.getDirection() == 1) - { - this.SetMovingOnlyDown(); - break; - } - if (this.getDirection() != 0) - break; - this.SetMovingOnlyLeft(); - break; - case 3: - if (this.getDirection() == 1) - { - this.SetMovingOnlyUp(); - break; - } - if (this.getDirection() != 2) - break; - this.SetMovingOnlyLeft(); - break; - case 4: - this.changeSchedulePathDirection(); - this.moveCharacterOnSchedulePath(); - break; - case 7: - this.ReachedEndPoint(); - break; - } - } - } - } - else - { - if (!this.IsWalkingInSquare) - return; - this.randomSquareMovement(time); - this.MovePosition(time, Game1.viewport, location); - } - } - } } From fd9f5d97030ce0b2d4474fe7b26f5c8dfb4896e4 Mon Sep 17 00:00:00 2001 From: Date: Sat, 24 Feb 2018 01:04:35 -0800 Subject: [PATCH 15/18] I think the integration is finished for the custom npc renderer. Who knows though. --- .../ModularNPCS/AnimatedSpriteCollection.cs | 38 +- .../ModularNPCS/AnimatedSpriteExtended.cs | 39 + .../CharacterAnimationBase.cs | 94 ++ .../StandardCharacterAnimation.cs} | 32 +- .../ModularRenderers/BasicRenderer.cs | 19 +- .../Framework/ModularNPCS/Portrait.cs | 43 + .../Framework/ModularNPCS/Sprite.cs | 44 + .../Framework/NPCS/ExtendedNPC.cs | 1059 ++--------------- 8 files changed, 404 insertions(+), 964 deletions(-) create mode 100644 GeneralMods/CustomNPCFramework/Framework/ModularNPCS/AnimatedSpriteExtended.cs create mode 100644 GeneralMods/CustomNPCFramework/Framework/ModularNPCS/CharacterAnimationBases/CharacterAnimationBase.cs rename GeneralMods/CustomNPCFramework/Framework/ModularNPCS/{CharacterAnimation.cs => CharacterAnimationBases/StandardCharacterAnimation.cs} (83%) create mode 100644 GeneralMods/CustomNPCFramework/Framework/ModularNPCS/Portrait.cs create mode 100644 GeneralMods/CustomNPCFramework/Framework/ModularNPCS/Sprite.cs diff --git a/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/AnimatedSpriteCollection.cs b/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/AnimatedSpriteCollection.cs index 625dc23c..711eb092 100644 --- a/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/AnimatedSpriteCollection.cs +++ b/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/AnimatedSpriteCollection.cs @@ -12,12 +12,12 @@ namespace CustomNPCFramework.Framework.ModularNPCS { public class AnimatedSpriteCollection { - AnimatedSprite leftSprite; - AnimatedSprite rightSprite; - AnimatedSprite upSprite; - AnimatedSprite downSprite; + AnimatedSpriteExtended leftSprite; + AnimatedSpriteExtended rightSprite; + AnimatedSpriteExtended upSprite; + AnimatedSpriteExtended downSprite; - public AnimatedSprite currentSprite; + public AnimatedSpriteExtended currentSprite; /// /// Constructor. @@ -27,7 +27,7 @@ namespace CustomNPCFramework.Framework.ModularNPCS /// Up animated sprite for this piece. /// Down animated sprite for this piece. /// - public AnimatedSpriteCollection(AnimatedSprite LeftSprite,AnimatedSprite RightSprite,AnimatedSprite UpSprite,AnimatedSprite DownSprite,Direction startingSpriteDirection) + public AnimatedSpriteCollection(AnimatedSpriteExtended LeftSprite,AnimatedSpriteExtended RightSprite,AnimatedSpriteExtended UpSprite,AnimatedSpriteExtended DownSprite,Direction startingSpriteDirection) { this.leftSprite = LeftSprite; this.rightSprite = RightSprite; @@ -51,6 +51,14 @@ namespace CustomNPCFramework.Framework.ModularNPCS } } + public virtual void reload() + { + this.leftSprite.reload(); + this.rightSprite.reload(); + this.upSprite.reload(); + this.downSprite.reload(); + } + /// /// Sets the current /// @@ -82,7 +90,7 @@ namespace CustomNPCFramework.Framework.ModularNPCS /// public void draw(SpriteBatch b, Vector2 screenPosition, float layerDepth) { - b.Draw(this.currentSprite.Texture, screenPosition, new Rectangle?(this.currentSprite.sourceRect), Color.White, 0.0f, Vector2.Zero, (float)Game1.pixelZoom, this.currentSprite.currentAnimation == null || !this.currentSprite.currentAnimation[this.currentSprite.currentAnimationIndex].flip ? SpriteEffects.None : SpriteEffects.FlipHorizontally, layerDepth); + b.Draw(this.currentSprite.sprite.Texture, screenPosition, new Rectangle?(this.currentSprite.sprite.sourceRect), Color.White, 0.0f, Vector2.Zero, (float)Game1.pixelZoom, this.currentSprite.sprite.currentAnimation == null || !this.currentSprite.sprite.currentAnimation[this.currentSprite.sprite.currentAnimationIndex].flip ? SpriteEffects.None : SpriteEffects.FlipHorizontally, layerDepth); } /// @@ -100,7 +108,7 @@ namespace CustomNPCFramework.Framework.ModularNPCS /// public void draw(SpriteBatch b, Vector2 screenPosition, float layerDepth, int xOffset, int yOffset, Color c, bool flip = false, float scale = 1f, float rotation = 0.0f, bool characterSourceRectOffset = false) { - b.Draw(this.currentSprite.Texture, screenPosition, new Rectangle?(new Rectangle(this.currentSprite.sourceRect.X + xOffset, this.currentSprite.sourceRect.Y + yOffset, this.currentSprite.sourceRect.Width, this.currentSprite.sourceRect.Height)), c, rotation, characterSourceRectOffset ? new Vector2((float)(this.currentSprite.spriteWidth / 2), (float)((double)this.currentSprite.spriteHeight * 3.0 / 4.0)) : Vector2.Zero, scale, flip || this.currentSprite.currentAnimation != null && this.currentSprite.currentAnimation[this.currentSprite.currentAnimationIndex].flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, layerDepth); + b.Draw(this.currentSprite.sprite.Texture, screenPosition, new Rectangle?(new Rectangle(this.currentSprite.sprite.sourceRect.X + xOffset, this.currentSprite.sprite.sourceRect.Y + yOffset, this.currentSprite.sprite.sourceRect.Width, this.currentSprite.sprite.sourceRect.Height)), c, rotation, characterSourceRectOffset ? new Vector2((float)(this.currentSprite.sprite.spriteWidth / 2), (float)((double)this.currentSprite.sprite.spriteHeight * 3.0 / 4.0)) : Vector2.Zero, scale, flip || this.currentSprite.sprite.currentAnimation != null && this.currentSprite.sprite.currentAnimation[this.currentSprite.sprite.currentAnimationIndex].flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, layerDepth); } /// @@ -118,17 +126,27 @@ namespace CustomNPCFramework.Framework.ModularNPCS /// public void draw(SpriteBatch b, ExtendedNPC npc, Vector2 position, Rectangle sourceRectangle,Color color, float alpha,Vector2 origin,float scale,SpriteEffects effects,float layerDepth) { - b.Draw(this.currentSprite.Texture,position,sourceRectangle, color* alpha, npc.rotation, origin,scale,effects,layerDepth); + b.Draw(this.currentSprite.sprite.Texture,position,sourceRectangle, color* alpha, npc.rotation, origin,scale,effects,layerDepth); //b.Draw(this.Sprite.Texture, npc.getLocalPosition(Game1.viewport) + new Vector2((float)(this.sprite.spriteWidth * Game1.pixelZoom / 2), (float)(this.GetBoundingBox().Height / 2)) + (this.shakeTimer > 0 ? new Vector2((float)Game1.random.Next(-1, 2), (float)Game1.random.Next(-1, 2)) : Vector2.Zero), new Microsoft.Xna.Framework.Rectangle?(this.Sprite.SourceRect), Color.White * alpha, this.rotation, new Vector2((float)(this.sprite.spriteWidth / 2), (float)((double)this.sprite.spriteHeight * 3.0 / 4.0)), Math.Max(0.2f, this.scale) * (float)Game1.pixelZoom, this.flip || this.sprite.currentAnimation != null && this.sprite.currentAnimation[this.sprite.currentAnimationIndex].flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, Math.Max(0.0f, this.drawOnTop ? 0.991f : (float)this.getStandingY() / 10000f)); } + /// /// Animate the current sprite. Theoreticlly works from index offset to how many frames /// /// public void Animate(float intervalFromCharacter) { - this.currentSprite.Animate(Game1.currentGameTime, 0, 3, intervalFromCharacter); + this.currentSprite.sprite.Animate(Game1.currentGameTime, 0,3, intervalFromCharacter); + } + + /// + /// Animate the current sprite. Theoreticlly works from index offset to how many frames + /// + /// + public void Animate(float intervalFromCharacter,int startFrame,int endFrame) + { + this.currentSprite.sprite.Animate(Game1.currentGameTime, startFrame, endFrame, intervalFromCharacter); } } } diff --git a/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/AnimatedSpriteExtended.cs b/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/AnimatedSpriteExtended.cs new file mode 100644 index 00000000..037b3679 --- /dev/null +++ b/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/AnimatedSpriteExtended.cs @@ -0,0 +1,39 @@ +using Microsoft.Xna.Framework.Graphics; +using StardewValley; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CustomNPCFramework.Framework.ModularNPCS +{ + public class AnimatedSpriteExtended + { + public AnimatedSprite sprite; + public string path; + + + + /// + /// Constructor. + /// + /// Full path to asset. + /// Starting animation frame. + /// Sprite width. + /// Sprite height + public AnimatedSpriteExtended(string path,int currentFrame,int spriteWidth, int spriteHeight) + { + this.path = Class1.getRelativeDirectory(path); + this.sprite=new AnimatedSprite(Class1.ModHelper.Content.Load(this.path),currentFrame,spriteWidth,spriteHeight); + } + + /// + /// Reloads the asset from disk. + /// + public void reload() + { + this.sprite.Texture = Class1.ModHelper.Content.Load(this.path); + } + } +} diff --git a/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/CharacterAnimationBases/CharacterAnimationBase.cs b/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/CharacterAnimationBases/CharacterAnimationBase.cs new file mode 100644 index 00000000..f68f8edb --- /dev/null +++ b/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/CharacterAnimationBases/CharacterAnimationBase.cs @@ -0,0 +1,94 @@ +using CustomNPCFramework.Framework.NPCS; +using Microsoft.Xna.Framework; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CustomNPCFramework.Framework.ModularNPCS +{ + public class CharacterAnimationBase + { + + public CharacterAnimationBase() + { + } + + public virtual void setLeft() + { + } + public virtual void setRight() + { + + } + public virtual void setUp() + { + + } + public virtual void setDown() + { + + } + + public virtual void reload() + { + } + + public virtual void Animate(float animationInterval) + { + + } + + /// + /// Used to draw the sprite to the screen. + /// + /// + /// + /// + public virtual void draw(SpriteBatch b, Vector2 screenPosition, float layerDepth) + { + + } + + + + /// + /// Used to draw the sprite to the screen. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public virtual void draw(SpriteBatch b, Vector2 screenPosition, float layerDepth, int xOffset, int yOffset, Color c, bool flip = false, float scale = 1f, float rotation = 0.0f, bool characterSourceRectOffset = false) + { + + } + + /// + /// A very verbose asset drawer. + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + /// + public virtual void draw(SpriteBatch b, ExtendedNPC npc, Vector2 position, Rectangle sourceRectangle, Color color, float alpha, Vector2 origin, float scale, SpriteEffects effects, float layerDepth) + { + + } + + } +} diff --git a/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/CharacterAnimation.cs b/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/CharacterAnimationBases/StandardCharacterAnimation.cs similarity index 83% rename from GeneralMods/CustomNPCFramework/Framework/ModularNPCS/CharacterAnimation.cs rename to GeneralMods/CustomNPCFramework/Framework/ModularNPCS/CharacterAnimationBases/StandardCharacterAnimation.cs index 1eeb06b3..54fb854a 100644 --- a/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/CharacterAnimation.cs +++ b/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/CharacterAnimationBases/StandardCharacterAnimation.cs @@ -7,9 +7,9 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace CustomNPCFramework.Framework.ModularNPCS +namespace CustomNPCFramework.Framework.ModularNPCS.CharacterAnimationBases { - public class CharacterAnimation + public class StandardCharacterAnimation :CharacterAnimationBase { public AnimatedSpriteCollection hair; public AnimatedSpriteCollection body; @@ -19,7 +19,7 @@ namespace CustomNPCFramework.Framework.ModularNPCS public AnimatedSpriteCollection shoes; public List accessories; - public CharacterAnimation(AnimatedSpriteCollection bodyAnimation, AnimatedSpriteCollection eyeAnimation, AnimatedSpriteCollection hairAnimation, AnimatedSpriteCollection shirtAnimation, AnimatedSpriteCollection pantsAnimation, AnimatedSpriteCollection shoesAnimation,List accessoriesWithAnimations) + public StandardCharacterAnimation(AnimatedSpriteCollection bodyAnimation, AnimatedSpriteCollection eyeAnimation, AnimatedSpriteCollection hairAnimation, AnimatedSpriteCollection shirtAnimation, AnimatedSpriteCollection pantsAnimation, AnimatedSpriteCollection shoesAnimation,List accessoriesWithAnimations) :base() { this.body = bodyAnimation; this.hair = hairAnimation; @@ -30,7 +30,7 @@ namespace CustomNPCFramework.Framework.ModularNPCS this.accessories = accessoriesWithAnimations; } - public void setLeft() + public override void setLeft() { this.body.setLeft(); this.hair.setLeft(); @@ -44,7 +44,7 @@ namespace CustomNPCFramework.Framework.ModularNPCS accessory.setLeft(); } } - public void setRight() + public override void setRight() { this.body.setRight(); this.hair.setRight(); @@ -58,7 +58,7 @@ namespace CustomNPCFramework.Framework.ModularNPCS accessory.setRight(); } } - public void setUp() + public override void setUp() { this.body.setUp(); this.hair.setUp(); @@ -72,7 +72,7 @@ namespace CustomNPCFramework.Framework.ModularNPCS accessory.setUp(); } } - public void setDown() + public override void setDown() { this.body.setDown(); this.hair.setDown(); @@ -87,7 +87,17 @@ namespace CustomNPCFramework.Framework.ModularNPCS } } - public void Animate(float animationInterval) + public override void reload() + { + this.body.reload(); + this.hair.reload(); + this.eyes.reload(); + this.shirt.reload(); + this.pants.reload(); + this.shoes.reload(); + } + + public override void Animate(float animationInterval) { this.body.Animate(animationInterval); this.hair.Animate(animationInterval); @@ -108,7 +118,7 @@ namespace CustomNPCFramework.Framework.ModularNPCS /// /// /// - public void draw(SpriteBatch b, Vector2 screenPosition, float layerDepth) + public override void draw(SpriteBatch b, Vector2 screenPosition, float layerDepth) { this.body.draw(b,screenPosition,layerDepth); this.hair.draw(b, screenPosition, layerDepth); @@ -138,7 +148,7 @@ namespace CustomNPCFramework.Framework.ModularNPCS /// /// /// - public void draw(SpriteBatch b, Vector2 screenPosition, float layerDepth, int xOffset, int yOffset, Color c, bool flip = false, float scale = 1f, float rotation = 0.0f, bool characterSourceRectOffset = false) + public override void draw(SpriteBatch b, Vector2 screenPosition, float layerDepth, int xOffset, int yOffset, Color c, bool flip = false, float scale = 1f, float rotation = 0.0f, bool characterSourceRectOffset = false) { // b.Draw(this.currentSprite.Texture, screenPosition, new Rectangle?(new Rectangle(this.currentSprite.sourceRect.X + xOffset, this.currentSprite.sourceRect.Y + yOffset, this.currentSprite.sourceRect.Width, this.currentSprite.sourceRect.Height)), c, rotation, characterSourceRectOffset ? new Vector2((float)(this.currentSprite.spriteWidth / 2), (float)((double)this.currentSprite.spriteHeight * 3.0 / 4.0)) : Vector2.Zero, scale, flip || this.currentSprite.currentAnimation != null && this.currentSprite.currentAnimation[this.currentSprite.currentAnimationIndex].flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, layerDepth); this.body.draw(b, screenPosition, layerDepth, xOffset, yOffset, c, flip, scale, rotation, characterSourceRectOffset); @@ -166,7 +176,7 @@ namespace CustomNPCFramework.Framework.ModularNPCS /// /// /// - public void draw(SpriteBatch b, ExtendedNPC npc, Vector2 position, Rectangle sourceRectangle, Color color, float alpha, Vector2 origin, float scale, SpriteEffects effects, float layerDepth) + public override void draw(SpriteBatch b, ExtendedNPC npc, Vector2 position, Rectangle sourceRectangle, Color color, float alpha, Vector2 origin, float scale, SpriteEffects effects, float layerDepth) { this.body.draw(b, npc, position, sourceRectangle, color, alpha, origin, scale, effects, layerDepth); this.hair.draw(b, npc, position, sourceRectangle, color, alpha, origin, scale, effects, layerDepth); diff --git a/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/ModularRenderers/BasicRenderer.cs b/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/ModularRenderers/BasicRenderer.cs index 46d9c9f6..1222ef84 100644 --- a/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/ModularRenderers/BasicRenderer.cs +++ b/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/ModularRenderers/BasicRenderer.cs @@ -1,4 +1,5 @@ -using CustomNPCFramework.Framework.NPCS; +using CustomNPCFramework.Framework.ModularNPCS.CharacterAnimationBases; +using CustomNPCFramework.Framework.NPCS; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using System; @@ -11,12 +12,12 @@ namespace CustomNPCFramework.Framework.ModularNPCS.ModularRenderers { public class BasicRenderer { - public Dictionary animationList; - public CharacterAnimation currentAnimation; + public Dictionary animationList; + public StandardCharacterAnimation currentAnimation; - public BasicRenderer(CharacterAnimation standingAnimation,CharacterAnimation walkingAnimation, CharacterAnimation swimmingAnimation) + public BasicRenderer(StandardCharacterAnimation standingAnimation,StandardCharacterAnimation walkingAnimation, StandardCharacterAnimation swimmingAnimation) { - animationList = new Dictionary(); + animationList = new Dictionary(); animationList.Add(AnimationKeys.standingKey, standingAnimation); animationList.Add(AnimationKeys.walkingKey, walkingAnimation); animationList.Add(AnimationKeys.swimmingKey, swimmingAnimation); @@ -61,6 +62,14 @@ namespace CustomNPCFramework.Framework.ModularNPCS.ModularRenderers this.currentAnimation.setDown(); } + public virtual void reloadSprites() + { + foreach(var v in this.animationList) + { + v.Value.reload(); + } + } + /// /// Used to draw the sprite to the screen. /// diff --git a/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/Portrait.cs b/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/Portrait.cs new file mode 100644 index 00000000..eae4739e --- /dev/null +++ b/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/Portrait.cs @@ -0,0 +1,43 @@ +using CustomNPCFramework.Framework.NPCS; +using Microsoft.Xna.Framework.Graphics; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CustomNPCFramework.Framework.ModularNPCS +{ + public class Portrait + { + public Texture2D portrait; + public string relativePath; + + /// + /// A class for handling portraits. + /// + /// The full path to the file. + public Portrait(string path) + { + this.relativePath =Class1.getRelativeDirectory(path); + this.portrait=Class1.ModHelper.Content.Load(path); + } + + /// + /// Sets the npc's portrait to be this portrait texture. + /// + /// + public void setCharacterPortraitFromThis(ExtendedNPC npc) + { + npc.Portrait = this.portrait; + } + + /// + /// Reloads the texture for the NPC portrait. + /// + public void reload() + { + this.portrait = Class1.ModHelper.Content.Load(this.relativePath); + } + } +} diff --git a/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/Sprite.cs b/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/Sprite.cs new file mode 100644 index 00000000..64962d08 --- /dev/null +++ b/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/Sprite.cs @@ -0,0 +1,44 @@ +using CustomNPCFramework.Framework.NPCS; +using Microsoft.Xna.Framework.Graphics; +using StardewValley; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace CustomNPCFramework.Framework.ModularNPCS +{ + public class Sprite + { + public AnimatedSprite sprite; + public string relativePath; + + /// + /// A class for handling portraits. + /// + /// The full path to the file. + public Sprite(string path) + { + this.relativePath = Class1.getRelativeDirectory(path); + this.sprite = new AnimatedSprite(Class1.ModHelper.Content.Load(this.relativePath)); + } + + /// + /// Sets the npc's portrait to be this portrait texture. + /// + /// + public void setCharacterSpriteFromThis(ExtendedNPC npc) + { + npc.Sprite = this.sprite; + } + + /// + /// Reloads the texture for the NPC portrait. + /// + public void reload() + { + this.sprite.Texture = Class1.ModHelper.Content.Load(this.relativePath); + } + } +} diff --git a/GeneralMods/CustomNPCFramework/Framework/NPCS/ExtendedNPC.cs b/GeneralMods/CustomNPCFramework/Framework/NPCS/ExtendedNPC.cs index 43d1130c..4ede7280 100644 --- a/GeneralMods/CustomNPCFramework/Framework/NPCS/ExtendedNPC.cs +++ b/GeneralMods/CustomNPCFramework/Framework/NPCS/ExtendedNPC.cs @@ -1,9 +1,12 @@ -using CustomNPCFramework.Framework.ModularNPCS.ModularRenderers; +using CustomNPCFramework.Framework.ModularNPCS; +using CustomNPCFramework.Framework.ModularNPCS.ModularRenderers; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; using StardewValley; +using StardewValley.Buildings; using StardewValley.Characters; using StardewValley.Locations; +using StardewValley.Menus; using System; using System.Collections.Generic; using System.Linq; @@ -18,51 +21,67 @@ namespace CustomNPCFramework.Framework.NPCS public class ExtendedNPC :StardewValley.NPC { public BasicRenderer characterRenderer; + public bool hasBeenKissedToday; + public Point previousEndPoint; + public bool returningToEndPoint; + public bool hasSaidAfternoonDialogue; + public int timeAfterSquare; - + public Sprite spriteInformation; + + public Portrait portraitInformation; public ExtendedNPC() :base() { } - public ExtendedNPC(BasicRenderer renderer,Vector2 position,int facingDirection,string name): base(null, position, facingDirection, name, null) + public ExtendedNPC(Sprite sprite,BasicRenderer renderer,Vector2 position,int facingDirection,string name): base(sprite.sprite, position, facingDirection, name, null) { this.characterRenderer = renderer; + this.Portrait = (Texture2D)null; + this.portraitInformation = null; + this.spriteInformation = sprite; + this.spriteInformation.setCharacterSpriteFromThis(this); } - public ExtendedNPC(BasicRenderer renderer,Texture2D portrait, Vector2 position, int facingDirection, string name) : base(null, position, facingDirection, name, null) + public ExtendedNPC(AnimatedSprite characterSprite,BasicRenderer renderer,Portrait portrait, Vector2 position, int facingDirection, string name) : base(characterSprite, position, facingDirection, name, null) { this.characterRenderer = renderer; - this.Portrait = portrait; + this.portraitInformation = portrait; + this.portraitInformation.setCharacterPortraitFromThis(this); } //ERROR NEED FIXING public override void reloadSprite() { - string name = this.name; - string str = name == "Old Mariner" ? "Mariner" : (name == "Dwarf King" ? "DwarfKing" : (name == "Mister Qi" ? "MrQi" : (name == "???" ? "Monsters\\Shadow Guy" : this.name))); - if (this.name.Equals(Utility.getOtherFarmerNames()[0])) - str = Game1.player.isMale ? "maleRival" : "femaleRival"; - if (!this.IsMonster) + if (this.characterRenderer == null) { - this.sprite = new AnimatedSprite(Game1.content.Load("Characters\\" + str)); - if (!this.name.Contains("Dwarf")) - this.sprite.spriteHeight = 32; + this.spriteInformation.reload(); + try + { + this.portraitInformation.reload(); + } + catch (Exception ex) + { + this.Portrait = (Texture2D)null; + } } else - this.sprite = new AnimatedSprite(Game1.content.Load("Monsters\\" + str)); - try { - this.portrait = Game1.content.Load("Portraits\\" + str); - } - catch (Exception ex) - { - this.portrait = (Texture2D)null; + this.characterRenderer.reloadSprites(); + try + { + this.portraitInformation.reload(); + } + catch (Exception ex) + { + this.Portrait = (Texture2D)null; + } } int num = this.isInvisible ? 1 : 0; if (!Game1.newDay && (int)Game1.gameMode != 6) return; this.faceDirection(this.DefaultFacingDirection); this.scheduleTimeToTry = 9999999; - this.previousEndPoint = new Point((int)this.defaultPosition.X / Game1.tileSize, (int)this.defaultPosition.Y / Game1.tileSize); + this.previousEndPoint = new Point((int)this.DefaultPosition.X / Game1.tileSize, (int)this.DefaultPosition.Y / Game1.tileSize); this.Schedule = this.getSchedule(Game1.dayOfMonth); this.faceDirection(this.defaultFacingDirection); this.sprite.standAndFaceDirection(this.defaultFacingDirection); @@ -71,425 +90,23 @@ namespace CustomNPCFramework.Framework.NPCS if (this.isMarried()) this.marriageDuties(); bool flag = Utility.isFestivalDay(Game1.dayOfMonth, Game1.currentSeason); - if (this.name.Equals("Robin") && Game1.player.daysUntilHouseUpgrade > 0 && !flag) - { - this.setTilePosition(68, 14); - this.ignoreMultiplayerUpdates = true; - this.sprite.setCurrentAnimation(new List() - { - new FarmerSprite.AnimationFrame(24, 75), - new FarmerSprite.AnimationFrame(25, 75), - new FarmerSprite.AnimationFrame(26, 300, false, false, new AnimatedSprite.endOfAnimationBehavior(this.robinHammerSound), false), - new FarmerSprite.AnimationFrame(27, 1000, false, false, new AnimatedSprite.endOfAnimationBehavior(this.robinVariablePause), false) - }); - this.ignoreScheduleToday = true; - this.CurrentDialogue.Clear(); - this.currentDialogue.Push(new StardewValley.Dialogue(Game1.player.daysUntilHouseUpgrade == 2 ? Game1.content.LoadString("Strings\\StringsFromCSFiles:NPC.cs.3926") : Game1.content.LoadString("Strings\\StringsFromCSFiles:NPC.cs.3927"), this)); - } - else if (this.name.Equals("Robin") && Game1.getFarm().isThereABuildingUnderConstruction() && !flag) - { - this.ignoreMultiplayerUpdates = true; - this.sprite.setCurrentAnimation(new List() - { - new FarmerSprite.AnimationFrame(24, 75), - new FarmerSprite.AnimationFrame(25, 75), - new FarmerSprite.AnimationFrame(26, 300, false, false, new AnimatedSprite.endOfAnimationBehavior(this.robinHammerSound), false), - new FarmerSprite.AnimationFrame(27, 1000, false, false, new AnimatedSprite.endOfAnimationBehavior(this.robinVariablePause), false) - }); - this.ignoreScheduleToday = true; - Building underConstruction = Game1.getFarm().getBuildingUnderConstruction(); - if (underConstruction.daysUntilUpgrade > 0) - { - if (!underConstruction.indoors.characters.Contains(this)) - underConstruction.indoors.addCharacter(this); - if (this.currentLocation != null) - this.currentLocation.characters.Remove(this); - this.currentLocation = underConstruction.indoors; - this.setTilePosition(1, 5); - } - else - { - Game1.warpCharacter(this, "Farm", new Vector2((float)(underConstruction.tileX + underConstruction.tilesWide / 2), (float)(underConstruction.tileY + underConstruction.tilesHigh / 2)), false, false); - this.position.X += (float)(Game1.tileSize / 4); - this.position.Y -= (float)(Game1.tileSize / 2); - } - this.CurrentDialogue.Clear(); - this.currentDialogue.Push(new StardewValley.Dialogue(Game1.content.LoadString("Strings\\StringsFromCSFiles:NPC.cs.3926"), this)); - } - if (this.name.Equals("Shane") || this.name.Equals("Emily")) - this.datable = true; try { - this.displayName = Game1.content.Load>("Data\\NPCDispositions")[this.name].Split('/')[11]; + this.displayName = this.name; } catch (Exception ex) { } + } - //ERROR NEED FIXING - public virtual bool checkAction(Farmer who, GameLocation l) + public override bool checkAction(StardewValley.Farmer who, GameLocation l) { - if (this.isInvisible) - return false; - if (who.isRidingHorse()) - who.Halt(); - if (this.name.Equals("Henchman") && l.name.Equals("WitchSwamp")) - { - if (!Game1.player.mailReceived.Contains("Henchman1")) - { - Game1.player.mailReceived.Add("Henchman1"); - this.CurrentDialogue.Push(new StardewValley.Dialogue(Game1.content.LoadString("Strings\\Characters:Henchman1"), this)); - Game1.drawDialogue(this); - Game1.player.addQuest(27); - Game1.player.friendships.Add("Henchman", new int[6]); - } - else - { - if (who.ActiveObject != null && who.ActiveObject.canBeGivenAsGift()) - { - this.tryToReceiveActiveObject(who); - return true; - } - if (this.controller == null) - { - this.CurrentDialogue.Push(new StardewValley.Dialogue(Game1.content.LoadString("Strings\\Characters:Henchman2"), this)); - Game1.drawDialogue(this); - } - } - return true; - } - if (Game1.NPCGiftTastes.ContainsKey(this.name) && !Game1.player.friendships.ContainsKey(this.name)) - { - Game1.player.friendships.Add(this.name, new int[6]); - if (this.name.Equals("Krobus")) - { - this.currentDialogue.Push(new StardewValley.Dialogue(Game1.content.LoadString("Strings\\StringsFromCSFiles:NPC.cs.3990"), this)); - Game1.drawDialogue(this); - return true; - } - } - if (who.checkForQuestComplete(this, -1, -1, (Item)who.ActiveObject, (string)null, -1, 5)) - { - this.faceTowardFarmerForPeriod(6000, 3, false, who); - return true; - } - if (this.name.Equals("Dwarf") && this.currentDialogue.Count <= 0 && (who.canUnderstandDwarves && l.name.Equals("Mine"))) - Game1.activeClickableMenu = (IClickableMenu)new ShopMenu(Utility.getDwarfShopStock(), 0, "Dwarf"); - if (this.name.Equals("Krobus")) - { - if (who.hasQuest(28)) - { - this.CurrentDialogue.Push(new StardewValley.Dialogue(Game1.content.LoadString("Strings\\Characters:KrobusDarkTalisman"), this)); - Game1.drawDialogue(this); - who.removeQuest(28); - who.mailReceived.Add("krobusUnseal"); - TemporaryAnimatedSprite t1 = new TemporaryAnimatedSprite(Projectile.projectileSheet, new Microsoft.Xna.Framework.Rectangle(0, 0, 16, 16), 3000f, 1, 0, new Vector2(31f, 17f) * (float)Game1.tileSize, false, false); - t1.scale = (float)Game1.pixelZoom; - t1.delayBeforeAnimationStart = 1; - t1.startSound = "debuffSpell"; - t1.motion = new Vector2(-9f, 1f); - t1.rotationChange = (float)Math.PI / 64f; - int num1 = 1; - t1.light = num1 != 0; - double num2 = 1.0; - t1.lightRadius = (float)num2; - Color color1 = new Color(150, 0, 50); - t1.lightcolor = color1; - double num3 = 1.0; - t1.layerDepth = (float)num3; - double num4 = 3.0 / 1000.0; - t1.alphaFade = (float)num4; - GameLocation l1 = l; - int timer1 = 200; - int num5 = 1; - DelayedAction.addTemporarySpriteAfterDelay(t1, l1, timer1, num5 != 0); - TemporaryAnimatedSprite t2 = new TemporaryAnimatedSprite(Projectile.projectileSheet, new Microsoft.Xna.Framework.Rectangle(0, 0, 16, 16), 3000f, 1, 0, new Vector2(31f, 17f) * (float)Game1.tileSize, false, false); - t2.startSound = "debuffSpell"; - t2.delayBeforeAnimationStart = 1; - double pixelZoom = (double)Game1.pixelZoom; - t2.scale = (float)pixelZoom; - Vector2 vector2 = new Vector2(-9f, 1f); - t2.motion = vector2; - double num6 = 0.0490873865783215; - t2.rotationChange = (float)num6; - int num7 = 1; - t2.light = num7 != 0; - double num8 = 1.0; - t2.lightRadius = (float)num8; - Color color2 = new Color(150, 0, 50); - t2.lightcolor = color2; - double num9 = 1.0; - t2.layerDepth = (float)num9; - double num10 = 3.0 / 1000.0; - t2.alphaFade = (float)num10; - GameLocation l2 = l; - int timer2 = 700; - int num11 = 1; - DelayedAction.addTemporarySpriteAfterDelay(t2, l2, timer2, num11 != 0); - return true; - } - if (this.currentDialogue.Count <= 0 && l is Sewer) - Game1.activeClickableMenu = (IClickableMenu)new ShopMenu((l as Sewer).getShadowShopStock(), 0, "Krobus"); - } - if (this.name.Equals(who.spouse) && who.IsMainPlayer) - { - int timeOfDay = Game1.timeOfDay; - if (this.sprite.currentAnimation == null) - this.faceDirection(-3); - if (this.sprite.currentAnimation == null && who.friendships.ContainsKey(this.name) && (who.friendships[this.name][0] >= 3375 && !who.mailReceived.Contains("CF_Spouse"))) - { - this.CurrentDialogue.Push(new StardewValley.Dialogue(Game1.content.LoadString("Strings\\StringsFromCSFiles:NPC.cs.4001"), this)); - Game1.player.addItemByMenuIfNecessary((Item)new Object(Vector2.Zero, 434, "Cosmic Fruit", false, false, false, false), (ItemGrabMenu.behaviorOnItemSelect)null); - who.mailReceived.Add("CF_Spouse"); - return true; - } - if (this.sprite.currentAnimation == null && !this.hasTemporaryMessageAvailable() && (this.CurrentDialogue.Count == 0 && Game1.timeOfDay < 2200) && (this.controller == null && who.ActiveObject == null)) - { - this.faceGeneralDirection(who.getStandingPosition(), 0); - who.faceGeneralDirection(this.getStandingPosition(), 0); - if (this.facingDirection == 3 || this.facingDirection == 1) - { - int frame = 28; - bool flag = true; - string name = this.name; - // ISSUE: reference to a compiler-generated method - uint stringHash = \u003CPrivateImplementationDetails\u003E.ComputeStringHash(name); - if (stringHash <= 1708213605U) - { - if (stringHash <= 587846041U) - { - if ((int)stringHash != 161540545) - { - if ((int)stringHash == 587846041 && name == "Penny") - { - frame = 35; - flag = true; - } - } - else if (name == "Sebastian") - { - frame = 40; - flag = false; - } - } - else if ((int)stringHash != 1067922812) - { - if ((int)stringHash != 1281010426) - { - if ((int)stringHash == 1708213605 && name == "Alex") - { - frame = 42; - flag = true; - } - } - else if (name == "Maru") - { - frame = 28; - flag = false; - } - } - else if (name == "Sam") - { - frame = 36; - flag = true; - } - } - else if (stringHash <= 2571828641U) - { - if ((int)stringHash != 1866496948) - { - if ((int)stringHash != 2010304804) - { - if ((int)stringHash == -1723138655 && name == "Emily") - { - frame = 33; - flag = false; - } - } - else if (name == "Harvey") - { - frame = 31; - flag = false; - } - } - else if (name == "Shane") - { - frame = 34; - flag = false; - } - } - else if ((int)stringHash != -1562053956) - { - if ((int)stringHash != -1468719973) - { - if ((int)stringHash == -1228790996 && name == "Elliott") - { - frame = 35; - flag = false; - } - } - else if (name == "Leah") - { - frame = 25; - flag = true; - } - } - else if (name == "Abigail") - { - frame = 33; - flag = false; - } - bool flip = flag && this.facingDirection == 3 || !flag && this.facingDirection == 1; - if (who.getFriendshipHeartLevelForNPC(this.name) > 9) - { - this.sprite.setCurrentAnimation(new List() - { - new FarmerSprite.AnimationFrame(frame, Game1.IsMultiplayer ? 1000 : 10, false, flip, new AnimatedSprite.endOfAnimationBehavior(this.haltMe), true) - }); - if (!this.hasBeenKissedToday) - { - who.changeFriendship(10, this); - who.currentLocation.TemporarySprites.Add(new TemporaryAnimatedSprite(Game1.mouseCursors, new Microsoft.Xna.Framework.Rectangle(211, 428, 7, 6), 2000f, 1, 0, new Vector2((float)this.getTileX(), (float)this.getTileY()) * (float)Game1.tileSize + new Vector2((float)(Game1.tileSize / 4), (float)-Game1.tileSize), false, false, 1f, 0.0f, Color.White, (float)Game1.pixelZoom, 0.0f, 0.0f, 0.0f, false) - { - motion = new Vector2(0.0f, -0.5f), - alphaFade = 0.01f - }); - Game1.playSound("dwop"); - who.exhausted = false; - } - this.hasBeenKissedToday = true; - } - else - { - this.faceDirection(Game1.random.NextDouble() < 0.5 ? 2 : 0); - this.doEmote(12, true); - } - who.CanMove = false; - who.FarmerSprite.pauseForSingleAnimation = false; - if (flag && !flip || !flag & flip) - who.faceDirection(3); - else - who.faceDirection(1); - who.FarmerSprite.animateOnce(new List() - { - new FarmerSprite.AnimationFrame(101, 1000, 0, false, who.facingDirection == 3, (AnimatedSprite.endOfAnimationBehavior) null, false, 0), - new FarmerSprite.AnimationFrame(6, 1, false, who.facingDirection == 3, new AnimatedSprite.endOfAnimationBehavior(Farmer.completelyStopAnimating), false) - }.ToArray()); - return true; - } - } - } - bool flag1 = false; - if (who.friendships.ContainsKey(this.name)) - { - flag1 = this.checkForNewCurrentDialogue(who.friendships[this.name][0], false); - if (!flag1) - flag1 = this.checkForNewCurrentDialogue(who.friendships[this.name][0], true); - } - if (who.IsMainPlayer && who.friendships.ContainsKey(this.name) && this.endOfRouteMessage != null | flag1) - { - if (!flag1 && this.setTemporaryMessages(who)) - { - Game1.player.checkForQuestComplete(this, -1, -1, (Item)null, (string)null, 5, -1); - return false; - } - if (this.sprite.Texture.Bounds.Height > 32) - this.faceTowardFarmerForPeriod(5000, 4, false, who); - if (who.ActiveObject != null && who.ActiveObject.canBeGivenAsGift()) - { - this.tryToReceiveActiveObject(who); - Game1.stats.checkForFriendshipAchievements(); - this.faceTowardFarmerForPeriod(3000, 4, false, who); - return true; - } - if (!this.name.Contains("King") && !who.hasPlayerTalkedToNPC(this.name) && who.friendships.ContainsKey(this.name)) - { - who.friendships[this.name][2] = 1; - who.changeFriendship(10, this); - Game1.stats.checkForFriendshipAchievements(); - Game1.player.checkForQuestComplete(this, -1, -1, (Item)null, (string)null, 5, -1); - } - Game1.drawDialogue(this); - } - else if (this.CurrentDialogue.Count > 0) - { - if (!this.name.Contains("King") && who.ActiveObject != null && who.ActiveObject.canBeGivenAsGift()) - { - if (who.IsMainPlayer) - { - this.tryToReceiveActiveObject(who); - Game1.stats.checkForFriendshipAchievements(); - } - else - this.faceTowardFarmerForPeriod(3000, 4, false, who); - } - else if (who.hasClubCard && this.name.Equals("Bouncer") && who.IsMainPlayer) - { - Response[] answerChoices = new Response[2] - { - new Response("Yes.", Game1.content.LoadString("Strings\\StringsFromCSFiles:NPC.cs.4018")), - new Response("That's", Game1.content.LoadString("Strings\\StringsFromCSFiles:NPC.cs.4020")) - }; - l.createQuestionDialogue(Game1.content.LoadString("Strings\\StringsFromCSFiles:NPC.cs.4021"), answerChoices, "ClubCard"); - } - else if (this.CurrentDialogue.Count >= 1 || this.endOfRouteMessage != null) - { - if (this.setTemporaryMessages(who)) - { - Game1.player.checkForQuestComplete(this, -1, -1, (Item)null, (string)null, 5, -1); - return false; - } - if (this.sprite.Texture.Bounds.Height > 32) - this.faceTowardFarmerForPeriod(5000, 4, false, who); - if (who.IsMainPlayer) - { - if (!this.name.Contains("King") && !who.hasPlayerTalkedToNPC(this.name) && who.friendships.ContainsKey(this.name)) - { - who.friendships[this.name][2] = 1; - Game1.player.checkForQuestComplete(this, -1, -1, (Item)null, (string)null, 5, -1); - who.changeFriendship(20, this); - Game1.stats.checkForFriendshipAchievements(); - } - Game1.drawDialogue(this); - } - } - else if (!this.doingEndOfRouteAnimation) - { - try - { - if (who.friendships.ContainsKey(this.name)) - this.faceTowardFarmerForPeriod(who.friendships[this.name][0] / 125 * 1000 + 1000, 4, false, who); - } - catch (Exception ex) - { - } - if (Game1.random.NextDouble() < 0.1) - this.doEmote(8, true); - } - } - else if (this.name.Equals("Cat") && !(this as StardewValley.Monsters.Cat).wasPet) - { - (this as StardewValley.Monsters.Cat).wasPet = true; - (this as StardewValley.Monsters.Cat).loveForMaster += 10; - this.doEmote(20, true); - Game1.playSound("purr"); - } - else if (who.ActiveObject != null && who.ActiveObject.canBeGivenAsGift()) - { - this.tryToReceiveActiveObject(who); - Game1.stats.checkForFriendshipAchievements(); - this.faceTowardFarmerForPeriod(3000, 4, false, who); - return true; - } - if (this.setTemporaryMessages(who) || !this.doingEndOfRouteAnimation && this.goingToDoEndOfRouteAnimation || this.endOfRouteMessage == null) - return false; - Game1.drawDialogue(this); return false; } - //ERROR NEED FIXING - public virtual void behaviorOnFarmerLocationEntry(GameLocation location, Farmer who) + + public override void behaviorOnFarmerLocationEntry(GameLocation location, StardewValley.Farmer who) { if (this.sprite == null || this.sprite.currentAnimation != null || this.sprite.sourceRect.Height <= 32) return; @@ -498,7 +115,6 @@ namespace CustomNPCFramework.Framework.NPCS this.sprite.CurrentFrame = 0; } - //ERROR NEED FIXING public override void updateMovement(GameLocation location, GameTime time) { this.lastPosition = this.position; @@ -761,147 +377,15 @@ namespace CustomNPCFramework.Framework.NPCS //ERROR NEED FIXING public override void update(GameTime time, GameLocation location) { - if (this.returningToEndPoint) - { - this.returnToEndPoint(); - this.MovePosition(time, Game1.viewport, location); - } - else if (this.temporaryController != null) - { - if (this.temporaryController.update(time)) - this.temporaryController = (PathFindController)null; - this.updateEmote(time); - } - else - base.update(time, location); - if (this.textAboveHeadTimer > 0) - { - if (this.textAboveHeadPreTimer > 0) - { - this.textAboveHeadPreTimer = this.textAboveHeadPreTimer - time.ElapsedGameTime.Milliseconds; - } - else - { - this.textAboveHeadTimer = this.textAboveHeadTimer - time.ElapsedGameTime.Milliseconds; - this.textAboveHeadAlpha = this.textAboveHeadTimer <= 500 ? Math.Max(0.0f, this.textAboveHeadAlpha - 0.04f) : Math.Min(1f, this.textAboveHeadAlpha + 0.1f); - } - } - if (this.isWalkingInSquare && !this.returningToEndPoint) - this.randomSquareMovement(time); - if (this.Sprite != null && this.Sprite.currentAnimation != null && (!Game1.eventUp && this.Sprite.animateOnce(time))) - this.Sprite.currentAnimation = (List)null; - TimeSpan timeSpan; - if (this.movementPause > 0 && (!Game1.dialogueUp || this.controller != null)) - { - this.freezeMotion = true; - int movementPause = this.movementPause; - timeSpan = time.ElapsedGameTime; - int milliseconds = timeSpan.Milliseconds; - this.movementPause = movementPause - milliseconds; - if (this.movementPause <= 0) - this.freezeMotion = false; - } - if (this.shakeTimer > 0) - { - int shakeTimer = this.shakeTimer; - timeSpan = time.ElapsedGameTime; - int milliseconds = timeSpan.Milliseconds; - this.shakeTimer = shakeTimer - milliseconds; - } - if (this.lastPosition.Equals(this.position)) - { - double sinceLastMovement = (double)this.timerSinceLastMovement; - timeSpan = time.ElapsedGameTime; - double milliseconds = (double)timeSpan.Milliseconds; - this.timerSinceLastMovement = (float)(sinceLastMovement + milliseconds); - } - else - this.timerSinceLastMovement = 0.0f; - if (!this.swimming) - return; - timeSpan = time.TotalGameTime; - this.yOffset = (float)Math.Cos(timeSpan.TotalMilliseconds / 2000.0) * (float)Game1.pixelZoom; - float swimTimer1 = this.swimTimer; - double swimTimer2 = (double)this.swimTimer; - timeSpan = time.ElapsedGameTime; - double milliseconds1 = (double)timeSpan.Milliseconds; - this.swimTimer = (float)(swimTimer2 - milliseconds1); - if ((double)this.timerSinceLastMovement == 0.0) - { - if ((double)swimTimer1 > 400.0 && (double)this.swimTimer <= 400.0 && location.Equals((object)Game1.currentLocation)) - { - location.temporarySprites.Add(new TemporaryAnimatedSprite(Game1.animations, new Microsoft.Xna.Framework.Rectangle(0, 0, Game1.tileSize, Game1.tileSize), (float)(150.0 - ((double)Math.Abs(this.xVelocity) + (double)Math.Abs(this.yVelocity)) * 3.0), 8, 0, new Vector2(this.position.X, (float)(this.getStandingY() - Game1.tileSize / 2)), false, Game1.random.NextDouble() < 0.5, 0.01f, 0.01f, Color.White, 1f, 3f / 1000f, 0.0f, 0.0f, false)); - Game1.playSound("slosh"); - } - if ((double)this.swimTimer >= 0.0) - return; - this.swimTimer = 800f; - if (!location.Equals((object)Game1.currentLocation)) - return; - Game1.playSound("slosh"); - location.temporarySprites.Add(new TemporaryAnimatedSprite(Game1.animations, new Microsoft.Xna.Framework.Rectangle(0, 0, Game1.tileSize, Game1.tileSize), (float)(150.0 - ((double)Math.Abs(this.xVelocity) + (double)Math.Abs(this.yVelocity)) * 3.0), 8, 0, new Vector2(this.position.X, (float)(this.getStandingY() - Game1.tileSize / 2)), false, Game1.random.NextDouble() < 0.5, 0.01f, 0.01f, Color.White, 1f, 3f / 1000f, 0.0f, 0.0f, false)); - } - else - { - if ((double)this.swimTimer >= 0.0) - return; - this.swimTimer = 100f; - } + base.update(time, location); } - //ERROR NEED FIXING public virtual void prepareToDisembarkOnNewSchedulePath() { - while (this.CurrentDialogue.Count > 0 && this.CurrentDialogue.Peek().removeOnNextMove) - this.CurrentDialogue.Pop(); - this.nextEndOfRouteMessage = (string)null; - this.endOfRouteMessage = (string)null; - if (this.doingEndOfRouteAnimation) - { - List animation = new List(); - for (int index = 0; index < this.routeEndOutro.Length; ++index) - { - if (index == this.routeEndOutro.Length - 1) - animation.Add(new FarmerSprite.AnimationFrame(this.routeEndOutro[index], 100, 0, false, false, new AnimatedSprite.endOfAnimationBehavior(this.routeEndAnimationFinished), true, 0)); - else - animation.Add(new FarmerSprite.AnimationFrame(this.routeEndOutro[index], 100, 0, false, false, (AnimatedSprite.endOfAnimationBehavior)null, false, 0)); - } - if (animation.Count > 0) - this.sprite.setCurrentAnimation(animation); - else - this.routeEndAnimationFinished((Farmer)null); - if (this.endOfRouteBehaviorName != null) - this.finishRouteBehavior(this.endOfRouteBehaviorName); - } - else - this.routeEndAnimationFinished((Farmer)null); - if (!this.isMarried()) - return; - if (this.temporaryController == null && Utility.getGameLocationOfCharacter(this) is FarmHouse) - { - this.temporaryController = new PathFindController((Character)this, this.getHome(), new Point(this.getHome().warps[0].X, this.getHome().warps[0].Y), 2, true) - { - NPCSchedule = true - }; - if (this.temporaryController.pathToEndPoint == null || this.temporaryController.pathToEndPoint.Count <= 0) - { - this.temporaryController = (PathFindController)null; - this.schedule = (Dictionary)null; - } - else - this.followSchedule = true; - } - else - { - if (!(Utility.getGameLocationOfCharacter(this) is Farm)) - return; - this.temporaryController = (PathFindController)null; - this.schedule = (Dictionary)null; - } + } - //ERROR NEED FIXING - public virtual void routeEndAnimationFinished(Farmer who) + public virtual void routeEndAnimationFinished(StardewValley.Farmer who) { this.doingEndOfRouteAnimation = false; this.freezeMotion = false; @@ -912,42 +396,21 @@ namespace CustomNPCFramework.Framework.NPCS this.speed = 2; this.addedSpeed = 0; this.goingToDoEndOfRouteAnimation = false; - if (!this.isWalkingInSquare) + if (!this.IsWalkingInSquare) return; this.returningToEndPoint = true; this.timeAfterSquare = Game1.timeOfDay; } - ///ERROR NEED FIXING public virtual void doAnimationAtEndOfScheduleRoute(Character c, GameLocation l) { - List animation = new List(); - for (int index = 0; index < this.routeEndIntro.Length; ++index) - { - if (index == this.routeEndIntro.Length - 1) - animation.Add(new FarmerSprite.AnimationFrame(this.routeEndIntro[index], 100, 0, false, false, new AnimatedSprite.endOfAnimationBehavior(this.doMiddleAnimation), true, 0)); - else - animation.Add(new FarmerSprite.AnimationFrame(this.routeEndIntro[index], 100, 0, false, false, (AnimatedSprite.endOfAnimationBehavior)null, false, 0)); - } - this.doingEndOfRouteAnimation = true; - this.freezeMotion = true; - this.sprite.setCurrentAnimation(animation); } - ///ERROR NEED FIXING - public virtual void doMiddleAnimation(Farmer who) + public virtual void doMiddleAnimation(StardewValley.Farmer who) { - List animation = new List(); - for (int index = 0; index < this.routeEndAnimation.Length; ++index) - animation.Add(new FarmerSprite.AnimationFrame(this.routeEndAnimation[index], 100, 0, false, false, (AnimatedSprite.endOfAnimationBehavior)null, false, 0)); - this.sprite.setCurrentAnimation(animation); - this.sprite.loop = true; - if (this.endOfRouteBehaviorName == null) - return; - this.startRouteBehavior(this.endOfRouteBehaviorName); + } - //ERROR NEED FIXING public virtual void startRouteBehavior(string behaviorName) { if (behaviorName.Length > 0 && (int)behaviorName[0] == 34) @@ -963,26 +426,6 @@ namespace CustomNPCFramework.Framework.NPCS this.walkInSquare(Convert.ToInt32(strArray[1]), Convert.ToInt32(strArray[2]), 6000); this.squareMovementFacingPreference = strArray.Length <= 3 ? -1 : Convert.ToInt32(strArray[3]); } - if (!(behaviorName == "abigail_videogames")) - { - if (!(behaviorName == "dick_fish")) - { - if (!(behaviorName == "clint_hammer")) - return; - this.extendSourceRect(16, 0, true); - this.sprite.spriteWidth = 32; - this.sprite.ignoreSourceRectUpdates = false; - this.sprite.CurrentFrame = 8; - this.sprite.currentAnimation[14] = new FarmerSprite.AnimationFrame(9, 100, 0, false, false, new AnimatedSprite.endOfAnimationBehavior(this.clintHammerSound), false, 0); - } - else - { - this.extendSourceRect(0, 32, true); - if (!Utility.isOnScreen(Utility.Vector2ToPoint(this.position), Game1.tileSize, this.currentLocation)) - return; - Game1.playSound("slosh"); - } - } else { Utility.getGameLocationOfCharacter(this).temporarySprites.Add(new TemporaryAnimatedSprite(Game1.mouseCursors, new Microsoft.Xna.Framework.Rectangle(167, 1714, 19, 14), 100f, 3, 999999, new Vector2(2f, 3f) * (float)Game1.tileSize + new Vector2(7f, 12f) * (float)Game1.pixelZoom, false, false, 0.0002f, 0.0f, Color.White, (float)Game1.pixelZoom, 0.0f, 0.0f, 0.0f, false) @@ -994,25 +437,8 @@ namespace CustomNPCFramework.Framework.NPCS } } - //ERROR NEED FIXING - public void finishRouteBehavior(string behaviorName) - { - if (!(behaviorName == "abigail_videogames")) - { - if (!(behaviorName == "clint_hammer") && !(behaviorName == "dick_fish")) - return; - this.reloadSprite(); - this.sprite.spriteWidth = 16; - this.sprite.spriteHeight = 32; - this.sprite.UpdateSourceRect(); - this.Halt(); - this.movementPause = 1; - } - else - Utility.getGameLocationOfCharacter(this).removeTemporarySpritesWithID(688); - } - //ERROR NEED FIXING - public virtual void getHitByPlayer(Farmer who, GameLocation location) + + public new void getHitByPlayer(StardewValley.Farmer who, GameLocation location) { this.doEmote(12, true); if (who == null) @@ -1027,9 +453,9 @@ namespace CustomNPCFramework.Framework.NPCS if (who.IsMainPlayer) { this.CurrentDialogue.Clear(); - this.CurrentDialogue.Push(new StardewValley.Dialogue(Game1.random.NextDouble() < 0.5 ? Game1.LoadStringByGender(this.gender, "Strings\\StringsFromCSFiles:NPC.cs.4293") : Game1.content.LoadString("Strings\\StringsFromCSFiles:NPC.cs.4294"), this)); + //this.CurrentDialogue.Push(new StardewValley.Dialogue(Game1.random.NextDouble() < 0.5 ? Game1.LoadStringByGender(this.gender, "Strings\\StringsFromCSFiles:NPC.cs.4293") : Game1.content.LoadString("Strings\\StringsFromCSFiles:NPC.cs.4294"), this)); } - location.debris.Add(new Debris(this.sprite.Texture, Game1.random.Next(3, 8), new Vector2((float)this.GetBoundingBox().Center.X, (float)this.GetBoundingBox().Center.Y))); + //location.debris.Add(new Debris(this.sprite.Texture, Game1.random.Next(3, 8), new Vector2((float)this.GetBoundingBox().Center.X, (float)this.GetBoundingBox().Center.Y))); } if (this.name.Equals("Bouncer")) Game1.playSound("crafting"); @@ -1041,17 +467,7 @@ namespace CustomNPCFramework.Framework.NPCS public override void dayUpdate(int dayOfMonth) { if (this.currentLocation != null) - Game1.warpCharacter(this, this.defaultMap, this.defaultPosition / (float)Game1.tileSize, true, false); - if (this.name.Equals("Maru") || this.name.Equals("Shane")) - this.sprite.Texture = Game1.content.Load("Characters\\" + this.name); - if (this.name.Equals("Willy") || this.name.Equals("Clint")) - { - this.sprite.spriteWidth = 16; - this.sprite.spriteHeight = 32; - this.sprite.ignoreSourceRectUpdates = false; - this.sprite.UpdateSourceRect(); - this.isInvisible = false; - } + Game1.warpCharacter(this, this.defaultMap, this.DefaultPosition / (float)Game1.tileSize, true, false); Game1.player.mailReceived.Remove(this.name); Game1.player.mailReceived.Remove(this.name + "Cooking"); this.doingEndOfRouteAnimation = false; @@ -1065,325 +481,36 @@ namespace CustomNPCFramework.Framework.NPCS this.Halt(); this.controller = (PathFindController)null; this.temporaryController = (PathFindController)null; - this.directionsToNewLocation = (SchedulePathDescription)null; + this.DirectionsToNewLocation = (SchedulePathDescription)null; this.faceDirection(this.DefaultFacingDirection); this.scheduleTimeToTry = 9999999; - this.previousEndPoint = new Point((int)this.defaultPosition.X / Game1.tileSize, (int)this.defaultPosition.Y / Game1.tileSize); - this.isWalkingInSquare = false; + this.previousEndPoint = new Point((int)this.DefaultPosition.X / Game1.tileSize, (int)this.DefaultPosition.Y / Game1.tileSize); + this.IsWalkingInSquare = false; this.returningToEndPoint = false; this.lastCrossroad = Microsoft.Xna.Framework.Rectangle.Empty; if (this.isVillager()) this.Schedule = this.getSchedule(dayOfMonth); this.endOfRouteMessage = (string)null; bool flag = Utility.isFestivalDay(dayOfMonth, Game1.currentSeason); - if (this.name.Equals("Robin") && Game1.player.daysUntilHouseUpgrade > 0 && !flag) - { - this.ignoreMultiplayerUpdates = true; - Game1.warpCharacter(this, "Farm", new Vector2(68f, 14f), false, false); - this.sprite.setCurrentAnimation(new List() - { - new FarmerSprite.AnimationFrame(24, 75), - new FarmerSprite.AnimationFrame(25, 75), - new FarmerSprite.AnimationFrame(26, 300, false, false, new AnimatedSprite.endOfAnimationBehavior(this.robinHammerSound), false), - new FarmerSprite.AnimationFrame(27, 1000, false, false, new AnimatedSprite.endOfAnimationBehavior(this.robinVariablePause), false) - }); - this.ignoreScheduleToday = true; - this.CurrentDialogue.Clear(); - this.currentDialogue.Push(new StardewValley.Dialogue(Game1.player.daysUntilHouseUpgrade == 2 ? Game1.content.LoadString("Strings\\StringsFromCSFiles:NPC.cs.3926") : Game1.content.LoadString("Strings\\StringsFromCSFiles:NPC.cs.3927"), this)); - } - else if (this.name.Equals("Robin") && Game1.getFarm().isThereABuildingUnderConstruction() && !flag) - { - Building underConstruction = Game1.getFarm().getBuildingUnderConstruction(); - if (underConstruction.daysUntilUpgrade > 0) - { - if (!underConstruction.indoors.characters.Contains(this)) - underConstruction.indoors.addCharacter(this); - if (this.currentLocation != null) - this.currentLocation.characters.Remove(this); - this.currentLocation = underConstruction.indoors; - this.setTilePosition(1, 5); - } - else - { - Game1.warpCharacter(this, "Farm", new Vector2((float)(underConstruction.tileX + underConstruction.tilesWide / 2), (float)(underConstruction.tileY + underConstruction.tilesHigh / 2)), false, false); - this.position.X += (float)(Game1.tileSize / 4); - this.position.Y -= (float)(Game1.tileSize / 2); - } - this.ignoreMultiplayerUpdates = true; - this.sprite.setCurrentAnimation(new List() - { - new FarmerSprite.AnimationFrame(24, 75), - new FarmerSprite.AnimationFrame(25, 75), - new FarmerSprite.AnimationFrame(26, 300, false, false, new AnimatedSprite.endOfAnimationBehavior(this.robinHammerSound), false), - new FarmerSprite.AnimationFrame(27, 1000, false, false, new AnimatedSprite.endOfAnimationBehavior(this.robinVariablePause), false) - }); - this.ignoreScheduleToday = true; - this.CurrentDialogue.Clear(); - this.currentDialogue.Push(new StardewValley.Dialogue(Game1.content.LoadString("Strings\\StringsFromCSFiles:NPC.cs.3926"), this)); - } if (!this.isMarried()) return; this.marriageDuties(); this.daysMarried = this.daysMarried + 1; } - //ERROR NEED FIXING - public virtual void setUpForOutdoorPatioActivity() + /// + /// Does effectively nothing. + /// + public new void setUpForOutdoorPatioActivity() { - Game1.warpCharacter(this, "Farm", new Vector2(71f, 10f), false, false); - this.setNewDialogue("MarriageDialogue", "patio_", -1, false, true); - string name = this.name; - // ISSUE: reference to a compiler-generated method - uint stringHash = \u003CPrivateImplementationDetails\u003E.ComputeStringHash(name); - if (stringHash <= 1866496948U) - { - if (stringHash <= 1067922812U) - { - if ((int)stringHash != 161540545) - { - if ((int)stringHash != 587846041) - { - if ((int)stringHash != 1067922812 || !(name == "Sam")) - return; - this.setTilePosition(71, 8); - this.sprite.setCurrentAnimation(new List() - { - new FarmerSprite.AnimationFrame(25, 3000), - new FarmerSprite.AnimationFrame(27, 500), - new FarmerSprite.AnimationFrame(26, 100), - new FarmerSprite.AnimationFrame(28, 100), - new FarmerSprite.AnimationFrame(27, 500), - new FarmerSprite.AnimationFrame(25, 2000), - new FarmerSprite.AnimationFrame(27, 500), - new FarmerSprite.AnimationFrame(26, 100), - new FarmerSprite.AnimationFrame(29, 100), - new FarmerSprite.AnimationFrame(30, 100), - new FarmerSprite.AnimationFrame(32, 500), - new FarmerSprite.AnimationFrame(31, 1000), - new FarmerSprite.AnimationFrame(30, 100), - new FarmerSprite.AnimationFrame(29, 100) - }); - } - else - { - if (!(name == "Penny")) - return; - this.setTilePosition(71, 8); - this.sprite.setCurrentAnimation(new List() - { - new FarmerSprite.AnimationFrame(18, 6000), - new FarmerSprite.AnimationFrame(19, 500) - }); - } - } - else - { - if (!(name == "Sebastian")) - return; - this.setTilePosition(71, 9); - this.drawOffset = new Vector2((float)(Game1.tileSize / 4), (float)(Game1.tileSize / 2 + Game1.pixelZoom * 2)); - this.sprite.setCurrentAnimation(new List() - { - new FarmerSprite.AnimationFrame(32, 500, Game1.tileSize, false, false, (AnimatedSprite.endOfAnimationBehavior) null, false, 0), - new FarmerSprite.AnimationFrame(36, 500, Game1.tileSize, false, false, (AnimatedSprite.endOfAnimationBehavior) null, false, 0), - new FarmerSprite.AnimationFrame(32, 500, Game1.tileSize, false, false, (AnimatedSprite.endOfAnimationBehavior) null, false, 0), - new FarmerSprite.AnimationFrame(36, 500, Game1.tileSize, false, false, (AnimatedSprite.endOfAnimationBehavior) null, false, 0), - new FarmerSprite.AnimationFrame(32, 500, Game1.tileSize, false, false, (AnimatedSprite.endOfAnimationBehavior) null, false, 0), - new FarmerSprite.AnimationFrame(36, 500, Game1.tileSize, false, false, (AnimatedSprite.endOfAnimationBehavior) null, false, 0), - new FarmerSprite.AnimationFrame(32, 500, Game1.tileSize, false, false, (AnimatedSprite.endOfAnimationBehavior) null, false, 0), - new FarmerSprite.AnimationFrame(36, 2000, Game1.tileSize, false, false, (AnimatedSprite.endOfAnimationBehavior) null, false, 0), - new FarmerSprite.AnimationFrame(33, 100, Game1.tileSize, false, false, (AnimatedSprite.endOfAnimationBehavior) null, false, 0), - new FarmerSprite.AnimationFrame(34, 100, Game1.tileSize, false, false, (AnimatedSprite.endOfAnimationBehavior) null, false, 0), - new FarmerSprite.AnimationFrame(35, 3000, Game1.tileSize, false, false, (AnimatedSprite.endOfAnimationBehavior) null, false, 0), - new FarmerSprite.AnimationFrame(34, 100, Game1.tileSize, false, false, (AnimatedSprite.endOfAnimationBehavior) null, false, 0), - new FarmerSprite.AnimationFrame(33, 100, Game1.tileSize, false, false, (AnimatedSprite.endOfAnimationBehavior) null, false, 0), - new FarmerSprite.AnimationFrame(32, 1500, Game1.tileSize, false, false, (AnimatedSprite.endOfAnimationBehavior) null, false, 0) - }); - } - } - else if ((int)stringHash != 1281010426) - { - if ((int)stringHash != 1708213605) - { - if ((int)stringHash != 1866496948 || !(name == "Shane")) - return; - this.setTilePosition(69, 9); - this.sprite.setCurrentAnimation(new List() - { - new FarmerSprite.AnimationFrame(28, 4000, Game1.tileSize, false, false, (AnimatedSprite.endOfAnimationBehavior) null, false, 0), - new FarmerSprite.AnimationFrame(29, 800, Game1.tileSize, false, false, (AnimatedSprite.endOfAnimationBehavior) null, false, 0) - }); - } - else - { - if (!(name == "Alex")) - return; - this.setTilePosition(71, 8); - this.sprite.setCurrentAnimation(new List() - { - new FarmerSprite.AnimationFrame(34, 4000), - new FarmerSprite.AnimationFrame(33, 300), - new FarmerSprite.AnimationFrame(28, 200), - new FarmerSprite.AnimationFrame(29, 100), - new FarmerSprite.AnimationFrame(30, 100), - new FarmerSprite.AnimationFrame(31, 100), - new FarmerSprite.AnimationFrame(32, 100), - new FarmerSprite.AnimationFrame(31, 100), - new FarmerSprite.AnimationFrame(30, 100), - new FarmerSprite.AnimationFrame(29, 100), - new FarmerSprite.AnimationFrame(28, 800), - new FarmerSprite.AnimationFrame(29, 100), - new FarmerSprite.AnimationFrame(30, 100), - new FarmerSprite.AnimationFrame(31, 100), - new FarmerSprite.AnimationFrame(32, 100), - new FarmerSprite.AnimationFrame(31, 100), - new FarmerSprite.AnimationFrame(30, 100), - new FarmerSprite.AnimationFrame(29, 100), - new FarmerSprite.AnimationFrame(28, 800), - new FarmerSprite.AnimationFrame(33, 200) - }); - } - } - else - { - if (!(name == "Maru")) - return; - this.setTilePosition(70, 8); - this.sprite.setCurrentAnimation(new List() - { - new FarmerSprite.AnimationFrame(16, 4000), - new FarmerSprite.AnimationFrame(17, 200), - new FarmerSprite.AnimationFrame(18, 200), - new FarmerSprite.AnimationFrame(19, 200), - new FarmerSprite.AnimationFrame(20, 200), - new FarmerSprite.AnimationFrame(21, 200), - new FarmerSprite.AnimationFrame(22, 200), - new FarmerSprite.AnimationFrame(23, 200) - }); - } - } - else if (stringHash <= 2571828641U) - { - if ((int)stringHash != 2010304804) - { - if ((int)stringHash != -1860673204) - { - if ((int)stringHash != -1723138655 || !(name == "Emily")) - return; - this.setTilePosition(70, 9); - this.sprite.setCurrentAnimation(new List() - { - new FarmerSprite.AnimationFrame(54, 4000, Game1.tileSize, false, false, (AnimatedSprite.endOfAnimationBehavior) null, false, 0) - }); - } - else - { - if (!(name == "Haley")) - return; - this.setTilePosition(70, 8); - this.sprite.setCurrentAnimation(new List() - { - new FarmerSprite.AnimationFrame(30, 2000), - new FarmerSprite.AnimationFrame(31, 200), - new FarmerSprite.AnimationFrame(24, 2000), - new FarmerSprite.AnimationFrame(25, 1000), - new FarmerSprite.AnimationFrame(32, 200), - new FarmerSprite.AnimationFrame(33, 2000), - new FarmerSprite.AnimationFrame(32, 200), - new FarmerSprite.AnimationFrame(25, 2000), - new FarmerSprite.AnimationFrame(32, 200), - new FarmerSprite.AnimationFrame(33, 2000) - }); - } - } - else - { - if (!(name == "Harvey")) - return; - this.setTilePosition(71, 8); - this.sprite.setCurrentAnimation(new List() - { - new FarmerSprite.AnimationFrame(42, 6000), - new FarmerSprite.AnimationFrame(43, 1000), - new FarmerSprite.AnimationFrame(39, 100), - new FarmerSprite.AnimationFrame(43, 500), - new FarmerSprite.AnimationFrame(39, 100), - new FarmerSprite.AnimationFrame(43, 1000), - new FarmerSprite.AnimationFrame(42, 5000), - new FarmerSprite.AnimationFrame(43, 3000) - }); - } - } - else if ((int)stringHash != -1562053956) - { - if ((int)stringHash != -1468719973) - { - if ((int)stringHash != -1228790996 || !(name == "Elliott")) - return; - this.setTilePosition(71, 8); - this.sprite.setCurrentAnimation(new List() - { - new FarmerSprite.AnimationFrame(33, 3000), - new FarmerSprite.AnimationFrame(32, 500), - new FarmerSprite.AnimationFrame(33, 3000), - new FarmerSprite.AnimationFrame(32, 500), - new FarmerSprite.AnimationFrame(33, 2000), - new FarmerSprite.AnimationFrame(34, 1500) - }); - } - else - { - if (!(name == "Leah")) - return; - this.setTilePosition(71, 8); - this.sprite.setCurrentAnimation(new List() - { - new FarmerSprite.AnimationFrame(16, 100), - new FarmerSprite.AnimationFrame(17, 100), - new FarmerSprite.AnimationFrame(18, 100), - new FarmerSprite.AnimationFrame(19, 300), - new FarmerSprite.AnimationFrame(16, 100), - new FarmerSprite.AnimationFrame(17, 100), - new FarmerSprite.AnimationFrame(18, 100), - new FarmerSprite.AnimationFrame(19, 1000), - new FarmerSprite.AnimationFrame(16, 100), - new FarmerSprite.AnimationFrame(17, 100), - new FarmerSprite.AnimationFrame(18, 100), - new FarmerSprite.AnimationFrame(19, 300), - new FarmerSprite.AnimationFrame(16, 100), - new FarmerSprite.AnimationFrame(17, 100), - new FarmerSprite.AnimationFrame(18, 100), - new FarmerSprite.AnimationFrame(19, 300), - new FarmerSprite.AnimationFrame(16, 100), - new FarmerSprite.AnimationFrame(17, 100), - new FarmerSprite.AnimationFrame(18, 100), - new FarmerSprite.AnimationFrame(19, 2000) - }); - } - } - else - { - if (!(name == "Abigail")) - return; - this.setTilePosition(71, 8); - this.sprite.setCurrentAnimation(new List() - { - new FarmerSprite.AnimationFrame(16, 500), - new FarmerSprite.AnimationFrame(17, 500), - new FarmerSprite.AnimationFrame(18, 500), - new FarmerSprite.AnimationFrame(19, 500) - }); - } } - - //ERROR NEED FIXING!!!!!!!!!!!!!!!!!! /// /// Used to draw the npc with the custom renderer. /// /// /// - public override void draw(SpriteBatch b, float alpha = 1f) + public virtual void drawModular(SpriteBatch b, float alpha = 1f) { if (this.characterRenderer == null || this.isInvisible || !Utility.isOnScreen(this.position, 2 * Game1.tileSize)) return; @@ -1427,7 +554,7 @@ namespace CustomNPCFramework.Framework.NPCS //Checks if the npc is glowing. if (this.isGlowing) - b.Draw(this.Sprite.Texture, this.getLocalPosition(Game1.viewport) + new Vector2((float)(this.sprite.spriteWidth * Game1.pixelZoom / 2), (float)(this.GetBoundingBox().Height / 2)) + (this.shakeTimer > 0 ? new Vector2((float)Game1.random.Next(-1, 2), (float)Game1.random.Next(-1, 2)) : Vector2.Zero), new Microsoft.Xna.Framework.Rectangle?(this.Sprite.SourceRect), this.glowingColor * this.glowingTransparency, this.rotation, new Vector2((float)(this.sprite.spriteWidth / 2), (float)((double)this.sprite.spriteHeight * 3.0 / 4.0)), Math.Max(0.2f, this.scale) * 4f, this.flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, Math.Max(0.0f, this.drawOnTop ? 0.99f : (float)((double)this.getStandingY() / 10000.0 + 1.0 / 1000.0))); + this.characterRenderer.draw(b,this, this.getLocalPosition(Game1.viewport) + new Vector2((float)(this.sprite.spriteWidth * Game1.pixelZoom / 2), (float)(this.GetBoundingBox().Height / 2)) + (this.shakeTimer > 0 ? new Vector2((float)Game1.random.Next(-1, 2), (float)Game1.random.Next(-1, 2)) : Vector2.Zero), new Microsoft.Xna.Framework.Rectangle?(this.Sprite.SourceRect), this.glowingColor * this.glowingTransparency, this.rotation, new Vector2((float)(this.sprite.spriteWidth / 2), (float)((double)this.sprite.spriteHeight * 3.0 / 4.0)), Math.Max(0.2f, this.scale) * 4f, this.flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, Math.Max(0.0f, this.drawOnTop ? 0.99f : (float)((double)this.getStandingY() / 10000.0 + 1.0 / 1000.0))); //This code runs if the npc is emoting. if (!this.IsEmoting || Game1.eventUp) @@ -1436,5 +563,61 @@ namespace CustomNPCFramework.Framework.NPCS localPosition1.Y -= (float)(Game1.tileSize / 2 + this.sprite.spriteHeight * Game1.pixelZoom); b.Draw(Game1.emoteSpriteSheet, localPosition1, new Microsoft.Xna.Framework.Rectangle?(new Microsoft.Xna.Framework.Rectangle(this.CurrentEmoteIndex * 16 % Game1.emoteSpriteSheet.Width, this.CurrentEmoteIndex * 16 / Game1.emoteSpriteSheet.Width * 16, 16, 16)), Color.White, 0.0f, Vector2.Zero, (float)Game1.pixelZoom, SpriteEffects.None, (float)this.getStandingY() / 10000f); } + + + public virtual void drawNonModularSprite(SpriteBatch b, float alpha = 1f) + { + if (this.sprite == null || this.isInvisible || !Utility.isOnScreen(this.position, 2 * Game1.tileSize)) + return; + if (this.swimming) + { + b.Draw(this.Sprite.Texture, this.getLocalPosition(Game1.viewport) + new Vector2((float)(Game1.tileSize / 2), (float)(Game1.tileSize + Game1.tileSize / 4 + this.yJumpOffset * 2)) + (this.shakeTimer > 0 ? new Vector2((float)Game1.random.Next(-1, 2), (float)Game1.random.Next(-1, 2)) : Vector2.Zero) - new Vector2(0.0f, this.yOffset), new Microsoft.Xna.Framework.Rectangle?(new Microsoft.Xna.Framework.Rectangle(this.sprite.SourceRect.X, this.sprite.SourceRect.Y, this.sprite.SourceRect.Width, this.sprite.SourceRect.Height / 2 - (int)((double)this.yOffset / (double)Game1.pixelZoom))), Color.White, this.rotation, new Vector2((float)(Game1.tileSize / 2), (float)(Game1.tileSize * 3 / 2)) / 4f, Math.Max(0.2f, this.scale) * (float)Game1.pixelZoom, this.flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, Math.Max(0.0f, this.drawOnTop ? 0.991f : (float)this.getStandingY() / 10000f)); + Vector2 localPosition = this.getLocalPosition(Game1.viewport); + b.Draw(Game1.staminaRect, new Microsoft.Xna.Framework.Rectangle((int)localPosition.X + (int)this.yOffset + Game1.pixelZoom * 2, (int)localPosition.Y - 32 * Game1.pixelZoom + this.sprite.SourceRect.Height * Game1.pixelZoom + Game1.tileSize * 3 / 4 + this.yJumpOffset * 2 - (int)this.yOffset, this.sprite.SourceRect.Width * Game1.pixelZoom - (int)this.yOffset * 2 - Game1.pixelZoom * 4, Game1.pixelZoom), new Microsoft.Xna.Framework.Rectangle?(Game1.staminaRect.Bounds), Color.White * 0.75f, 0.0f, Vector2.Zero, SpriteEffects.None, (float)((double)this.getStandingY() / 10000.0 + 1.0 / 1000.0)); + } + else + b.Draw(this.Sprite.Texture, this.getLocalPosition(Game1.viewport) + new Vector2((float)(this.sprite.spriteWidth * Game1.pixelZoom / 2), (float)(this.GetBoundingBox().Height / 2)) + (this.shakeTimer > 0 ? new Vector2((float)Game1.random.Next(-1, 2), (float)Game1.random.Next(-1, 2)) : Vector2.Zero), new Microsoft.Xna.Framework.Rectangle?(this.Sprite.SourceRect), Color.White * alpha, this.rotation, new Vector2((float)(this.sprite.spriteWidth / 2), (float)((double)this.sprite.spriteHeight * 3.0 / 4.0)), Math.Max(0.2f, this.scale) * (float)Game1.pixelZoom, this.flip || this.sprite.currentAnimation != null && this.sprite.currentAnimation[this.sprite.currentAnimationIndex].flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, Math.Max(0.0f, this.drawOnTop ? 0.991f : (float)this.getStandingY() / 10000f)); + if (this.breather && this.shakeTimer <= 0 && (!this.swimming && this.sprite.CurrentFrame < 16) && !this.farmerPassesThrough) + { + Microsoft.Xna.Framework.Rectangle sourceRect = this.sprite.SourceRect; + sourceRect.Y += this.sprite.spriteHeight / 2 + this.sprite.spriteHeight / 32; + sourceRect.Height = this.sprite.spriteHeight / 4; + sourceRect.X += this.sprite.spriteWidth / 4; + sourceRect.Width = this.sprite.spriteWidth / 2; + Vector2 vector2 = new Vector2((float)(this.sprite.spriteWidth * Game1.pixelZoom / 2), (float)(Game1.tileSize / 8)); + if (this.age == 2) + { + sourceRect.Y += this.sprite.spriteHeight / 6 + 1; + sourceRect.Height /= 2; + vector2.Y += (float)(this.sprite.spriteHeight / 8 * Game1.pixelZoom); + } + else if (this.gender == 1) + { + ++sourceRect.Y; + vector2.Y -= (float)Game1.pixelZoom; + sourceRect.Height /= 2; + } + float num = Math.Max(0.0f, (float)(Math.Ceiling(Math.Sin(Game1.currentGameTime.TotalGameTime.TotalMilliseconds / 600.0 + (double)this.DefaultPosition.X * 20.0)) / 4.0)); + b.Draw(this.Sprite.Texture, this.getLocalPosition(Game1.viewport) + vector2 + (this.shakeTimer > 0 ? new Vector2((float)Game1.random.Next(-1, 2), (float)Game1.random.Next(-1, 2)) : Vector2.Zero), new Microsoft.Xna.Framework.Rectangle?(sourceRect), Color.White * alpha, this.rotation, new Vector2((float)(sourceRect.Width / 2), (float)(sourceRect.Height / 2 + 1)), Math.Max(0.2f, this.scale) * (float)Game1.pixelZoom + num, this.flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, Math.Max(0.0f, this.drawOnTop ? 0.992f : (float)((double)this.getStandingY() / 10000.0 + 1.0 / 1000.0))); + } + if (this.isGlowing) + b.Draw(this.Sprite.Texture, this.getLocalPosition(Game1.viewport) + new Vector2((float)(this.sprite.spriteWidth * Game1.pixelZoom / 2), (float)(this.GetBoundingBox().Height / 2)) + (this.shakeTimer > 0 ? new Vector2((float)Game1.random.Next(-1, 2), (float)Game1.random.Next(-1, 2)) : Vector2.Zero), new Microsoft.Xna.Framework.Rectangle?(this.Sprite.SourceRect), this.glowingColor * this.glowingTransparency, this.rotation, new Vector2((float)(this.sprite.spriteWidth / 2), (float)((double)this.sprite.spriteHeight * 3.0 / 4.0)), Math.Max(0.2f, this.scale) * 4f, this.flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, Math.Max(0.0f, this.drawOnTop ? 0.99f : (float)((double)this.getStandingY() / 10000.0 + 1.0 / 1000.0))); + Vector2 localPosition1 = this.getLocalPosition(Game1.viewport); + localPosition1.Y -= (float)(Game1.tileSize / 2 + this.sprite.spriteHeight * Game1.pixelZoom); + b.Draw(Game1.emoteSpriteSheet, localPosition1, new Microsoft.Xna.Framework.Rectangle?(new Microsoft.Xna.Framework.Rectangle(this.CurrentEmoteIndex * 16 % Game1.emoteSpriteSheet.Width, this.CurrentEmoteIndex * 16 / Game1.emoteSpriteSheet.Width * 16, 16, 16)), Color.White, 0.0f, Vector2.Zero, (float)Game1.pixelZoom, SpriteEffects.None, (float)this.getStandingY() / 10000f); + } + + + public override void draw(SpriteBatch b, float alpha = 1f) + { + if (this.characterRenderer == null) + { + this.drawNonModularSprite(b, alpha); + } + else + { + this.drawModular(b, alpha); + } + } } } From 45c5b69ba0e8c02939812f350b37d642337d1eaa Mon Sep 17 00:00:00 2001 From: Date: Sat, 24 Feb 2018 01:05:58 -0800 Subject: [PATCH 16/18] Updated a constuctor to used the new character sprite class. --- GeneralMods/CustomNPCFramework/Framework/NPCS/ExtendedNPC.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/GeneralMods/CustomNPCFramework/Framework/NPCS/ExtendedNPC.cs b/GeneralMods/CustomNPCFramework/Framework/NPCS/ExtendedNPC.cs index 4ede7280..b894aad9 100644 --- a/GeneralMods/CustomNPCFramework/Framework/NPCS/ExtendedNPC.cs +++ b/GeneralMods/CustomNPCFramework/Framework/NPCS/ExtendedNPC.cs @@ -42,11 +42,13 @@ namespace CustomNPCFramework.Framework.NPCS this.spriteInformation.setCharacterSpriteFromThis(this); } - public ExtendedNPC(AnimatedSprite characterSprite,BasicRenderer renderer,Portrait portrait, Vector2 position, int facingDirection, string name) : base(characterSprite, position, facingDirection, name, null) + public ExtendedNPC(Sprite sprite,BasicRenderer renderer,Portrait portrait, Vector2 position, int facingDirection, string name) : base(sprite.sprite, position, facingDirection, name, null) { this.characterRenderer = renderer; this.portraitInformation = portrait; this.portraitInformation.setCharacterPortraitFromThis(this); + this.spriteInformation = sprite; + this.spriteInformation.setCharacterSpriteFromThis(this); } //ERROR NEED FIXING From 4fb792db11ff7912f78ccc595bfd00ea9b3b6ba8 Mon Sep 17 00:00:00 2001 From: Date: Sat, 24 Feb 2018 01:36:41 -0800 Subject: [PATCH 17/18] Fixed the default non-modular spriter renderer to draw normal npcs again. --- GeneralMods/CustomNPCFramework/Class1.cs | 15 +- .../CustomNPCFramework.csproj | 10 ++ .../Framework/ModularNPCS/Sprite.cs | 2 + .../Framework/NPCS/ExtendedNPC.cs | 154 +----------------- 4 files changed, 28 insertions(+), 153 deletions(-) diff --git a/GeneralMods/CustomNPCFramework/Class1.cs b/GeneralMods/CustomNPCFramework/Class1.cs index e0801aea..24bdda7f 100644 --- a/GeneralMods/CustomNPCFramework/Class1.cs +++ b/GeneralMods/CustomNPCFramework/Class1.cs @@ -1,4 +1,6 @@ using CustomNPCFramework.Framework.Graphics; +using CustomNPCFramework.Framework.ModularNPCS; +using CustomNPCFramework.Framework.ModularNPCS.CharacterAnimationBases; using CustomNPCFramework.Framework.NPCS; using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Graphics; @@ -36,8 +38,8 @@ namespace CustomNPCFramework foreach (var v in Game1.player.currentLocation.characters) { v.speed = 5; - v.MovePosition(Game1.currentGameTime, Game1.viewport, Game1.player.currentLocation); - ModMonitor.Log(v.name); + //v.MovePosition(Game1.currentGameTime, Game1.viewport, Game1.player.currentLocation); + ModMonitor.Log(v.sprite.spriteHeight.ToString()); } } @@ -50,8 +52,9 @@ namespace CustomNPCFramework { string path = Path.Combine(ModHelper.DirectoryPath, "Content", "Graphics", "NPCS", "Characters", "RainMan"); assetManager.addPathCreateDirectory(new KeyValuePair("characters", path)); - Texture2D tex=ModHelper.Content.Load(Path.Combine(getShortenedDirectory(path).Remove(0,1), "character.png")); - ExtendedNPC myNpc3 = new ExtendedNPC(new StardewValley.AnimatedSprite(tex, 0, 16, 32), new Vector2(14, 14)*Game1.tileSize, 2, "b2"); + Texture2D tex = ModHelper.Content.Load(Path.Combine(getShortenedDirectory(path).Remove(0, 1), "character.png")); + ModMonitor.Log("PATH???: " + path); + ExtendedNPC myNpc3 = new ExtendedNPC(new Framework.ModularNPCS.Sprite(Path.Combine(path,"character.png")),null, new Vector2(14, 14)*Game1.tileSize, 2, "b2"); Game1.getLocationFromName("BusStop").addCharacter(myNpc3); myNpc3.SetMovingDown(true); } @@ -70,8 +73,8 @@ namespace CustomNPCFramework public static string getShortenedDirectory(string path) { - - string[] spliter = path.Split(new string[] { ModHelper.DirectoryPath },StringSplitOptions.None); + string lol = (string)path.Clone(); + string[] spliter = lol.Split(new string[] { ModHelper.DirectoryPath },StringSplitOptions.None); return spliter[1]; } diff --git a/GeneralMods/CustomNPCFramework/CustomNPCFramework.csproj b/GeneralMods/CustomNPCFramework/CustomNPCFramework.csproj index 8fd07e7e..8711c538 100644 --- a/GeneralMods/CustomNPCFramework/CustomNPCFramework.csproj +++ b/GeneralMods/CustomNPCFramework/CustomNPCFramework.csproj @@ -46,12 +46,22 @@ + + + + + + + + + + diff --git a/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/Sprite.cs b/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/Sprite.cs index 64962d08..578d7867 100644 --- a/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/Sprite.cs +++ b/GeneralMods/CustomNPCFramework/Framework/ModularNPCS/Sprite.cs @@ -22,6 +22,8 @@ namespace CustomNPCFramework.Framework.ModularNPCS { this.relativePath = Class1.getRelativeDirectory(path); this.sprite = new AnimatedSprite(Class1.ModHelper.Content.Load(this.relativePath)); + this.sprite.spriteWidth = this.sprite.Texture.Width; + this.sprite.spriteHeight = this.sprite.Texture.Height; } /// diff --git a/GeneralMods/CustomNPCFramework/Framework/NPCS/ExtendedNPC.cs b/GeneralMods/CustomNPCFramework/Framework/NPCS/ExtendedNPC.cs index b894aad9..dd429a7a 100644 --- a/GeneralMods/CustomNPCFramework/Framework/NPCS/ExtendedNPC.cs +++ b/GeneralMods/CustomNPCFramework/Framework/NPCS/ExtendedNPC.cs @@ -40,6 +40,7 @@ namespace CustomNPCFramework.Framework.NPCS this.portraitInformation = null; this.spriteInformation = sprite; this.spriteInformation.setCharacterSpriteFromThis(this); + this.swimming = false; } public ExtendedNPC(Sprite sprite,BasicRenderer renderer,Portrait portrait, Vector2 position, int facingDirection, string name) : base(sprite.sprite, position, facingDirection, name, null) @@ -49,6 +50,7 @@ namespace CustomNPCFramework.Framework.NPCS this.portraitInformation.setCharacterPortraitFromThis(this); this.spriteInformation = sprite; this.spriteInformation.setCharacterSpriteFromThis(this); + this.swimming = false; } //ERROR NEED FIXING @@ -107,145 +109,11 @@ namespace CustomNPCFramework.Framework.NPCS return false; } - - public override void behaviorOnFarmerLocationEntry(GameLocation location, StardewValley.Farmer who) - { - if (this.sprite == null || this.sprite.currentAnimation != null || this.sprite.sourceRect.Height <= 32) - return; - this.sprite.spriteWidth = 16; - this.sprite.spriteHeight = 16; - this.sprite.CurrentFrame = 0; - } - - public override void updateMovement(GameLocation location, GameTime time) - { - this.lastPosition = this.position; - if (this.DirectionsToNewLocation != null && !Game1.newDay) - { - if (this.getStandingX() < -Game1.tileSize || this.getStandingX() > location.map.DisplayWidth + Game1.tileSize || (this.getStandingY() < -Game1.tileSize || this.getStandingY() > location.map.DisplayHeight + Game1.tileSize)) - { - this.IsWalkingInSquare = false; - Game1.warpCharacter(this, this.DefaultMap, this.DefaultPosition, true, true); - location.characters.Remove(this); - } - else if (this.IsWalkingInSquare) - { - this.returnToEndPoint(); - this.MovePosition(time, Game1.viewport, location); - } - else - { - if (!this.followSchedule) - return; - this.MovePosition(time, Game1.viewport, location); - Warp warp = location.isCollidingWithWarp(this.GetBoundingBox()); - PropertyValue propertyValue = (PropertyValue)null; - Tile tile1 = location.map.GetLayer("Buildings").PickTile(this.nextPositionPoint(), Game1.viewport.Size); - if (tile1 != null) - tile1.Properties.TryGetValue("Action", out propertyValue); - string[] strArray1; - if (propertyValue != null) - strArray1 = propertyValue.ToString().Split(' '); - else - strArray1 = (string[])null; - string[] strArray2 = strArray1; - if (warp != null) - { - if (location is BusStop && warp.TargetName.Equals("Farm")) - { - Point entryLocation = ((this.isMarried() ? (GameLocation)(this.getHome() as FarmHouse) : Game1.getLocationFromName("FarmHouse")) as FarmHouse).getEntryLocation(); - warp = new Warp(warp.X, warp.Y, "FarmHouse", entryLocation.X, entryLocation.Y, false); - } - else if (location is FarmHouse && warp.TargetName.Equals("Farm")) - warp = new Warp(warp.X, warp.Y, "BusStop", 0, 23, false); - Game1.warpCharacter(this, warp.TargetName, new Vector2((float)(warp.TargetX * Game1.tileSize), (float)(warp.TargetY * Game1.tileSize - this.Sprite.getHeight() / 2 - Game1.tileSize / 4)), false, location.IsOutdoors); - location.characters.Remove(this); - } - else if (strArray2 != null && strArray2.Length >= 1 && strArray2[0].Contains("Warp")) - { - Game1.warpCharacter(this, strArray2[3], new Vector2((float)Convert.ToInt32(strArray2[1]), (float)Convert.ToInt32(strArray2[2])), false, location.IsOutdoors); - if (Game1.currentLocation.name.Equals(location.name) && Utility.isOnScreen(this.getStandingPosition(), Game1.tileSize * 3)) - Game1.playSound("doorClose"); - location.characters.Remove(this); - } - else if (strArray2 != null && strArray2.Length >= 1 && strArray2[0].Contains("Door")) - { - location.openDoor(new Location(this.nextPositionPoint().X / Game1.tileSize, this.nextPositionPoint().Y / Game1.tileSize), Game1.player.currentLocation.Equals((object)location)); - } - else - { - if (location.map.GetLayer("Paths") == null) - return; - Tile tile2 = location.map.GetLayer("Paths").PickTile(new Location(this.getStandingX(), this.getStandingY()), Game1.viewport.Size); - Microsoft.Xna.Framework.Rectangle boundingBox = this.GetBoundingBox(); - boundingBox.Inflate(2, 2); - if (tile2 == null || !new Microsoft.Xna.Framework.Rectangle(this.getStandingX() - this.getStandingX() % Game1.tileSize, this.getStandingY() - this.getStandingY() % Game1.tileSize, Game1.tileSize, Game1.tileSize).Contains(boundingBox)) - return; - switch (tile2.TileIndex) - { - case 0: - if (this.getDirection() == 3) - { - this.SetMovingOnlyUp(); - break; - } - if (this.getDirection() != 2) - break; - this.SetMovingOnlyRight(); - break; - case 1: - if (this.getDirection() == 3) - { - this.SetMovingOnlyDown(); - break; - } - if (this.getDirection() != 0) - break; - this.SetMovingOnlyRight(); - break; - case 2: - if (this.getDirection() == 1) - { - this.SetMovingOnlyDown(); - break; - } - if (this.getDirection() != 0) - break; - this.SetMovingOnlyLeft(); - break; - case 3: - if (this.getDirection() == 1) - { - this.SetMovingOnlyUp(); - break; - } - if (this.getDirection() != 2) - break; - this.SetMovingOnlyLeft(); - break; - case 4: - this.changeSchedulePathDirection(); - this.moveCharacterOnSchedulePath(); - break; - case 7: - this.ReachedEndPoint(); - break; - } - } - } - } - else - { - if (!this.IsWalkingInSquare) - return; - this.randomSquareMovement(time); - this.MovePosition(time, Game1.viewport, location); - } - } - //ERROR NEED FIXING public override void MovePosition(GameTime time, xTile.Dimensions.Rectangle viewport, GameLocation currentLocation) { + base.MovePosition(time,viewport,currentLocation); + return; if (this.GetType() == typeof(FarmAnimal)) this.willDestroyObjectsUnderfoot = false; if ((double)this.xVelocity != 0.0 || (double)this.yVelocity != 0.0) @@ -382,11 +250,6 @@ namespace CustomNPCFramework.Framework.NPCS base.update(time, location); } - public virtual void prepareToDisembarkOnNewSchedulePath() - { - - } - public virtual void routeEndAnimationFinished(StardewValley.Farmer who) { this.doingEndOfRouteAnimation = false; @@ -408,10 +271,6 @@ namespace CustomNPCFramework.Framework.NPCS { } - public virtual void doMiddleAnimation(StardewValley.Farmer who) - { - - } public virtual void startRouteBehavior(string behaviorName) { @@ -575,7 +434,7 @@ namespace CustomNPCFramework.Framework.NPCS { b.Draw(this.Sprite.Texture, this.getLocalPosition(Game1.viewport) + new Vector2((float)(Game1.tileSize / 2), (float)(Game1.tileSize + Game1.tileSize / 4 + this.yJumpOffset * 2)) + (this.shakeTimer > 0 ? new Vector2((float)Game1.random.Next(-1, 2), (float)Game1.random.Next(-1, 2)) : Vector2.Zero) - new Vector2(0.0f, this.yOffset), new Microsoft.Xna.Framework.Rectangle?(new Microsoft.Xna.Framework.Rectangle(this.sprite.SourceRect.X, this.sprite.SourceRect.Y, this.sprite.SourceRect.Width, this.sprite.SourceRect.Height / 2 - (int)((double)this.yOffset / (double)Game1.pixelZoom))), Color.White, this.rotation, new Vector2((float)(Game1.tileSize / 2), (float)(Game1.tileSize * 3 / 2)) / 4f, Math.Max(0.2f, this.scale) * (float)Game1.pixelZoom, this.flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, Math.Max(0.0f, this.drawOnTop ? 0.991f : (float)this.getStandingY() / 10000f)); Vector2 localPosition = this.getLocalPosition(Game1.viewport); - b.Draw(Game1.staminaRect, new Microsoft.Xna.Framework.Rectangle((int)localPosition.X + (int)this.yOffset + Game1.pixelZoom * 2, (int)localPosition.Y - 32 * Game1.pixelZoom + this.sprite.SourceRect.Height * Game1.pixelZoom + Game1.tileSize * 3 / 4 + this.yJumpOffset * 2 - (int)this.yOffset, this.sprite.SourceRect.Width * Game1.pixelZoom - (int)this.yOffset * 2 - Game1.pixelZoom * 4, Game1.pixelZoom), new Microsoft.Xna.Framework.Rectangle?(Game1.staminaRect.Bounds), Color.White * 0.75f, 0.0f, Vector2.Zero, SpriteEffects.None, (float)((double)this.getStandingY() / 10000.0 + 1.0 / 1000.0)); + //b.Draw(Game1.staminaRect, new Microsoft.Xna.Framework.Rectangle((int)localPosition.X + (int)this.yOffset + Game1.pixelZoom * 2, (int)localPosition.Y - 32 * Game1.pixelZoom + this.sprite.SourceRect.Height * Game1.pixelZoom + Game1.tileSize * 3 / 4 + this.yJumpOffset * 2 - (int)this.yOffset, this.sprite.SourceRect.Width * Game1.pixelZoom - (int)this.yOffset * 2 - Game1.pixelZoom * 4, Game1.pixelZoom), new Microsoft.Xna.Framework.Rectangle?(Game1.staminaRect.Bounds), Color.White * 0.75f, 0.0f, Vector2.Zero, SpriteEffects.None, (float)((double)this.getStandingY() / 10000.0 + 1.0 / 1000.0)); } else b.Draw(this.Sprite.Texture, this.getLocalPosition(Game1.viewport) + new Vector2((float)(this.sprite.spriteWidth * Game1.pixelZoom / 2), (float)(this.GetBoundingBox().Height / 2)) + (this.shakeTimer > 0 ? new Vector2((float)Game1.random.Next(-1, 2), (float)Game1.random.Next(-1, 2)) : Vector2.Zero), new Microsoft.Xna.Framework.Rectangle?(this.Sprite.SourceRect), Color.White * alpha, this.rotation, new Vector2((float)(this.sprite.spriteWidth / 2), (float)((double)this.sprite.spriteHeight * 3.0 / 4.0)), Math.Max(0.2f, this.scale) * (float)Game1.pixelZoom, this.flip || this.sprite.currentAnimation != null && this.sprite.currentAnimation[this.sprite.currentAnimationIndex].flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, Math.Max(0.0f, this.drawOnTop ? 0.991f : (float)this.getStandingY() / 10000f)); @@ -600,13 +459,14 @@ namespace CustomNPCFramework.Framework.NPCS sourceRect.Height /= 2; } float num = Math.Max(0.0f, (float)(Math.Ceiling(Math.Sin(Game1.currentGameTime.TotalGameTime.TotalMilliseconds / 600.0 + (double)this.DefaultPosition.X * 20.0)) / 4.0)); + b.Draw(this.Sprite.Texture, this.getLocalPosition(Game1.viewport) + vector2 + (this.shakeTimer > 0 ? new Vector2((float)Game1.random.Next(-1, 2), (float)Game1.random.Next(-1, 2)) : Vector2.Zero), new Microsoft.Xna.Framework.Rectangle?(sourceRect), Color.White * alpha, this.rotation, new Vector2((float)(sourceRect.Width / 2), (float)(sourceRect.Height / 2 + 1)), Math.Max(0.2f, this.scale) * (float)Game1.pixelZoom + num, this.flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, Math.Max(0.0f, this.drawOnTop ? 0.992f : (float)((double)this.getStandingY() / 10000.0 + 1.0 / 1000.0))); } if (this.isGlowing) b.Draw(this.Sprite.Texture, this.getLocalPosition(Game1.viewport) + new Vector2((float)(this.sprite.spriteWidth * Game1.pixelZoom / 2), (float)(this.GetBoundingBox().Height / 2)) + (this.shakeTimer > 0 ? new Vector2((float)Game1.random.Next(-1, 2), (float)Game1.random.Next(-1, 2)) : Vector2.Zero), new Microsoft.Xna.Framework.Rectangle?(this.Sprite.SourceRect), this.glowingColor * this.glowingTransparency, this.rotation, new Vector2((float)(this.sprite.spriteWidth / 2), (float)((double)this.sprite.spriteHeight * 3.0 / 4.0)), Math.Max(0.2f, this.scale) * 4f, this.flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, Math.Max(0.0f, this.drawOnTop ? 0.99f : (float)((double)this.getStandingY() / 10000.0 + 1.0 / 1000.0))); Vector2 localPosition1 = this.getLocalPosition(Game1.viewport); localPosition1.Y -= (float)(Game1.tileSize / 2 + this.sprite.spriteHeight * Game1.pixelZoom); - b.Draw(Game1.emoteSpriteSheet, localPosition1, new Microsoft.Xna.Framework.Rectangle?(new Microsoft.Xna.Framework.Rectangle(this.CurrentEmoteIndex * 16 % Game1.emoteSpriteSheet.Width, this.CurrentEmoteIndex * 16 / Game1.emoteSpriteSheet.Width * 16, 16, 16)), Color.White, 0.0f, Vector2.Zero, (float)Game1.pixelZoom, SpriteEffects.None, (float)this.getStandingY() / 10000f); + //b.Draw(Game1.emoteSpriteSheet, localPosition1, new Microsoft.Xna.Framework.Rectangle?(new Microsoft.Xna.Framework.Rectangle(this.CurrentEmoteIndex * 16 % Game1.emoteSpriteSheet.Width, this.CurrentEmoteIndex * 16 / Game1.emoteSpriteSheet.Width * 16, 16, 16)), Color.White, 0.0f, Vector2.Zero, (float)Game1.pixelZoom, SpriteEffects.None, (float)this.getStandingY() / 10000f); } From e5808eeb5cabfe45808ad9250634d5ba4f3a7bbb Mon Sep 17 00:00:00 2001 From: Date: Sat, 3 Mar 2018 19:24:36 -0800 Subject: [PATCH 18/18] Yup. --- .../Framework/NPCS/ExtendedNPC.cs | 6 ++ GeneralMods/HappyBirthday/HappyBirthday.cs | 80 ++++++++++++++++--- .../HappyBirthday/HappyBirthday.csproj | 11 +-- GeneralMods/HappyBirthday/PossibleGifts.cs | 58 ++++++++++++++ 4 files changed, 135 insertions(+), 20 deletions(-) create mode 100644 GeneralMods/HappyBirthday/PossibleGifts.cs diff --git a/GeneralMods/CustomNPCFramework/Framework/NPCS/ExtendedNPC.cs b/GeneralMods/CustomNPCFramework/Framework/NPCS/ExtendedNPC.cs index dd429a7a..173c4e3f 100644 --- a/GeneralMods/CustomNPCFramework/Framework/NPCS/ExtendedNPC.cs +++ b/GeneralMods/CustomNPCFramework/Framework/NPCS/ExtendedNPC.cs @@ -18,6 +18,12 @@ using xTile.Tiles; namespace CustomNPCFramework.Framework.NPCS { + /// + /// TODO: Add in an resource loader for all of the character graphics and use it to populate some character graphics. + /// Make .json way to load in assets to the mod. + /// Organize it all. + /// Profit??? + /// public class ExtendedNPC :StardewValley.NPC { public BasicRenderer characterRenderer; diff --git a/GeneralMods/HappyBirthday/HappyBirthday.cs b/GeneralMods/HappyBirthday/HappyBirthday.cs index 869e4829..83270f9a 100644 --- a/GeneralMods/HappyBirthday/HappyBirthday.cs +++ b/GeneralMods/HappyBirthday/HappyBirthday.cs @@ -13,7 +13,7 @@ using SObject = StardewValley.Object; namespace Omegasis.HappyBirthday { /// The mod entry point. - public class HappyBirthday : Mod + public class HappyBirthday : Mod, IAssetEditor, IAssetLoader { /********* ** Properties @@ -46,6 +46,68 @@ namespace Omegasis.HappyBirthday private bool CheckedForBirthday; //private Dictionary Dialogue; //private bool SeenEvent; + public bool CanLoad(IAssetInfo asset) + { + return asset.AssetNameEquals(@"Data\FarmerBirthdayDialogue"); + } + + /// Load a matched asset. + /// Basic metadata about the asset being loaded. + public T Load(IAssetInfo asset) + { + return (T)(object)new Dictionary // (T)(object) is a trick to cast anything to T if we know it's compatible + { + ["Robin"] = "Hey @, happy birthday! I'm glad you choose this town to move here to. ", + ["Demetrius"] = "Happy birthday @! Make sure you take some time off today to enjoy yourself. $h", + ["Maru"] = "Happy birthday @. I tried to make you an everlasting candle but sadly that didn't work out. Maybe next year right? $h", + ["Sebastian"] = "Happy birthday @. Here's to another year of chilling. ", + ["Linus"] = "Happy birthday @. Thanks for visiting me even on your birthday. It makes me really happy. ", + ["Pierre"] = "Hey @, happy birthday! Hopefully this next year for you will be a great one! ", + ["Caroline"] = "Happy birthday @. Thank you for all that you've done for our community. I'm sure your parents must be proud of you.$h", + ["Abigail"] = "Happy Birthday @! Hopefully this year we can go on even more adventures together $h!", + ["Alex"] = "Yo @, happy birthday! Maybe this will be your best year yet.$h", + ["George"] = "When you get to my age birthdays come and go. Still happy birthday @.", + ["Evelyn"] = "Happy birthday @. You have grown up to be such a fine individual and I'm sure you'll continue to grow. ", + ["Lewis"] = "Happy birthday @! I'm thankful for what you have done for the town and I'm sure your grandfather would be proud of you.", + ["Clint"] = "Hey happy birthday @. I'm sure this year is going to be great for you.", + ["Penny"] = "Happy birthday @. May you enjoy all of life's blessings this year. ", + ["Pam"] = "Happy birthday kid. We should have a drink to celebrate another year of life for you! $h", + ["Emily"] = "I'm sensing a strong positive life energy about you, so it must be your birthday. Happy birthday @!$h", + ["Haley"] = "Happy birthday @. Hopefully this year you'll get some good presents!$h", + ["Jas"] = "Happy birthday @. I hope you have a good birthday.", + ["Vincent"] = "Hey @ have you come to pl...oh it's your birthday? Happy birthday! ", + ["Jodi"] = "Hello there @. Rumor has it that today is your birthday. In that case, happy birthday!$h", + ["Kent"] = "Jodi told me that it was your birthday today @. Happy birthday and make sure to cherish every single day.", + ["Sam"] = "Yo @ happy birthday! We'll have to have a birthday jam session for you some time!$h ", + ["Leah"] = "Hey @ happy birthday! We should go to the saloon tonight and celebrate!$h ", + ["Shane"] = "Happy birthday @. Keep working hard and I'm sure this next year for you will be a great one.", + ["Marnie"] = "Hello there @. Everyone is talking about your birthday today and I wanted to make sure that I wished you a happy birthday as well, so happy birthday! $h ", + ["Elliott"] = "What a wonderful day isn't it @? Especially since today is your birthday. I tried to make you a poem but I feel like the best way of putting it is simply, happy birthday. $h ", + ["Gus"] = "Hey @ happy birthday! Hopefully you enjoy the rest of the day and make sure you aren't a stranger at the saloon!", + ["Dwarf"] = "Happy birthday @. I hope that what I got you is acceptable for humans as well. ", + ["Wizard"] = "The spirits told me that today is your birthday. In that case happy birthday @. ", + ["Harvey"] = "Hey @, happy birthday! Make sure to come in for a checkup some time to make sure you live many more years! ", + ["Sandy"] = "Hello there @. I heard that today was your birthday and I didn't want you feeling left out, so happy birthday!", + ["Willy"] = "Aye @ happy birthday. Looking at you reminds me of ye days when I was just a guppy swimming out to sea. Continue to enjoy them youngin.$h", + ["Krobus"] = "I have heard that it is tradition to give a gift to others on their birthday. In that case, happy birthday @." + }; + } + + public bool CanEdit(IAssetInfo asset) + { + return asset.AssetNameEquals(@"Data\mail"); + } + + public void Edit(IAssetData asset) + { + asset + .AsDictionary() + .Set("birthdayMom", "Dear @,^ Happy birthday sweetheart. It's been amazing watching you grow into the kind, hard working person that I've always dreamed that you would become. I hope you continue to make many more fond memories with the ones you love. ^ Love, Mom ^ P.S. Here's a little something that I made for you. %item object 221 1 %%"); + + asset + .AsDictionary() + .Set("birthdayDad", "Dear @,^ Happy birthday kiddo. It's been a little quiet around here on your birthday since you aren't around, but your mother and I know that you are making both your grandpa and us proud. We both know that living on your own can be tough but we believe in you one hundred percent, just keep following your dreams.^ Love, Dad ^ P.S. Here's some spending money to help you out on the farm. Good luck! %item money 5000 5001 %%"); + } /********* @@ -55,6 +117,7 @@ namespace Omegasis.HappyBirthday /// Provides simplified APIs for writing mods. public override void Entry(IModHelper helper) { + helper.Content.AssetLoaders.Add(new PossibleGifts()); this.Config = helper.ReadConfig(); TimeEvents.AfterDayStarted += this.TimeEvents_AfterDayStarted; @@ -299,8 +362,7 @@ namespace Omegasis.HappyBirthday { // read from birthday gifts file IDictionary data = Game1.content.Load>("Data\\PossibleBirthdayGifts"); - string text; - data.TryGetValue(name, out text); + data.TryGetValue(name, out string text); if (text != null) { string[] fields = text.Split('/'); @@ -400,8 +462,7 @@ namespace Omegasis.HappyBirthday if (!isBirthdayGiftList) { // get raw data - string text; - Game1.NPCGiftTastes.TryGetValue($"Universal_{group}", out text); + Game1.NPCGiftTastes.TryGetValue($"Universal_{group}", out string text); if (text == null) yield break; @@ -417,8 +478,7 @@ namespace Omegasis.HappyBirthday { // get raw data Dictionary data = Game1.content.Load>("Data\\PossibleBirthdayGifts"); - string text; - data.TryGetValue($"Universal_{group}_Gift", out text); + data.TryGetValue($"Universal_{group}_Gift", out string text); if (text == null) yield break; @@ -437,8 +497,7 @@ namespace Omegasis.HappyBirthday private IEnumerable GetLikedItems(string name) { // get raw data - string text; - Game1.NPCGiftTastes.TryGetValue(name, out text); + Game1.NPCGiftTastes.TryGetValue(name, out string text); if (text == null) yield break; @@ -457,8 +516,7 @@ namespace Omegasis.HappyBirthday private IEnumerable GetLovedItems(string name) { // get raw data - string text; - Game1.NPCGiftTastes.TryGetValue(name, out text); + Game1.NPCGiftTastes.TryGetValue(name, out string text); if (text == null) yield break; diff --git a/GeneralMods/HappyBirthday/HappyBirthday.csproj b/GeneralMods/HappyBirthday/HappyBirthday.csproj index b5255214..efee159d 100644 --- a/GeneralMods/HappyBirthday/HappyBirthday.csproj +++ b/GeneralMods/HappyBirthday/HappyBirthday.csproj @@ -23,6 +23,7 @@ prompt 4 false + x86 pdbonly @@ -47,18 +48,10 @@ + - - PreserveNewest - - - PreserveNewest - - - PreserveNewest - diff --git a/GeneralMods/HappyBirthday/PossibleGifts.cs b/GeneralMods/HappyBirthday/PossibleGifts.cs new file mode 100644 index 00000000..0e212841 --- /dev/null +++ b/GeneralMods/HappyBirthday/PossibleGifts.cs @@ -0,0 +1,58 @@ +using StardewModdingAPI; +using System.Collections.Generic; + +namespace Omegasis.HappyBirthday +{ + class PossibleGifts : IAssetLoader + { + public bool CanLoad(IAssetInfo asset) + { + return asset.AssetNameEquals(@"Data\PossibleBirthdayGifts"); + } + + /// Load a matched asset. + /// Basic metadata about the asset being loaded. + public T Load(IAssetInfo asset) + { + return (T)(object)new Dictionary // (T)(object) is a trick to cast anything to T if we know it's compatible + { + ["Universal_Love_Gift"] = "74 1 446 1 204 1 446 5 773 1", + ["Universal_Like_Gift"] = "-2 3 -7 1 -26 2 -75 5 -80 3 72 1 220 1 221 1 395 1 613 1 634 1 635 1 636 1 637 1 638 1 724 1 233 1 223 1 465 20 -79 5", + ["Universal_Neutral_Gift"] = "194 1 262 5 -74 5 -75 3 334 5 335 1 390 20 388 20 -81 5 -79 3", + ["Robin"] = " BestGifts/224 1 426 1 636 1/GoodGift/-6 5 -79 5 424 1 709 1/NeutralGift//", + ["Demetrius"] = " Best Gifts/207 1 232 1 233 1 400 1/Good Gifts/-5 3 -79 5 422 1/NeutralGift/-4 3/", + ["Maru"] = " BestGift/72 1 197 1 190 1 215 1 222 1 243 1 336 1 337 1 400 1 787 1/Good Gift/-260 1 62 1 64 1 66 1 68 1 70 1 334 1 335 1 725 1 726 1/NeutralGift/", + ["Sebastian"] = " Best/84 1 227 1 236 1 575 1 305 1 /Good/267 1 276 1/Neutral/-4 3/", + ["Linus"] = " Best/88 1 90 1 234 1 242 1 280 1/Good/-5 3 -6 5 -79 5 -81 10/Neutral/-4 3/", + ["Pierre"] = " Best/202 1/Good/-5 3 -6 5 -7 1 18 1 22 1 402 1 418 1 259 1/Neutral//", + ["Caroline"] = " Best/213 1 593 1/Good/-7 1 18 1 402 1 418 1/Neutral// ", + ["Abigail"] = " Best/66 1 128 1 220 1 226 1 276 1 611 1/Good//Neutral// ", + ["Alex"] = " Best/201 1 212 1 662 1 664 1/Good/-5 3/Neutral// ", + ["George"] = " Best/20 1 205 1/Good/18 1 195 1 199 1 200 1 214 1 219 1 223 1 231 1 233 1/Neutral// ", + ["Evelyn"] = " Best/72 1 220 1 239 1 284 1 591 1 595 1/Good/-6 5 18 1 402 1 418 1/Neutral// ", + ["Lewis"] = " Best/200 1 208 1 235 1 260 1/Good/-80 5 24 1 88 1 90 1 192 1 258 1 264 1 272 1 274 1 278 1/Neutral// ", + ["Clint"] = " Best/60 1 62 1 64 1 66 1 68 1 70 1 336 1 337 1 605 1 649 1 749 1 337 5/Good/334 20 335 10 336 5/Neutral// ", + ["Penny"] = " Best/60 1 376 1 651 1 72 1 164 1 218 1 230 1 244 1 254 1/Good/-6 5 20 1 22 1/Neutral// ", + ["Pam"] = " Best/24 1 90 1 199 1 208 1 303 1 346 1/Good/-6 5 -75 5 -79 5 18 1 227 1 228 1 231 1 232 1 233 1 234 1 235 1 236 1 238 1 402 1 418 1/Neutral/-4 3/ ", + ["Emily"] = " Best/60 1 62 1 64 1 66 1 68 1 70 1 241 1 428 1 440 1 /Good/18 1 82 1 84 1 86 1 196 1 200 1 207 1 230 1 235 1 402 1 418 1/Neutral// ", + ["Haley"] = " Best/221 1 421 1 610 1 88 1 /Good/18 1 60 1 62 1 64 1 70 1 88 1 222 1 223 1 232 1 233 1 234 1 402 1 418 1 /Neutral// ", + ["Jas"] = " Best/221 1 595 1 604 1 /Good/18 1 60 1 64 1 70 1 88 1 232 1 233 1 234 1 222 1 223 1 340 1 344 1 402 1 418 1 /Neutral// ", + ["Vincent"] = " Best/221 1 398 1 612 1 /Good/18 1 60 1 64 1 70 1 88 1 232 1 233 1 234 1 222 1 223 1 340 1 344 1 402 1 418 1 /Neutral// ", + ["Jodi"] = " Best/72 1 200 1 211 1 214 1 220 1 222 1 225 1 231 1 /Good/-5 3 -6 5 -79 5 18 1 402 1 418 1 /Neutral// ", + ["Kent"] = " Best/607 1 649 1 /Good/-5 3 -79 5 18 1 402 1 418 1 /Neutral// ", + ["Sam"] = " Best/90 1 206 1 655 1 658 1 562 1 731 1/Good/167 1 210 1 213 1 220 1 223 1 224 1 228 1 232 1 233 1 239 1 -5 3/Neutral// ", + ["Leah"] = " Best/196 1 200 1 348 1 606 1 651 1 650 1 426 1 430 1 /Good/-5 3 -6 5 -79 5 -81 10 18 1 402 1 406 1 408 1 418 1 86 1 /Neutral// ", + ["Shane"] = " Best/206 1 215 1 260 1 346 1 /Good/-5 3 -79 5 303 1 /Neutral// ", + ["Marnie"] = " Best/72 1 221 1 240 1 608 1 /Good/-5 3 -6 5 402 1 418 1 /Neutral// ", + ["Elliott"] = " Best/715 1 732 1 218 1 444 1 /Good/727 1 728 1 -79 5 60 1 80 1 82 1 84 1 149 1 151 1 346 1 348 1 728 1 /Neutral/-4 3 / ", + ["Gus"] = " Best/72 1 213 1 635 1 729 1 /Good/348 1 303 1 -7 1 18 1 /Neutral// ", + ["Dwarf"] = " Best/60 1 62 1 64 1 66 1 68 1 70 1 749 1 /Good/82 1 84 1 86 1 96 1 97 1 98 1 99 1 121 1 122 1 /Neutral/-28 20 / ", + ["Wizard"] = " Best/107 1 155 1 422 1 769 1 768 1 /Good/-12 3 72 1 82 1 84 1/Neutral// ", + ["Harvey"] = " Best/348 1 237 1 432 1 395 1 342 1 /Good/-81 10 -79 5 -7 1 402 1 418 1 422 1 436 1 438 1 442 1 444 1 422 1 /Neutral// ", + ["Sandy"] = " Best/18 1 402 1 418 1 /Good/-75 5 -79 5 88 1 428 1 436 1 438 1 440 1 /Neutral// ", + ["Willy"] = " Best/72 1 143 1 149 1 154 1 276 1 337 1 698 1 /Good/66 1 336 1 340 1 699 1 707 1 /Neutral/-4 3 / ", + ["Krobus"] = " Best/72 1 16 1 276 1 337 1 305 1 /Good/66 1 336 1 340 1 /Neutral// " + }; + } + } +}