Merge pull request #51 from janavarro95/Development

Development
This commit is contained in:
Joshua Navarro 2019-01-14 12:28:14 -08:00 committed by GitHub
commit 82499561b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
360 changed files with 10866 additions and 17717 deletions

67
.editorconfig Normal file
View File

@ -0,0 +1,67 @@
# topmost editorconfig
root: true
##########
## General formatting
## documentation: https://editorconfig.org
##########
[*]
indent_style = space
indent_size = 4
insert_final_newline = true
trim_trailing_whitespace = true
charset = utf-8
[*.{csproj,json,nuspec,targets}]
indent_size = 2
[*.csproj]
insert_final_newline = false
##########
## C# formatting
## documentation: https://docs.microsoft.com/en-us/visualstudio/ide/editorconfig-code-style-settings-reference
##########
[*.cs]
#sort 'system' usings first
dotnet_sort_system_directives_first = true
# use 'this.' qualifier
dotnet_style_qualification_for_field = true:error
dotnet_style_qualification_for_property = true:error
dotnet_style_qualification_for_method = true:error
dotnet_style_qualification_for_event = true:error
# use language keywords (like int) instead of type (like Int32)
dotnet_style_predefined_type_for_locals_parameters_members = true:error
dotnet_style_predefined_type_for_member_access = true:error
# don't use 'var' for language keywords
csharp_style_var_for_built_in_types = false:error
# suggest modern C# features where simpler
dotnet_style_object_initializer = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_explicit_tuple_names = true:suggestion
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
csharp_style_conditional_delegate_call = true:suggestion
csharp_prefer_simple_default_expression = true:suggestion
# prefer method block bodies
csharp_style_expression_bodied_methods = false:suggestion
csharp_style_expression_bodied_constructors = false:suggestion
# prefer property expression bodies
csharp_style_expression_bodied_properties = true:suggestion
csharp_style_expression_bodied_indexers = true:suggestion
csharp_style_expression_bodied_accessors = true:suggestion
# prefer inline out variables
csharp_style_inlined_variable_declaration = true:warning
# avoid superfluous braces
csharp_prefer_braces = false:suggestion

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -11,8 +11,6 @@
<AssemblyName>AdvancedSaveBackup</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -67,6 +65,9 @@
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Pathoschild.Stardew.ModBuildConfig" Version="2.2.0" />
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.IO.Compression" />
@ -83,19 +84,8 @@
</ItemGroup>
<ItemGroup>
<None Include="manifest.json" />
<None Include="packages.config" />
<None Include="README.md" />
</ItemGroup>
<ItemGroup>
<Analyzer Include="..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\analyzers\dotnet\cs\StardewModdingAPI.ModBuildConfig.Analyzer.dll" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\deploy.targets" />
<Import Project="..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets" Condition="Exists('..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>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}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets'))" />
</Target>
</Project>

View File

@ -1,4 +1,4 @@
namespace Omegasis.SaveBackup.Framework
namespace Omegasis.SaveBackup.Framework
{
/// <summary>The mod configuration.</summary>
internal class ModConfig

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.IO;
using System.IO.Compression;
using System.Linq;
@ -12,7 +12,7 @@ namespace Omegasis.SaveBackup
public class SaveBackup : Mod
{
/*********
** Properties
** Fields
*********/
/// <summary>The folder path containing the game's app data.</summary>
private static readonly string AppDataPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "StardewValley");
@ -41,17 +41,17 @@ namespace Omegasis.SaveBackup
this.BackupSaves(SaveBackup.PrePlayBackupsPath);
SaveEvents.BeforeSave += this.SaveEvents_BeforeSave;
helper.Events.GameLoop.Saving += this.OnSaving;
}
/*********
** Private methods
*********/
/// <summary>The method invoked before the save is updated.</summary>
/// <summary>Raised before the game begins writes data to the save file (except the initial save creation).</summary>
/// <param name="sender">The event sender.</param>
/// <param name="e">The event data.</param>
private void SaveEvents_BeforeSave(object sender, EventArgs e)
/// <param name="e">The event arguments.</param>
private void OnSaving(object sender, SavingEventArgs e)
{
this.BackupSaves(SaveBackup.NightlyBackupsPath);
}

View File

@ -1,10 +1,10 @@
{
"Name": "Advanced Save Backup",
"Author": "Alpha_Omegasis",
"Version": "1.5.0",
"Version": "1.6.0",
"Description": "Backs up your save files when loading SMAPI and every in game night when saving.",
"UniqueID": "Omegasis.AdvancedSaveBackup",
"EntryDll": "AdvancedSaveBackup.dll",
"MinimumApiVersion": "2.0",
"MinimumApiVersion": "2.10.1",
"UpdateKeys": [ "Nexus:435" ]
}

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Pathoschild.Stardew.ModBuildConfig" version="2.2.0" targetFramework="net45" />
</packages>

View File

@ -1,4 +1,3 @@
using System;
using Omegasis.AutoSpeed.Framework;
using StardewModdingAPI;
using StardewModdingAPI.Events;
@ -10,7 +9,7 @@ namespace Omegasis.AutoSpeed
public class AutoSpeed : Mod
{
/*********
** Properties
** Fields
*********/
/// <summary>The mod configuration.</summary>
private ModConfig Config;
@ -23,7 +22,7 @@ namespace Omegasis.AutoSpeed
/// <param name="helper">Provides simplified APIs for writing mods.</param>
public override void Entry(IModHelper helper)
{
GameEvents.UpdateTick += this.GameEvents_UpdateTick;
helper.Events.GameLoop.UpdateTicked += this.OnUpdateTicked;
this.Config = helper.ReadConfig<ModConfig>();
}
@ -31,10 +30,10 @@ namespace Omegasis.AutoSpeed
/*********
** Private methods
*********/
/// <summary>The method invoked when the game updates (roughly 60 times per second).</summary>
/// <summary>Raised after the game state is updated (≈60 times per second).</summary>
/// <param name="sender">The event sender.</param>
/// <param name="e">The event data.</param>
private void GameEvents_UpdateTick(object sender, EventArgs e)
/// <param name="e">The event arguments.</param>
private void OnUpdateTicked(object sender, UpdateTickedEventArgs e)
{
if (Context.IsPlayerFree)
Game1.player.addedSpeed = this.Config.Speed;

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -11,8 +11,6 @@
<AssemblyName>AutoSpeed</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -67,6 +65,9 @@
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Pathoschild.Stardew.ModBuildConfig" Version="2.2.0" />
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Xml" />
@ -81,19 +82,8 @@
</ItemGroup>
<ItemGroup>
<None Include="manifest.json" />
<None Include="packages.config" />
<None Include="README.md" />
</ItemGroup>
<ItemGroup>
<Analyzer Include="..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\analyzers\dotnet\cs\StardewModdingAPI.ModBuildConfig.Analyzer.dll" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\deploy.targets" />
<Import Project="..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets" Condition="Exists('..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>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}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets'))" />
</Target>
</Project>

View File

@ -1,4 +1,4 @@
namespace Omegasis.AutoSpeed.Framework
namespace Omegasis.AutoSpeed.Framework
{
/// <summary>The mod configuration.</summary>
internal class ModConfig

View File

@ -1,10 +1,10 @@
{
"Name": "Auto Speed",
"Author": "Alpha_Omegasis",
"Version": "1.6.0",
"Version": "1.7.0",
"Description": "Got to go fast!",
"UniqueID": "Omegasis.AutoSpeed",
"EntryDll": "AutoSpeed.dll",
"MinimumApiVersion": "2.0",
"MinimumApiVersion": "2.10.1",
"UpdateKeys": [ "Nexus:443" ]
}

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Pathoschild.Stardew.ModBuildConfig" version="2.2.0" targetFramework="net45" />
</packages>

View File

@ -1,4 +1,4 @@
using Omegasis.BillboardAnywhere.Framework;
using Omegasis.BillboardAnywhere.Framework;
using StardewModdingAPI;
using StardewModdingAPI.Events;
using StardewValley;
@ -10,7 +10,7 @@ namespace Omegasis.BillboardAnywhere
public class BillboardAnywhere : Mod
{
/*********
** Properties
** Fields
*********/
/// <summary>The mod configuration.</summary>
private ModConfig Config;
@ -25,20 +25,20 @@ namespace Omegasis.BillboardAnywhere
{
this.Config = helper.ReadConfig<ModConfig>();
ControlEvents.KeyPressed += this.ControlEvents_KeyPressed;
helper.Events.Input.ButtonPressed += this.OnButtonPressed;
}
/*********
** Private methods
*********/
/// <summary>The method invoked when the presses a keyboard button.</summary>
/// <summary>Raised after the player presses a button on the keyboard, controller, or mouse.</summary>
/// <param name="sender">The event sender.</param>
/// <param name="e">The event data.</param>
public void ControlEvents_KeyPressed(object sender, EventArgsKeyPressed e)
/// <param name="e">The event arguments.</param>
public void OnButtonPressed(object sender, ButtonPressedEventArgs e)
{
// load menu if key pressed
if (Context.IsPlayerFree && e.KeyPressed.ToString() == this.Config.KeyBinding)
if (Context.IsPlayerFree && e.Button == this.Config.KeyBinding)
Game1.activeClickableMenu = new Billboard();
}
}

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -11,8 +11,6 @@
<AssemblyName>BillboardAnywhere</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -67,6 +65,9 @@
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Pathoschild.Stardew.ModBuildConfig" Version="2.2.0" />
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Xml" />
@ -83,19 +84,8 @@
<None Include="manifest.json" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="README.md" />
</ItemGroup>
<ItemGroup>
<Analyzer Include="..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\analyzers\dotnet\cs\StardewModdingAPI.ModBuildConfig.Analyzer.dll" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\deploy.targets" />
<Import Project="..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets" Condition="Exists('..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>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}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets'))" />
</Target>
</Project>

View File

@ -1,9 +1,11 @@
namespace Omegasis.BillboardAnywhere.Framework
using StardewModdingAPI;
namespace Omegasis.BillboardAnywhere.Framework
{
/// <summary>The mod configuration.</summary>
internal class ModConfig
{
/// <summary>The key which shows the billboard menu.</summary>
public string KeyBinding { get; set; } = "B";
public SButton KeyBinding { get; set; } = SButton.B;
}
}

View File

@ -1,10 +1,10 @@
{
"Name": "Billboard Anywhere",
"Author": "Alpha_Omegasis",
"Version": "1.6.0",
"Version": "1.7.0",
"Description": "Lets you view the billboard from anywhere.",
"UniqueID": "Omegasis.BillboardAnywhere",
"EntryDll": "BillboardAnywhere.dll",
"MinimumApiVersion": "2.0",
"MinimumApiVersion": "2.10.1",
"UpdateKeys": [ "Nexus:492" ]
}

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Pathoschild.Stardew.ModBuildConfig" version="2.2.0" targetFramework="net45" />
</packages>

View File

@ -1,6 +1,4 @@
using System;
using System.IO;
using System.Linq;
using Omegasis.BuildEndurance.Framework;
using StardewModdingAPI;
using StardewModdingAPI.Events;
@ -12,13 +10,10 @@ namespace Omegasis.BuildEndurance
public class BuildEndurance : Mod
{
/*********
** Properties
** Fields
*********/
/// <summary>The relative path for the current player's data file.</summary>
private string DataFilePath => Path.Combine("data", $"{Constants.SaveFolderName}.json");
/// <summary>The absolute path for the current player's legacy data file.</summary>
private string LegacyDataFilePath => Path.Combine(this.Helper.DirectoryPath, "PlayerData", $"BuildEndurance_data_{Game1.player.Name}.txt");
private string RelativeDataPath => Path.Combine("data", $"{Constants.SaveFolderName}.json");
/// <summary>The mod settings.</summary>
private ModConfig Config;
@ -38,10 +33,10 @@ namespace Omegasis.BuildEndurance
/// <summary>Whether the player was eating last time we checked.</summary>
private bool WasEating;
public IModHelper ModHelper;
public IMonitor ModMonitor;
/*********
** Public methods
*********/
@ -51,10 +46,9 @@ namespace Omegasis.BuildEndurance
{
this.Config = helper.ReadConfig<ModConfig>();
GameEvents.UpdateTick += this.GameEvents_UpdateTick;
GameEvents.OneSecondTick += this.GameEvents_OneSecondTick;
SaveEvents.AfterLoad += this.SaveEvents_AfterLoad;
SaveEvents.BeforeSave += this.SaveEvents_BeforeSave;
helper.Events.GameLoop.UpdateTicked += this.OnUpdateTicked;
helper.Events.GameLoop.SaveLoaded += this.OnSaveLoaded;
helper.Events.GameLoop.Saving += this.OnSaving;
this.ModHelper = this.Helper;
this.ModMonitor = this.Monitor;
@ -64,24 +58,18 @@ namespace Omegasis.BuildEndurance
/*********
** Private methods
*********/
/// <summary>The method invoked once per second during a game update.</summary>
/// <summary>Raised after the game state is updated (≈60 times per second).</summary>
/// <param name="sender">The event sender.</param>
/// <param name="e">The event data.</param>
private void GameEvents_OneSecondTick(object sender, EventArgs e)
{
// nerf how quickly tool xp is gained (I hope)
if (this.HasRecentToolExp)
this.HasRecentToolExp = false;
}
/// <summary>The method invoked when the game updates (roughly 60 times per second).</summary>
/// <param name="sender">The event sender.</param>
/// <param name="e">The event data.</param>
private void GameEvents_UpdateTick(object sender, EventArgs e)
/// <param name="e">The event arguments.</param>
private void OnUpdateTicked(object sender, UpdateTickedEventArgs e)
{
if (!Context.IsWorldReady)
return;
// nerf how quickly tool xp is gained (I hope)
if (e.IsOneSecond && this.HasRecentToolExp)
this.HasRecentToolExp = false;
// give XP when player finishes eating
if (Game1.player.isEating)
this.WasEating = true;
@ -107,7 +95,7 @@ namespace Omegasis.BuildEndurance
}
// give XP when player stays up too late or collapses
if (!this.WasCollapsed && shouldFarmerPassout())
if (!this.WasCollapsed && this.shouldFarmerPassout())
{
this.PlayerData.CurrentExp += this.Config.ExpForCollapsing;
@ -116,10 +104,10 @@ namespace Omegasis.BuildEndurance
}
}
/// <summary>The method invoked after the player loads a save.</summary>
/// <summary>Raised after the player loads a save slot and the world is initialised.</summary>
/// <param name="sender">The event sender.</param>
/// <param name="e">The event data.</param>
private void SaveEvents_AfterLoad(object sender, EventArgs e)
/// <param name="e">The event arguments.</param>
private void OnSaveLoaded(object sender, SaveLoadedEventArgs e)
{
// reset state
this.WasExhausted = false;
@ -128,8 +116,7 @@ namespace Omegasis.BuildEndurance
this.WasEating = false;
// load player data
this.MigrateLegacyData();
this.PlayerData = this.Helper.ReadJsonFile<PlayerData>(this.DataFilePath) ?? new PlayerData();
this.PlayerData = this.Helper.Data.ReadJsonFile<PlayerData>(this.RelativeDataPath) ?? new PlayerData();
if (this.PlayerData.OriginalMaxStamina == 0)
this.PlayerData.OriginalMaxStamina = Game1.player.MaxStamina;
@ -155,10 +142,10 @@ namespace Omegasis.BuildEndurance
}
}
/// <summary>The method invoked just before the game is saved.</summary>
/// <summary>Raised before the game begins writes data to the save file (except the initial save creation).</summary>
/// <param name="sender">The event sender.</param>
/// <param name="e">The event data.</param>
private void SaveEvents_BeforeSave(object sender, EventArgs e)
/// <param name="e">The event arguments.</param>
private void OnSaving(object sender, SavingEventArgs e)
{
// reset data
this.WasExhausted = false;
@ -184,47 +171,10 @@ namespace Omegasis.BuildEndurance
this.PlayerData.NightlyStamina = Game1.player.MaxStamina;
// save data
this.Helper.WriteJsonFile(this.DataFilePath, this.PlayerData);
this.Helper.Data.WriteJsonFile(this.RelativeDataPath, this.PlayerData);
}
/// <summary>Migrate the legacy settings for the current player.</summary>
private void MigrateLegacyData()
{
// skip if no legacy data or new data already exists
if (!File.Exists(this.LegacyDataFilePath) || File.Exists(this.DataFilePath))
return;
// migrate to new file
try
{
string[] text = File.ReadAllLines(this.LegacyDataFilePath);
this.Helper.WriteJsonFile(this.DataFilePath, new PlayerData
{
CurrentLevel = Convert.ToInt32(text[3]),
CurrentExp = Convert.ToDouble(text[5]),
ExpToNextLevel = Convert.ToDouble(text[7]),
BaseStaminaBonus = Convert.ToInt32(text[9]),
CurrentLevelStaminaBonus = Convert.ToInt32(text[11]),
ClearModEffects = Convert.ToBoolean(text[14]),
OriginalMaxStamina = Convert.ToInt32(text[16]),
NightlyStamina = Convert.ToInt32(text[18])
});
FileInfo file = new FileInfo(this.LegacyDataFilePath);
file.Delete();
if (!file.Directory.EnumerateFiles().Any())
file.Directory.Delete();
}
catch (Exception ex)
{
this.Monitor.Log($"Error migrating data from the legacy 'PlayerData' folder for the current player. Technical details:\n {ex}", LogLevel.Error);
}
}
/// <summary>
/// Try and emulate the old Game1.shouldFarmerPassout logic.
/// </summary>
/// <returns></returns>
/// <summary>Try and emulate the old Game1.shouldFarmerPassout logic.</summary>
public bool shouldFarmerPassout()
{
if (Game1.player.stamina <= 0 || Game1.player.health <= 0 || Game1.timeOfDay >= 2600) return true;

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -11,8 +11,6 @@
<AssemblyName>BuildEndurance</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -67,6 +65,9 @@
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Pathoschild.Stardew.ModBuildConfig" Version="2.2.0" />
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Xml" />
@ -82,19 +83,8 @@
</ItemGroup>
<ItemGroup>
<None Include="manifest.json" />
<None Include="packages.config" />
<None Include="README.md" />
</ItemGroup>
<ItemGroup>
<Analyzer Include="..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\analyzers\dotnet\cs\StardewModdingAPI.ModBuildConfig.Analyzer.dll" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\deploy.targets" />
<Import Project="..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets" Condition="Exists('..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>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}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets'))" />
</Target>
</Project>

View File

@ -1,10 +1,10 @@
{
"Name": "Build Endurance",
"Author": "Alpha_Omegasis",
"Version": "1.6.0",
"Version": "1.7.0",
"Description": "Increase your health as you play.",
"UniqueID": "Omegasis.BuildEndurance",
"EntryDll": "BuildEndurance.dll",
"MinimumApiVersion": "2.0",
"MinimumApiVersion": "2.10.1",
"UpdateKeys": [ "Nexus:445" ]
}

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Pathoschild.Stardew.ModBuildConfig" version="2.2.0" targetFramework="net45" />
</packages>

View File

@ -1,6 +1,4 @@
using System;
using System.IO;
using System.Linq;
using Omegasis.BuildHealth.Framework;
using StardewModdingAPI;
using StardewModdingAPI.Events;
@ -12,13 +10,10 @@ namespace Omegasis.BuildHealth
public class BuildHealth : Mod
{
/*********
** Properties
** Fields
*********/
/// <summary>The relative path for the current player's data file.</summary>
private string DataFilePath => Path.Combine("data", $"{Constants.SaveFolderName}.json");
/// <summary>The absolute path for the current player's legacy data file.</summary>
private string LegacyDataFilePath => Path.Combine(this.Helper.DirectoryPath, "PlayerData", $"BuildHealth_data_{Game1.player.Name}.txt");
private string RelativeDataPath => Path.Combine("data", $"{Constants.SaveFolderName}.json");
/// <summary>The mod settings and player data.</summary>
private ModConfig Config;
@ -46,10 +41,9 @@ namespace Omegasis.BuildHealth
/// <param name="helper">Provides simplified APIs for writing mods.</param>
public override void Entry(IModHelper helper)
{
GameEvents.UpdateTick += this.GameEvents_UpdateTick;
GameEvents.OneSecondTick += this.GameEvents_OneSecondTick;
TimeEvents.AfterDayStarted += this.SaveEvents_BeforeSave;
SaveEvents.AfterLoad += this.SaveEvents_AfterLoaded;
helper.Events.GameLoop.UpdateTicked += this.OnUpdateTicked;
helper.Events.GameLoop.DayStarted += this.OnDayStarted;
helper.Events.GameLoop.SaveLoaded += this.OnSaveLoaded;
this.Config = helper.ReadConfig<ModConfig>();
}
@ -58,24 +52,18 @@ namespace Omegasis.BuildHealth
/*********
** Private methods
*********/
/// <summary>The method invoked once per second during a game update.</summary>
/// <summary>Raised after the game state is updated (≈60 times per second).</summary>
/// <param name="sender">The event sender.</param>
/// <param name="e">The event data.</param>
private void GameEvents_OneSecondTick(object sender, EventArgs e)
{
// nerf how quickly tool xp is gained (I hope)
if (this.HasRecentToolExp)
this.HasRecentToolExp = false;
}
/// <summary>The method invoked when the game updates (roughly 60 times per second).</summary>
/// <param name="sender">The event sender.</param>
/// <param name="e">The event data.</param>
private void GameEvents_UpdateTick(object sender, EventArgs e)
/// <param name="e">The event arguments.</param>
private void OnUpdateTicked(object sender, UpdateTickedEventArgs e)
{
if (!Context.IsWorldReady)
return;
// nerf how quickly tool xp is gained (I hope)
if (e.IsOneSecond && this.HasRecentToolExp)
this.HasRecentToolExp = false;
// give XP when player finishes eating
if (Game1.player.isEating)
this.WasEating = true;
@ -103,17 +91,17 @@ namespace Omegasis.BuildHealth
this.LastHealth = player.health;
// give XP when player stays up too late or collapses
if (!this.WasCollapsed && shouldFarmerPassout())
if (!this.WasCollapsed && this.shouldFarmerPassout())
{
this.PlayerData.CurrentExp += this.Config.ExpForCollapsing;
this.WasCollapsed = true;
}
}
/// <summary>The method invoked after the player loads a save.</summary>
/// <summary>Raised after the player loads a save slot and the world is initialised.</summary>
/// <param name="sender">The event sender.</param>
/// <param name="e">The event data.</param>
private void SaveEvents_AfterLoaded(object sender, EventArgs e)
/// <param name="e">The event arguments.</param>
private void OnSaveLoaded(object sender, SaveLoadedEventArgs e)
{
// reset state
this.HasRecentToolExp = false;
@ -122,8 +110,7 @@ namespace Omegasis.BuildHealth
this.WasCollapsed = false;
// load player data
this.MigrateLegacyData();
this.PlayerData = this.Helper.ReadJsonFile<PlayerData>(this.DataFilePath) ?? new PlayerData();
this.PlayerData = this.Helper.Data.ReadJsonFile<PlayerData>(this.RelativeDataPath) ?? new PlayerData();
if (this.PlayerData.OriginalMaxHealth == 0)
this.PlayerData.OriginalMaxHealth = Game1.player.maxHealth;
@ -145,10 +132,10 @@ namespace Omegasis.BuildHealth
Game1.player.maxHealth = this.PlayerData.BaseHealthBonus + this.PlayerData.CurrentLevelHealthBonus + this.PlayerData.OriginalMaxHealth;
}
/// <summary>The method invoked just before the game saves.</summary>
/// <summary>Raised after the game begins a new day (including when the player loads a save).</summary>
/// <param name="sender">The event sender.</param>
/// <param name="e">The event data.</param>
private void SaveEvents_BeforeSave(object sender, EventArgs e)
/// <param name="e">The event arguments.</param>
private void OnDayStarted(object sender, DayStartedEventArgs e)
{
// reset data
this.LastHealth = Game1.player.maxHealth;
@ -174,40 +161,7 @@ namespace Omegasis.BuildHealth
}
// save data
this.Helper.WriteJsonFile(this.DataFilePath, this.PlayerData);
}
/// <summary>Migrate the legacy settings for the current player.</summary>
private void MigrateLegacyData()
{
// skip if no legacy data or new data already exists
if (!File.Exists(this.LegacyDataFilePath) || File.Exists(this.DataFilePath))
return;
// migrate to new file
try
{
string[] text = File.ReadAllLines(this.LegacyDataFilePath);
this.Helper.WriteJsonFile(this.DataFilePath, new PlayerData
{
CurrentLevel = Convert.ToInt32(text[3]),
CurrentExp = Convert.ToDouble(text[5]),
ExpToNextLevel = Convert.ToDouble(text[7]),
BaseHealthBonus = Convert.ToInt32(text[9]),
CurrentLevelHealthBonus = Convert.ToInt32(text[11]),
ClearModEffects = Convert.ToBoolean(text[14]),
OriginalMaxHealth = Convert.ToInt32(text[16])
});
FileInfo file = new FileInfo(this.LegacyDataFilePath);
file.Delete();
if (!file.Directory.EnumerateFiles().Any())
file.Directory.Delete();
}
catch (Exception ex)
{
this.Monitor.Log($"Error migrating data from the legacy 'PlayerData' folder for the current player. Technical details:\n {ex}", LogLevel.Error);
}
this.Helper.Data.WriteJsonFile(this.RelativeDataPath, this.PlayerData);
}
public bool shouldFarmerPassout()

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -11,8 +11,6 @@
<AssemblyName>BuildHealth</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -67,6 +65,9 @@
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Pathoschild.Stardew.ModBuildConfig" Version="2.2.0" />
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Xml" />
@ -82,19 +83,8 @@
</ItemGroup>
<ItemGroup>
<None Include="manifest.json" />
<None Include="packages.config" />
<None Include="README.md" />
</ItemGroup>
<ItemGroup>
<Analyzer Include="..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\analyzers\dotnet\cs\StardewModdingAPI.ModBuildConfig.Analyzer.dll" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\deploy.targets" />
<Import Project="..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets" Condition="Exists('..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>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}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets'))" />
</Target>
</Project>

View File

@ -1,4 +1,4 @@
namespace Omegasis.BuildHealth.Framework
namespace Omegasis.BuildHealth.Framework
{
/// <summary>The mod settings and player data.</summary>
internal class ModConfig

View File

@ -1,4 +1,4 @@
namespace Omegasis.BuildHealth.Framework
namespace Omegasis.BuildHealth.Framework
{
/// <summary>The data for the current player.</summary>
internal class PlayerData

View File

@ -1,10 +1,10 @@
{
"Name": "Build Health",
"Author": "Alpha_Omegasis",
"Version": "1.6.0",
"Version": "1.7.0",
"Description": "Increase your health as you play.",
"UniqueID": "Omegasis.BuildHealth",
"EntryDll": "BuildHealth.dll",
"MinimumApiVersion": "2.0",
"MinimumApiVersion": "2.10.1",
"UpdateKeys": [ "Nexus:446" ]
}

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Pathoschild.Stardew.ModBuildConfig" version="2.2.0" targetFramework="net45" />
</packages>

View File

@ -1,4 +1,4 @@
using Omegasis.BuyBackCollectables.Framework;
using Omegasis.BuyBackCollectables.Framework;
using StardewModdingAPI;
using StardewModdingAPI.Events;
using StardewValley;
@ -9,7 +9,7 @@ namespace Omegasis.BuyBackCollectables
public class BuyBackCollectables : Mod
{
/*********
** Properties
** Fields
*********/
/// <summary>The mod configuration.</summary>
private ModConfig Config;
@ -24,19 +24,19 @@ namespace Omegasis.BuyBackCollectables
{
this.Config = helper.ReadConfig<ModConfig>();
ControlEvents.KeyPressed += this.ControlEvents_KeyPressed;
helper.Events.Input.ButtonPressed += this.OnButtonPressed;
}
/*********
** Private methods
*********/
/// <summary>The method invoked when the presses a keyboard button.</summary>
/// <summary>Raised after the player presses a button on the keyboard, controller, or mouse.</summary>
/// <param name="sender">The event sender.</param>
/// <param name="e">The event data.</param>
public void ControlEvents_KeyPressed(object sender, EventArgsKeyPressed e)
/// <param name="e">The event arguments.</param>
private void OnButtonPressed(object sender, ButtonPressedEventArgs e)
{
if (Context.IsPlayerFree && e.KeyPressed.ToString() == this.Config.KeyBinding)
if (Context.IsPlayerFree && e.Button == this.Config.KeyBinding)
Game1.activeClickableMenu = new BuyBackMenu(this.Config.CostMultiplier);
}
}

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -11,8 +11,6 @@
<AssemblyName>BuyBackCollectables</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -67,6 +65,9 @@
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Pathoschild.Stardew.ModBuildConfig" Version="2.2.0" />
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Xml" />
@ -84,19 +85,8 @@
<None Include="manifest.json" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="README.md" />
</ItemGroup>
<ItemGroup>
<Analyzer Include="..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\analyzers\dotnet\cs\StardewModdingAPI.ModBuildConfig.Analyzer.dll" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\deploy.targets" />
<Import Project="..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets" Condition="Exists('..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>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}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets'))" />
</Target>
</Project>

View File

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
@ -13,7 +13,7 @@ namespace Omegasis.BuyBackCollectables.Framework
internal class BuyBackMenu : IClickableMenu
{
/*********
** Properties
** Fields
*********/
/// <summary>The organics tab ID.</summary>
private const int OrganicsTab = 0;

View File

@ -1,10 +1,12 @@
namespace Omegasis.BuyBackCollectables.Framework
using StardewModdingAPI;
namespace Omegasis.BuyBackCollectables.Framework
{
/// <summary>The mod configuration.</summary>
internal class ModConfig
{
/// <summary>The key which shows the menu.</summary>
public string KeyBinding { get; set; } = "B";
public SButton KeyBinding { get; set; } = SButton.B;
/// <summary>The multiplier applied to the cost of buying back a collectable.</summary>
public double CostMultiplier { get; set; } = 3.0;

View File

@ -1,10 +1,10 @@
{
"Name": "Buy Back Collectables",
"Author": "Alpha_Omegasis",
"Version": "1.5.0",
"Version": "1.6.0",
"Description": "Lets you buy back any obtained collectable.",
"UniqueID": "Omegasis.BuyBackCollectables",
"EntryDll": "BuyBackCollectables.dll",
"MinimumApiVersion": "2.0",
"MinimumApiVersion": "2.10.1",
"UpdateKeys": [ "Nexus:507" ]
}

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Pathoschild.Stardew.ModBuildConfig" version="2.2.0" targetFramework="net45" />
</packages>

View File

@ -0,0 +1,19 @@
using StardewModdingAPI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using PyTK;
using PyTK.CustomElementHandler;
namespace CustomFurnitureFramework
{
public class Class1 : Mod
{
public override void Entry(IModHelper helper)
{
}
}
}

View File

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{2FA81A17-D9A1-46D9-A5F7-A76AF9C70526}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>CustomFurnitureFramework</RootNamespace>
<AssemblyName>CustomFurnitureFramework</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Class1.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Analyzer Include="..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\analyzers\dotnet\cs\StardewModdingAPI.ModBuildConfig.Analyzer.dll" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets" Condition="Exists('..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>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}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets'))" />
</Target>
</Project>

View File

@ -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("CustomFurnitureFramework")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("CustomFurnitureFramework")]
[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("2fa81a17-d9a1-46d9-a5f7-a76af9c70526")]
// 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")]

View File

@ -1,20 +1,16 @@
using CustomNPCFramework.Framework.Enums;
using CustomNPCFramework.Framework.Graphics;
using CustomNPCFramework.Framework.ModularNPCS;
using CustomNPCFramework.Framework.ModularNPCS.CharacterAnimationBases;
using CustomNPCFramework.Framework.ModularNPCS.ColorCollections;
using CustomNPCFramework.Framework.NPCS;
using CustomNPCFramework.Framework.Utilities;
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;
using CustomNPCFramework.Framework.Enums;
using CustomNPCFramework.Framework.Graphics;
using CustomNPCFramework.Framework.ModularNpcs.ColorCollections;
using CustomNPCFramework.Framework.NPCS;
using CustomNPCFramework.Framework.Utilities;
using Microsoft.Xna.Framework;
using StardewModdingAPI;
using StardewModdingAPI.Events;
using StardewValley;
namespace CustomNPCFramework
{
@ -44,90 +40,75 @@ namespace CustomNPCFramework
/// Find way to make sideways shirts render correctly.
///
///Get suggestions from modding community on requests and ways to improve the mod.
/// </summary>
public class Class1 : Mod
{
/// <summary>
/// The mod helper for the mod.
/// </summary>
/// <summary>The mod helper for the mod.</summary>
public static IModHelper ModHelper;
/// <summary>
/// The mod monitor for the mod.
/// </summary>
/// <summary>The mod monitor for the mod.</summary>
public static IMonitor ModMonitor;
/// <summary>
/// The npc tracker for the mod. Keeps track of all npcs added by the custom framework and cleans them up during saving.
/// </summary>
public static NPCTracker npcTracker;
/// <summary>
/// Keeps track of all of the asets/textures added in by the framework. Also manages all of the asset managers that are the ones actually managing the textures.
/// </summary>
/// <summary>The npc tracker for the mod. Keeps track of all npcs added by the custom framework and cleans them up during saving.</summary>
public static NpcTracker npcTracker;
/// <summary>Keeps track of all of the asets/textures added in by the framework. Also manages all of the asset managers that are the ones actually managing the textures.</summary>
public static AssetPool assetPool;
/// <summary>
/// Ran when loading the SMAPI. Used to initialize data.
/// </summary>
/// <param name="helper"></param>
public static IManifest Manifest;
/// <summary>The mod entry point, called after the mod is first loaded.</summary>
/// <param name="helper">Provides simplified APIs for writing mods.</param>
public override void Entry(IModHelper helper)
{
ModHelper = this.Helper;
ModMonitor = this.Monitor;
Manifest = this.ModManifest;
StardewModdingAPI.Events.SaveEvents.AfterLoad += SaveEvents_LoadChar;
StardewModdingAPI.Events.SaveEvents.BeforeSave += SaveEvents_BeforeSave;
StardewModdingAPI.Events.SaveEvents.AfterSave += SaveEvents_AfterSave;
StardewModdingAPI.Events.PlayerEvents.Warped += LocationEvents_CurrentLocationChanged;
StardewModdingAPI.Events.GameEvents.UpdateTick += GameEvents_UpdateTick;
npcTracker = new NPCTracker();
helper.Events.GameLoop.SaveLoaded += this.OnSaveLoaded;
helper.Events.GameLoop.Saving += this.OnSaving;
helper.Events.GameLoop.Saved += this.OnSaved;
helper.Events.GameLoop.UpdateTicked += this.OnUpdateTicked;
npcTracker = new NpcTracker();
assetPool = new AssetPool();
var assetManager = new AssetManager();
assetPool.addAssetManager(new KeyValuePair<string, AssetManager>("testNPC", assetManager));
initializeExamples();
initializeAssetPool();
this.initializeExamples();
this.initializeAssetPool();
assetPool.loadAllAssets();
}
/// <summary>
/// Initialize the asset pool with some test variables.
/// </summary>
/// <summary>Initialize the asset pool with some test variables.</summary>
public void initializeAssetPool()
{
string path = Path.Combine(ModHelper.DirectoryPath, "Content", "Graphics", "NPCS");
assetPool.getAssetManager("testNPC").addPathCreateDirectory(new KeyValuePair<string, string>("characters", path));
string relativePath = Path.Combine("Content", "Graphics", "NPCS");
assetPool.getAssetManager("testNPC").addPathCreateDirectory(new KeyValuePair<string, string>("characters", relativePath));
}
/// <summary>
/// A function that is called when the game finishes saving.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void SaveEvents_AfterSave(object sender, EventArgs e)
/// <summary>Raised after the game finishes writing data to the save file (except the initial save creation).</summary>
/// <param name="sender">The event sender.</param>
/// <param name="e">The event arguments.</param>
private void OnSaved(object sender, SavedEventArgs e)
{
npcTracker.afterSave();
}
/// <summary>
/// A function that is called when the game is about to load. Used to clean up all the npcs from the game world to prevent it from crashing.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void SaveEvents_BeforeSave(object sender, EventArgs e)
/// <summary>Raised before the game begins writes data to the save file (except the initial save creation).</summary>
/// <param name="sender">The event sender.</param>
/// <param name="e">The event arguments.</param>
private void OnSaving(object sender, SavingEventArgs e)
{
// clean up all the npcs from the game world to prevent it from crashing
npcTracker.cleanUpBeforeSave();
}
/// <summary>
/// Called upon 60 times a second. For testing purposes only. Will remove in future release.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void GameEvents_UpdateTick(object sender, EventArgs e)
/// <summary>Raised after the game state is updated (≈60 times per second).</summary>
/// <param name="sender">The event sender.</param>
/// <param name="e">The event arguments.</param>
private void OnUpdateTicked(object sender, UpdateTickedEventArgs e)
{
// TODO For testing purposes only. Will remove in future release.
/*
if (Game1.player.currentLocation == null) return;
if (Game1.activeClickableMenu != null) return;
@ -144,93 +125,59 @@ namespace CustomNPCFramework
*/
}
/// <summary>
/// Called when the player's location changes.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void LocationEvents_CurrentLocationChanged(object sender, StardewModdingAPI.Events.EventArgsPlayerWarped e)
/// <summary>Raised after the player loads a save slot and the world is initialised.</summary>
/// <param name="sender">The event sender.</param>
/// <param name="e">The event arguments.</param>
private void OnSaveLoaded(object sender, SaveLoadedEventArgs e)
{
// TODO Used to spawn a custom npc just as an example. Don't keep this code. GENERATE NPC AND CALL THE CODE
}
/// <summary>
/// Used to spawn a custom npc just as an example. Don't keep this code.
/// GENERATE NPC AND CALL THE CODE
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void SaveEvents_LoadChar(object sender, EventArgs e)
{
ExtendedNPC myNpc3 = assetPool.generateNPC(Genders.female, 0, 1,new StandardColorCollection(null, null, Color.Blue, null, Color.Yellow, null));
MerchantNPC merch = new MerchantNPC(new List<Item>()
ExtendedNpc myNpc3 = assetPool.generateNPC(Genders.female, 0, 1, new StandardColorCollection(null, null, Color.Blue, null, Color.Yellow, null));
MerchantNpc merch = new MerchantNpc(new List<Item>()
{
new StardewValley.Object(475,999)
}, myNpc3);
npcTracker.addNewNPCToLocation(Game1.getLocationFromName("BusStop", false), merch,new Vector2(2,23));
npcTracker.addNewNpcToLocation(Game1.getLocationFromName("BusStop", false), merch, new Vector2(2, 23));
}
/// <summary>
/// Used to initialize examples for other modders to look at as reference.
/// </summary>
/// <summary>Used to initialize examples for other modders to look at as reference.</summary>
public void initializeExamples()
{
return;
string dirPath = Path.Combine(ModHelper.DirectoryPath, "Content", "Templates");
string relativeDirPath = Path.Combine("Content", "Templates");
var aManager = assetPool.getAssetManager("testNPC");
aManager.addPathCreateDirectory(new KeyValuePair<string, string>("templates", dirPath));
string filePath =Path.Combine(dirPath, "Example.json");
if (!File.Exists(filePath))
aManager.addPathCreateDirectory(new KeyValuePair<string, string>("templates", relativeDirPath));
// write example
{
string getRelativePath = getShortenedDirectory(filePath);
ModMonitor.Log("THIS IS THE PATH::: " + getRelativePath);
string relativeFilePath = Path.Combine(relativeDirPath, "Example.json");
if (!File.Exists(Path.Combine(this.Helper.DirectoryPath, relativeFilePath)))
{
ModMonitor.Log("THIS IS THE PATH::: " + relativeFilePath);
AssetInfo info = new AssetInfo("MyExample", new NamePairings("StandingExampleL", "StandingExampleR", "StandingExampleU", "StandingExampleD"), new NamePairings("MovingExampleL", "MovingExampleR", "MovingExampleU", "MovingExampleD"), new NamePairings("SwimmingExampleL", "SwimmingExampleR", "SwimmingExampleU", "SwimmingExampleD"), new NamePairings("SittingExampleL", "SittingExampleR", "SittingExampleU", "SittingExampleD"), new Vector2(16, 16), false);
info.writeToJson(filePath);
info.writeToJson(relativeFilePath);
}
string filePath2 = Path.Combine(dirPath, "AdvancedExample.json");
if (!File.Exists(filePath2))
{
ExtendedAssetInfo info2 = new ExtendedAssetInfo("AdvancedExample", new NamePairings("AdvancedStandingExampleL", "AdvancedStandingExampleR", "AdvancedStandingExampleU", "AdvancedStandingExampleD"), new NamePairings("AdvancedMovingExampleL", "AdvancedMovingExampleR", "AdvancedMovingExampleU", "AdvancedMovingExampleD"), new NamePairings("AdvancedSwimmingExampleL", "AdvancedSwimmingExampleR", "AdvancedSwimmingExampleU", "AdvancedSwimmingExampleD"), new NamePairings("AdvancedSittingExampleL", "AdvancedSittingExampleR", "AdvancedSittingExampleU", "AdvancedSittingExampleD"), new Vector2(16, 16), false, Genders.female, new List<Seasons>()
{
Seasons.spring,
Seasons.summer
}, PartType.hair
);
info2.writeToJson(filePath2);
}
}
/// <summary>
/// Used to splice the mod directory to get relative paths.
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public static string getShortenedDirectory(string path)
// write advanced example
{
string lol = (string)path.Clone();
string[] spliter = lol.Split(new string[] { ModHelper.DirectoryPath },StringSplitOptions.None);
try
string relativeFilePath = Path.Combine(relativeDirPath, "AdvancedExample.json");
if (!File.Exists(Path.Combine(this.Helper.DirectoryPath, relativeFilePath)))
{
return spliter[1];
ExtendedAssetInfo info2 = new ExtendedAssetInfo("AdvancedExample", new NamePairings("AdvancedStandingExampleL", "AdvancedStandingExampleR", "AdvancedStandingExampleU", "AdvancedStandingExampleD"), new NamePairings("AdvancedMovingExampleL", "AdvancedMovingExampleR", "AdvancedMovingExampleU", "AdvancedMovingExampleD"), new NamePairings("AdvancedSwimmingExampleL", "AdvancedSwimmingExampleR", "AdvancedSwimmingExampleU", "AdvancedSwimmingExampleD"), new NamePairings("AdvancedSittingExampleL", "AdvancedSittingExampleR", "AdvancedSittingExampleU", "AdvancedSittingExampleD"), new Vector2(16, 16), false, Genders.female, new List<Seasons>() { Seasons.spring, Seasons.summer }, PartType.hair);
info2.writeToJson(relativeFilePath);
}
catch(Exception err)
{
err.ToString();
return spliter[0];
}
}
/// <summary>
/// Used to finish cleaning up absolute asset paths into a shortened relative path.
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
/// <summary>Used to finish cleaning up absolute asset paths into a shortened relative path.</summary>
public static string getRelativeDirectory(string path)
{
string s = getShortenedDirectory(path);
return s.Remove(0, 1);
return path
.Split(new[] { ModHelper.DirectoryPath }, 2, StringSplitOptions.None)
.Last()
.TrimStart(Path.DirectorySeparatorChar);
}
}
}

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -11,9 +11,6 @@
<AssemblyName>CustomNPCFramework</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -70,6 +67,9 @@
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Pathoschild.Stardew.ModBuildConfig" Version="2.2.0" />
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
@ -93,20 +93,20 @@
<Compile Include="Framework\Enums\Genders.cs" />
<Compile Include="Framework\Graphics\AssetPool.cs" />
<Compile Include="Framework\Graphics\TextureGroups\TextureGroup.cs" />
<Compile Include="Framework\ModularNPCS\AnimatedSpriteCollection.cs" />
<Compile Include="Framework\ModularNPCS\AnimatedSpriteExtended.cs" />
<Compile Include="Framework\ModularNPCS\CharacterAnimationBases\StandardCharacterAnimation.cs" />
<Compile Include="Framework\ModularNPCS\CharacterAnimationBases\CharacterAnimationBase.cs" />
<Compile Include="Framework\ModularNpcs\AnimatedSpriteCollection.cs" />
<Compile Include="Framework\ModularNpcs\AnimatedSpriteExtended.cs" />
<Compile Include="Framework\ModularNpcs\CharacterAnimationBases\StandardCharacterAnimation.cs" />
<Compile Include="Framework\ModularNpcs\CharacterAnimationBases\CharacterAnimationBase.cs" />
<Compile Include="Framework\Enums\Direction.cs" />
<Compile Include="Framework\ModularNPCS\ColorCollections\StandardColorCollection.cs" />
<Compile Include="Framework\ModularNPCS\ModularRenderers\AnimationKeys.cs" />
<Compile Include="Framework\ModularNPCS\ModularRenderers\BasicRenderer.cs" />
<Compile Include="Framework\ModularNPCS\Portrait.cs" />
<Compile Include="Framework\ModularNPCS\Sprite.cs" />
<Compile Include="Framework\NPCNames.cs" />
<Compile Include="Framework\NPCS\ExtendedNPC.cs" />
<Compile Include="Framework\NPCS\MerchantNPC.cs" />
<Compile Include="Framework\Utilities\NPCTracker.cs" />
<Compile Include="Framework\ModularNpcs\ColorCollections\StandardColorCollection.cs" />
<Compile Include="Framework\ModularNpcs\ModularRenderers\AnimationKeys.cs" />
<Compile Include="Framework\ModularNpcs\ModularRenderers\BasicRenderer.cs" />
<Compile Include="Framework\ModularNpcs\Portrait.cs" />
<Compile Include="Framework\ModularNpcs\Sprite.cs" />
<Compile Include="Framework\NpcNames.cs" />
<Compile Include="Framework\NPCS\ExtendedNpc.cs" />
<Compile Include="Framework\NPCS\MerchantNpc.cs" />
<Compile Include="Framework\Utilities\NpcTracker.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
@ -116,24 +116,7 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Analyzer Include="..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\analyzers\dotnet\cs\StardewModdingAPI.ModBuildConfig.Analyzer.dll" />
<None Include="manifest.json" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets" Condition="Exists('..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>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}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets'))" />
</Target>
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -1,31 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CustomNPCFramework.Framework.Enums
{
/// <summary>
/// A enum of different types of animations supported by the framework.
/// </summary>
/// <summary>A enum of different types of animations supported by the framework.</summary>
public enum AnimationType
{
/// <summary>
/// A key to be used whenever an npc uses a standing animation.
/// </summary>
/// <summary>A key to be used whenever an npc uses a standing animation.</summary>
standing,
/// <summary>
/// A key to be used wheneven an npc uses a walking/moving animation.
/// </summary>
/// <summary>A key to be used wheneven an npc uses a walking/moving animation.</summary>
walking,
/// <summary>
/// A key to be used whenever an npc uses a swimming animation.
/// </summary>
/// <summary>A key to be used whenever an npc uses a swimming animation.</summary>
swimming,
/// <summary>
/// A key to be used whenever an npc uses a sitting animation.
/// </summary>
/// <summary>A key to be used whenever an npc uses a sitting animation.</summary>
sitting
}
}

View File

@ -1,36 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CustomNPCFramework.Framework.Enums
{
/// <summary>
/// An enum to be used to signify directions.
/// The enum order corresponds to the same order Stardew Valley uses for directions where
/// Up=0
/// Right=1
/// Down=2
/// Left=3
/// </summary>
/// <summary>An enum to be used to signify directions. The enum order corresponds to the same order Stardew Valley uses for directions.</summary>
public enum Direction
{
/// <summary>
/// Used to signify something to face/move up.
/// </summary>
up,
/// <summary>
/// Used to signify something to face/move right.
/// </summary>
right,
/// <summary>
/// Used to signify something to face/move down.
/// </summary>
down,
/// <summary>
/// Used to signify something to face/move left.
/// </summary>
left
/// <summary>Used to signify something to face/move up.</summary>
up = 0,
/// <summary>Used to signify something to face/move right.</summary>
right = 1,
/// <summary>Used to signify something to face/move down.</summary>
down = 2,
/// <summary>Used to signify something to face/move left.</summary>
left = 3
}
}

View File

@ -1,28 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using StardewValley;
namespace CustomNPCFramework.Framework.Enums
{
/// <summary>
/// Gender enum to signify the different genders for npcs.
/// Do what you want with this. For code simplicity anything that is non-binary is specified under other.
/// </summary>
/// <summary>Gender enum to signify the different genders for NPCs. Do what you want with this. For code simplicity anything that is non-binary is specified under other.</summary>
public enum Genders
{
/// <summary>
/// Used for npcs to signify that they are the male gender.
/// </summary>
male,
/// <summary>
/// Used for npcs to signify that they are the female gender.
/// </summary>
female,
/// <summary>
/// Used for npcs to signify that they are a non gender binary gender.
/// </summary>
other
/// <summary>Used for npcs to signify that they are the male gender.</summary>
male = NPC.male,
/// <summary>Used for npcs to signify that they are the female gender.</summary>
female = NPC.female,
/// <summary>Used for npcs to signify that they are a non gender binary gender.</summary>
other = NPC.undefined
}
}

View File

@ -1,55 +1,36 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CustomNPCFramework.Framework.Enums
{
/// <summary>
/// An enum used to signify the different asset types that can be used for npcs.
/// </summary>
/// <summary>An enum used to signify the different asset types that can be used for NPCs.</summary>
public enum PartType
{
/// <summary>
/// Used to signify that the asset is of the body part category. Without this the npc is basically a ghost.
/// </summary>
/// <summary>Used to signify that the asset is of the body part category. Without this the npc is basically a ghost.</summary>
body,
/// <summary>
/// Used to signify that the asset is of the eyes part category. The window to the soul.
/// </summary>
/// <summary>Used to signify that the asset is of the eyes part category. The window to the soul.</summary>
eyes,
/// <summary>
/// Used to signify that the asset is of the hair part category. Volume looks good in 2D.
/// </summary>
/// <summary>Used to signify that the asset is of the hair part category. Volume looks good in 2D.</summary>
hair,
/// <summary>
/// Used to signify that the asset is of the shirt part category.No shirt = no service.
/// </summary>
/// <summary>Used to signify that the asset is of the shirt part category.No shirt = no service.</summary>
shirt,
/// <summary>
/// Used to signify that the asset is of the pants/bottoms part category. Also known as bottoms, skirts, shorts, etc.
/// </summary>
/// <summary>Used to signify that the asset is of the pants/bottoms part category. Also known as bottoms, skirts, shorts, etc.</summary>
pants,
/// <summary>
/// Used to signify that the asset is of the shoes part category. Lace up those kicks.
/// </summary>
/// <summary>Used to signify that the asset is of the shoes part category. Lace up those kicks.</summary>
shoes,
/// <summary>
/// Used to signify that the asset is of the accessort part category. Got to wear that bling.
/// </summary>
/// <summary>Used to signify that the asset is of the accessort part category. Got to wear that bling.</summary>
accessory,
/// <summary>
/// Used to signify that the asset is of the other part category. Who knows what this really is...
/// </summary>
/// <summary>Used to signify that the asset is of the other part category. Who knows what this really is...</summary>
other,
/// <summary>
/// Used to signify that the asset is of the swimsuit part category. Got to be decent when taking a dip.
/// </summary>
/// <summary>Used to signify that the asset is of the swimsuit part category. Got to be decent when taking a dip.</summary>
swimsuit,
/// <summary>
/// Used to signify that the asset is of the amrs part category. Arms need to be rendered above a shirt on npcs otherwise they get covered.
/// </summary>
/// <summary>Used to signify that the asset is of the amrs part category. Arms need to be rendered above a shirt on npcs otherwise they get covered.</summary>
arms
}
}

View File

@ -1,36 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CustomNPCFramework.Framework.Enums
{
/// <summary>
/// An enum signifying the different seasons that are supported when chosing npc graphics.
/// </summary>
/// <summary>An enum signifying the different seasons that are supported when choosing NPC graphics.</summary>
public enum Seasons
{
/// <summary>
/// The spring season. This ensures that a corresponding graphic with this enum in it's seasons list can be chosen in the spring time.
/// Also used for functionality to check seasons.
/// </summary>
/// <summary>The spring season. This ensures that a corresponding graphic with this enum in it's seasons list can be chosen in the spring time. Also used for functionality to check seasons.</summary>
spring,
/// <summary>
/// The summer season. This ensures that a corresponding graphic with this enum in it's seasons list can be chosen in the summer time.
/// Also used for functionality to check seasons.
/// </summary>
/// <summary>The summer season. This ensures that a corresponding graphic with this enum in it's seasons list can be chosen in the summer time. Also used for functionality to check seasons.</summary>
summer,
/// <summary>
/// The fall season. This ensures that a corresponding graphic with this enum in it's seasons list can be chosen in the fall time.
/// Also used for functionality to check seasons.
/// </summary>
/// <summary>The fall season. This ensures that a corresponding graphic with this enum in it's seasons list can be chosen in the fall time. Also used for functionality to check seasons.</summary>
fall,
/// <summary>
/// The winter season. This ensures that a corresponding graphic with this enum in it's seasons list can be chosen in the winter time.
/// Also used for functionality to check seasons.
/// </summary>
/// <summary>The winter season. This ensures that a corresponding graphic with this enum in it's seasons list can be chosen in the winter time. Also used for functionality to check seasons.</summary>
winter
}
}

View File

@ -1,92 +1,65 @@
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
namespace CustomNPCFramework.Framework.Graphics
{
/// <summary>
/// A class to be used to hold information regarding assets such as the name of the assets and the paths to the images.
/// </summary>
/// <summary>A class to be used to hold information regarding assets such as the name of the assets and the paths to the images.</summary>
public class AssetInfo
{
/// <summary>
/// The name of the asset to be used in the main asset pool.
/// </summary>
/// <summary>The name of the asset to be used in the main asset pool.</summary>
public string assetName;
/// <summary>
/// The list of files to be used for the standing animation.
/// </summary>
/// <summary>The list of files to be used for the standing animation.</summary>
public NamePairings standingAssetPaths;
/// <summary>
/// The list of files to be used for the swimming animation.
/// </summary>
/// <summary>The list of files to be used for the swimming animation.</summary>
public NamePairings swimmingAssetPaths;
/// <summary>
/// The list of files to be used with the moving animation.
/// </summary>
/// <summary>The list of files to be used with the moving animation.</summary>
public NamePairings movingAssetPaths;
/// <summary>
/// The list of files to be used with the sitting animation.
/// </summary>
/// <summary>The list of files to be used with the sitting animation.</summary>
public NamePairings sittingAssetPaths;
/// <summary>
/// The size of the asset texture. Width and height.
/// </summary>
/// <summary>The size of the asset texture. Width and height.</summary>
public Vector2 assetSize;
/// <summary>
/// Not really used anymore. More of a legacy feature.
/// </summary>
/// <summary>Not really used anymore. More of a legacy feature.</summary>
public bool randomizeUponLoad;
/// <summary>
/// Empty constructor.
/// </summary>
public AssetInfo()
{
/// <summary>Construct an instance.</summary>
public AssetInfo() { }
}
/// <summary>
/// Constructor that assigns values to the class.
/// </summary>
/// <summary>Construct an instance.</summary>
/// <param name="assetName">The name of the asset. This is the name that will be referenced in any asset manager or asset pool.</param>
/// <param name="StandingAssetPaths">The name of the files to be used for the standing animation.</param>
/// <param name="MovingAssetPaths">The name of the files to be used for the moving animation.</param>
/// <param name="SwimmingAssetPaths">The name of the files to be used for the swimming animation.</param>
/// <param name="SittingAssetPaths">The name of the files to be used for the sitting animation.</param>
/// <param name="standingAssetPaths">The name of the files to be used for the standing animation.</param>
/// <param name="movingAssetPaths">The name of the files to be used for the moving animation.</param>
/// <param name="swimmingAssetPaths">The name of the files to be used for the swimming animation.</param>
/// <param name="sittingAssetPaths">The name of the files to be used for the sitting animation.</param>
/// <param name="assetSize">The size of the asset. Width and height of the texture.</param>
/// <param name="randomizeUponLoad">Legacy, not really used anymore.</param>
public AssetInfo(string assetName,NamePairings StandingAssetPaths, NamePairings MovingAssetPaths, NamePairings SwimmingAssetPaths, NamePairings SittingAssetPaths, Vector2 assetSize, bool randomizeUponLoad)
public AssetInfo(string assetName, NamePairings standingAssetPaths, NamePairings movingAssetPaths, NamePairings swimmingAssetPaths, NamePairings sittingAssetPaths, Vector2 assetSize, bool randomizeUponLoad)
{
this.assetName = assetName;
this.sittingAssetPaths = SittingAssetPaths;
this.standingAssetPaths = StandingAssetPaths;
this.movingAssetPaths = MovingAssetPaths;
this.swimmingAssetPaths = SwimmingAssetPaths;
this.sittingAssetPaths = sittingAssetPaths;
this.standingAssetPaths = standingAssetPaths;
this.movingAssetPaths = movingAssetPaths;
this.swimmingAssetPaths = swimmingAssetPaths;
this.assetSize = assetSize;
this.randomizeUponLoad = randomizeUponLoad;
}
/// <summary>
/// Save the json to a certain location.
/// </summary>
/// <param name="path"></param>
public void writeToJson(string path)
/// <summary>Save the json to a certain location.</summary>
/// <param name="relativeFilePath">The relative path to save.</param>
public void writeToJson(string relativeFilePath)
{
Class1.ModHelper.WriteJsonFile<AssetInfo>(path, this);
Class1.ModHelper.Data.WriteJsonFile(relativeFilePath, this);
}
/// <summary>
/// Read the json from a certain location.
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public static AssetInfo readFromJson(string path)
/// <summary>Read the json from a certain location.</summary>
/// <param name="relativePath">The relative path to save.</param>
public static AssetInfo readFromJson(string relativePath)
{
return Class1.ModHelper.ReadJsonFile<AssetInfo>(path);
return Class1.ModHelper.Data.ReadJsonFile<AssetInfo>(relativePath);
}
}
}

View File

@ -1,286 +1,211 @@
using CustomNPCFramework.Framework.Enums;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CustomNPCFramework.Framework.Enums;
namespace CustomNPCFramework.Framework.Graphics
{
/// <summary>
/// Used to hold assets from specified directories.
/// </summary>
/// <summary>Used to hold assets from specified directories.</summary>
public class AssetManager
{
/// <summary>
/// A list of all of the assets held by this asset manager.
/// </summary>
public List<AssetSheet> assets;
/// <summary>
/// A list of all of the directories managed by this asset manager.
/// </summary>
public Dictionary<string,string> paths;
/// <summary>A list of all of the assets held by this asset manager.</summary>
public List<AssetSheet> assets { get; } = new List<AssetSheet>();
/// <summary>
/// Basic constructor.
/// </summary>
public AssetManager()
{
this.assets = new List<AssetSheet>();
this.paths = new Dictionary<string, string>();
}
/// <summary>A list of directories managed by this asset manager, relative to the mod folder.</summary>
public Dictionary<string, string> relativePaths { get; } = new Dictionary<string, string>();
/// <summary>
/// Constructor.
/// </summary>
/// <param name="assetsPathsToLoadFrom">A list of all directories to be managed by the asset manager. Name, path is the key pair value.</param>
public AssetManager(Dictionary<string,string> assetsPathsToLoadFrom)
{
this.assets = new List<AssetSheet>();
this.paths = assetsPathsToLoadFrom;
}
/// <summary>
/// Default loading function from hard coded paths.
/// </summary>
/// <summary>Default loading function from hardcoded paths.</summary>
public void loadAssets()
{
foreach(var path in this.paths)
{
ProcessDirectory(path.Value);
}
foreach (var relativePath in this.relativePaths)
this.ProcessDirectory(relativePath.Value);
}
/// <summary>
/// Taken from Microsoft c# documented webpages.
/// Process all .json files in the given directory. If there are more nested directories, keep digging to find more .json files. Also allows us to specify a broader directory like Content/Grahphics/ModularNPC/Hair to have multiple hair styles.
/// </summary>
/// <param name="targetDirectory"></param>
private void ProcessDirectory(string targetDirectory)
/// <summary>Process all .json files in the given directory. If there are more nested directories, keep digging to find more .json files. Also allows us to specify a broader directory like Content/Grahphics/ModularNPC/Hair to have multiple hair styles.</summary>
/// <param name="relativeDirPath">The relative directory path to process.</param>
/// <remarks>Taken from Microsoft c# documented webpages.</remarks>
private void ProcessDirectory(string relativeDirPath)
{
// Process the list of files found in the directory.
string[] files = Directory.GetFiles(targetDirectory, "*.json");
foreach (var file in files)
{
ProcessFile(file,targetDirectory);
}
DirectoryInfo root = new DirectoryInfo(Path.Combine(Class1.ModHelper.DirectoryPath, relativeDirPath));
foreach (FileInfo file in root.GetFiles("*.json"))
this.ProcessFile(Path.Combine(relativeDirPath, file.Name), relativeDirPath);
// Recurse into subdirectories of this directory.
string[] subdirectoryEntries = Directory.GetDirectories(targetDirectory);
foreach (string subdirectory in subdirectoryEntries)
ProcessDirectory(subdirectory);
foreach (DirectoryInfo subdir in root.GetDirectories())
this.ProcessDirectory(Path.Combine(relativeDirPath, subdir.Name));
}
/// <summary>
/// Actually load in the asset information.
/// </summary>
/// <param name="file"></param>
/// <param name="path"></param>
private void ProcessFile(string file,string path)
/// <summary>Actually load in the asset information.</summary>
/// <param name="relativeFilePath">The relative path to the file to process.</param>
/// <param name="relativeDirPath">The relative path containing the file.</param>
private void ProcessFile(string relativeFilePath, string relativeDirPath)
{
try
{
ExtendedAssetInfo info = ExtendedAssetInfo.readFromJson(file);
AssetSheet sheet = new AssetSheet(info, path);
addAsset(sheet);
ExtendedAssetInfo info = ExtendedAssetInfo.readFromJson(relativeFilePath);
AssetSheet sheet = new AssetSheet(info, relativeDirPath);
this.addAsset(sheet);
Class1.ModMonitor.Log("Loaded in new modular asset: " + info.assetName + " asset type: " + info.type);
}
catch (Exception err)
catch
{
AssetInfo info = AssetInfo.readFromJson(file);
AssetSheet sheet = new AssetSheet(info, path);
addAsset(sheet);
AssetInfo info = AssetInfo.readFromJson(relativeFilePath);
AssetSheet sheet = new AssetSheet(info, relativeDirPath);
this.addAsset(sheet);
}
}
/// <summary>
/// Add an asset to be handled from the asset manager.
/// </summary>
/// <param name="asset"></param>
/// <summary>Add an asset to be handled from the asset manager.</summary>
/// <param name="asset">The asset sheet.</param>
public void addAsset(AssetSheet asset)
{
this.assets.Add(asset);
}
/// <summary>
/// Get an individual asset by its name.
/// </summary>
/// <param name="s"></param>
/// <returns></returns>
/// <summary>Get an individual asset by its name.</summary>
/// <param name="s">The asset name.</param>
public AssetSheet getAssetByName(string s)
{
foreach(var v in assets)
foreach (var v in this.assets)
{
if (v.assetInfo.assetName == s) return v;
if (v.assetInfo.assetName == s)
return v;
}
return null;
}
/// <summary>
/// Add a new path to the asset manager and create the directory for it.
/// </summary>
/// <param name="path"></param>
/// <summary>Add a new path to the asset manager and create the directory for it.</summary>
/// <param name="path">The absolute path to add.</param>
public void addPathCreateDirectory(KeyValuePair<string, string> 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));
}
}
/// <summary>
/// Add a path to the dictionary.
/// </summary>
/// <param name="path"></param>
/// <summary>Add a path to the dictionary.</summary>
/// <param name="path">The relative path to add.</param>
private void addPath(KeyValuePair<string, string> path)
{
this.paths.Add(path.Key, path.Value);
this.relativePaths.Add(path.Key, path.Value);
}
/// <summary>
/// Create appropriate directories for the path.
/// </summary>
/// <summary>Create appropriate directories for the path.</summary>
private void createDirectoriesFromPaths()
{
foreach(var v in paths)
{
foreach (var v in this.relativePaths)
Directory.CreateDirectory(Path.Combine(Class1.ModHelper.DirectoryPath, v.Value));
}
}
/// <summary>
/// Returns a list of assets from this manager that match the given critera.
/// </summary>
/// <param name="gender">The criteria we are searching for this time is gender.</param>
/// <returns></returns>
/// <summary>Get a list of assets which match the given critera.</summary>
/// <param name="gender">The gender to match.</param>
public List<AssetSheet> getListOfAssetsThatMatchThisCriteria(Genders gender)
{
List<AssetSheet> aSheet = new List<AssetSheet>();
List<AssetSheet> sheets = new List<AssetSheet>();
foreach (var v in this.assets)
{
if(v.assetInfo is ExtendedAssetInfo)
if (v.assetInfo is ExtendedAssetInfo info)
{
if ((v.assetInfo as ExtendedAssetInfo).gender == gender) aSheet.Add(v);
if (info.gender == gender)
sheets.Add(v);
}
}
return aSheet;
return sheets;
}
/// <summary>
/// Get a list of all the assets of this kind of part.
/// </summary>
/// <param name="type">The type of part to return a list of from this asset manager.</param>
/// <returns></returns>
/// <summary>Get a list of assets which match the given critera.</summary>
/// <param name="type">The part type to match.</param>
public List<AssetSheet> getListOfAssetsThatMatchThisCriteria(PartType type)
{
List<AssetSheet> aSheet = new List<AssetSheet>();
List<AssetSheet> sheets = new List<AssetSheet>();
foreach (var v in this.assets)
{
if (v.assetInfo is ExtendedAssetInfo)
if (v.assetInfo is ExtendedAssetInfo info)
{
if ((v.assetInfo as ExtendedAssetInfo).type == type) aSheet.Add(v);
if (info.type == type)
sheets.Add(v);
}
}
return aSheet;
return sheets;
}
/// <summary>
/// Get a list of assets that match the critera.
/// </summary>
/// <param name="gender">The gender criteria for this asset, such as if this part belongs to either a female or male character.</param>
/// <param name="type">The type of asset to return. Hair eyes, shoes, etc.</param>
/// <returns></returns>
/// <summary>Get a list of assets which match the given critera.</summary>
/// <param name="gender">The gender to match.</param>
/// <param name="type">The part type to match.</param>
public List<AssetSheet> getListOfAssetsThatMatchThisCriteria(Genders gender, PartType type)
{
List<AssetSheet> aSheet = new List<AssetSheet>();
List<AssetSheet> sheets = new List<AssetSheet>();
foreach (var v in this.assets)
{
if (v.assetInfo is ExtendedAssetInfo)
if (v.assetInfo is ExtendedAssetInfo info)
{
if ((v.assetInfo as ExtendedAssetInfo).type == type && (v.assetInfo as ExtendedAssetInfo).gender == gender) aSheet.Add(v);
if (info.type == type && info.gender == gender)
sheets.Add(v);
}
}
return aSheet;
return sheets;
}
/// <summary>
/// Returns a list of assets from this manager that match the given critera.
/// </summary>
/// <param name="gender">The criteria we are searching for this time is gender.</param>
/// <returns></returns>
/// <summary>Get a list of assets which match the given critera.</summary>
/// <param name="season">The season to match.</param>
public List<AssetSheet> getListOfAssetsThatMatchThisCriteria(Seasons season)
{
List<AssetSheet> aSheet = new List<AssetSheet>();
List<AssetSheet> sheets = new List<AssetSheet>();
foreach (var v in this.assets)
{
if (v.assetInfo is ExtendedAssetInfo)
if (v.assetInfo is ExtendedAssetInfo info)
{
foreach (var sea in (v.assetInfo as ExtendedAssetInfo).seasons) {
if (sea == season) aSheet.Add(v);
foreach (var sea in info.seasons)
{
if (sea == season)
sheets.Add(v);
break; //Only need to find first validation that this is a valid asset.
}
}
}
return aSheet;
return sheets;
}
/// <summary>
/// Get a list of assets that match this criteria of gender and seasons.
/// </summary>
/// <param name="gender"></param>
/// <param name="season"></param>
/// <returns></returns>
/// <summary>Get a list of assets which match the given critera.</summary>
/// <param name="gender">The gender to match.</param>
/// <param name="season">The season to match.</param>
public List<AssetSheet> getListOfAssetsThatMatchThisCriteria(Genders gender, Seasons season)
{
List<AssetSheet> aSheet = new List<AssetSheet>();
List<AssetSheet> sheets = new List<AssetSheet>();
foreach (var v in this.assets)
{
if (v.assetInfo is ExtendedAssetInfo)
if (v.assetInfo is ExtendedAssetInfo info)
{
foreach (var sea in (v.assetInfo as ExtendedAssetInfo).seasons)
foreach (var sea in info.seasons)
{
if (sea == season && (v.assetInfo as ExtendedAssetInfo).gender==gender) aSheet.Add(v);
if (sea == season && info.gender == gender)
sheets.Add(v);
break; //Only need to find first validation that this is a valid asset.
}
}
}
return aSheet;
return sheets;
}
/// <summary>
/// Get a list of asssets that match certain critera.
/// </summary>
/// <param name="gender">The gengder certain assets belong to, such as male or female.</param>
/// <param name="season">The season that an asset can be displayed in. Good for seasonal assets.</param>
/// <param name="type">The type of part to return a list of such as hair, eyes, or pants.</param>
/// <returns></returns>
/// <summary>Get a list of assets which match the given critera.</summary>
/// <param name="gender">The gender to match.</param>
/// <param name="season">The season to match.</param>
/// <param name="type">The part type to match.</param>
public List<AssetSheet> getListOfAssetsThatMatchThisCriteria(Genders gender, Seasons season, PartType type)
{
List<AssetSheet> aSheet = new List<AssetSheet>();
List<AssetSheet> sheets = new List<AssetSheet>();
foreach (var v in this.assets)
{
if (v.assetInfo is ExtendedAssetInfo)
if (v.assetInfo is ExtendedAssetInfo info)
{
foreach (var sea in (v.assetInfo as ExtendedAssetInfo).seasons)
foreach (var sea in info.seasons)
{
//Class1.ModMonitor.Log("Searching: seasons");
if (sea == season && (v.assetInfo as ExtendedAssetInfo).gender == gender && (v.assetInfo as ExtendedAssetInfo).type == type)
{
aSheet.Add(v);
}
else
{
//Class1.ModMonitor.Log("Not what I was looking for.");
if (sea == season && info.gender == gender && info.type == type)
sheets.Add(v);
}
}
}
}
//Class1.ModMonitor.Log("ok it's over: "+aSheet.Count.ToString());
return aSheet;
}
return sheets;
}
}
}

View File

@ -1,31 +1,25 @@

using CustomNPCFramework.Framework.Enums;
using CustomNPCFramework.Framework.ModularNPCS;
using CustomNPCFramework.Framework.ModularNPCS.CharacterAnimationBases;
using CustomNPCFramework.Framework.ModularNPCS.ColorCollections;
using CustomNPCFramework.Framework.ModularNPCS.ModularRenderers;
using CustomNPCFramework.Framework.NPCS;
using Microsoft.Xna.Framework;
using StardewValley;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CustomNPCFramework.Framework.Enums;
using CustomNPCFramework.Framework.ModularNpcs;
using CustomNPCFramework.Framework.ModularNpcs.CharacterAnimationBases;
using CustomNPCFramework.Framework.ModularNpcs.ColorCollections;
using CustomNPCFramework.Framework.ModularNpcs.ModularRenderers;
using CustomNPCFramework.Framework.NPCS;
using StardewValley;
namespace CustomNPCFramework.Framework.Graphics
{
/// <summary>
/// Used to hold a collection of strings.
/// </summary>
/// <summary>Used to hold a collection of strings.</summary>
public class NamePairings
{
public string leftString;
public string rightString;
public string upString;
public string downString;
public NamePairings(string LeftString, string RightString, string UpString, string DownString)
{
this.leftString = LeftString;
@ -35,37 +29,26 @@ namespace CustomNPCFramework.Framework.Graphics
}
}
/// <summary>
/// Used to contain all of the asset managers.
/// </summary>
/// <summary>Used to contain all of the asset managers.</summary>
public class AssetPool
{
/// <summary>
/// A dictionary holding all of the asset managers. (Name, AssetManager)
/// </summary>
/// <summary>A dictionary holding all of the asset managers. (Name, AssetManager)</summary>
public Dictionary<string, AssetManager> assetPool;
/// <summary>
/// Constructor.
/// </summary>
/// <summary>Construct an instance.</summary>
public AssetPool()
{
this.assetPool = new Dictionary<string, AssetManager>();
}
/// <summary>
/// Adds an asset manager to the asset pool.
/// </summary>
/// <summary>Adds an asset manager to the asset pool.</summary>
/// <param name="pair">A key value pair with the convention being (Manager Name, Asset Manager)</param>
public void addAssetManager(KeyValuePair<string, AssetManager> pair)
{
this.assetPool.Add(pair.Key, pair.Value);
}
/// <summary>
/// Adds an asset manager to the asset pool.
/// </summary>
/// <summary>Adds an asset manager to the asset pool.</summary>
/// <param name="assetManagerName">The name of the asset manager to be added.</param>
/// <param name="assetManager">The asset manager object to be added to the asset pool.</param>
public void addAssetManager(string assetManagerName, AssetManager assetManager)
@ -73,56 +56,40 @@ namespace CustomNPCFramework.Framework.Graphics
this.assetPool.Add(assetManagerName, assetManager);
}
/// <summary>
/// Get an asset manager from the asset pool from a name.
/// </summary>
/// <summary>Get an asset manager from the asset pool from a name.</summary>
/// <param name="name">The name of the asset manager to return.</param>
/// <returns></returns>
public AssetManager getAssetManager(string name)
{
assetPool.TryGetValue(name, out AssetManager asset);
this.assetPool.TryGetValue(name, out AssetManager asset);
return asset;
}
/// <summary>
/// Remove an asset manager from the asset pool.
/// </summary>
/// <summary>Remove an asset manager from the asset pool.</summary>
/// <param name="key">The name of the asset manager to remove.</param>
public void removeAssetManager(string key)
{
assetPool.Remove(key);
this.assetPool.Remove(key);
}
/// <summary>
/// Go through all of the asset managers and load assets according to their respective paths.
/// </summary>
/// <summary>Go through all of the asset managers and load assets according to their respective paths.</summary>
public void loadAllAssets()
{
foreach (KeyValuePair<string, AssetManager> assetManager in this.assetPool)
{
assetManager.Value.loadAssets();
}
}
/// <summary>
/// Creates an extended animated sprite object given the asset name in the asset manager.
/// </summary>
/// <param name="name"></param>
/// <returns></returns>
/// <summary>Creates an extended animated sprite object given the asset name in the asset manager.</summary>
/// <param name="name">The asset name.</param>
public AnimatedSpriteExtended getAnimatedSpriteFromAsset(string name)
{
assetPool.TryGetValue(name, out AssetManager asset);
this.assetPool.TryGetValue(name, out AssetManager asset);
var assetSheet = asset.getAssetByName(name);
return new AnimatedSpriteExtended(assetSheet.path.Clone().ToString(), assetSheet.index, (int)assetSheet.assetInfo.assetSize.X, (int)assetSheet.assetInfo.assetSize.Y);
}
/// <summary>
/// Generates a new AnimatedSpriteCollection object from the data held in an asset sheet.
/// </summary>
/// <summary>Generates a new AnimatedSpriteCollection object from the data held in an asset sheet.</summary>
/// <param name="assetSheet">An asset sheet that holds the data for textures.</param>
/// <param name="type">The type of asset to get from the sheet. Hair, eyes, shoes, etc.</param>
/// <returns></returns>
public AnimatedSpriteCollection getSpriteCollectionFromSheet(AssetSheet assetSheet, AnimationType type)
{
var left = new AnimatedSpriteExtended(assetSheet.clone().getTexture(Direction.left, type), assetSheet);
@ -132,40 +99,31 @@ namespace CustomNPCFramework.Framework.Graphics
return new AnimatedSpriteCollection(left, right, up, down, Direction.down);
}
/// <summary>
/// Gets an animated sprite collection (ie a hair style facing all four directions) from a list of asset names.
/// </summary>
/// <summary>Gets an animated sprite collection (ie a hair style facing all four directions) from a list of asset names.</summary>
/// <param name="left">The name of the asset for the left facing sprite.</param>
/// <param name="right">The name of the asset for the right facing sprite.</param>
/// <param name="up">The name of the asset for the up facing sprite.</param>
/// <param name="down">The name of the asset for the down facing sprite.</param>
/// <param name="startingDirection"></param>
/// <returns></returns>
/// <param name="startingDirection">The sprite's starting direction.</param>
public AnimatedSpriteCollection getAnimatedSpriteCollectionFromAssets(string left, string right, string up, string down, Direction startingDirection = Direction.down)
{
var Left = getAnimatedSpriteFromAsset(left);
var Right = getAnimatedSpriteFromAsset(right);
var Up = getAnimatedSpriteFromAsset(up);
var Down = getAnimatedSpriteFromAsset(down);
return new AnimatedSpriteCollection(Left, Right, Up, Down, startingDirection);
var leftSprite = this.getAnimatedSpriteFromAsset(left);
var rightSprite = this.getAnimatedSpriteFromAsset(right);
var upSprite = this.getAnimatedSpriteFromAsset(up);
var downSprite = this.getAnimatedSpriteFromAsset(down);
return new AnimatedSpriteCollection(leftSprite, rightSprite, upSprite, downSprite, startingDirection);
}
/// <summary>
/// Get an AnimatedSpriteCollection from a name pairing.
/// </summary>
/// <summary>Get an AnimatedSpriteCollection from a name pairing.</summary>
/// <param name="pair">A collection of strings that hold information on directional textures.</param>
/// <param name="startingDirection">The direction in which the sprite should face.</param>
/// <returns></returns>
public AnimatedSpriteCollection getAnimatedSpriteCollectionFromAssets(NamePairings pair, Direction startingDirection = Direction.down)
{
return getAnimatedSpriteCollectionFromAssets(pair.leftString, pair.rightString, pair.upString, pair.downString);
return this.getAnimatedSpriteCollectionFromAssets(pair.leftString, pair.rightString, pair.upString, pair.downString);
}
/// <summary>
/// Get a collection of sprites to generate a collective animated sprite.
/// </summary>
/// <summary>Get a collection of sprites to generate a collective animated sprite.</summary>
/// <param name="BodySprites">The collection of sprites to be used for the boyd of the npc.</param>
/// <param name="EyeSprites">The collection of sprites to be used for the eye of the npc.</param>
/// <param name="HairSprites">The collection of sprites to be used for the hair of the npc.</param>
@ -174,46 +132,42 @@ namespace CustomNPCFramework.Framework.Graphics
/// <param name="ShoesSprites">The collection of sprites to be used for the shoes of the npc.</param>
/// <param name="AccessoriesSprites">The collection of sprites to be used for the accessories of the npc.</param>
/// <param name="DrawColors">The collection of collors to be used for chaing the color of an individual asset.</param>
/// <returns></returns>
public StandardCharacterAnimation GetStandardCharacterAnimation(NamePairings BodySprites, NamePairings EyeSprites, NamePairings HairSprites, NamePairings ShirtsSprites, NamePairings PantsSprites, NamePairings ShoesSprites, List<NamePairings> AccessoriesSprites, StandardColorCollection DrawColors = null)
{
var body = getAnimatedSpriteCollectionFromAssets(BodySprites);
var eyes = getAnimatedSpriteCollectionFromAssets(EyeSprites);
var hair = getAnimatedSpriteCollectionFromAssets(HairSprites);
var shirts = getAnimatedSpriteCollectionFromAssets(ShirtsSprites);
var pants = getAnimatedSpriteCollectionFromAssets(PantsSprites);
var shoes = getAnimatedSpriteCollectionFromAssets(ShoesSprites);
var body = this.getAnimatedSpriteCollectionFromAssets(BodySprites);
var eyes = this.getAnimatedSpriteCollectionFromAssets(EyeSprites);
var hair = this.getAnimatedSpriteCollectionFromAssets(HairSprites);
var shirts = this.getAnimatedSpriteCollectionFromAssets(ShirtsSprites);
var pants = this.getAnimatedSpriteCollectionFromAssets(PantsSprites);
var shoes = this.getAnimatedSpriteCollectionFromAssets(ShoesSprites);
List<AnimatedSpriteCollection> accessories = new List<AnimatedSpriteCollection>();
foreach (var v in AccessoriesSprites)
{
accessories.Add(getAnimatedSpriteCollectionFromAssets(v));
}
if (DrawColors == null) DrawColors = new StandardColorCollection();
accessories.Add(this.getAnimatedSpriteCollectionFromAssets(v));
if (DrawColors == null)
DrawColors = new StandardColorCollection();
return new StandardCharacterAnimation(body, eyes, hair, shirts, pants, shoes, accessories, DrawColors);
}
/// <summary>
/// Get a list of parts that can apply for this criteria.
/// </summary>
/// <summary>Get a list of parts that can apply for this criteria.</summary>
/// <param name="assetManagerName">The name of the asset manager.</param>
/// <param name="gender">The gender critera.</param>
/// <param name="season">The season critera.</param>
/// <param name="type">The part type critera.</param>
/// <returns></returns>
public List<AssetSheet> getListOfApplicableBodyParts(string assetManagerName, Genders gender, Seasons season, PartType type)
{
var parts = this.getAssetManager(assetManagerName).getListOfAssetsThatMatchThisCriteria(gender, season, type);
return parts;
}
/// <summary>
/// Generate a basic npc based off of all all of the NPC data here.
/// </summary>
/// <param name="gender"></param>
/// <param name="minNumOfAccessories"></param>
/// <param name="maxNumOfAccessories"></param>
public ExtendedNPC generateNPC(Genders gender, int minNumOfAccessories, int maxNumOfAccessories ,StandardColorCollection DrawColors=null)
/// <summary>Generate a basic NPC based on the NPC data here.</summary>
/// <param name="gender">The NPC gender.</param>
/// <param name="minNumOfAccessories">The minimum number of accessories to generate.</param>
/// <param name="maxNumOfAccessories">The maximum number of accessories to generate.</param>
/// <param name="drawColors">The colors for the NPC's different assets.</param>
public ExtendedNpc generateNPC(Genders gender, int minNumOfAccessories, int maxNumOfAccessories, StandardColorCollection drawColors = null)
{
Seasons myseason = Seasons.spring;
@ -233,95 +187,87 @@ namespace CustomNPCFramework.Framework.Graphics
//Get all applicable parts from this current asset manager
foreach (var assetManager in this.assetPool)
{
var body = getListOfApplicableBodyParts(assetManager.Key, gender, myseason, PartType.body);
var body = this.getListOfApplicableBodyParts(assetManager.Key, gender, myseason, PartType.body);
foreach (var piece in body) bodyList.Add(piece);
var eyes = getListOfApplicableBodyParts(assetManager.Key, gender, myseason, PartType.eyes);
var eyes = this.getListOfApplicableBodyParts(assetManager.Key, gender, myseason, PartType.eyes);
foreach (var piece in eyes) eyesList.Add(piece);
var hair = getListOfApplicableBodyParts(assetManager.Key, gender, myseason, PartType.hair);
var hair = this.getListOfApplicableBodyParts(assetManager.Key, gender, myseason, PartType.hair);
foreach (var piece in hair) hairList.Add(piece);
var shirt = getListOfApplicableBodyParts(assetManager.Key, gender, myseason, PartType.shirt);
var shirt = this.getListOfApplicableBodyParts(assetManager.Key, gender, myseason, PartType.shirt);
foreach (var piece in shirt) shirtList.Add(piece);
var pants = getListOfApplicableBodyParts(assetManager.Key, gender, myseason, PartType.pants);
var pants = this.getListOfApplicableBodyParts(assetManager.Key, gender, myseason, PartType.pants);
foreach (var piece in pants) pantsList.Add(piece);
var shoes = getListOfApplicableBodyParts(assetManager.Key, gender, myseason, PartType.shoes);
var shoes = this.getListOfApplicableBodyParts(assetManager.Key, gender, myseason, PartType.shoes);
foreach (var piece in shoes) shoesList.Add(piece);
var accessory = getListOfApplicableBodyParts(assetManager.Key, gender, myseason, PartType.accessory);
var accessory = this.getListOfApplicableBodyParts(assetManager.Key, gender, myseason, PartType.accessory);
foreach (var piece in accessory) accessoryList.Add(piece);
}
Random r = new Random(System.DateTime.Now.Millisecond);
int amount = 0;
Random r = new Random(DateTime.Now.Millisecond);
int amount = r.Next(minNumOfAccessories, maxNumOfAccessories + 1);
amount = r.Next(minNumOfAccessories,maxNumOfAccessories + 1); //Necessary since r.next returns a num between min and (max-1)
int bodyIndex;
int eyesIndex;
int hairIndex;
int shirtIndex;
int pantsIndex;
int shoesIndex;
int bodyIndex = 0;
int eyesIndex = 0;
int hairIndex = 0;
int shirtIndex = 0;
int pantsIndex = 0;
int shoesIndex = 0;
if (bodyList.Count != 0) {
if (bodyList.Count != 0)
bodyIndex = r.Next(0, bodyList.Count - 1);
}
else
{
Class1.ModMonitor.Log("Error: Not enough body templates to generate an npc. Aborting", StardewModdingAPI.LogLevel.Error);
return null;
}
if (eyesList.Count != 0) {
if (eyesList.Count != 0)
eyesIndex = r.Next(0, eyesList.Count - 1);
}
else
{
Class1.ModMonitor.Log("Error: Not enough eyes templates to generate an npc. Aborting", StardewModdingAPI.LogLevel.Error);
return null;
}
if (hairList.Count != 0) {
if (hairList.Count != 0)
hairIndex = r.Next(0, hairList.Count - 1);
}
else
{
Class1.ModMonitor.Log("Error: Not enough hair templates to generate an npc. Aborting", StardewModdingAPI.LogLevel.Error);
return null;
}
if (shirtList.Count != 0) {
if (shirtList.Count != 0)
shirtIndex = r.Next(0, shirtList.Count - 1);
}
else
{
Class1.ModMonitor.Log("Error: Not enough shirt templates to generate an npc. Aborting", StardewModdingAPI.LogLevel.Error);
return null;
}
if (pantsList.Count != 0) {
if (pantsList.Count != 0)
pantsIndex = r.Next(0, pantsList.Count - 1);
}
else
{
Class1.ModMonitor.Log("Error: Not enough pants templates to generate an npc. Aborting", StardewModdingAPI.LogLevel.Error);
return null;
}
if (shoesList.Count != 0) {
if (shoesList.Count != 0)
shoesIndex = r.Next(0, shoesList.Count - 1);
}
else
{
Class1.ModMonitor.Log("Error: Not enough shoes templates to generate an npc. Aborting", StardewModdingAPI.LogLevel.Error);
return null;
}
List<int> accIntList = new List<int>();
if (accessoryList.Count != 0)
{
@ -333,97 +279,80 @@ namespace CustomNPCFramework.Framework.Graphics
}
//Get a single sheet to pull from.
AssetSheet bodySheet;
AssetSheet eyesSheet;
AssetSheet hairSheet;
AssetSheet shirtSheet;
AssetSheet shoesSheet;
AssetSheet pantsSheet;
bodySheet = bodyList.ElementAt(bodyIndex);
eyesSheet = eyesList.ElementAt(eyesIndex);
hairSheet = hairList.ElementAt(hairIndex);
shirtSheet = shirtList.ElementAt(shirtIndex);
pantsSheet = pantsList.ElementAt(pantsIndex);
shoesSheet = shoesList.ElementAt(shoesIndex);
AssetSheet bodySheet = bodyList.ElementAt(bodyIndex);
AssetSheet eyesSheet = eyesList.ElementAt(eyesIndex);
AssetSheet hairSheet = hairList.ElementAt(hairIndex);
AssetSheet shirtSheet = shirtList.ElementAt(shirtIndex);
AssetSheet pantsSheet = pantsList.ElementAt(pantsIndex);
AssetSheet shoesSheet = shoesList.ElementAt(shoesIndex);
List<AssetSheet> accessorySheet = new List<AssetSheet>();
foreach (var v in accIntList)
{
foreach (int v in accIntList)
accessorySheet.Add(accessoryList.ElementAt(v));
}
if (DrawColors == null) DrawColors = new StandardColorCollection();
var render = generateBasicRenderer(bodySheet, eyesSheet, hairSheet, shirtSheet, pantsSheet, shoesSheet, accessorySheet,DrawColors);
ExtendedNPC npc = new ExtendedNPC(new Sprite(getDefaultSpriteImage(bodySheet)), render, new Microsoft.Xna.Framework.Vector2(0,0) * Game1.tileSize, 2, NPCNames.getRandomNPCName(gender));
return npc;
if (drawColors == null)
drawColors = new StandardColorCollection();
var render = this.generateBasicRenderer(bodySheet, eyesSheet, hairSheet, shirtSheet, pantsSheet, shoesSheet, accessorySheet, drawColors);
return new ExtendedNpc(new Sprite(this.getDefaultSpriteImage(bodySheet)), render, new Microsoft.Xna.Framework.Vector2(0, 0) * Game1.tileSize, 2, NpcNames.getRandomNpcName(gender));
}
/// <summary>
/// Creates a character renderer (a collection of textures) from a bunch of different asset sheets.
/// </summary>
/// <param name="bodySheet">The textures for the npc's body.</param>
/// <param name="eyesSheet">The textures for the npc's eyes.</param>
/// <param name="hairSheet">The textures for the npc's hair.</param>
/// <param name="shirtSheet">The textures for the npc's shirt.</param>
/// <param name="pantsSheet">The textures for the npc's pants.</param>
/// <param name="shoesSheet">The textures for the npc's shoes.</param>
/// <param name="accessorySheet">The textures for the npc's accessories.</param>
/// <param name="DrawColors">The colors for the npc's different assets.</param>
/// <returns></returns>
public virtual BasicRenderer generateBasicRenderer(AssetSheet bodySheet, AssetSheet eyesSheet, AssetSheet hairSheet, AssetSheet shirtSheet, AssetSheet pantsSheet, AssetSheet shoesSheet, List<AssetSheet> accessorySheet, StandardColorCollection DrawColors=null)
/// <summary>Creates a character renderer (a collection of textures) from a bunch of different asset sheets.</summary>
/// <param name="bodySheet">The textures for the NPC's body.</param>
/// <param name="eyesSheet">The textures for the NPC's eyes.</param>
/// <param name="hairSheet">The textures for the NPC's hair.</param>
/// <param name="shirtSheet">The textures for the NPC's shirt.</param>
/// <param name="pantsSheet">The textures for the NPC's pants.</param>
/// <param name="shoesSheet">The textures for the NPC's shoes.</param>
/// <param name="accessorySheet">The textures for the NPC's accessories.</param>
/// <param name="drawColors">The colors for the NPC's different assets.</param>
public virtual BasicRenderer generateBasicRenderer(AssetSheet bodySheet, AssetSheet eyesSheet, AssetSheet hairSheet, AssetSheet shirtSheet, AssetSheet pantsSheet, AssetSheet shoesSheet, List<AssetSheet> accessorySheet, StandardColorCollection drawColors = null)
{
if (DrawColors == null) DrawColors = new StandardColorCollection();
if (drawColors == null)
drawColors = new StandardColorCollection();
// Get all of the appropriate animations.
AnimationType type = AnimationType.standing;
var standingAnimation = generateCharacterAnimation(bodySheet, eyesSheet, hairSheet, shirtSheet, pantsSheet, shoesSheet, accessorySheet, type,DrawColors);
type = AnimationType.walking;
var movingAnimation = generateCharacterAnimation(bodySheet, eyesSheet, hairSheet, shirtSheet, pantsSheet, shoesSheet, accessorySheet, type,DrawColors);
type = AnimationType.swimming;
var swimmingAnimation = generateCharacterAnimation(bodySheet, eyesSheet, hairSheet, shirtSheet, pantsSheet, shoesSheet, accessorySheet, type,DrawColors);
StandardCharacterAnimation standingAnimation = this.generateCharacterAnimation(bodySheet, eyesSheet, hairSheet, shirtSheet, pantsSheet, shoesSheet, accessorySheet, AnimationType.standing, drawColors);
StandardCharacterAnimation movingAnimation = this.generateCharacterAnimation(bodySheet, eyesSheet, hairSheet, shirtSheet, pantsSheet, shoesSheet, accessorySheet, AnimationType.walking, drawColors);
StandardCharacterAnimation swimmingAnimation = this.generateCharacterAnimation(bodySheet, eyesSheet, hairSheet, shirtSheet, pantsSheet, shoesSheet, accessorySheet, AnimationType.swimming, drawColors);
BasicRenderer render = new BasicRenderer(standingAnimation, movingAnimation, swimmingAnimation);
return render;
return new BasicRenderer(standingAnimation, movingAnimation, swimmingAnimation);
}
/// <summary>
/// Generate a Standard Character Animation from some asset sheets.
/// (collection of textures to animations)
/// </summary>
/// <param name="body">The textures for the npc's body.</param>
/// <param name="eyes">The textures for the npc's eyes.</param>
/// <param name="hair">The textures for the npc's hair.</param>
/// <param name="shirt">The textures for the npc's shirt.</param>
/// <param name="pants">The textures for the npc's pants.</param>
/// <param name="shoes">The textures for the npc's shoes.</param>
/// <param name="accessoryType">The textures for the npc's accessories.</param>
/// <param name="DrawColors">The colors for the npc's different assets.</param>
/// <returns></returns>
public virtual StandardCharacterAnimation generateCharacterAnimation(AssetSheet body, AssetSheet eyes, AssetSheet hair, AssetSheet shirt, AssetSheet pants, AssetSheet shoes,List<AssetSheet> accessories, AnimationType animationType, StandardColorCollection DrawColors=null)
/// <summary>Generate a Standard Character Animation from some asset sheets. (collection of textures to animations)</summary>
/// <param name="body">The textures for the NPC's body.</param>
/// <param name="eyes">The textures for the NPC's eyes.</param>
/// <param name="hair">The textures for the NPC's hair.</param>
/// <param name="shirt">The textures for the NPC's shirt.</param>
/// <param name="pants">The textures for the NPC's pants.</param>
/// <param name="shoes">The textures for the NPC's shoes.</param>
/// <param name="accessories">The textures for the NPC's accessories.</param>
/// <param name="animationType">The animation type to generate.</param>
/// <param name="drawColors">The colors for the NPC's different assets.</param>
public virtual StandardCharacterAnimation generateCharacterAnimation(AssetSheet body, AssetSheet eyes, AssetSheet hair, AssetSheet shirt, AssetSheet pants, AssetSheet shoes, List<AssetSheet> accessories, AnimationType animationType, StandardColorCollection drawColors = null)
{
var bodySprite = getSpriteCollectionFromSheet(body, animationType);
var eyesSprite = getSpriteCollectionFromSheet(eyes, animationType);
var hairSprite = getSpriteCollectionFromSheet(hair, animationType);
var shirtSprite = getSpriteCollectionFromSheet(shirt, animationType);
var pantsSprite = getSpriteCollectionFromSheet(pants, animationType);
var shoesSprite = getSpriteCollectionFromSheet(shoes, animationType);
AnimatedSpriteCollection bodySprite = this.getSpriteCollectionFromSheet(body, animationType);
AnimatedSpriteCollection eyesSprite = this.getSpriteCollectionFromSheet(eyes, animationType);
AnimatedSpriteCollection hairSprite = this.getSpriteCollectionFromSheet(hair, animationType);
AnimatedSpriteCollection shirtSprite = this.getSpriteCollectionFromSheet(shirt, animationType);
AnimatedSpriteCollection pantsSprite = this.getSpriteCollectionFromSheet(pants, animationType);
AnimatedSpriteCollection shoesSprite = this.getSpriteCollectionFromSheet(shoes, animationType);
List<AnimatedSpriteCollection> accessoryCollection = new List<AnimatedSpriteCollection>();
foreach (var v in accessories)
{
AnimatedSpriteCollection acc = getSpriteCollectionFromSheet(v, AnimationType.standing);
AnimatedSpriteCollection acc = this.getSpriteCollectionFromSheet(v, AnimationType.standing);
accessoryCollection.Add(acc);
}
if (DrawColors == null) DrawColors = new StandardColorCollection();
StandardCharacterAnimation standingAnimation = new StandardCharacterAnimation(bodySprite, eyesSprite, hairSprite, shirtSprite, pantsSprite, shoesSprite, accessoryCollection,DrawColors);
return standingAnimation;
if (drawColors == null)
drawColors = new StandardColorCollection();
return new StandardCharacterAnimation(bodySprite, eyesSprite, hairSprite, shirtSprite, pantsSprite, shoesSprite, accessoryCollection, drawColors);
}
/// <summary>
/// Get the string for the standard character sprite to be used from this asset sheet.
/// </summary>
/// <summary>Get the relative path for the standard character sprite to be used from this asset sheet.</summary>
/// <param name="imageGraphics">The standard asset sheet to be used.</param>
/// <returns></returns>
public virtual string getDefaultSpriteImage(AssetSheet imageGraphics)
{
return Class1.getRelativeDirectory(Path.Combine(imageGraphics.path, imageGraphics.assetInfo.standingAssetPaths.downString));

View File

@ -1,130 +1,86 @@
using CustomNPCFramework.Framework.Enums;
using System.Collections.Generic;
using CustomNPCFramework.Framework.Enums;
using CustomNPCFramework.Framework.Graphics.TextureGroups;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using StardustCore.UIUtilities;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CustomNPCFramework.Framework.Graphics
{
/// <summary>
/// Used to handle loading different textures and handling opperations on those textures.
/// </summary>
/// <summary>Used to handle loading different textures and handling opperations on those textures.</summary>
public class AssetSheet
{
/// <summary>
/// Used to hold the textures for the AssetSheet.
/// </summary>
public TextureGroups.TextureGroup textures;
/// <summary>Used to hold the textures for the AssetSheet.</summary>
public TextureGroup textures;
/// <summary>
/// Used to hold the info for the paths to these textures.
/// </summary>
/// <summary>Used to hold the info for the paths to these textures.</summary>
public AssetInfo assetInfo;
/// <summary>
/// The path to this assetinfo.json file
/// </summary>
/// <summary>The path to this assetinfo.json file</summary>
public string path;
/// <summary>
/// The soruce rectangle for the current texture to draw.
/// </summary>
/// <summary>The source rectangle for the current texture to draw.</summary>
public Rectangle currentAsset;
public int index;
/// <summary>
/// Constructor.
/// </summary>
/// <summary>Construct an instance.</summary>
/// <param name="info">The asset info file to be read in or created. Holds path information.</param>
/// <param name="path">The path to the assetinfo file.</param>
/// <param name="relativeDirPath">The relative path to the assetinfo file.</param>
/// <param name="direction">The direction to set the animation.</param>
public AssetSheet(AssetInfo info,string path,Direction direction=Direction.down)
public AssetSheet(AssetInfo info, string relativeDirPath, Direction direction = Direction.down)
{
this.assetInfo = info;
this.textures = new TextureGroup(info,path,direction);
try
{
this.path = Class1.getShortenedDirectory(path);
}
catch(Exception err)
{
this.path = path;
}
this.textures = new TextureGroup(info, relativeDirPath, direction);
this.path = relativeDirPath;
this.index = 0;
}
/// <summary>
/// Get the path to the current texture.
/// </summary>
/// <returns></returns>
/// <summary>Get the path to the current texture.</summary>
public virtual KeyValuePair<string, Texture2DExtended> getPathTexturePair()
{
return new KeyValuePair<string, Texture2DExtended>(this.path, this.textures.currentTexture.currentTexture);
}
/// <summary>
/// Used just to get a copy of this asset sheet.
/// </summary>
/// <summary>Used just to get a copy of this asset sheet.</summary>
public virtual AssetSheet clone()
{
var asset = new AssetSheet(this.assetInfo, (string)this.path.Clone());
return asset;
}
/// <summary>
/// Sets the textures for this sheet to face left.
/// </summary>
/// <summary>Sets the textures for this sheet to face left.</summary>
public virtual void setLeft()
{
this.textures.setLeft();
}
/// <summary>
/// Sets the textures for this sheet to face up.
/// </summary>
/// <summary>Sets the textures for this sheet to face up.</summary>
public virtual void setUp()
{
this.textures.setUp();
}
/// <summary>
/// Sets the textures for this sheet to face down.
/// </summary>
/// <summary>Sets the textures for this sheet to face down.</summary>
public virtual void setDown()
{
this.textures.setDown();
}
/// <summary>
/// Sets the textures for this sheet to face left.
/// </summary>
/// <summary>Sets the textures for this sheet to face left.</summary>
public virtual void setRight()
{
this.textures.setRight();
}
/// <summary>
/// Get the current animation texture.
/// </summary>
/// <returns></returns>
/// <summary>Get the current animation texture.</summary>
public virtual Texture2DExtended getCurrentSpriteTexture()
{
return this.textures.currentTexture.currentTexture;
}
/// <summary>
/// Get the specific texture depending on the direction and animation type.
/// </summary>
/// <param name="direction"></param>
/// <param name="type"></param>
/// <returns></returns>
/// <summary>Get the specific texture depending on the direction and animation type.</summary>
/// <param name="direction">The facing direction.</param>
/// <param name="type">The animation type.</param>
public virtual Texture2DExtended getTexture(Direction direction, AnimationType type)
{
return this.textures.getTextureFromAnimation(type).getTextureFromDirection(direction);

View File

@ -1,47 +1,29 @@
using CustomNPCFramework.Framework.Enums;
using Microsoft.Xna.Framework.Graphics;
using System.IO;
using CustomNPCFramework.Framework.Enums;
using StardewModdingAPI;
using StardustCore.UIUtilities;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CustomNPCFramework.Framework.Graphics
{
/// <summary>
/// A class that's used to hold textures for different directions.
/// </summary>
/// <summary>A class that's used to hold textures for different directions.</summary>
public class DirectionalTexture
{
/// <summary>
/// The left texture for this group.
/// </summary>
/// <summary>The left texture for this group.</summary>
public Texture2DExtended leftTexture;
/// <summary>
/// The right texture for this group.
/// </summary>
/// <summary>The right texture for this group.</summary>
public Texture2DExtended rightTexture;
/// <summary>
/// The down textiure for this group.
/// </summary>
/// <summary>The down textiure for this group.</summary>
public Texture2DExtended downTexture;
/// <summary>
/// The up texture for this group.
/// </summary>
/// <summary>The up texture for this group.</summary>
public Texture2DExtended upTexture;
/// <summary>
/// The current texture for this group.
/// </summary>
/// <summary>The current texture for this group.</summary>
public Texture2DExtended currentTexture;
/// <summary>
/// Constructor.
/// </summary>
/// <summary>Construct an instance.</summary>
/// <param name="left">The left texture to use.</param>
/// <param name="right">The right texture to use.</param>
/// <param name="up">The up texture to use.</param>
@ -54,81 +36,98 @@ namespace CustomNPCFramework.Framework.Graphics
this.upTexture = up;
this.downTexture = down;
if (direction == Direction.left) this.currentTexture = leftTexture;
if (direction == Direction.right) this.currentTexture = rightTexture;
if (direction == Direction.up) this.currentTexture = upTexture;
if (direction == Direction.down) this.currentTexture = downTexture;
}
public DirectionalTexture(IModHelper helper ,NamePairings info, string path, Direction direction = Direction.down)
switch (direction)
{
case Direction.left:
this.currentTexture = this.leftTexture;
break;
new Texture2DExtended(helper, path);
case Direction.right:
this.currentTexture = this.rightTexture;
break;
string leftString= Class1.getShortenedDirectory(Path.Combine(path, info.leftString + ".png")).Remove(0, 1);
string rightString = Class1.getShortenedDirectory(Path.Combine(path, info.rightString + ".png")).Remove(0, 1);
string upString = Class1.getShortenedDirectory(Path.Combine(path, info.upString + ".png")).Remove(0, 1);
string downString = Class1.getShortenedDirectory(Path.Combine(path, info.downString + ".png")).Remove(0, 1);
case Direction.up:
this.currentTexture = this.upTexture;
break;
this.leftTexture = new Texture2DExtended(helper, leftString);
this.rightTexture = new Texture2DExtended(helper, rightString);
this.upTexture = new Texture2DExtended(helper, upString);
this.downTexture = new Texture2DExtended(helper, downString);
if (direction == Direction.left) this.currentTexture = leftTexture;
if (direction == Direction.right) this.currentTexture = rightTexture;
if (direction == Direction.up) this.currentTexture = upTexture;
if (direction == Direction.down) this.currentTexture = downTexture;
case Direction.down:
this.currentTexture = this.downTexture;
break;
}
}
/// <summary>
/// Sets the direction of this current texture to left.
/// </summary>
public DirectionalTexture(IModHelper helper, NamePairings info, string relativePath, Direction direction = Direction.down)
{
this.leftTexture = new Texture2DExtended(helper, Path.Combine(relativePath, $"{info.leftString}.png"));
this.rightTexture = new Texture2DExtended(helper, Path.Combine(relativePath, $"{info.rightString}.png"));
this.upTexture = new Texture2DExtended(helper, Path.Combine(relativePath, $"{info.upString}.png"));
this.downTexture = new Texture2DExtended(helper, Path.Combine(relativePath, $"{info.downString}.png"));
switch (direction)
{
case Direction.left:
this.currentTexture = this.leftTexture;
break;
case Direction.right:
this.currentTexture = this.rightTexture;
break;
case Direction.up:
this.currentTexture = this.upTexture;
break;
case Direction.down:
this.currentTexture = this.downTexture;
break;
}
}
/// <summary>Sets the direction of this current texture to left.</summary>
public void setLeft()
{
this.currentTexture = leftTexture;
this.currentTexture = this.leftTexture;
}
/// <summary>
/// Sets the direction of this current texture to up.
/// </summary>
/// <summary>Sets the direction of this current texture to up.</summary>
public void setUp()
{
this.currentTexture = upTexture;
this.currentTexture = this.upTexture;
}
/// <summary>
/// Sets the direction of this current texture to down.
/// </summary>
/// <summary>Sets the direction of this current texture to down.</summary>
public void setDown()
{
this.currentTexture = downTexture;
this.currentTexture = this.downTexture;
}
/// <summary>
/// Sets the direction of this current texture to right.
/// </summary>
/// <summary>Sets the direction of this current texture to right.</summary>
public void setRight()
{
this.currentTexture = rightTexture;
this.currentTexture = this.rightTexture;
}
/// <summary>
/// Gets the texture from this texture group depending on the direction.
/// </summary>
/// <param name="direction"></param>
/// <returns></returns>
/// <summary>Gets the texture from this texture group depending on the direction.</summary>
/// <param name="direction">The facing direction.</param>
public virtual Texture2DExtended getTextureFromDirection(Direction direction)
{
if (direction == Direction.left) return this.leftTexture;
if (direction == Direction.right) return this.rightTexture;
if (direction == Direction.up) return this.upTexture;
if (direction == Direction.down) return this.downTexture;
switch (direction)
{
case Direction.left:
return this.leftTexture;
case Direction.right:
return this.rightTexture;
case Direction.up:
return this.upTexture;
case Direction.down:
return this.downTexture;
default:
return null;
}
}
}
}

View File

@ -1,73 +1,55 @@
using CustomNPCFramework.Framework.Enums;
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CustomNPCFramework.Framework.Enums;
using Microsoft.Xna.Framework;
namespace CustomNPCFramework.Framework.Graphics
{
/// <summary>
/// An expanded Asset info class that deals with seasons and genders.
/// </summary>
/// <summary>An expanded Asset info class that deals with seasons and genders.</summary>
public class ExtendedAssetInfo : AssetInfo
{
/// <summary>
/// The genders this part is associated with. 0=Male, 1=female, 2=other.
/// </summary>
/// <summary>The genders this part is associated with.</summary>
public Genders gender;
/// <summary>
/// A list of seasons where this part can be displayed
/// </summary>
/// <summary>A list of seasons where this part can be displayed.</summary>
public List<Seasons> seasons = new List<Seasons>();
/// <summary>
/// The part type to be used for this asset such as hair, eyes, etc.
/// </summary>
/// <summary>The part type to be used for this asset such as hair, eyes, etc.</summary>
public PartType type;
/// <summary>
/// Constructor.
/// </summary>
public ExtendedAssetInfo()
/// <summary>Construct an instance.</summary>
public ExtendedAssetInfo() { }
/// <summary>Construct an instance.</summary>
/// <param name="name">The name of the asset. This is the name that will be referenced in any asset manager or asset pool.</param>
/// <param name="standingAssetPaths">The name of the files to be used for the standing animation.</param>
/// <param name="movingAssetPaths">The name of the files to be used for the moving animation.</param>
/// <param name="swimmingAssetPaths">The name of the files to be used for the swimming animation.</param>
/// <param name="sittingAssetPaths">The name of the files to be used for the sitting animation.</param>
/// <param name="assetSize">The size of the asset. Width and height of the texture.</param>
/// <param name="randomizeOnLoad">Legacy, not really used anymore.</param>
/// <param name="gender">The type of gender this asset will be associated with.</param>
/// <param name="season">The type of season this asset will be associated with.</param>
/// <param name="type">The part type to be used for this asset such as hair, eyes, etc.</param>
public ExtendedAssetInfo(string name, NamePairings standingAssetPaths, NamePairings movingAssetPaths, NamePairings swimmingAssetPaths, NamePairings sittingAssetPaths, Vector2 assetSize, bool randomizeOnLoad, Genders gender, List<Seasons> season, PartType type)
: base(name, standingAssetPaths, movingAssetPaths, swimmingAssetPaths, sittingAssetPaths, assetSize, randomizeOnLoad)
{
this.seasons = new List<Seasons>();
this.gender = gender;
this.seasons = season ?? new List<Seasons>();
this.type = type;
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="name"></param>
/// <param name="assetSize"></param>
/// <param name="randomizeOnLoad"></param>
/// <param name="Gender">The type of gender this asset will be associated with.</param>
/// <param name="Season">The type of season this asset will be associated with.</param>
public ExtendedAssetInfo(string name, NamePairings StandingAssetPaths, NamePairings MovingAssetPaths, NamePairings SwimmingAssetPaths, NamePairings SittingAssetPaths, Vector2 assetSize, bool randomizeOnLoad, Genders Gender, List<Seasons> Season, PartType Type): base(name,StandingAssetPaths,MovingAssetPaths,SwimmingAssetPaths,SittingAssetPaths, assetSize, randomizeOnLoad)
/// <summary>Save the json to a certain location.</summary>
/// <param name="relativePath">The relative path to write.</param>
public new void writeToJson(string relativePath)
{
this.gender = Gender;
this.seasons = Season;
if (this.seasons == null) this.seasons = new List<Seasons>();
this.type = Type;
Class1.ModHelper.Data.WriteJsonFile<ExtendedAssetInfo>(relativePath, this);
}
/// <summary>
/// Save the json to a certain location.
/// </summary>
/// <param name="path"></param>
public new void writeToJson(string path)
/// <summary>Read the json from a certain location.</summary>
/// <param name="relativePath">The relative path to read.</param>
public new static ExtendedAssetInfo readFromJson(string relativePath)
{
Class1.ModHelper.WriteJsonFile<ExtendedAssetInfo>(path, this);
}
/// <summary>
/// Read the json from a certain location.
/// </summary>
/// <param name="path"></param>
/// <returns></returns>
public new static ExtendedAssetInfo readFromJson(string path)
{
return Class1.ModHelper.ReadJsonFile<ExtendedAssetInfo>(path);
}
return Class1.ModHelper.Data.ReadJsonFile<ExtendedAssetInfo>(relativePath);
}
}
}

View File

@ -1,60 +1,38 @@
using CustomNPCFramework.Framework.Enums;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CustomNPCFramework.Framework.Enums;
namespace CustomNPCFramework.Framework.Graphics.TextureGroups
{
/// <summary>
/// A group of a textures used to hold all of the textures associated with a single asset such as a hair style or a shirt.
/// </summary>
/// <summary>A group of a textures used to hold all of the textures associated with a single asset such as a hair style or a shirt.</summary>
public class TextureGroup
{
/// <summary>
/// The directional (Left, Right, Up, Down) textures to be used when the NPC is standing.
/// </summary>
/// <summary>The directional (Left, Right, Up, Down) textures to be used when the NPC is standing.</summary>
public DirectionalTexture standingTexture;
/// <summary>
/// The directional (Left, Right, Up, Down) textures to be used when the NPC is sitting.
/// </summary>
/// <summary>The directional (Left, Right, Up, Down) textures to be used when the NPC is sitting.</summary>
public DirectionalTexture sittingTexture;
/// <summary>
/// The directional (Left, Right, Up, Down) textures to be used when the NPC is swimming.
/// </summary>
/// <summary>The directional (Left, Right, Up, Down) textures to be used when the NPC is swimming.</summary>
public DirectionalTexture swimmingTexture;
/// <summary>
/// The directional (Left, Right, Up, Down) textures to be used when the NPC is moving.
/// </summary>
/// <summary>The directional (Left, Right, Up, Down) textures to be used when the NPC is moving.</summary>
public DirectionalTexture movingTexture;
/// <summary>
/// The current directional texture to be used by the npc. Can be things such as the standing, swimming, moving, or sitting texture.
/// </summary>
/// <summary>The current directional texture to be used by the npc. Can be things such as the standing, swimming, moving, or sitting texture.</summary>
public DirectionalTexture currentTexture;
/// <summary>
/// Asset info loaded in from the corresponding .json file.
/// </summary>
private AssetInfo info;
/// <summary>
/// The path to the .json file.
/// </summary>
private string path;
/// <summary>
/// The current direction of the texture group. See Direction.cs
/// </summary>
private Direction dir;
/// <summary>
/// The type of asset this is. Body, hair, eyes, shirt,etc...
/// </summary>
private AnimationType type;
/// <summary>Asset info loaded in from the corresponding .json file.</summary>
private readonly AssetInfo info;
/// <summary>
/// Constructor.
/// </summary>
/// <summary>The path to the .json file.</summary>
private readonly string path;
/// <summary>The current direction of the texture group.</summary>
private readonly Direction dir;
/// <summary>The type of asset this is. Body, hair, eyes, shirt, etc.</summary>
private readonly AnimationType type;
/// <summary>Construct an instance.</summary>
/// <param name="info">The asset info file to be stored with this texture group.</param>
/// <param name="path">Use to locate the files on disk.</param>
/// <param name="direction">Used to determine the current direction/animation to load</param>
@ -71,26 +49,19 @@ namespace CustomNPCFramework.Framework.Graphics.TextureGroups
this.dir = direction;
this.type = animationType;
if (animationType == AnimationType.standing) this.currentTexture = standingTexture;
if (animationType == AnimationType.sitting) this.currentTexture = sittingTexture;
if (animationType == AnimationType.swimming) this.currentTexture = swimmingTexture;
if (animationType == AnimationType.walking) this.currentTexture = movingTexture;
if (animationType == AnimationType.standing) this.currentTexture = this.standingTexture;
if (animationType == AnimationType.sitting) this.currentTexture = this.sittingTexture;
if (animationType == AnimationType.swimming) this.currentTexture = this.swimmingTexture;
if (animationType == AnimationType.walking) this.currentTexture = this.movingTexture;
}
/// <summary>
/// Gets a clone of this texture group.
/// </summary>
/// <returns></returns>
/// <summary>Gets a clone of this texture group. </summary>
public TextureGroup clone()
{
return new TextureGroup(this.info, this.path, this.dir, this.type);
}
/// <summary>
/// Sets all of the different animations to use their left facing sprites.
/// </summary>
/// <summary>Sets all of the different animations to use their left facing sprites.</summary>
public virtual void setLeft()
{
this.movingTexture.setLeft();
@ -99,9 +70,7 @@ namespace CustomNPCFramework.Framework.Graphics.TextureGroups
this.swimmingTexture.setLeft();
}
/// <summary>
/// Sets all of the different animations to use their up facing sprites.
/// </summary>
/// <summary>Sets all of the different animations to use their up facing sprites.</summary>
public virtual void setUp()
{
this.movingTexture.setUp();
@ -110,9 +79,7 @@ namespace CustomNPCFramework.Framework.Graphics.TextureGroups
this.swimmingTexture.setUp();
}
/// <summary>
/// Sets all of the different animations to use their down facing sprites.
/// </summary>
/// <summary>Sets all of the different animations to use their down facing sprites.</summary>
public virtual void setDown()
{
this.movingTexture.setDown();
@ -121,9 +88,7 @@ namespace CustomNPCFramework.Framework.Graphics.TextureGroups
this.swimmingTexture.setDown();
}
/// <summary>
/// Sets all of the different animations to use their right facing sprites.
/// </summary>
/// <summary>Sets all of the different animations to use their right facing sprites.</summary>
public virtual void setRight()
{
this.movingTexture.setRight();
@ -132,11 +97,8 @@ namespace CustomNPCFramework.Framework.Graphics.TextureGroups
this.swimmingTexture.setRight();
}
/// <summary>
/// Get's the appropriate animation texture based on the type of animation key passed in.
/// </summary>
/// <param name="type"></param>
/// <returns></returns>
/// <summary>Gets the appropriate animation texture based on the type of animation key passed in.</summary>
/// <param name="type">The animation type.</param>
public virtual DirectionalTexture getTextureFromAnimation(AnimationType type)
{
if (type == AnimationType.standing) return this.standingTexture;
@ -145,6 +107,5 @@ namespace CustomNPCFramework.Framework.Graphics.TextureGroups
if (type == AnimationType.sitting) return this.sittingTexture;
return null;
}
}
}

View File

@ -1,78 +1,62 @@
using CustomNPCFramework.Framework.Enums;
using CustomNPCFramework.Framework.Enums;
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
namespace CustomNPCFramework.Framework.ModularNpcs
{
/// <summary>
/// Used to hold all of the sprites for a single asset such as hair or bodies.
/// </summary>
/// <summary>Used to hold all of the sprites for a single asset such as hair or bodies.</summary>
public class AnimatedSpriteCollection
{
/// <summary>
/// The left sprite for this sprite asset part.
/// </summary>
/// <summary>The left sprite for this sprite asset part.</summary>
AnimatedSpriteExtended leftSprite;
/// <summary>
/// The right sprite for this sprite asset part.
/// </summary>
/// <summary>The right sprite for this sprite asset part.</summary>
AnimatedSpriteExtended rightSprite;
/// <summary>
/// The up sprite for this sprite asset part.
/// </summary>
/// <summary>The up sprite for this sprite asset part.</summary>
AnimatedSpriteExtended upSprite;
/// <summary>
/// The down sprite for this sprite asset part.
/// </summary>
/// <summary>The down sprite for this sprite asset part.</summary>
AnimatedSpriteExtended downSprite;
/// <summary>
/// The current sprite for this sprite collection. This is one of the four directions for this collection.
/// </summary>
/// <summary>The current sprite for this sprite collection. This is one of the four directions for this collection.</summary>
public AnimatedSpriteExtended currentSprite;
/// <summary>
/// Constructor.
/// </summary>
/// <summary>Construct an instance.</summary>
/// <param name="LeftSprite">Left animated sprite for this piece.</param>
/// <param name="RightSprite">Right animated sprite for this piece.</param>
/// <param name="UpSprite">Up animated sprite for this piece.</param>
/// <param name="DownSprite">Down animated sprite for this piece.</param>
/// <param name="startingSpriteDirection"></param>
/// <param name="startingSpriteDirection">The sprite's initial facing direction.</param>
public AnimatedSpriteCollection(AnimatedSpriteExtended LeftSprite, AnimatedSpriteExtended RightSprite, AnimatedSpriteExtended UpSprite, AnimatedSpriteExtended DownSprite, Direction startingSpriteDirection)
{
this.leftSprite = LeftSprite;
this.rightSprite = RightSprite;
this.upSprite = UpSprite;
this.downSprite = DownSprite;
if (startingSpriteDirection == Direction.down)
switch (startingSpriteDirection)
{
setDown();
}
if (startingSpriteDirection == Direction.left)
{
setLeft();
}
if (startingSpriteDirection == Direction.right)
{
setRight();
}
if (startingSpriteDirection == Direction.up)
{
setUp();
case Direction.down:
this.setDown();
break;
case Direction.left:
this.setLeft();
break;
case Direction.right:
this.setRight();
break;
case Direction.up:
this.setUp();
break;
}
}
/// <summary>
/// Reloads all of the directional textures for this texture collection.
/// </summary>
/// <summary>Reloads all of the directional textures for this texture collection.</summary>
public virtual void reload()
{
this.leftSprite.reload();
@ -81,81 +65,44 @@ namespace CustomNPCFramework.Framework.ModularNPCS
this.downSprite.reload();
}
/// <summary>
/// Sets the current sprite direction to face left.
/// </summary>
/// <summary>Sets the current sprite direction to face left.</summary>
public void setLeft()
{
this.currentSprite = leftSprite;
this.currentSprite = this.leftSprite;
}
/// <summary>
/// Sets the current sprite direction to face right.
/// </summary>
/// <summary>Sets the current sprite direction to face right.</summary>
public void setRight()
{
this.currentSprite = rightSprite;
this.currentSprite = this.rightSprite;
}
/// <summary>
/// Sets the current sprite direction to face down.
/// </summary>
/// <summary>Sets the current sprite direction to face down.</summary>
public void setDown()
{
this.currentSprite = downSprite;
this.currentSprite = this.downSprite;
}
/// <summary>
/// Sets the current sprite direction to face up.
/// </summary>
/// <summary>Sets the current sprite direction to face up.</summary>
public void setUp()
{
this.currentSprite = upSprite;
this.currentSprite = this.upSprite;
}
/// <summary>
/// Used to draw the sprite to the screen.
/// </summary>
/// <param name="b"></param>
/// <param name="screenPosition"></param>
/// <param name="layerDepth"></param>
/// <summary>Used to draw the sprite to the screen.</summary>
public void draw(SpriteBatch b, Vector2 screenPosition, float 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);
}
/// <summary>
/// Used to draw the sprite to the screen.
/// </summary>
/// <param name="b"></param>
/// <param name="screenPosition"></param>
/// <param name="layerDepth"></param>
/// <param name="xOffset"></param>
/// <param name="yOffset"></param>
/// <param name="c"></param>
/// <param name="flip"></param>
/// <param name="scale"></param>
/// <param name="rotation"></param>
/// <param name="characterSourceRectOffset"></param>
/// <summary>Used to draw the sprite to the screen.</summary>
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.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);
}
/// <summary>
/// A very verbose asset drawer.
/// </summary>
/// <param name="b"></param>
/// <param name="npc"></param>
/// <param name="position"></param>
/// <param name="sourceRectangle"></param>
/// <param name="color"></param>
/// <param name="alpha"></param>
/// <param name="origin"></param>
/// <param name="scale"></param>
/// <param name="effects"></param>
/// <param name="layerDepth"></param>
public void draw(SpriteBatch b, ExtendedNPC npc, Vector2 position, Rectangle sourceRectangle,Color color, float alpha,Vector2 origin,float scale,SpriteEffects effects,float layerDepth)
/// <summary>A very verbose asset drawer.</summary>
public void draw(SpriteBatch b, ExtendedNpc npc, Vector2 position, Rectangle sourceRectangle, Color color, float alpha, Vector2 origin, float scale, SpriteEffects effects, float layerDepth)
{
//DEFINITELY FIX THIS PART. Something is wrong with how these two functions handle the drawing of my npc to the scene.
//this.draw(b, position, layerDepth);
@ -163,26 +110,20 @@ namespace CustomNPCFramework.Framework.ModularNPCS
//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));
}
/// <summary>
/// Animate the current sprite. Theoreticlly works from index offset to how many frames
/// </summary>
/// <summary>Animate the current sprite. Theoreticlly works from index offset to how many frames</summary>
/// <param name="intervalDelay">The delay in milliseconds between frames.</param>
public void Animate(float intervalDelay, bool loop = true)
{
this.Animate(Game1.currentGameTime, 0, 2, intervalDelay, this.currentSprite.sprite, loop);
}
/// <summary>
/// Animate the current sprite.
/// </summary>
/// <summary>Animate the current sprite.</summary>
/// <param name="gameTime">The game time from Monogames/XNA</param>
/// <param name="startFrame">The starting frame of the animation on the sprite sheet.</param>
/// <param name="numberOfFrames">The number of frames to animate the sprite.</param>
/// <param name="interval">The delay between frames in milliseconds.</param>
/// <param name="sprite">The animated sprite from the npc.</param>
/// <param name="loop">If true, the animation plays over and over again.</param>
/// <returns></returns>
public virtual bool Animate(GameTime gameTime, int startFrame, int numberOfFrames, float interval, AnimatedSprite sprite, bool loop = true)
{
if (sprite.CurrentFrame >= startFrame + numberOfFrames + 1 || sprite.CurrentFrame < startFrame)
@ -204,10 +145,7 @@ namespace CustomNPCFramework.Framework.ModularNPCS
return false;
}
/// <summary>
/// Update the source rectangle on the sprite sheet. Needed for animation.
/// </summary>
/// <param name="sprite"></param>
/// <summary>Update the source rectangle on the sprite sheet. Needed for animation.</summary>
public virtual void UpdateSourceRect(AnimatedSprite sprite)
{
if (sprite.ignoreSourceRectUpdates)
@ -217,10 +155,7 @@ namespace CustomNPCFramework.Framework.ModularNPCS
//sprite.SourceRect = new Rectangle(, 0, sprite.spriteWidth, sprite.spriteHeight);
}
/// <summary>
/// Animate the current sprite. Theoreticlly works from index offset to how many frames
/// </summary>
/// <param name="intervalFromCharacter"></param>
/// <summary>Animate the current sprite. Theoreticlly works from index offset to how many frames</summary>
public void Animate(float intervalFromCharacter, int startFrame, int endFrame, bool loop)
{
this.currentSprite.sprite.loop = loop;

View File

@ -1,36 +1,25 @@
using CustomNPCFramework.Framework.Graphics;
using Microsoft.Xna.Framework.Content;
using CustomNPCFramework.Framework.Graphics;
using Microsoft.Xna.Framework.Graphics;
using StardewValley;
using StardustCore.UIUtilities;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CustomNPCFramework.Framework.ModularNPCS
namespace CustomNPCFramework.Framework.ModularNpcs
{
/// <summary>
/// Used as a wrapper for the AnimatedSprite class.
/// </summary>
/// <summary>Used as a wrapper for the AnimatedSprite class.</summary>
public class AnimatedSpriteExtended
{
/// <summary>
/// The actual sprite of the object.
/// </summary>
/// <summary>The actual sprite of the object.</summary>
public AnimatedSprite sprite;
/// <summary>
/// The path to the texture to load the sprite from.
/// </summary>
/// <summary>The path to the texture to load the sprite from.</summary>
public string path;
/// <summary>Construct an instance.</summary>
public AnimatedSpriteExtended(Texture2DExtended texture, AssetSheet assetSheet)
{
//Set the sprite texture
this.sprite = new AnimatedSprite();
Texture2D load = texture.Copy().texture;
Texture2D load = texture.Copy().Texture;
var thing = Class1.ModHelper.Reflection.GetField<Texture2D>(this.sprite, "Texture", true);
thing.SetValue(load);
@ -39,17 +28,9 @@ namespace CustomNPCFramework.Framework.ModularNPCS
this.sprite.SpriteWidth = (int)assetSheet.assetInfo.assetSize.X;
this.sprite.SpriteHeight = (int)assetSheet.assetInfo.assetSize.Y;
}
/// <summary>
/// Constructor.
/// </summary>
/// <param name="path"></param>
/// <param name="currentFrame"></param>
/// <param name="spriteWidth"></param>
/// <param name="spriteHeight"></param>
/// <summary>Construct an instance.</summary>
public AnimatedSpriteExtended(string path, int currentFrame, int spriteWidth, int spriteHeight)
{
this.path = Class1.getRelativeDirectory(path);
@ -68,9 +49,7 @@ namespace CustomNPCFramework.Framework.ModularNPCS
//this.sprite = new AnimatedSprite(texture, currentFrame, spriteWidth, spriteHeight);
}
/// <summary>
/// Reloads the asset from disk.
/// </summary>
/// <summary>Reloads the asset from disk.</summary>
public void reload()
{
//Set the sprite texture

View File

@ -1,131 +1,43 @@
using CustomNPCFramework.Framework.NPCS;
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
namespace CustomNPCFramework.Framework.ModularNpcs
{
/// <summary>
/// Used as a base class for character animations.
/// </summary>
/// <summary>Used as a base class for character animations.</summary>
public class CharacterAnimationBase
{
/// <summary>Set the character sprites to left.</summary>
public virtual void setLeft() { }
/// <summary>
/// Constructor.
/// </summary>
public CharacterAnimationBase()
{
}
/// <summary>Set the character sprites to right.</summary>
public virtual void setRight() { }
/// <summary>
/// Set the character sprites to left.
/// </summary>
public virtual void setLeft()
{
}
/// <summary>Set the character sprites to up.</summary>
public virtual void setUp() { }
/// <summary>
/// Set the character sprites to right.
/// </summary>
public virtual void setRight()
{
/// <summary>Set the character sprites to down.</summary>
public virtual void setDown() { }
}
/// <summary>Used to reload the sprite textures.</summary>
public virtual void reload() { }
/// <summary>
/// Set the character sprites to up.
/// </summary>
public virtual void setUp()
{
}
/// <summary>
/// Set the character sprites to down.
/// </summary>
public virtual void setDown()
{
}
/// <summary>
/// Used to reload the sprite textures.
/// </summary>
public virtual void reload()
{
}
/// <summary>
/// Animate the sprites.
/// </summary>
/// <summary>Animate the sprites.</summary>
/// <param name="animationInterval">How long between animation frames in milliseconds.</param>
public virtual void Animate(float animationInterval)
{
public virtual void Animate(float animationInterval) { }
}
/// <summary>
/// Used to animate sprites.
/// </summary>
/// <summary>Used to animate sprites.</summary>
/// <param name="animationInterval">How long between animation frames in milliseconds.</param>
/// <param name="loop">Loop the animation.</param>
public virtual void Animate(float animationInterval, bool loop=true)
{
public virtual void Animate(float animationInterval, bool loop = true) { }
}
/// <summary>Used to draw the sprite to the screen.</summary>
public virtual void draw(SpriteBatch b, Vector2 screenPosition, float layerDepth) { }
/// <summary>
/// Used to draw the sprite to the screen.
/// </summary>
/// <param name="b"></param>
/// <param name="screenPosition"></param>
/// <param name="layerDepth"></param>
public virtual void draw(SpriteBatch b, Vector2 screenPosition, float layerDepth)
{
}
/// <summary>
/// Used to draw the sprite to the screen.
/// </summary>
/// <param name="b"></param>
/// <param name="screenPosition"></param>
/// <param name="layerDepth"></param>
/// <param name="xOffset"></param>
/// <param name="yOffset"></param>
/// <param name="c"></param>
/// <param name="flip"></param>
/// <param name="scale"></param>
/// <param name="rotation"></param>
/// <param name="characterSourceRectOffset"></param>
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)
{
}
/// <summary>
/// A very verbose asset drawer.
/// </summary>
/// <param name="b"></param>
/// <param name="npc"></param>
/// <param name="position"></param>
/// <param name="sourceRectangle"></param>
/// <param name="color"></param>
/// <param name="alpha"></param>
/// <param name="origin"></param>
/// <param name="scale"></param>
/// <param name="effects"></param>
/// <param name="layerDepth"></param>
public virtual void draw(SpriteBatch b, ExtendedNPC npc, Vector2 position, Rectangle sourceRectangle, Color color, float alpha, Vector2 origin, float scale, SpriteEffects effects, float layerDepth)
{
}
/// <summary>Used to draw the sprite to the screen.</summary>
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) { }
/// <summary>A very verbose asset drawer.</summary>
public virtual void draw(SpriteBatch b, ExtendedNpc npc, Vector2 position, Rectangle sourceRectangle, Color color, float alpha, Vector2 origin, float scale, SpriteEffects effects, float layerDepth) { }
}
}

View File

@ -1,54 +1,39 @@
using CustomNPCFramework.Framework.ModularNPCS.ColorCollections;
using System;
using System.Collections.Generic;
using CustomNPCFramework.Framework.ModularNpcs.ColorCollections;
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.CharacterAnimationBases
namespace CustomNPCFramework.Framework.ModularNpcs.CharacterAnimationBases
{
/// <summary>
/// A class used to reference the different textures used to comprise the different parts for character rendering.
/// </summary>
/// <summary>A class used to reference the different textures used to comprise the different parts for character rendering.</summary>
public class StandardCharacterAnimation : CharacterAnimationBase
{
/// <summary>
/// Used to hold all of the information for the npc hair part.
/// </summary>
/// <summary>Used to hold all of the information for the npc hair part.</summary>
public AnimatedSpriteCollection hair;
/// <summary>
/// Used to hold all of the information for the npc body part.
/// </summary>
/// <summary>Used to hold all of the information for the npc body part.</summary>
public AnimatedSpriteCollection body;
/// <summary>
/// Used to hold all of the information for the npc eyes part.
/// </summary>
/// <summary>Used to hold all of the information for the npc eyes part.</summary>
public AnimatedSpriteCollection eyes;
/// <summary>
/// Used to hold all of the information for the npc shirt part.
/// </summary>
/// <summary>Used to hold all of the information for the npc shirt part.</summary>
public AnimatedSpriteCollection shirt;
/// <summary>
/// Used to hold all of the information for the npc pants part.
/// </summary>
/// <summary>Used to hold all of the information for the npc pants part.</summary>
public AnimatedSpriteCollection pants;
/// <summary>
/// Used to hold all of the information for the npc shoes part.
/// </summary>
/// <summary>Used to hold all of the information for the npc shoes part.</summary>
public AnimatedSpriteCollection shoes;
/// <summary>
/// Used to hold all of the information for draw colors for the different parts.
/// </summary>
/// <summary>Used to hold all of the information for draw colors for the different parts.</summary>
public StandardColorCollection drawColors;
public List<AnimatedSpriteCollection> accessories;
/// <summary>
/// Constructor.
/// </summary>
/// <summary>Construct an instance.</summary>
/// <param name="bodyAnimation">The collection of textures to be used for the body part for the npc.</param>
/// <param name="eyeAnimation">The collection of textures to be used for the eyes part for the npc.</param>
/// <param name="hairAnimation">The collection of textures to be used for the hair part for the npc.</param>
@ -57,7 +42,7 @@ namespace CustomNPCFramework.Framework.ModularNPCS.CharacterAnimationBases
/// <param name="shoesAnimation">The collection of textures to be used for the shoes part for the npc.</param>
/// <param name="accessoriesWithAnimations">The collection of textures to be used for the accessories part for the npc.</param>
/// <param name="DrawColors">The collection of draw colors for the different parts for the npc.</param>
public StandardCharacterAnimation(AnimatedSpriteCollection bodyAnimation, AnimatedSpriteCollection eyeAnimation, AnimatedSpriteCollection hairAnimation, AnimatedSpriteCollection shirtAnimation, AnimatedSpriteCollection pantsAnimation, AnimatedSpriteCollection shoesAnimation,List<AnimatedSpriteCollection> accessoriesWithAnimations, StandardColorCollection DrawColors) :base()
public StandardCharacterAnimation(AnimatedSpriteCollection bodyAnimation, AnimatedSpriteCollection eyeAnimation, AnimatedSpriteCollection hairAnimation, AnimatedSpriteCollection shirtAnimation, AnimatedSpriteCollection pantsAnimation, AnimatedSpriteCollection shoesAnimation, List<AnimatedSpriteCollection> accessoriesWithAnimations, StandardColorCollection DrawColors)
{
this.body = bodyAnimation;
this.hair = hairAnimation;
@ -69,9 +54,7 @@ namespace CustomNPCFramework.Framework.ModularNPCS.CharacterAnimationBases
this.drawColors = DrawColors;
}
/// <summary>
/// Sets all of the different textures to face left.
/// </summary>
/// <summary>Sets all of the different textures to face left.</summary>
public override void setLeft()
{
this.body.setLeft();
@ -82,13 +65,10 @@ namespace CustomNPCFramework.Framework.ModularNPCS.CharacterAnimationBases
this.shoes.setLeft();
foreach (var accessory in this.accessories)
{
accessory.setLeft();
}
}
/// <summary>
/// Sets all of the different textures to face right.
/// </summary>
/// <summary>Sets all of the different textures to face right.</summary>
public override void setRight()
{
this.body.setRight();
@ -99,13 +79,10 @@ namespace CustomNPCFramework.Framework.ModularNPCS.CharacterAnimationBases
this.shoes.setRight();
foreach (var accessory in this.accessories)
{
accessory.setRight();
}
}
/// <summary>
/// Sets all of the different textures to face up.
/// </summary>
/// <summary>Sets all of the different textures to face up.</summary>
public override void setUp()
{
this.body.setUp();
@ -116,13 +93,10 @@ namespace CustomNPCFramework.Framework.ModularNPCS.CharacterAnimationBases
this.shoes.setUp();
foreach (var accessory in this.accessories)
{
accessory.setUp();
}
}
/// <summary>
/// Sets all of the different textures to face down.
/// </summary>
/// <summary>Sets all of the different textures to face down.</summary>
public override void setDown()
{
this.body.setDown();
@ -133,14 +107,10 @@ namespace CustomNPCFramework.Framework.ModularNPCS.CharacterAnimationBases
this.shoes.setDown();
foreach (var accessory in this.accessories)
{
accessory.setDown();
}
}
/// <summary>
/// Reloads all of the sprite textures.
/// </summary>
/// <summary>Reloads all of the sprite textures.</summary>
public override void reload()
{
this.body.reload();
@ -151,9 +121,7 @@ namespace CustomNPCFramework.Framework.ModularNPCS.CharacterAnimationBases
this.shoes.reload();
}
/// <summary>
/// Animates all of the textures for this sprite.
/// </summary>
/// <summary>Animates all of the textures for this sprite.</summary>
/// <param name="animationInterval">The delay in milliseconds between animation frames.</param>
/// <param name="loop">Determines if the animation continuously plays over and over.</param>
public override void Animate(float animationInterval, bool loop = true)
@ -165,18 +133,10 @@ namespace CustomNPCFramework.Framework.ModularNPCS.CharacterAnimationBases
this.pants.Animate(animationInterval, loop);
this.shoes.Animate(animationInterval, loop);
foreach (var accessory in this.accessories)
{
accessory.Animate(animationInterval, loop);
}
}
/// <summary>
/// Used to draw the sprite to the screen.
/// </summary>
/// <param name="b"></param>
/// <param name="screenPosition"></param>
/// <param name="layerDepth"></param>
/// <summary>Used to draw the sprite to the screen.</summary>
public override void draw(SpriteBatch b, Vector2 screenPosition, float layerDepth)
{
this.body.draw(b, screenPosition, layerDepth);
@ -186,27 +146,11 @@ namespace CustomNPCFramework.Framework.ModularNPCS.CharacterAnimationBases
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);
}
/// <summary>
/// Used to draw the sprite to the screen.
/// </summary>
/// <param name="b"></param>
/// <param name="screenPosition"></param>
/// <param name="layerDepth"></param>
/// <param name="xOffset"></param>
/// <param name="yOffset"></param>
/// <param name="c"></param>
/// <param name="flip"></param>
/// <param name="scale"></param>
/// <param name="rotation"></param>
/// <param name="characterSourceRectOffset"></param>
/// <summary>Used to draw the sprite to the screen.</summary>
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);
@ -217,25 +161,11 @@ namespace CustomNPCFramework.Framework.ModularNPCS.CharacterAnimationBases
this.pants.draw(b, screenPosition, layerDepth, xOffset, yOffset, StandardColorCollection.colorMult(c, this.drawColors.bottomsColor), flip, scale, rotation, characterSourceRectOffset);
this.shoes.draw(b, screenPosition, layerDepth, xOffset, yOffset, StandardColorCollection.colorMult(c, this.drawColors.shoesColor), flip, scale, rotation, characterSourceRectOffset);
foreach (var accessory in this.accessories)
{
accessory.draw(b, screenPosition, layerDepth, xOffset, yOffset, c, flip, scale, rotation, characterSourceRectOffset);
}
}
/// <summary>
/// A very verbose asset drawer.
/// </summary>
/// <param name="b"></param>
/// <param name="npc"></param>
/// <param name="position"></param>
/// <param name="sourceRectangle"></param>
/// <param name="color"></param>
/// <param name="alpha"></param>
/// <param name="origin"></param>
/// <param name="scale"></param>
/// <param name="effects"></param>
/// <param name="layerDepth"></param>
public override void draw(SpriteBatch b, ExtendedNPC npc, Vector2 position, Rectangle sourceRectangle, Color color, float alpha, Vector2 origin, float scale, SpriteEffects effects, float layerDepth)
/// <summary>A very verbose asset drawer.</summary>
public override void draw(SpriteBatch b, ExtendedNpc npc, Vector2 position, Rectangle sourceRectangle, Color color, float alpha, Vector2 origin, float scale, SpriteEffects effects, float layerDepth)
{
//Class1.ModMonitor.Log(sourceRectangle.ToString());
Vector2 generalOffset = new Vector2(0, 1 * Game1.tileSize); //Puts the sprite at the correct positioning.
@ -259,11 +189,9 @@ namespace CustomNPCFramework.Framework.ModularNPCS.CharacterAnimationBases
}
this.pants.draw(b, npc, position - generalOffset, sourceRectangle, StandardColorCollection.colorMult(color, this.drawColors.bottomsColor), alpha, origin, scale * Game1.pixelZoom, effects, layerDepth + smallOffset + (tinyOffset * 4));
this.shoes.draw(b, npc, position - generalOffset, sourceRectangle, StandardColorCollection.colorMult(color, this.drawColors.shoesColor), alpha, origin, scale * Game1.pixelZoom, effects, layerDepth + smallOffset + (tinyOffset * 5));
foreach (var accessory in this.accessories)
{
accessory.draw(b, npc, position - generalOffset, sourceRectangle, color, alpha, origin, scale, effects, layerDepth + 0.0006f);
}
}
}
}

View File

@ -1,93 +1,72 @@
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xna.Framework;
namespace CustomNPCFramework.Framework.ModularNPCS.ColorCollections
namespace CustomNPCFramework.Framework.ModularNpcs.ColorCollections
{
/// <summary>
/// Collection of colors to be used for the StandardCharacterAnimation object.
/// </summary>
/// <summary>Collection of colors to be used for the StandardCharacterAnimation object.</summary>
public class StandardColorCollection
{
/// <summary>
/// The draw color to be used for the body sprite for the npc.
/// </summary>
/// <summary>The draw color to be used for the body sprite for the npc.</summary>
public Color bodyColor;
/// <summary>
/// The draw color to be used for the eye sprite for the npc.
/// </summary>
/// <summary>The draw color to be used for the eye sprite for the npc.</summary>
public Color eyeColor;
/// <summary>
/// The draw color to be used for the hair sprite for the npc.
/// </summary>
/// <summary>The draw color to be used for the hair sprite for the npc.</summary>
public Color hairColor;
/// <summary>
/// The draw color to be used for the shirt sprite for the npc.
/// </summary>
/// <summary>The draw color to be used for the shirt sprite for the npc.</summary>
public Color shirtColor;
/// <summary>
/// The draw color to be used for the bottoms/pants sprite for the npc.
/// </summary>
/// <summary>The draw color to be used for the bottoms/pants sprite for the npc.</summary>
public Color bottomsColor;
/// <summary>
/// The draw color to be used for the shoes sprite for the npc.
/// </summary>
/// <summary>The draw color to be used for the shoes sprite for the npc.</summary>
public Color shoesColor;
/// <summary>
/// Default constrctor that sets all of the draw colors to white.
/// </summary>
/// <summary>Construct an instance.</summary>
public StandardColorCollection()
{
defaultColor(this.bodyColor);
defaultColor(this.eyeColor);
defaultColor(this.hairColor);
defaultColor(this.shirtColor);
defaultColor(this.bottomsColor);
defaultColor(this.shoesColor);
this.defaultColor(this.bodyColor);
this.defaultColor(this.eyeColor);
this.defaultColor(this.hairColor);
this.defaultColor(this.shirtColor);
this.defaultColor(this.bottomsColor);
this.defaultColor(this.shoesColor);
}
/// <summary>
/// Constructor that takes different colors as parameters.
/// </summary>
/// <param name="BodyColor">Color for the body texture.</param>
/// <param name="EyeColor">Color for the eyes texture.</param>
/// <param name="HairColor">Color for the hair texture.</param>
/// <param name="ShirtColor">Color for the shirt texture.</param>
/// <param name="BottomsColor">Color for the bottoms texture.</param>
/// <param name="ShoesColor">Color for the shoes texture.</param>
public StandardColorCollection(Color? BodyColor, Color? EyeColor, Color? HairColor, Color? ShirtColor, Color? BottomsColor, Color? ShoesColor)
/// <summary>Construct an instance.</summary>
/// <param name="bodyColor">Color for the body texture.</param>
/// <param name="eyeColor">Color for the eyes texture.</param>
/// <param name="hairColor">Color for the hair texture.</param>
/// <param name="shirtColor">Color for the shirt texture.</param>
/// <param name="bottomsColor">Color for the bottoms texture.</param>
/// <param name="shoesColor">Color for the shoes texture.</param>
public StandardColorCollection(Color? bodyColor, Color? eyeColor, Color? hairColor, Color? shirtColor, Color? bottomsColor, Color? shoesColor)
{
this.bodyColor = (Color)BodyColor.GetValueOrDefault(Color.White);
this.eyeColor = (Color)EyeColor.GetValueOrDefault(Color.White);
this.hairColor = (Color)HairColor.GetValueOrDefault(Color.White);
this.shirtColor = (Color)ShirtColor.GetValueOrDefault(Color.White);
this.bottomsColor = (Color)BottomsColor.GetValueOrDefault(Color.White);
this.shoesColor = (Color)ShoesColor.GetValueOrDefault(Color.White);
this.bodyColor = bodyColor.GetValueOrDefault(Color.White);
this.eyeColor = eyeColor.GetValueOrDefault(Color.White);
this.hairColor = hairColor.GetValueOrDefault(Color.White);
this.shirtColor = shirtColor.GetValueOrDefault(Color.White);
this.bottomsColor = bottomsColor.GetValueOrDefault(Color.White);
this.shoesColor = shoesColor.GetValueOrDefault(Color.White);
defaultColor(this.bodyColor);
defaultColor(this.eyeColor);
defaultColor(this.hairColor);
defaultColor(this.shirtColor);
defaultColor(this.bottomsColor);
defaultColor(this.shoesColor);
this.defaultColor(this.bodyColor);
this.defaultColor(this.eyeColor);
this.defaultColor(this.hairColor);
this.defaultColor(this.shirtColor);
this.defaultColor(this.bottomsColor);
this.defaultColor(this.shoesColor);
}
/// <summary>
/// If a color is null, make it white.
/// </summary>
/// <param name="color"></param>
/// <summary>If a color is null, make it white.</summary>
/// <param name="color">The color to check.</param>
public void defaultColor(Color color)
{
if (color == null) color = Color.White;
if (color == null)
color = Color.White;
}
/// <summary>
/// Used to mix colors together.
/// </summary>
/// <summary>Used to mix colors together.</summary>
/// <param name="cBase">The base color to mix.</param>
/// <param name="cMult">The modifier color to mix.</param>
/// <returns>A color that is a mix between the two colors passed in.</returns>

View File

@ -1,31 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CustomNPCFramework.Framework.ModularNPCS.ModularRenderers
namespace CustomNPCFramework.Framework.ModularNpcs.ModularRenderers
{
/// <summary>
/// A class used instead of an enum to hold keys for all of the different animations.
/// </summary>
/// <summary>A class used instead of an enum to hold keys for all of the different animations.</summary>
public class AnimationKeys
{
/// <summary>
/// The string that is used for the standing animation.
/// </summary>
/// <summary>The string that is used for the standing animation.</summary>
public static string standingKey = "standing";
/// <summary>
/// The string that is used for the walking/moving animation.
/// </summary>
/// <summary>The string that is used for the walking/moving animation.</summary>
public static string walkingKey = "walking";
/// <summary>
/// The string that is used for the sitting animation.
/// </summary>
/// <summary>The string that is used for the sitting animation.</summary>
public static string sittingKey = "sitting";
/// <summary>
/// The string that is used for the swimming animation.
/// </summary>
/// <summary>The string that is used for the swimming animation.</summary>
public static string swimmingKey = "swimming";
}
}

View File

@ -1,54 +1,39 @@
using CustomNPCFramework.Framework.Enums;
using CustomNPCFramework.Framework.Graphics;
using CustomNPCFramework.Framework.ModularNPCS.CharacterAnimationBases;
using System.Collections.Generic;
using CustomNPCFramework.Framework.Enums;
using CustomNPCFramework.Framework.ModularNpcs.CharacterAnimationBases;
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.ModularRenderers
namespace CustomNPCFramework.Framework.ModularNpcs.ModularRenderers
{
/// <summary>
/// A class used to hold all of the textures/animations/information to make modular npc rendering possible.
/// </summary>
/// <summary>A class used to hold all of the textures/animations/information to make modular npc rendering possible.</summary>
public class BasicRenderer
{
/// <summary>
/// Dictionary that holds key pair values of (animationName,Animation). USed to manage multiple animations.
/// </summary>
/// <summary>Dictionary that holds key pair values of (animationName,Animation). USed to manage multiple animations. </summary>
public Dictionary<string, StandardCharacterAnimation> animationList;
/// <summary>
/// Used to keep track of what animation is currently being used.
/// </summary>
/// <summary>Used to keep track of what animation is currently being used.</summary>
public StandardCharacterAnimation currentAnimation;
/// <summary>
/// Constructor.
/// </summary>
/// <summary>Construct an instance.</summary>
/// <param name="standingAnimation">The animation information to be used when the character is standing.</param>
/// <param name="walkingAnimation">The animation information to be used when the character is walking/moving.</param>
/// <param name="swimmingAnimation">The animation information to be used when the character is walking/moving.</param>
public BasicRenderer(StandardCharacterAnimation standingAnimation, StandardCharacterAnimation walkingAnimation, StandardCharacterAnimation swimmingAnimation)
{
animationList = new Dictionary<string, StandardCharacterAnimation>();
animationList.Add(AnimationKeys.standingKey, standingAnimation);
animationList.Add(AnimationKeys.walkingKey, walkingAnimation);
animationList.Add(AnimationKeys.swimmingKey, swimmingAnimation);
setAnimation(AnimationKeys.standingKey);
this.animationList = new Dictionary<string, StandardCharacterAnimation>();
this.animationList.Add(AnimationKeys.standingKey, standingAnimation);
this.animationList.Add(AnimationKeys.walkingKey, walkingAnimation);
this.animationList.Add(AnimationKeys.swimmingKey, swimmingAnimation);
this.setAnimation(AnimationKeys.standingKey);
}
/// <summary>
/// Sets the animation associated with the key name; If it fails the npc will just default to standing.
/// </summary>
/// <summary>Sets the animation associated with the key name; If it fails the npc will just default to standing.</summary>
/// <param name="key">The name of the animation to swap the current animation to.</param>
public virtual void setAnimation(string key)
{
this.currentAnimation = animationList[key];
this.currentAnimation = this.animationList[key];
if (this.currentAnimation == null)
{
Class1.ModMonitor.Log("ERROR SETTING AN ANIMATION: " + key);
@ -56,148 +41,95 @@ namespace CustomNPCFramework.Framework.ModularNPCS.ModularRenderers
}
}
/// <summary>
/// Sets the direction of the current animated sprite respectively.
/// </summary>
/// <summary>Sets the direction of the current animated sprite respectively.</summary>
/// <param name="facingDirection">The direction to face. 0=up, 1=right, 2= down, 3=left.</param>
public virtual void setDirection(int facingDirection)
{
if (facingDirection == 0) setUp();
if (facingDirection == 1) setRight();
if (facingDirection == 2) setDown();
if (facingDirection == 2) setLeft();
this.setDirection((Direction)facingDirection);
}
/// <summary>
/// Sets the direction of the current animated sprite respectively to the direction passed in.
/// </summary>
/// <summary>Sets the direction of the current animated sprite respectively to the direction passed in.</summary>
/// <param name="direction">The direction to face.</param>
public virtual void setDirection(Direction direction)
{
if (direction == Direction.up) setUp();
if (direction == Direction.right) setRight();
if (direction == Direction.down) setDown();
if (direction == Direction.left) setLeft();
switch (direction)
{
case Direction.up:
this.setUp();
break;
case Direction.right:
this.setRight();
break;
case Direction.down:
this.setDown();
break;
case Direction.left:
this.setLeft();
break;
}
}
/// <summary>
/// Sets the current animated sprite to face left.
/// </summary>
/// <summary>Sets the current animated sprite to face left.</summary>
public virtual void setLeft()
{
this.currentAnimation.setLeft();
}
/// <summary>
/// Sets the current animated sprite to face right.
/// </summary>
/// <summary>Sets the current animated sprite to face right.</summary>
public virtual void setRight()
{
this.currentAnimation.setRight();
}
/// <summary>
/// Sets the current animated sprite to face up.
/// </summary>
/// <summary>Sets the current animated sprite to face up.</summary>
public virtual void setUp()
{
this.currentAnimation.setUp();
}
/// <summary>
/// Sets the current animated sprite to face down.
/// </summary>
/// <summary>Sets the current animated sprite to face down.</summary>
public virtual void setDown()
{
this.currentAnimation.setDown();
}
/// <summary>
/// Used to reload all of the sprites pertaining to all of the animations stored in this renderer.
/// </summary>
/// <summary>Used to reload all of the sprites pertaining to all of the animations stored in this renderer.</summary>
public virtual void reloadSprites()
{
foreach (var v in this.animationList)
{
v.Value.reload();
}
}
/// <summary>
/// Used to draw the sprite to the screen.
/// </summary>
/// <param name="b"></param>
/// <param name="screenPosition"></param>
/// <param name="layerDepth"></param>
/// <summary>Used to draw the sprite to the screen.</summary>
public virtual void draw(SpriteBatch b, Vector2 screenPosition, float layerDepth)
{
this.currentAnimation.draw(b, screenPosition, layerDepth);
}
/// <summary>
/// Used to draw the sprite to the screen.
/// </summary>
/// <param name="b"></param>
/// <param name="screenPosition"></param>
/// <param name="layerDepth"></param>
/// <param name="xOffset"></param>
/// <param name="yOffset"></param>
/// <param name="c"></param>
/// <param name="flip"></param>
/// <param name="scale"></param>
/// <param name="rotation"></param>
/// <param name="characterSourceRectOffset"></param>
/// <summary>Used to draw the sprite to the screen.</summary>
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);
}
/// <summary>
/// A very verbose asset drawer.
/// </summary>
/// <param name="b"></param>
/// <param name="npc"></param>
/// <param name="position"></param>
/// <param name="sourceRectangle"></param>
/// <param name="color"></param>
/// <param name="alpha"></param>
/// <param name="origin"></param>
/// <param name="scale"></param>
/// <param name="effects"></param>
/// <param name="layerDepth"></param>
public virtual void draw(SpriteBatch b, ExtendedNPC npc, Vector2 position, Rectangle sourceRectangle, Color color, float alpha, Vector2 origin, float scale, SpriteEffects effects, float layerDepth)
/// <summary>A very verbose asset drawer.</summary>
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);
}
/// <summary>
/// Animates the current animation for the current sprite.
/// </summary>
/// <param name="interval"></param>
/// <param name="loop"></param>
/// <summary>Animates the current animation for the current sprite.</summary>
public virtual void Animate(float interval, bool loop = true)
{
this.currentAnimation.Animate(interval, loop);
}
/// <summary>
/// Wrapper for a draw function that accepts rectangles to be null.
/// </summary>
/// <param name="b"></param>
/// <param name="extendedNPC"></param>
/// <param name="vector21"></param>
/// <param name="v1"></param>
/// <param name="white"></param>
/// <param name="rotation"></param>
/// <param name="vector22"></param>
/// <param name="v2"></param>
/// <param name="spriteEffects"></param>
/// <param name="v3"></param>
public virtual void draw(SpriteBatch b, ExtendedNPC extendedNPC, Vector2 position, Rectangle? v1, Color white, float rotation, Vector2 origin, float scale, SpriteEffects spriteEffects, float v3)
/// <summary>Wrapper for a draw function that accepts rectangles to be null.</summary>
public virtual void draw(SpriteBatch b, ExtendedNpc extendedNPC, Vector2 position, Rectangle? v1, Color white, float rotation, Vector2 origin, float scale, SpriteEffects spriteEffects, float v3)
{
this.draw(b, extendedNPC, position, new Rectangle(0, 0, 16, 32), white, rotation, origin, scale, spriteEffects, v3);
}

View File

@ -1,30 +1,18 @@
using CustomNPCFramework.Framework.NPCS;
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
namespace CustomNPCFramework.Framework.ModularNpcs
{
/// <summary>
/// Used as a wrapper for npc portraits.
/// </summary>
/// <summary>Used as a wrapper for npc portraits.</summary>
public class Portrait
{
/// <summary>
/// Used to display the npc portrait.
/// </summary>
/// <summary>Used to display the npc portrait.</summary>
public Texture2D portrait;
/// <summary>
/// Used to hold the path to the texture to use for the npc portrait.
/// </summary>
/// <summary>Used to hold the path to the texture to use for the npc portrait.</summary>
public string relativePath;
/// <summary>
/// A class for handling portraits.
/// </summary>
/// <summaryConstruct an instance.</summary>
/// <param name="path">The full path to the file.</param>
public Portrait(string path)
{
@ -32,18 +20,13 @@ namespace CustomNPCFramework.Framework.ModularNPCS
this.portrait = Class1.ModHelper.Content.Load<Texture2D>(path);
}
/// <summary>
/// Sets the npc's portrait to be this portrait texture.
/// </summary>
/// <param name="npc"></param>
public void setCharacterPortraitFromThis(ExtendedNPC npc)
/// <summary>Sets the npc's portrait to be this portrait texture.</summary>
public void setCharacterPortraitFromThis(ExtendedNpc npc)
{
npc.Portrait = this.portrait;
}
/// <summary>
/// Reloads the texture for the NPC portrait.
/// </summary>
/// <summary>Reloads the texture for the NPC portrait.</summary>
public void reload()
{
this.portrait = Class1.ModHelper.Content.Load<Texture2D>(this.relativePath);

View File

@ -1,43 +1,23 @@
using CustomNPCFramework.Framework.ModularNPCS.ModularRenderers;
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
namespace CustomNPCFramework.Framework.ModularNpcs
{
/// <summary>
/// Used as a wrapper for the npcs to hold sprite information.
/// </summary>
/// <summary>Used as a wrapper for the npcs to hold sprite information.</summary>
public class Sprite
{
/// <summary>
/// The actual sprite to draw for the npc.
/// </summary>
/// <summary>The actual sprite to draw for the npc.</summary>
public AnimatedSprite sprite;
/// <summary>
/// The path to the texture to use for the animated sprite.
/// </summary>
/// <summary>The path to the texture to use for the animated sprite.</summary>
public string relativePath;
/// <summary>
/// A class for handling character sprites.
/// </summary>
/// <param name="path">The full path to the file.</param>
public Sprite(string path)
/// <summary>Construct an instance.</summary>
/// <param name="relativePath">The relative path to the file.</param>
public Sprite(string relativePath)
{
try
{
this.relativePath = Class1.getShortenedDirectory(path);
}
catch(Exception err)
{
this.relativePath = path;
}
this.relativePath = relativePath;
try
{
this.sprite = new AnimatedSprite();
@ -46,7 +26,7 @@ namespace CustomNPCFramework.Framework.ModularNPCS
reflect.SetValue(text);
}
catch(Exception err)
catch
{
this.sprite = new AnimatedSprite();
Texture2D text = Class1.ModHelper.Content.Load<Texture2D>(this.relativePath);
@ -57,9 +37,7 @@ namespace CustomNPCFramework.Framework.ModularNPCS
this.sprite.SpriteHeight = this.sprite.Texture.Height;
}
/// <summary>
/// Constructor.
/// </summary>
/// <summary>Construct an instance.</summary>
/// <param name="path">Used to hold the path to the asset.</param>
/// <param name="texture">Used to assign the texture to the sprite from a pre-loaded asset.</param>
public Sprite(string path, string texture)
@ -70,75 +48,42 @@ namespace CustomNPCFramework.Framework.ModularNPCS
this.sprite.SpriteHeight = this.sprite.Texture.Height;
}
/// <summary>
/// Sets the npc's portrait to be this portrait texture.
/// </summary>
/// <param name="npc"></param>
public void setCharacterSpriteFromThis(ExtendedNPC npc)
/// <summary>Sets the npc's portrait to be this portrait texture.</summary>
public void setCharacterSpriteFromThis(ExtendedNpc npc)
{
npc.Sprite = this.sprite;
}
/// <summary>
/// Reloads the texture for the NPC portrait.
/// </summary>
/// <summary>Reloads the texture for the NPC portrait.</summary>
public void reload()
{
var text=CustomNPCFramework.Class1.ModHelper.Reflection.GetField<Texture2D>(this.sprite.Texture, "Texture", true);
var text = Class1.ModHelper.Reflection.GetField<Texture2D>(this.sprite.Texture, "Texture", true);
Texture2D loaded = Class1.ModHelper.Content.Load<Texture2D>(this.relativePath);
text.SetValue(loaded);
}
/// <summary>
/// Set's the npc's sprites to face left IF and only if there is a non-null modular Renderer attached to the npc.
/// </summary>
/// <param name="npc"></param>
public void setLeft(ExtendedNPC npc)
/// <summary>Set's the npc's sprites to face left IF and only if there is a non-null modular Renderer attached to the npc.</summary>
public void setLeft(ExtendedNpc npc)
{
if (npc.characterRenderer == null)
{
return;
}
else npc.characterRenderer.setLeft();
npc.characterRenderer?.setLeft();
}
/// <summary>
/// Set's the npc's sprites to face left IF and only if there is a non-null modular Renderer attached to the npc.
/// </summary>
/// <param name="npc"></param>
public void setRight(ExtendedNPC npc)
/// <summary>Set's the npc's sprites to face left IF and only if there is a non-null modular Renderer attached to the npc.</summary>
public void setRight(ExtendedNpc npc)
{
if (npc.characterRenderer == null)
{
return;
}
else npc.characterRenderer.setRight();
npc.characterRenderer?.setRight();
}
/// <summary>
/// Set's the npc's sprites to face left IF and only if there is a non-null modular Renderer attached to the npc.
/// </summary>
/// <param name="npc"></param>
public void setDown(ExtendedNPC npc)
/// <summary>Set's the npc's sprites to face left IF and only if there is a non-null modular Renderer attached to the npc.</summary>
public void setDown(ExtendedNpc npc)
{
if (npc.characterRenderer == null)
{
return;
}
else npc.characterRenderer.setDown();
npc.characterRenderer?.setDown();
}
/// <summary>
/// Set's the npc's sprites to face left IF and only if there is a non-null modular Renderer attached to the npc.
/// </summary>
/// <param name="npc"></param>
public void setUp(ExtendedNPC npc)
/// <summary>Set's the npc's sprites to face left IF and only if there is a non-null modular Renderer attached to the npc.</summary>
public void setUp(ExtendedNpc npc)
{
if (npc.characterRenderer == null)
{
return;
}
else npc.characterRenderer.setUp();
npc.characterRenderer?.setUp();
}
}
}

View File

@ -1,77 +1,59 @@
using CustomNPCFramework.Framework.Enums;
using StardewValley;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using CustomNPCFramework.Framework.Enums;
using StardewValley;
namespace CustomNPCFramework.Framework
{
/// <summary>
/// Used as a class to hold all of the possible npc names.
/// </summary>
public class NPCNames
/// <summary>Used as a class to hold all of the possible NPC names.</summary>
public class NpcNames
{
/// <summary>
/// Holds all of the npc male names.
/// </summary>
public static List<string> maleNames = new List<string>()
/// <summary>Holds all of the NPC male names.</summary>
public static List<string> maleNames = new List<string>
{
"Freddy",
"Josh",
"Ash"
};
/// <summary>
/// Holds all of the npc female names.
/// </summary>
public static List<string> femaleNames = new List<string>()
/// <summary>Holds all of the NPC female names.</summary>
public static List<string> femaleNames = new List<string>
{
"Rebecca",
"Sierra",
"Lisa"
};
/// <summary>
/// Holds all of the npc gender non-binary names.
/// </summary>
public static List<string> otherGenderNames = new List<string>()
/// <summary>Holds all of the NPC gender non-binary names.</summary>
public static List<string> otherGenderNames = new List<string>
{
"Jayden",
"Ryanne",
"Skylar"
};
/// <summary>
/// Get a gender appropriate name from the pool of npc names.
/// </summary>
/// <param name="gender"></param>
/// <returns></returns>
public static string getRandomNPCName(Genders gender)
/// <summary>Get a gender appropriate name from the pool of NPC names.</summary>
public static string getRandomNpcName(Genders gender)
{
if (gender == Genders.female)
{
if (gender == Genders.female) {
int rand = Game1.random.Next(0, femaleNames.Count - 1);
return femaleNames.ElementAt(rand);
}
if (gender == Genders.male)
{
int rand = Game1.random.Next(0, maleNames.Count - 1);
return maleNames.ElementAt(rand);
}
if (gender == Genders.other)
{
int rand = Game1.random.Next(0, otherGenderNames.Count - 1);
return otherGenderNames.ElementAt(rand);
}
return "";
}
}
}

View File

@ -1,35 +1,22 @@
using CustomNPCFramework.Framework.Enums;
using CustomNPCFramework.Framework.ModularNPCS;
using CustomNPCFramework.Framework.ModularNPCS.ModularRenderers;
using System;
using CustomNPCFramework.Framework.Enums;
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;
using System.Text;
using System.Threading.Tasks;
using xTile.Dimensions;
using xTile.ObjectModel;
using xTile.Tiles;
namespace CustomNPCFramework.Framework.NPCS
{
/// <summary>
/// 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???
/// </summary>
public class ExtendedNPC :StardewValley.NPC
// 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 : NPC
{
/// <summary>
/// The custom character renderer for this npc.
/// </summary>
/// <summary>The custom character renderer for this npc.</summary>
public BasicRenderer characterRenderer;
public bool hasBeenKissedToday;
public Point previousEndPoint;
@ -37,122 +24,89 @@ namespace CustomNPCFramework.Framework.NPCS
public bool hasSaidAfternoonDialogue;
public int timeAfterSquare;
/// <summary>
/// Used to hold sprite information to be used in the case the npc renderer is null.
/// </summary>
/// <summary>Used to hold sprite information to be used in the case the npc renderer is null.</summary>
public Sprite spriteInformation;
/// <summary>
/// Used to hold the portrait information for the npc and display it.
/// </summary>
/// <summary>Used to hold the portrait information for the npc and display it.</summary>
public Portrait portraitInformation;
/// <summary>
/// The default location for this npc to reside in.
/// </summary>
/// <summary>The default location for this npc to reside in.</summary>
public GameLocation defaultLocation;
/// <summary>
/// Empty Constructor.
/// </summary>
public ExtendedNPC() :base()
{
}
/// <summary>Construct an instance.</summary>
public ExtendedNpc() { }
/// <summary>
/// Non modular npc Constructor.
/// </summary>
/// <summary>Construct an instance.</summary>
/// <param name="sprite">The sprite for the character.</param>
/// <param name="position">The position of the npc on the map.</param>
/// <param name="facingDirection">The direction of the npc</param>
/// <param name="name">The name of the npc.</param>
public ExtendedNPC(Sprite sprite, Vector2 position, int facingDirection, string name) : base(sprite.sprite, position, facingDirection, name, null)
public ExtendedNpc(Sprite sprite, Vector2 position, int facingDirection, string name)
: base(sprite.sprite, position, facingDirection, name)
{
this.characterRenderer = null;
this.Portrait = (Texture2D)null;
this.Portrait = null;
this.portraitInformation = null;
this.spriteInformation = sprite;
if (this.spriteInformation != null)
{
this.spriteInformation.setCharacterSpriteFromThis(this);
}
this.spriteInformation?.setCharacterSpriteFromThis(this);
this.swimming.Value = false;
}
/// <summary>
/// Non modular npc Constructor.
/// </summary>
/// <summary>Construct an instance.</summary>
/// <param name="sprite">The sprite for the character.</param>
/// <param name="portrait">The portrait texture for this npc.</param>
/// <param name="position">The position of the npc on the map.</param>
/// <param name="facingDirection">The direction of the npc</param>
/// <param name="name">The name of the npc.</param>
public ExtendedNPC(Sprite sprite, Portrait portrait, Vector2 position, int facingDirection, string name) : base(sprite.sprite, position, facingDirection, name, null)
public ExtendedNpc(Sprite sprite, Portrait portrait, Vector2 position, int facingDirection, string name)
: base(sprite.sprite, position, facingDirection, name)
{
this.characterRenderer = null;
this.portraitInformation = portrait;
if (this.portraitInformation != null)
{
this.portraitInformation.setCharacterPortraitFromThis(this);
}
this.portraitInformation?.setCharacterPortraitFromThis(this);
this.spriteInformation = sprite;
this.spriteInformation.setCharacterSpriteFromThis(this);
this.swimming.Value = false;
}
/// <summary>
/// Modular npc constructor.
/// </summary>
/// <summary>Construct an instance.</summary>
/// <param name="sprite">The sprite for the character to use incase the renderer is null.</param>
/// <param name="renderer">The custom npc render. Used to draw the npcfrom a collection of assets.</param>
/// <param name="portrait">The portrait texture for this npc.</param>
/// <param name="position">The position of the npc on the map.</param>
/// <param name="facingDirection">The direction of the npc</param>
/// <param name="name">The name of the npc.</param>
public ExtendedNPC(Sprite sprite,BasicRenderer renderer,Vector2 position,int facingDirection,string name): base(sprite.sprite, position, facingDirection, name, null)
public ExtendedNpc(Sprite sprite, BasicRenderer renderer, Vector2 position, int facingDirection, string name)
: base(sprite.sprite, position, facingDirection, name)
{
this.characterRenderer = renderer;
this.Portrait = (Texture2D)null;
this.Portrait = null;
this.portraitInformation = null;
this.spriteInformation = sprite;
if (this.spriteInformation != null)
{
this.spriteInformation.setCharacterSpriteFromThis(this);
}
this.spriteInformation?.setCharacterSpriteFromThis(this);
this.swimming.Value = false;
}
/// <summary>
/// Modular constructor for the npc.
/// </summary>
/// <summary>Construct an instance.</summary>
/// <param name="sprite">The sprite for the npc to use incase the renderer is null.</param>
/// <param name="renderer">The custom npc renderer used to draw the npc from the collection of textures.</param>
/// <param name="portrait">The portrait texture for the npc.</param>
/// <param name="position">The positon for the npc to be.</param>
/// <param name="facingDirection">The direction for the npc to face.</param>
/// <param name="name">The name for the npc.</param>
public ExtendedNPC(Sprite sprite,BasicRenderer renderer,Portrait portrait, Vector2 position, int facingDirection, string name) : base(sprite.sprite, position, facingDirection, name, null)
public ExtendedNpc(Sprite sprite, BasicRenderer renderer, Portrait portrait, Vector2 position, int facingDirection, string name)
: base(sprite.sprite, position, facingDirection, name)
{
this.characterRenderer = renderer;
this.portraitInformation = portrait;
if (this.portraitInformation != null)
{
this.portraitInformation.setCharacterPortraitFromThis(this);
}
this.portraitInformation?.setCharacterPortraitFromThis(this);
this.spriteInformation = sprite;
if (this.spriteInformation != null)
{
this.spriteInformation.setCharacterSpriteFromThis(this);
}
this.spriteInformation?.setCharacterSpriteFromThis(this);
this.swimming.Value = false;
}
/// <summary>
/// Used to reload the sprite for the npc.
/// </summary>
/// <summary>Used to reload the sprite for the npc.</summary>
public void reloadSprite()
{
if (this.characterRenderer == null)
{
this.spriteInformation.reload();
@ -160,10 +114,9 @@ namespace CustomNPCFramework.Framework.NPCS
{
this.portraitInformation.reload();
}
catch (Exception ex)
catch
{
ex.ToString();
this.Portrait = (Texture2D)null;
this.Portrait = null;
}
}
else
@ -173,14 +126,12 @@ namespace CustomNPCFramework.Framework.NPCS
{
this.portraitInformation.reload();
}
catch (Exception ex)
catch
{
ex.ToString();
this.Portrait = (Texture2D)null;
this.Portrait = null;
}
}
int num = this.IsInvisible ? 1 : 0;
if (!Game1.newDay && (int)Game1.gameMode != 6)
if (!Game1.newDay && Game1.gameMode != 6)
return;
this.faceDirection(this.DefaultFacingDirection);
this.scheduleTimeToTry = 9999999;
@ -191,161 +142,130 @@ namespace CustomNPCFramework.Framework.NPCS
if (this.isMarried())
this.marriageDuties();
bool flag = Utility.isFestivalDay(Game1.dayOfMonth, Game1.currentSeason);
try
{
this.displayName = this.Name;
}
catch (Exception ex)
{
ex.ToString();
catch { }
}
}
/// <summary>
/// Functionality used when interacting with the npc.
/// </summary>
/// <param name="who"></param>
/// <param name="l"></param>
/// <returns></returns>
public override bool checkAction(StardewValley.Farmer who, GameLocation l)
/// <summary>Functionality used when interacting with the npc.</summary>
public override bool checkAction(Farmer who, GameLocation l)
{
base.checkAction(who, l);
return false;
}
/// <summary>
/// Used to move the npc. Different code is used depending if the character renderer is null or not.
/// </summary>
/// <param name="time"></param>
/// <param name="viewport"></param>
/// <param name="currentLocation"></param>
/// <summary>Used to move the npc. Different code is used depending if the character renderer is null or not.</summary>
public override void MovePosition(GameTime time, xTile.Dimensions.Rectangle viewport, GameLocation currentLocation)
{
if (this.characterRenderer != null)
{
ModularMovement(time,viewport,currentLocation);
}
this.ModularMovement(time, viewport, currentLocation);
else
{
NonModularMovement(time,viewport,currentLocation);
}
return;
this.NonModularMovement(time, viewport, currentLocation);
}
/// <summary>
/// Set's the npc to move a certain direction and then executes the movement.
/// </summary>
/// <param name="time"></param>
/// <param name="viewport"></param>
/// <param name="currentLocation"></param>
/// <param name="MoveDirection">The direction to move the npc.</param>
/// <summary>Set's the npc to move a certain direction and then executes the movement.</summary>
/// <param name="moveDirection">The direction to move the npc.</param>
/// <param name="Move">Set's the npc's sprite to halt if Move=false. Else set it to true.</param>
public virtual void SetMovingAndMove(GameTime time, xTile.Dimensions.Rectangle viewport, GameLocation currentLocation, Direction MoveDirection, bool Move=true)
public virtual void SetMovingAndMove(GameTime time, xTile.Dimensions.Rectangle viewport, GameLocation currentLocation, Direction moveDirection, bool Move = true)
{
if (MoveDirection == Direction.down) this.SetMovingDown(Move);
if (MoveDirection == Direction.left) this.SetMovingLeft(Move);
if (MoveDirection == Direction.up) this.SetMovingUp(Move);
if (MoveDirection == Direction.right) this.SetMovingRight(Move);
switch (moveDirection)
{
case Direction.down:
this.SetMovingDown(Move);
break;
case Direction.left:
this.SetMovingLeft(Move);
break;
case Direction.up:
this.SetMovingUp(Move);
break;
case Direction.right:
this.SetMovingRight(Move);
break;
}
this.MovePosition(time, viewport, currentLocation);
}
/// <summary>
/// USed to move the npc if the character renderer is null.
/// </summary>
/// <param name="time"></param>
/// <param name="viewport"></param>
/// <param name="location"></param>
/// <summary>USed to move the npc if the character renderer is null.</summary>
public virtual void NonModularMovement(GameTime time, xTile.Dimensions.Rectangle viewport, GameLocation location)
{
base.MovePosition(time, viewport, currentLocation);
return;
base.MovePosition(time, viewport, this.currentLocation);
}
/// <summary>
/// Used to determine if the npc can move past the next location.
/// </summary>
/// <param name="viewport"></param>
/// <returns></returns>
/// <summary>Used to determine if the npc can move past the next location.</summary>
public virtual bool canMovePastNextLocation(xTile.Dimensions.Rectangle viewport)
{
//Up
if (!currentLocation.isTilePassable(this.nextPosition(0), viewport) || !this.willDestroyObjectsUnderfoot)
{
if (!this.currentLocation.isTilePassable(this.nextPosition(0), viewport) || !this.willDestroyObjectsUnderfoot)
return false;
}
//Right
if (!currentLocation.isTilePassable(this.nextPosition(1), viewport) || !this.willDestroyObjectsUnderfoot)
{
if (!this.currentLocation.isTilePassable(this.nextPosition(1), viewport) || !this.willDestroyObjectsUnderfoot)
return false;
}
//Down
if (!currentLocation.isTilePassable(this.nextPosition(2), viewport) || !this.willDestroyObjectsUnderfoot)
{
if (!this.currentLocation.isTilePassable(this.nextPosition(2), viewport) || !this.willDestroyObjectsUnderfoot)
return false;
}
//Left
if (!currentLocation.isTilePassable(this.nextPosition(3), viewport) || !this.willDestroyObjectsUnderfoot)
{
if (!this.currentLocation.isTilePassable(this.nextPosition(3), viewport) || !this.willDestroyObjectsUnderfoot)
return false;
}
return true;
}
/// <summary>
/// Used to move the npc if the character renderer is valid. Handles animating all of the sprites associated with the renderer.
/// </summary>
/// <param name="time"></param>
/// <param name="viewport"></param>
/// <param name="location"></param>
/// <param name="interval"></param>
/// <summary>Used to move the npc if the character renderer is valid. Handles animating all of the sprites associated with the renderer.</summary>
public virtual void ModularMovement(GameTime time, xTile.Dimensions.Rectangle viewport, GameLocation location, float interval = 1000f)
{
this.characterRenderer.setAnimation(AnimationKeys.walkingKey);
if (this.canMovePastNextLocation(viewport) == false)
if (!this.canMovePastNextLocation(viewport))
{
this.Halt();
return;
}
if (this.GetType() == typeof(FarmAnimal))
this.willDestroyObjectsUnderfoot = false;
if ((double)this.xVelocity != 0.0 || (double)this.yVelocity != 0.0)
if (this.xVelocity != 0.0 || this.yVelocity != 0.0)
{
Microsoft.Xna.Framework.Rectangle boundingBox = this.GetBoundingBox();
var boundingBox = this.GetBoundingBox();
boundingBox.X += (int)this.xVelocity;
boundingBox.Y -= (int)this.yVelocity;
if (currentLocation == null || !currentLocation.isCollidingPosition(boundingBox, viewport, false, 0, false, this))
if (this.currentLocation == null || !this.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);
this.xVelocity = (int)(this.xVelocity - this.xVelocity / 2.0);
this.yVelocity = (int)(this.yVelocity - this.yVelocity / 2.0);
}
else if (this.moveUp)
{
if (currentLocation == null || !currentLocation.isCollidingPosition(this.nextPosition(0), viewport, false, 0, false, this) || this.isCharging)
if (this.currentLocation == null || !this.currentLocation.isCollidingPosition(this.nextPosition(0), viewport, false, 0, false, this) || this.isCharging)
{
this.position.Y -= (float)(this.speed + this.addedSpeed);
this.position.Y -= this.speed + this.addedSpeed;
if (!this.ignoreMovementAnimation)
{
this.spriteInformation.setUp(this);
this.characterRenderer.Animate(interval,true);
this.characterRenderer.Animate(interval);
//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)
else if (!this.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))
Vector2 vector2 = new Vector2(this.getStandingX() / Game1.tileSize, this.getStandingY() / Game1.tileSize - 1);
if (this.currentLocation.characterDestroyObjectWithinRectangle(this.nextPosition(0), true))
{
this.doEmote(12, true);
this.position.Y -= (float)(this.speed + this.addedSpeed);
this.doEmote(12);
this.position.Y -= this.speed + this.addedSpeed;
}
else
this.blockedInterval = this.blockedInterval + time.ElapsedGameTime.Milliseconds;
@ -353,27 +273,27 @@ namespace CustomNPCFramework.Framework.NPCS
}
else if (this.moveRight)
{
if (currentLocation == null || !currentLocation.isCollidingPosition(this.nextPosition(1), viewport, false, 0, false, this) || this.isCharging)
if (this.currentLocation == null || !this.currentLocation.isCollidingPosition(this.nextPosition(1), viewport, false, 0, false, this) || this.isCharging)
{
this.position.X += (float)(this.speed + this.addedSpeed);
this.position.X += this.speed + this.addedSpeed;
if (!this.ignoreMovementAnimation)
{
this.spriteInformation.setRight(this);
this.characterRenderer.Animate(interval,true);
this.characterRenderer.Animate(interval);
//this.spriteInformation.sprite.Animate(time, 0, 3, 1f);
//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)
else if (!this.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))
Vector2 vector2 = new Vector2(this.getStandingX() / Game1.tileSize + 1, this.getStandingY() / Game1.tileSize);
if (this.currentLocation.characterDestroyObjectWithinRectangle(this.nextPosition(1), true))
{
this.doEmote(12, true);
this.position.X += (float)(this.speed + this.addedSpeed);
this.doEmote(12);
this.position.X += this.speed + this.addedSpeed;
}
else
this.blockedInterval = this.blockedInterval + time.ElapsedGameTime.Milliseconds;
@ -381,27 +301,27 @@ namespace CustomNPCFramework.Framework.NPCS
}
else if (this.moveDown)
{
if (currentLocation == null || !currentLocation.isCollidingPosition(this.nextPosition(2), viewport, false, 0, false, this) || this.isCharging)
if (this.currentLocation == null || !this.currentLocation.isCollidingPosition(this.nextPosition(2), viewport, false, 0, false, this) || this.isCharging)
{
this.position.Y += (float)(this.speed + this.addedSpeed);
this.position.Y += this.speed + this.addedSpeed;
if (!this.ignoreMovementAnimation)
{
this.spriteInformation.setDown(this);
this.characterRenderer.Animate(interval,true);
this.characterRenderer.Animate(interval);
//this.spriteInformation.sprite.Animate(time, 0, 3, 1f);
//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)
else if (!this.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))
Vector2 vector2 = new Vector2(this.getStandingX() / Game1.tileSize, this.getStandingY() / Game1.tileSize + 1);
if (this.currentLocation.characterDestroyObjectWithinRectangle(this.nextPosition(2), true))
{
this.doEmote(12, true);
this.position.Y += (float)(this.speed + this.addedSpeed);
this.doEmote(12);
this.position.Y += this.speed + this.addedSpeed;
}
else
this.blockedInterval = this.blockedInterval + time.ElapsedGameTime.Milliseconds;
@ -409,35 +329,35 @@ namespace CustomNPCFramework.Framework.NPCS
}
else if (this.moveLeft)
{
if (currentLocation == null || !currentLocation.isCollidingPosition(this.nextPosition(3), viewport, false, 0, false, this) || this.isCharging)
if (this.currentLocation == null || !this.currentLocation.isCollidingPosition(this.nextPosition(3), viewport, false, 0, false, this) || this.isCharging)
{
this.position.X -= (float)(this.speed + this.addedSpeed);
this.position.X -= this.speed + this.addedSpeed;
if (!this.ignoreMovementAnimation)
{
this.spriteInformation.setLeft(this);
this.characterRenderer.Animate(interval,true);
this.characterRenderer.Animate(interval);
//this.spriteInformation.sprite.Animate(time, 0, 3, 1f);
//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)
else if (!this.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))
Vector2 vector2 = new Vector2(this.getStandingX() / Game1.tileSize - 1, this.getStandingY() / Game1.tileSize);
if (this.currentLocation.characterDestroyObjectWithinRectangle(this.nextPosition(3), true))
{
this.doEmote(12, true);
this.position.X -= (float)(this.speed + this.addedSpeed);
this.doEmote(12);
this.position.X -= this.speed + this.addedSpeed;
}
else
this.blockedInterval = this.blockedInterval + time.ElapsedGameTime.Milliseconds;
}
}
if (this.blockedInterval >= 3000 && (double)this.blockedInterval <= 3750.0 && !Game1.eventUp)
if (this.blockedInterval >= 3000 && this.blockedInterval <= 3750.0 && !Game1.eventUp)
{
this.doEmote(Game1.random.NextDouble() < 0.5 ? 8 : 40, true);
this.doEmote(Game1.random.NextDouble() < 0.5 ? 8 : 40);
this.blockedInterval = 3750;
}
else
@ -450,33 +370,15 @@ namespace CustomNPCFramework.Framework.NPCS
}
}
/// <summary>
/// Used to halt the npc sprite. Sets the npc's animation to the standing animation if the character renderer is not null.
/// </summary>
/// <summary>Used to halt the npc sprite. Sets the npc's animation to the standing animation if the character renderer is not null.</summary>
public override void Halt()
{
if (this.characterRenderer != null)
{
this.characterRenderer.setAnimation(AnimationKeys.standingKey);
}
this.characterRenderer?.setAnimation(AnimationKeys.standingKey);
base.Halt();
}
/// <summary>
/// Used to update npc information.
/// </summary>
/// <param name="time"></param>
/// <param name="location"></param>
public override void update(GameTime time, GameLocation location)
{
base.update(time, location);
}
/// <summary>
/// Pathfinding code.
/// </summary>
/// <param name="who"></param>
public virtual void routeEndAnimationFinished(StardewValley.Farmer who)
/// <summary>Pathfinding code.</summary>
public virtual void routeEndAnimationFinished(Farmer who)
{
this.doingEndOfRouteAnimation.Value = false;
this.freezeMotion = false;
@ -493,26 +395,15 @@ namespace CustomNPCFramework.Framework.NPCS
this.timeAfterSquare = Game1.timeOfDay;
}
/// <summary>
/// Pathfinding code.
/// </summary>
/// <param name="c"></param>
/// <param name="l"></param>
public virtual void doAnimationAtEndOfScheduleRoute(Character c, GameLocation l)
{
}
/// <summary>Pathfinding code.</summary>
public virtual void doAnimationAtEndOfScheduleRoute(Character c, GameLocation l) { }
/// <summary>
/// Pathfinding code.
/// </summary>
/// <param name="behaviorName"></param>
/// <summary>Pathfinding code.</summary>
public virtual void startRouteBehavior(string behaviorName)
{
if (behaviorName.Length > 0 && (int)behaviorName[0] == 34)
{
this.endOfRouteMessage.Value = behaviorName.Replace("\"", "");
}
else
{
if (behaviorName.Contains("square_"))
@ -524,24 +415,20 @@ namespace CustomNPCFramework.Framework.NPCS
}
else
{
Utility.getGameLocationOfCharacter(this).temporarySprites.Add(new TemporaryAnimatedSprite("LooseSprites\\Cursors", 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)
Utility.getGameLocationOfCharacter(this).temporarySprites.Add(new TemporaryAnimatedSprite("LooseSprites\\Cursors", 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)
{
id = 688f
});
this.doEmote(52, true);
this.doEmote(52);
}
}
}
/// <summary>
/// Occurs when the npc gets hit by the player.
/// </summary>
/// <param name="who"></param>
/// <param name="location"></param>
/// <summary>Occurs when the npc gets hit by the player.</summary>
public new void getHitByPlayer(StardewValley.Farmer who, GameLocation location)
{
this.doEmote(12, true);
this.doEmote(12);
if (who == null)
{
if (Game1.IsMultiplayer)
@ -550,8 +437,7 @@ namespace CustomNPCFramework.Framework.NPCS
}
if (who.friendshipData.ContainsKey(this.Name))
{
Friendship f;
who.friendshipData.TryGetValue(this.Name, out f);
who.friendshipData.TryGetValue(this.Name, out Friendship f);
f.Points -= 30;
if (who.IsMainPlayer)
{
@ -570,7 +456,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);
Game1.warpCharacter(this, this.DefaultMap, this.DefaultPosition / Game1.tileSize);
Game1.player.mailReceived.Remove(this.Name);
Game1.player.mailReceived.Remove(this.Name + "Cooking");
this.doingEndOfRouteAnimation.Value = false;
@ -582,18 +468,18 @@ namespace CustomNPCFramework.Framework.NPCS
this.hasSaidAfternoonDialogue = false;
this.ignoreScheduleToday = false;
this.Halt();
this.controller = (PathFindController)null;
this.temporaryController = (PathFindController)null;
this.DirectionsToNewLocation = (SchedulePathDescription)null;
this.controller = null;
this.temporaryController = null;
this.DirectionsToNewLocation = 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;
this.lastCrossroad = Rectangle.Empty;
if (this.isVillager())
this.Schedule = this.getSchedule(dayOfMonth);
this.endOfRouteMessage.Value = (string)null;
this.endOfRouteMessage.Value = null;
bool flag = Utility.isFestivalDay(dayOfMonth, Game1.currentSeason);
if (!this.isMarried())
return;
@ -602,18 +488,10 @@ namespace CustomNPCFramework.Framework.NPCS
//this.daysMarried = this.daysMarried + 1;
}
/// <summary>
/// Does effectively nothing.
/// </summary>
public new void setUpForOutdoorPatioActivity()
{
}
/// <summary>Does effectively nothing.</summary>
public new void setUpForOutdoorPatioActivity() { }
/// <summary>
/// Used to draw the npc with the custom renderer.
/// </summary>
/// <param name="b"></param>
/// <param name="alpha"></param>
/// <summary>Used to draw the npc with the custom renderer.</summary>
public virtual void drawModular(SpriteBatch b, float alpha = 1f)
{
if (this.characterRenderer == null || this.IsInvisible || !Utility.isOnScreen(this.position, 2 * Game1.tileSize))
@ -677,9 +555,7 @@ namespace CustomNPCFramework.Framework.NPCS
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);
}
/// <summary>
/// Used to draw the sprite without the modular npc renderer
/// </summary>
/// <summary>Used to draw the sprite without the modular npc renderer</summary>
/// <param name="b"></param>
/// <param name="alpha"></param>
public virtual void drawNonModularSprite(SpriteBatch b, float alpha = 1f)
@ -728,9 +604,7 @@ namespace CustomNPCFramework.Framework.NPCS
}
/// <summary>
/// Basic draw functionality to checkn whether or not to draw the npc using it's default sprite or using a custom character renderer.
/// </summary>
/// <summary>Basic draw functionality to checkn whether or not to draw the npc using it's default sprite or using a custom character renderer.</summary>
/// <param name="b"></param>
/// <param name="alpha"></param>
public override void draw(SpriteBatch b, float alpha = 1f)

View File

@ -1,56 +1,41 @@
using CustomNPCFramework.Framework.ModularNPCS;
using CustomNPCFramework.Framework.ModularNPCS.ModularRenderers;
using System.Collections.Generic;
using CustomNPCFramework.Framework.ModularNpcs;
using CustomNPCFramework.Framework.ModularNpcs.ModularRenderers;
using Microsoft.Xna.Framework;
using StardewValley;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CustomNPCFramework.Framework.NPCS
{
/// <summary>
/// Extended merchant npc from ExtendedNPC.
/// </summary>
class MerchantNPC: ExtendedNPC
/// <summary>Extended merchant npc from ExtendedNPC.</summary>
class MerchantNpc : ExtendedNpc
{
/// <summary>
/// Thelist of items this npc has for sale.
/// </summary>
/// <summary>The list of items this npc has for sale.</summary>
public List<Item> stock;
/// <summary>
/// Constructor.
/// </summary>
/// <summary>Construct an instance.</summary>
/// <param name="Stock">The list of items this npc will sell.</param>
/// <param name="sprite">The sprite for the npc to use.</param>
/// <param name="renderer">The renderer for the npc to use.</param>
/// <param name="position">The position for the npc to use.</param>
/// <param name="facingDirection">The facing direction for the player to face.</param>
/// <param name="name">The name for the npc.</param>
public MerchantNPC(List<Item> Stock, Sprite sprite, BasicRenderer renderer,Vector2 position,int facingDirection,string name): base(sprite,renderer,position,facingDirection,name)
public MerchantNpc(List<Item> Stock, Sprite sprite, BasicRenderer renderer, Vector2 position, int facingDirection, string name)
: base(sprite, renderer, position, facingDirection, name)
{
this.stock = Stock;
}
/// <summary>
/// Constructor.
/// </summary>
/// <summary>Construct an instance.</summary>
/// <param name="Stock">The list of items for the npc to sell.</param>
/// <param name="npcBase">The npc base for the character to be expanded upon.</param>
public MerchantNPC(List<Item> Stock, ExtendedNPC npcBase) : base(npcBase.spriteInformation, npcBase.characterRenderer, npcBase.portraitInformation, npcBase.position, npcBase.facingDirection, npcBase.Name)
public MerchantNpc(List<Item> Stock, ExtendedNpc npcBase)
: base(npcBase.spriteInformation, npcBase.characterRenderer, npcBase.portraitInformation, npcBase.position, npcBase.facingDirection, npcBase.Name)
{
this.stock = Stock;
}
/// <summary>
/// Used to interact with the npc. When interacting pulls up a shop menu for the npc with their current stock.
/// </summary>
/// <param name="who"></param>
/// <param name="l"></param>
/// <returns></returns>
public override bool checkAction(StardewValley.Farmer who, GameLocation l)
/// <summary>Used to interact with the npc. When interacting pulls up a shop menu for the npc with their current stock.</summary>
public override bool checkAction(Farmer who, GameLocation l)
{
if (Game1.activeClickableMenu == null)
{

View File

@ -1,89 +1,64 @@
using CustomNPCFramework.Framework.NPCS;
using System.Collections.Generic;
using CustomNPCFramework.Framework.NPCS;
using Microsoft.Xna.Framework;
using StardewValley;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CustomNPCFramework.Framework.Utilities
{
/// <summary>
/// Used to keep track of all of the custom npcs.
/// </summary>
public class NPCTracker
/// <summary>Used to keep track of all of the custom npcs.</summary>
public class NpcTracker
{
/// <summary>
/// A list used to keep track of the npcs.
/// </summary>
public List<ExtendedNPC> moddedNPCS;
/// <summary>A list used to keep track of the npcs.</summary>
public List<ExtendedNpc> moddedNpcs;
/// <summary>
/// Constructor.
/// </summary>
public NPCTracker()
/// <summary>Construct an instance.</summary>
public NpcTracker()
{
this.moddedNPCS = new List<ExtendedNPC>();
this.moddedNpcs = new List<ExtendedNpc>();
}
/// <summary>
/// Use this to add a new npc into the game.
/// </summary>
/// <summary>Use this to add a new npc into the game.</summary>
/// <param name="loc">The game location to add the npc to.</param>
/// <param name="npc">The extended npc to add to the location.</param>
public void addNewNPCToLocation(GameLocation loc,ExtendedNPC npc)
public void addNewNpcToLocation(GameLocation loc, ExtendedNpc npc)
{
this.moddedNPCS.Add(npc);
this.moddedNpcs.Add(npc);
npc.defaultLocation = loc;
npc.currentLocation = loc;
loc.addCharacter(npc);
}
/// <summary>
/// Add a npc to a location.
/// </summary>
/// <summary>Add a npc to a location.</summary>
/// <param name="loc">The game location to add an npc to.</param>
/// <param name="npc">The extended npc to add to the location.</param>
/// <param name="tilePosition">The tile position at the game location to add the mpc to.</param>
public void addNewNPCToLocation(GameLocation loc, ExtendedNPC npc, Vector2 tilePosition)
public void addNewNpcToLocation(GameLocation loc, ExtendedNpc npc, Vector2 tilePosition)
{
this.moddedNPCS.Add(npc);
this.moddedNpcs.Add(npc);
npc.defaultLocation = loc;
npc.currentLocation = loc;
npc.position.Value = tilePosition * Game1.tileSize;
loc.addCharacter(npc);
}
/// <summary>
/// Use this simply to remove a single npc from a location.
/// </summary>
/// <param name="loc"></param>
/// <param name="npc"></param>
public void removeCharacterFromLocation(GameLocation loc, ExtendedNPC npc)
/// <summary>Use this simply to remove a single npc from a location.</summary>
public void removeCharacterFromLocation(GameLocation loc, ExtendedNpc npc)
{
loc.characters.Remove(npc);
}
/// <summary>
/// Use this to completly remove and npc from the game as it is removed from the location and is no longer tracked.
/// </summary>
/// <summary>Use this to completly remove and npc from the game as it is removed from the location and is no longer tracked.</summary>
/// <param name="npc">The npc to remove from the location.</param>
public void removeFromLocationAndTrackingList(ExtendedNPC npc)
public void removeFromLocationAndTrackingList(ExtendedNpc npc)
{
if (npc.currentLocation != null)
{
npc.currentLocation.characters.Remove(npc);
}
this.moddedNPCS.Remove(npc);
npc.currentLocation?.characters.Remove(npc);
this.moddedNpcs.Remove(npc);
}
/// <summary>
/// Use this to clean up all of the npcs before the game is saved.
/// </summary>
/// <summary>Use this to clean up all of the npcs before the game is saved.</summary>
public void cleanUpBeforeSave()
{
foreach(ExtendedNPC npc in this.moddedNPCS)
foreach (ExtendedNpc npc in this.moddedNpcs)
{
//npc.currentLocation.characters.Remove(npc);
//Game1.removeThisCharacterFromAllLocations(npc);
@ -91,19 +66,13 @@ namespace CustomNPCFramework.Framework.Utilities
Class1.ModMonitor.Log("Removed an npc!");
//Do some saving code here.
}
}
/// <summary>
/// Use this to load in all of the npcs again after saving.
/// </summary>
/// <summary>Use this to load in all of the npcs again after saving.</summary>
public void afterSave()
{
foreach(ExtendedNPC npc in this.moddedNPCS)
{
foreach (ExtendedNpc npc in this.moddedNpcs)
npc.defaultLocation.addCharacter(npc);
}
}
}
}

View File

@ -2,9 +2,12 @@
"Name": "Custom NPC Framework",
"Author": "Alpha_Omegasis",
"Version": "0.1.0",
"Description": "A system to add custom npcs to Stardew.",
"Description": "A system to add custom NPCs to Stardew.",
"UniqueID": "Omegasis.CustomNPCFramework",
"EntryDll": "CustomNPCFramework.dll",
"MinimumApiVersion": "2.0",
"UpdateKeys": [ ]
"MinimumApiVersion": "2.10.1",
"UpdateKeys": [],
"Dependencies": [
{ "UniqueID": "Omegasis.StardustCore" }
]
}

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Pathoschild.Stardew.ModBuildConfig" version="2.2.0" targetFramework="net45" />
</packages>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
</configuration>

View File

@ -0,0 +1,52 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{901B46C9-38B6-469F-BB2F-E1BE2B770FC0}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>CustomObjectFramework</RootNamespace>
<AssemblyName>CustomObjectFramework</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

View File

@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CustomObjectFramework
{
class Program
{
static void Main(string[] args)
{
}
}
}

View File

@ -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("CustomObjectFramework")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("CustomObjectFramework")]
[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("901b46c9-38b6-469f-bb2f-e1be2b770fc0")]
// 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")]

View File

@ -1,22 +1,21 @@
using Omegasis.DailyQuestAnywhere.Framework;
using System;
using Omegasis.DailyQuestAnywhere.Framework;
using StardewModdingAPI;
using StardewModdingAPI.Events;
using StardewValley;
using StardewValley.Menus;
using StardewValley.Quests;
using System;
namespace Omegasis.DailyQuestAnywhere
{
/*
*TODO: Make quest core mod???
*/
/// <summary>The mod entry point.</summary>
public class DailyQuestAnywhere : Mod
{
/*********
** Properties
** Fields
*********/
/// <summary>The mod configuration.</summary>
private ModConfig Config;
@ -33,67 +32,69 @@ namespace Omegasis.DailyQuestAnywhere
{
this.Config = helper.ReadConfig<ModConfig>();
ControlEvents.KeyPressed += this.ControlEvents_KeyPressed;
StardewModdingAPI.Events.SaveEvents.AfterSave += SaveEvents_AfterSave;
helper.Events.Input.ButtonPressed += this.OnButtonPressed;
helper.Events.GameLoop.SaveLoaded += this.OnSaveLoaded;
}
/*********
** Private methods
*********/
/// <summary>The method invoked when the presses a keyboard button.</summary>
/// <summary>Raised after the player presses a button on the keyboard, controller, or mouse.</summary>
/// <param name="sender">The event sender.</param>
/// <param name="e">The event data.</param>
private void ControlEvents_KeyPressed(object sender, EventArgsKeyPressed e)
/// <param name="e">The event arguments.</param>
private void OnButtonPressed(object sender, ButtonPressedEventArgs e)
{
if (Context.IsPlayerFree && e.KeyPressed.ToString() == this.Config.KeyBinding)
if (Game1.player.hasDailyQuest() == false )
if (Context.IsPlayerFree && e.Button == this.Config.KeyBinding)
{
if (!Game1.player.hasDailyQuest())
{
if (this.dailyQuest == null)
{
this.dailyQuest = generateDailyQuest();
}
this.dailyQuest = this.generateDailyQuest();
Game1.questOfTheDay = this.dailyQuest;
Game1.activeClickableMenu = new Billboard(true);
}
}
/// <summary>
/// Makes my daily quest referene null so we can't just keep getting a new reference.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void SaveEvents_AfterSave(object sender, System.EventArgs e)
{
this.dailyQuest = null; //Nullify my quest reference.
}
/// <summary>
/// Generate a daily quest for sure.
/// </summary>
/// <returns></returns>
/// <summary>Raised after the player loads a save slot and the world is initialised.</summary>
/// <param name="sender">The event sender.</param>
/// <param name="e">The event arguments.</param>
private void OnSaveLoaded(object sender, SaveLoadedEventArgs e)
{
// makes daily quest null so we can't just keep getting a new reference
this.dailyQuest = null;
}
/// <summary>Generate a daily quest for sure.</summary>
public Quest generateDailyQuest()
{
Random chanceRandom = new Random((int)Game1.uniqueIDForThisGame + (int)Game1.stats.DaysPlayed);
int chance = chanceRandom.Next(0, 101);
float actualChance = chance / 100;
//If we hit the chance for actually generating a daily quest do so, otherwise don't generate a daily quest.
if (actualChance <= Config.chanceForDailyQuest)
if (actualChance <= this.Config.chanceForDailyQuest)
{
Random r = new Random((int)Game1.uniqueIDForThisGame + (int)Game1.stats.DaysPlayed);
int rand = r.Next(0, 7);
if (rand == 0) return new ItemDeliveryQuest();
if (rand == 1) return new FishingQuest();
if (rand == 2) return new StardewValley.Quests.CraftingQuest();
if (rand == 3) return new StardewValley.Quests.ItemDeliveryQuest();
if (rand == 4) return new StardewValley.Quests.ItemHarvestQuest();
if (rand == 5) return new StardewValley.Quests.ResourceCollectionQuest();
if (rand == 6) return new StardewValley.Quests.SlayMonsterQuest();
switch (rand)
{
case 0:
return new ItemDeliveryQuest();
case 1:
return new FishingQuest();
case 2:
return new CraftingQuest();
case 3:
return new ItemDeliveryQuest();
case 4:
return new ItemHarvestQuest();
case 5:
return new ResourceCollectionQuest();
case 6:
return new SlayMonsterQuest();
}
}
return null; //This should never happen.
}

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -11,8 +11,6 @@
<AssemblyName>DailyQuestAnywhere</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -67,6 +65,9 @@
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Pathoschild.Stardew.ModBuildConfig" Version="2.2.0" />
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Xml" />
@ -83,19 +84,8 @@
<None Include="manifest.json" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="README.md" />
</ItemGroup>
<ItemGroup>
<Analyzer Include="..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\analyzers\dotnet\cs\StardewModdingAPI.ModBuildConfig.Analyzer.dll" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\deploy.targets" />
<Import Project="..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets" Condition="Exists('..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>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}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets'))" />
</Target>
</Project>

View File

@ -1,14 +1,14 @@
namespace Omegasis.DailyQuestAnywhere.Framework
using StardewModdingAPI;
namespace Omegasis.DailyQuestAnywhere.Framework
{
/// <summary>The mod configuration.</summary>
internal class ModConfig
{
/// <summary>The key which shows the menu.</summary>
public string KeyBinding { get; set; } = "H";
public SButton KeyBinding { get; set; } = SButton.H;
/// <summary>
/// The chance for a daily quest to actually happen.
/// </summary>
/// <summary>The chance for a daily quest to actually happen.</summary>
public float chanceForDailyQuest { get; set; } = .75f;
}
}

View File

@ -1,10 +1,10 @@
{
"Name": "Daily Quest Anywhere",
"Author": "Alpha_Omegasis",
"Version": "1.5.0",
"Version": "1.6.0",
"Description": "Open the daily quest board from anywhere in the game.",
"UniqueID": "Omegasis.DailyQuestAnywhere",
"EntryDll": "DailyQuestAnywhere.dll",
"MinimumApiVersion": "2.0",
"MinimumApiVersion": "2.10.1",
"UpdateKeys": [ "Nexus:513" ]
}

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Pathoschild.Stardew.ModBuildConfig" version="2.2.0" targetFramework="net45" />
</packages>

View File

@ -1,4 +1,3 @@
using System;
using StardewModdingAPI;
using StardewModdingAPI.Events;
using StardewValley;
@ -15,17 +14,17 @@ namespace Omegasis.Fall28SnowDay
/// <param name="helper">Provides simplified APIs for writing mods.</param>
public override void Entry(IModHelper helper)
{
SaveEvents.BeforeSave += this.SaveEvents_BeforeSave;
helper.Events.GameLoop.Saving += this.OnSaving;
}
/*********
** Private methods
*********/
/// <summary>The method invoked just before the game saves.</summary>
/// <summary>Raised before the game begins writes data to the save file (except the initial save creation).</summary>
/// <param name="sender">The event sender.</param>
/// <param name="e">The event data.</param>
public void SaveEvents_BeforeSave(object sender, EventArgs e)
/// <param name="e">The event arguments.</param>
public void OnSaving(object sender, SavingEventArgs e)
{
if (Game1.IsFall && Game1.dayOfMonth == 27)
Game1.weatherForTomorrow = Game1.weather_snow;

View File

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -11,8 +11,6 @@
<AssemblyName>Fall28SnowDay</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -67,6 +65,9 @@
<ErrorReport>prompt</ErrorReport>
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Pathoschild.Stardew.ModBuildConfig" Version="2.2.0" />
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Xml" />
@ -82,19 +83,8 @@
<None Include="manifest.json" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="README.md" />
</ItemGroup>
<ItemGroup>
<Analyzer Include="..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\analyzers\dotnet\cs\StardewModdingAPI.ModBuildConfig.Analyzer.dll" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="$(SolutionDir)\deploy.targets" />
<Import Project="..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets" Condition="Exists('..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>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}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets'))" />
</Target>
</Project>

View File

@ -1,10 +1,10 @@
{
"Name": "Fall 28 Snow Day",
"Author": "Alpha_Omegasis",
"Version": "1.5.0",
"Version": "1.6.0",
"Description": "Makes it snow on Fall 28, which makes a good explanation for all the snow on the next day.",
"UniqueID": "Omegasis.Fall28SnowDay",
"EntryDll": "Fall28SnowDay.dll",
"MinimumApiVersion": "2.0",
"MinimumApiVersion": "2.10.1",
"UpdateKeys": [ "Nexus:486" ]
}

View File

@ -1,4 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Pathoschild.Stardew.ModBuildConfig" version="2.2.0" targetFramework="net45" />
</packages>

View File

@ -1,17 +1,13 @@
using EventSystem.Framework.FunctionEvents;
using System;
using EventSystem.Framework.FunctionEvents;
using FarmersMarketStall.Framework.MapEvents;
using Microsoft.Xna.Framework;
using StardewModdingAPI;
using StardewModdingAPI.Events;
using StardewValley;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace FarmersMarketStall
{
/// <summary>
/// TODO:
/// Make a farmers market menu
@ -21,32 +17,39 @@ namespace FarmersMarketStall
/// Make a selling menu
/// Make a minigame event for bonus money to earn.
/// </summary>
/// <param name="helper"></param>
public class Class1 : Mod
{
public static IModHelper ModHelper;
public static IMonitor ModMonitor;
public static FarmersMarketStall.Framework.MarketStall marketStall;
public static Framework.MarketStall marketStall;
/// <summary>The mod entry point, called after the mod is first loaded.</summary>
/// <param name="helper">Provides simplified APIs for writing mods.</param>
public override void Entry(IModHelper helper)
{
ModHelper = Helper;
ModMonitor = Monitor;
ModHelper = this.Helper;
ModMonitor = this.Monitor;
StardewModdingAPI.Events.SaveEvents.BeforeSave += SaveEvents_BeforeSave;
StardewModdingAPI.Events.SaveEvents.AfterLoad += SaveEvents_AfterLoad;
helper.Events.GameLoop.Saving += this.OnSaving;
helper.Events.GameLoop.SaveLoaded += this.OnSaveLoaded;
marketStall = new Framework.MarketStall();
}
private void SaveEvents_AfterLoad(object sender, EventArgs e)
/// <summary>Raised after the player loads a save slot and the world is initialised.</summary>
/// <param name="sender">The event sender.</param>
/// <param name="e">The event arguments.</param>
private void OnSaveLoaded(object sender, EventArgs e)
{
EventSystem.EventSystem.eventManager.addEvent(Game1.getLocationFromName("BusStop"), new ShopInteractionEvent("FarmersMarketStall", Game1.getLocationFromName("BusStop"), new Vector2(6, 11), new MouseButtonEvents(null, true), new MouseEntryLeaveEvent(null, null)));
}
private void SaveEvents_BeforeSave(object sender, EventArgs e)
/// <summary>Raised before the game begins writes data to the save file (except the initial save creation).</summary>
/// <param name="sender">The event sender.</param>
/// <param name="e">The event arguments.</param>
private void OnSaving(object sender, SavingEventArgs e)
{
if (marketStall.stock.Count > 0)
{
if (marketStall.stock.Count > 0) {
// Game1.endOfNightMenus.Push(new StardewValley.Menus.ShippingMenu(marketStall.stock));
marketStall.sellAllItems();
}

View File

@ -11,8 +11,6 @@
<AssemblyName>FarmersMarketStall</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
@ -68,9 +66,9 @@
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
</PropertyGroup>
<ItemGroup>
<Reference Include="EventSystem">
<HintPath>..\MapEvents\bin\Release\EventSystem.dll</HintPath>
</Reference>
<PackageReference Include="Pathoschild.Stardew.ModBuildConfig" Version="2.2.0" />
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
@ -88,17 +86,13 @@
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<ProjectReference Include="..\MapEvents\EventSystem.csproj">
<Project>{bb737337-2d82-4245-aa46-f3b82fc6f228}</Project>
<Name>EventSystem</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Analyzer Include="..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\analyzers\dotnet\cs\StardewModdingAPI.ModBuildConfig.Analyzer.dll" />
<None Include="manifest.json" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets" Condition="Exists('..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>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}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Pathoschild.Stardew.ModBuildConfig.2.2.0\build\Pathoschild.Stardew.ModBuildConfig.targets'))" />
</Target>
</Project>

View File

@ -1,9 +1,3 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using EventSystem;
using EventSystem.Framework.FunctionEvents;
using Microsoft.Xna.Framework;
using StardewValley;
@ -12,7 +6,8 @@ namespace FarmersMarketStall.Framework.MapEvents
{
public class ShopInteractionEvent : EventSystem.Framework.MapEvent
{
public ShopInteractionEvent(string Name, GameLocation Location, Vector2 Position, MouseButtonEvents MouseEvents, MouseEntryLeaveEvent EntryLeave) : base(Name, Location, Position)
public ShopInteractionEvent(string Name, GameLocation Location, Vector2 Position, MouseButtonEvents MouseEvents, MouseEntryLeaveEvent EntryLeave)
: base(Name, Location, Position)
{
this.name = Name;
this.location = Location;
@ -24,18 +19,17 @@ namespace FarmersMarketStall.Framework.MapEvents
this.mouseEntryLeaveEvents = EntryLeave;
}
public override bool OnLeftClick()
{
if (base.OnLeftClick() == false) return false;
if (this.location.isObjectAt((int)this.tilePosition.X * Game1.tileSize, (int)this.tilePosition.Y * Game1.tileSize)) return false;
if (!base.OnLeftClick())
return false;
if (this.location.isObjectAt((int)this.tilePosition.X * Game1.tileSize, (int)this.tilePosition.Y * Game1.tileSize))
return false;
Game1.activeClickableMenu = Menus.MarketStallMenu.openMenu(Class1.marketStall);
return true;
}
/// <summary>
/// Used to update the event and check for interaction.
/// </summary>
/// <summary>Used to update the event and check for interaction.</summary>
public override void update()
{
this.clickEvent();
@ -43,6 +37,5 @@ namespace FarmersMarketStall.Framework.MapEvents
this.OnMouseEnter();
this.OnMouseLeave();
}
}
}

View File

@ -1,9 +1,5 @@
using StardewValley;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using StardewValley;
namespace FarmersMarketStall.Framework
{
@ -11,10 +7,7 @@ namespace FarmersMarketStall.Framework
{
public List<Item> stock;
public MarketStall()
{
}
public MarketStall() { }
public void addItemToSell(Item item)
{
@ -28,12 +21,10 @@ namespace FarmersMarketStall.Framework
public void sellAllItems()
{
foreach(var item in stock)
{
foreach (var item in this.stock)
Game1.player.money += (int)(item.salePrice() * 1.10f); //Replace the multiplier with some sort of level.
}
this.stock.Clear();
}
}
}

View File

@ -1,10 +1,5 @@
using StardewValley;
using StardewValley.Menus;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using StardewValley.Menus;
namespace FarmersMarketStall.Framework.Menus
{
@ -20,6 +15,5 @@ namespace FarmersMarketStall.Framework.Menus
throw new NotImplementedException("This menu isn't implemented because the author is busy/lazy. Please encorage Omegasis to finish it!", null);
//return new StardewValley.Menus.InventoryMenu((int)(Game1.viewport.Width*.25f),(int)(Game1.viewport.Height*.25f),true,marketStall.stock);
}
}
}

View File

@ -5,12 +5,9 @@
"Description": "A system to add a farmers market stall to Sundrop.",
"UniqueID": "SunDrop.SunDropMapEvents.FarmersMarketStall",
"EntryDll": "FarmersMarketStall.dll",
"MinimumApiVersion": "2.0",
"MinimumApiVersion": "2.10.1",
"UpdateKeys": [],
"Dependencies": [
{
"UniqueID": "Omegasis.EventSystem",
"IsRequired": true
}
{ "UniqueID": "Omegasis.EventSystem" }
]
}

View File

@ -1,16 +1,9 @@
using StardewValley;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using StardewValley;
namespace Omegasis.HappyBirthday
{
/// <summary>
/// TODO:Make all the events
/// Resources:https://stardewvalleywiki.com/Modding:Event_data
/// </summary>
// TODO: Make all the events
// Resources:https://stardewvalleywiki.com/Modding:Event_data
public class BirthdayEvents
{
public Event communityCenterJunimoEvent;
@ -21,7 +14,7 @@ namespace Omegasis.HappyBirthday
public BirthdayEvents()
{
initializeEvents();
this.initializeEvents();
}
public void initializeEvents()
@ -29,7 +22,5 @@ namespace Omegasis.HappyBirthday
Event e = new Event("", -1, Game1.player);
Game1.player.currentLocation.currentEvent = new Event();
}
}
}

View File

@ -1,25 +1,16 @@
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
namespace Omegasis.HappyBirthday
{
public class BirthdayMessages
{
/// <summary>
/// The actual birthday wishes given by an npc.
/// </summary>
/// <summary>The actual birthday wishes given by an npc.</summary>
public Dictionary<string, string> birthdayWishes;
public Dictionary<string, string> spouseBirthdayWishes;
/// <summary>
/// TODO: Make this.
/// </summary>
public Dictionary<string, string> defaultSpouseBirthdayWishes = new Dictionary<string, string>()
{
["Alex"] = "",
@ -36,9 +27,7 @@ namespace Omegasis.HappyBirthday
["Penny"] = "",
};
/// <summary>
/// Used to contain
/// </summary>
/// <summary>Used to contain birthday wishes should the mod not find any available.</summary>
public Dictionary<string, string> defaultBirthdayWishes = new Dictionary<string, string>()
{
["Robin"] = "Hey @, happy birthday! I'm glad you choose this town to move here to. ",
@ -76,12 +65,79 @@ namespace Omegasis.HappyBirthday
["Krobus"] = "I have heard that it is tradition to give a gift to others on their birthday. In that case, happy birthday @."
};
/// <summary>
/// Used to load all of the default birthday greetings.
/// </summary>
public BirthdayMessages()
{
createBirthdayGreetings();
loadTranslationStrings();
}
public Dictionary<StardewValley.LocalizedContentManager.LanguageCode, Dictionary<string, string>> translatedStrings = new Dictionary<StardewValley.LocalizedContentManager.LanguageCode, Dictionary<string, string>>()
{
[StardewValley.LocalizedContentManager.LanguageCode.de] = new Dictionary<string, string>()
{
["Mail:birthdayMom"] = "",
["Mail:birthdayDad"] = "",
["Happy Birthday: Star Message"] = "",
["Happy Birthday: Farmhand Birthday Message"] = ""
},
[StardewValley.LocalizedContentManager.LanguageCode.en] = new Dictionary<string, string>()
{
["Mail: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 %%",
["Mail: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 %%",
["Happy Birthday: Star Message"] = "It's your birthday today! Happy birthday!",
["Happy Birthday: Farmhand Birthday Message"] = "It's @'s birthday! Happy birthday to them!"
},
[StardewValley.LocalizedContentManager.LanguageCode.es] = new Dictionary<string, string>()
{
["Mail:birthdayMom"] = "",
["Mail:birthdayDad"] = "",
["Happy Birthday: Star Message"] = "",
["Happy Birthday: Farmhand Birthday Message"] = ""
},
[StardewValley.LocalizedContentManager.LanguageCode.ja] = new Dictionary<string, string>()
{
["Mail:birthdayMom"] = "",
["Mail:birthdayDad"] = "",
["Happy Birthday: Star Message"] = "",
["Happy Birthday: Farmhand Birthday Message"] = ""
},
[StardewValley.LocalizedContentManager.LanguageCode.pt] = new Dictionary<string, string>()
{
["Mail:birthdayMom"] = "",
["Mail:birthdayDad"] = "",
["Happy Birthday: Star Message"] = "",
["Happy Birthday: Farmhand Birthday Message"] = ""
},
[StardewValley.LocalizedContentManager.LanguageCode.ru] = new Dictionary<string, string>()
{
["Mail:birthdayMom"] = "",
["Mail:birthdayDad"] = "",
["Happy Birthday: Star Message"] = "",
["Happy Birthday: Farmhand Birthday Message"] = ""
},
[StardewValley.LocalizedContentManager.LanguageCode.th] = new Dictionary<string, string>()
{
["Mail:birthdayMom"] = "",
["Mail:birthdayDad"] = "",
["Happy Birthday: Star Message"] = "",
["Happy Birthday: Farmhand Birthday Message"] = ""
},
[StardewValley.LocalizedContentManager.LanguageCode.zh] = new Dictionary<string, string>()
{
["Mail:birthdayMom"] = "亲爱的@^ 生日快乐宝贝。看着你成长成为一个善良努力的人,就如我一直梦想着你成为的样子,我感到十分欣喜。我希望你能继续跟你爱的人制造更多美好的回忆。 ^ 爱你的,妈妈 ^ 附言:这是我给你做的一点小礼物。 %item object 221 1 %%",
["Mail:birthdayDad"] = "亲爱的@^ 生日快乐孩子。你生日的这天没有你,我们这儿还挺寂寞的,但我和你妈妈都知道你让我们和你爷爷感到骄傲。我们知道你一个人生活可能会很艰难,但我们百分百相信你能做到,所以继续追求你的梦想吧。^ 爱你的,爸爸 ^ 附言:这是能在农场上帮到你的一些零用钱。祝你好运! %item money 5000 5001 %%",
["Happy Birthday: Star Message"] = "今天是你的生日!生日快乐!",
["Happy Birthday: Farmhand Birthday Message"] = ""
}
};
/// <summary>Used to load all of the default birthday greetings.</summary>
public void createBirthdayGreetings()
{
var serializer = JsonSerializer.Create();
serializer.Formatting = Formatting.Indented;
@ -95,14 +151,12 @@ namespace Omegasis.HappyBirthday
//Handle normal birthday wishes.
if (!File.Exists(Path.Combine(HappyBirthday.ModHelper.DirectoryPath, path)))
{
HappyBirthday.ModHelper.Data.WriteJsonFile<Dictionary<string, string>>(path, defaultBirthdayWishes);
this.birthdayWishes = defaultBirthdayWishes;
HappyBirthday.ModMonitor.Log("Creating Villager Birthday Messages", StardewModdingAPI.LogLevel.Alert);
HappyBirthday.ModHelper.Data.WriteJsonFile<Dictionary<string, string>>(path, this.defaultBirthdayWishes);
this.birthdayWishes = this.defaultBirthdayWishes;
}
else
{
birthdayWishes = HappyBirthday.ModHelper.Data.ReadJsonFile<Dictionary<string, string>>(path);
}
this.birthdayWishes = HappyBirthday.ModHelper.Data.ReadJsonFile<Dictionary<string, string>>(path);
//handle spouse birthday wishes.
string spouseBirthdayFileDict = HappyBirthday.Config.translationInfo.getjsonForTranslation("SpouseBirthdayWishes", HappyBirthday.Config.translationInfo.currentTranslation);
@ -110,20 +164,21 @@ namespace Omegasis.HappyBirthday
if (!File.Exists(Path.Combine(HappyBirthday.ModHelper.DirectoryPath, spousePath)))
{
HappyBirthday.ModMonitor.Log("Creating Spouse Messages", StardewModdingAPI.LogLevel.Alert);
HappyBirthday.ModHelper.Data.WriteJsonFile<Dictionary<string, string>>(spousePath, defaultSpouseBirthdayWishes);
this.spouseBirthdayWishes = defaultSpouseBirthdayWishes;
HappyBirthday.ModHelper.Data.WriteJsonFile<Dictionary<string, string>>(spousePath, this.defaultSpouseBirthdayWishes);
this.spouseBirthdayWishes = this.defaultSpouseBirthdayWishes;
}
else
{
spouseBirthdayWishes = HappyBirthday.ModHelper.Data.ReadJsonFile<Dictionary<string, string>>(spousePath);
}
this.spouseBirthdayWishes = HappyBirthday.ModHelper.Data.ReadJsonFile<Dictionary<string, string>>(spousePath);
//Non-english logic for creating templates.
foreach (var translation in HappyBirthday.Config.translationInfo.translationCodes)
{
if (translation.Key == "English") continue;
if (translation.Key == "English")
continue;
string basePath = Path.Combine(HappyBirthday.ModHelper.DirectoryPath, "Content", "Dialogue", translation.Key);
if (!Directory.Exists(basePath)) Directory.CreateDirectory(basePath);
if (!Directory.Exists(basePath))
Directory.CreateDirectory(basePath);
string tempBirthdayFile = Path.Combine("Content", "Dialogue", translation.Key, HappyBirthday.Config.translationInfo.getjsonForTranslation("BirthdayWishes", translation.Key));
string tempSpouseBirthdayFile = Path.Combine("Content", "Dialogue", translation.Key, HappyBirthday.Config.translationInfo.getjsonForTranslation("SpouseBirthdayWishes", translation.Key));
@ -131,33 +186,23 @@ namespace Omegasis.HappyBirthday
Dictionary<string, string> tempBirthdayDict = new Dictionary<string, string>();
if (!File.Exists(Path.Combine(HappyBirthday.ModHelper.DirectoryPath, tempBirthdayFile)))
{
foreach (var pair in defaultBirthdayWishes)
{
foreach (var pair in this.defaultBirthdayWishes)
tempBirthdayDict.Add(pair.Key, "");
}
HappyBirthday.ModHelper.Data.WriteJsonFile<Dictionary<string, string>>(tempBirthdayFile, tempBirthdayDict);
}
else
{
tempBirthdayDict = HappyBirthday.ModHelper.Data.ReadJsonFile<Dictionary<string, string>>(tempBirthdayFile);
}
Dictionary<string, string> tempSpouseBirthdayDict = new Dictionary<string, string>();
if (!File.Exists(Path.Combine(HappyBirthday.ModHelper.DirectoryPath, tempSpouseBirthdayFile)))
{
foreach (var pair in defaultSpouseBirthdayWishes)
{
foreach (var pair in this.defaultSpouseBirthdayWishes)
tempSpouseBirthdayDict.Add(pair.Key, "");
}
HappyBirthday.ModHelper.Data.WriteJsonFile<Dictionary<string, string>>(tempSpouseBirthdayFile, tempSpouseBirthdayDict);
}
else
{
tempBirthdayDict = HappyBirthday.ModHelper.Data.ReadJsonFile<Dictionary<string, string>>(tempSpouseBirthdayFile);
}
tempSpouseBirthdayDict = HappyBirthday.ModHelper.Data.ReadJsonFile<Dictionary<string, string>>(tempSpouseBirthdayFile);
//Set translated birthday info.
if (HappyBirthday.Config.translationInfo.currentTranslation == translation.Key)
@ -166,10 +211,50 @@ namespace Omegasis.HappyBirthday
this.spouseBirthdayWishes = tempSpouseBirthdayDict;
HappyBirthday.ModMonitor.Log("Language set to: " + translation);
}
}
}
public static string GetTranslatedString(string key)
{
StardewValley.LocalizedContentManager.LanguageCode code = HappyBirthday.Config.translationInfo.translationCodes[HappyBirthday.Config.translationInfo.currentTranslation];
string value= HappyBirthday.Instance.messages.translatedStrings[code][key];
if (string.IsNullOrEmpty(value))
{
return GetEnglishMessageString(key);
}
else return value;
}
public static string GetEnglishMessageString(string key)
{
StardewValley.LocalizedContentManager.LanguageCode code = StardewValley.LocalizedContentManager.LanguageCode.en;
return HappyBirthday.Instance.messages.translatedStrings[code][key];
}
public void loadTranslationStrings()
{
//Non-english logic for creating templates.
foreach (var translation in HappyBirthday.Config.translationInfo.translationCodes)
{
StardewValley.LocalizedContentManager.LanguageCode code = translation.Value;
string basePath = Path.Combine(HappyBirthday.ModHelper.DirectoryPath, "Content", "Dialogue", translation.Key);
if (!Directory.Exists(basePath))
Directory.CreateDirectory(basePath);
string stringsFile = Path.Combine("Content", "Dialogue", translation.Key, HappyBirthday.Config.translationInfo.getjsonForTranslation("TranslatedStrings", translation.Key));
if (!File.Exists(Path.Combine(HappyBirthday.ModHelper.DirectoryPath, stringsFile)))
{
HappyBirthday.ModHelper.Data.WriteJsonFile<Dictionary<string, string>>(stringsFile, this.translatedStrings[code]);
}
else
this.translatedStrings[code] = HappyBirthday.ModHelper.Data.ReadJsonFile<Dictionary<string, string>>(stringsFile);
}
}
}
}

View File

@ -1,10 +1,12 @@
Happy Birthday Change Log
~~~~~~~~~~~~~~~~
1.8.0 Changelog
Manifest 1.8.0 Changelog
~~~~~~~~~~~~~~~~
General Changes
General Changes
-NPCs now wish you a happy birthday if you have 2+ hearts with them. (Configurable in config file)
-A language can be set for birthday messages in the Config.json file.
-Added support for birthday messages to be in .json files for easier editing.
-Added support for birthday messages to be in multiple supported languages
-English
@ -12,15 +14,14 @@ General Changes
-German
-Chinese
-Japanese
-Brazillian Portuguese
-Added in spouse specific birthday dialogue messages which can be selected by the players.
-Added in multiple langages for spouse birthday messages.
-Brazilian Portuguese
-Added in spouse specific birthday dialogue messages which can be created by the players.
-Added in multiple languages for spouse birthday messages.
-Added in birthday gifts to be in .json files.
-Added in a new pool of spouse specific gifts that can be set by the player located in SpouseBirthdayGifts.json
-Added in support for loading legacy birthday gift.xnb info from StardewValley/Content/Data/PossibleBirthdayGifts.xnb
-Added in support for loading legacy birthday messages from StardewValley/Content/Data/BirthdayMessages.xnb
-Added in player portraits to be shown on the callendar.
Multiplayer changes:
-Added in multiplayer portraits to be shown on the callendar.
-Added in multiplayer farmhand portraits to be shown on the callendar.
-Added in a hud message that displays when another player has a birthday.

View File

@ -0,0 +1,35 @@
{
"Robin": "",
"Demetrius": "",
"Maru": "",
"Sebastian": "",
"Linus": "",
"Pierre": "",
"Caroline": "",
"Abigail": "",
"Alex": "",
"George": "",
"Evelyn": "",
"Lewis": "",
"Clint": "",
"Penny": "",
"Pam": "",
"Emily": "",
"Haley": "",
"Jas": "",
"Vincent": "",
"Jodi": "",
"Kent": "",
"Sam": "",
"Leah": "",
"Shane": "",
"Marnie": "",
"Elliott": "",
"Gus": "",
"Dwarf": "",
"Wizard": "",
"Harvey": "",
"Sandy": "",
"Willy": "",
"Krobus": ""
}

View File

@ -0,0 +1,14 @@
{
"Alex": "",
"Elliott": "",
"Harvey": "",
"Sam": "",
"Sebastian": "",
"Shane": "",
"Abigail": "",
"Emily": "",
"Haley": "",
"Leah": "",
"Maru": "",
"Penny": ""
}

View File

@ -0,0 +1,6 @@
{
"Mail:birthdayMom": "",
"Mail:birthdayDad": "",
"Happy Birthday: Star Message": "",
"Happy Birthday: Farmhand Birthday Message": ""
}

View File

@ -0,0 +1,35 @@
{
"Robin": "嘿,@,生日快乐!我很高兴你选择搬到这里来。",
"Demetrius": "生日快乐@!记得偶尔要抽出时间来好好享受一下。$h",
"Maru": "生日快乐@。我本来想给我做个永恒不灭的蜡烛,但是好像行不通。也许明年再给你吧?$h",
"Sebastian": "生日快乐@。又是平静的一年。",
"Linus": "生日快乐@。谢谢你在你生日的这天依旧来看我。这让我很开心。",
"Pierre": "嘿@,生日快乐!希望你的下一年会更好!",
"Caroline": "生日快乐@。谢谢你为这个社区做的一切。我相信你的父母一定都很为你骄傲。$h",
"Abigail": "生日快乐@!希望之后的一年我们可以一起去更多的地方冒险!$h",
"Alex": "哟@,生日快乐!也许这会是你有生以来最棒的一年。$h",
"George": "等你到我的年纪,生日就像其他的日子一样来去匆匆。不过还是祝你生日快乐,@。",
"Evelyn": "生日快乐@。你成长成为了一个优秀的人,我相信你还会继续成长的。",
"Lewis": "生日快乐@!我很感激你为这个小镇做的一切,我相信你爷爷也会为你骄傲的。",
"Clint": "嘿生日快乐@。我相信接下来对你来说会是很棒的一年。",
"Penny": "生日快乐@。希望你这一年都能得到所有的祝福。",
"Pam": "生日快乐孩子。我们应该一起去喝一杯,庆祝你生命的又一年。",
"Emily": "我今天感受到了很多关于你的正能量,所以一定是你的生日到了。生日快乐@$h",
"Haley": "生日快乐@。希望你今年能收到些很棒的礼物!$h",
"Jas": "生日快乐@。希望你过个愉快的生日。",
"Vincent": "嘿@,你是来玩的……哦今天是你的生日?生日快乐!",
"Jodi": "你好啊@。听说今天是你的生日。既然如此,祝你生日快乐!$h",
"Kent": "乔迪告诉我今天是你的生日,@。生日快乐,记得要珍惜每一天。",
"Sam": "哟@,生日快乐!有机会我们来给你办个生日派对吧!$h",
"Leah": "嘿@,生日快乐!我们今晚去酒吧庆祝一下吧!$h",
"Shane": "生日快乐@。继续努力工作,我相信你接下来的这一年会更好。",
"Marnie": "你好@。今天大家都在谈论你的生日,我也想跟你说一声生日快乐,那么,生日快乐!$h",
"Elliott": "真是美好的一天不是吗,@?尤其今天是你的生日。我本想给你写一首诗,但我觉得简单的才是最好的,生日快乐。$h",
"Gus": "嘿@,生日快乐!希望你今天过得愉快,酒吧永远都欢迎你!",
"Dwarf": "生日快乐@。我希望我给你的东西是人类可以接受的。",
"Wizard": "有精灵告诉我今天是你的生日。这么说,生日快乐@。希望你下一年辉煌灿烂!",
"Harvey": "嘿@,生日快乐!有空记得到我这来做检查,这能让你多活很多年!",
"Sandy": "你好啊@。我听说今天是你的生日,我可不想让你觉得被冷落了。生日快乐!",
"Willy": "哎@,生日快乐。看到你让我想起了我曾经一个人漂在海上的日子。继续享受青春吧年轻人。$h",
"Krobus": "我听说在别人生日的时候送一份礼物是传统。那么,生日快乐@。"
}

View File

@ -0,0 +1,14 @@
{
"Alex": "",
"Elliott": "",
"Harvey": "",
"Sam": "",
"Sebastian": "",
"Shane": "",
"Abigail": "",
"Emily": "",
"Haley": "",
"Leah": "",
"Maru": "",
"Penny": ""
}

View File

@ -0,0 +1,6 @@
{
"Mail:birthdayMom": "亲爱的@^ 生日快乐宝贝。看着你成长成为一个善良努力的人,就如我一直梦想着你成为的样子,我感到十分欣喜。我希望你能继续跟你爱的人制造更多美好的回忆。 ^ 爱你的,妈妈 ^ 附言:这是我给你做的一点小礼物。 %item object 221 1 %%",
"Mail:birthdayDad": "亲爱的@^ 生日快乐孩子。你生日的这天没有你,我们这儿还挺寂寞的,但我和你妈妈都知道你让我们和你爷爷感到骄傲。我们知道你一个人生活可能会很艰难,但我们百分百相信你能做到,所以继续追求你的梦想吧。^ 爱你的,爸爸 ^ 附言:这是能在农场上帮到你的一些零用钱。祝你好运! %item money 5000 5001 %%",
"Happy Birthday: Star Message": "今天是你的生日!生日快乐!",
"Happy Birthday: Farmhand Birthday Message": ""
}

View File

@ -0,0 +1,35 @@
{
"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 for you, 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 @. May your year shine bright! ",
"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 @."
}

View File

@ -0,0 +1,14 @@
{
"Alex": "",
"Elliott": "",
"Harvey": "",
"Sam": "",
"Sebastian": "",
"Shane": "",
"Abigail": "",
"Emily": "",
"Haley": "",
"Leah": "",
"Maru": "",
"Penny": ""
}

View File

@ -0,0 +1,6 @@
{
"Mail: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 %%",
"Mail: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 %%",
"Happy Birthday: Star Message": "It's your birthday today! Happy birthday!",
"Happy Birthday: Farmhand Birthday Message": "It's @'s birthday! Happy birthday to them!"
}

View File

@ -0,0 +1,35 @@
{
"Robin": "",
"Demetrius": "",
"Maru": "",
"Sebastian": "",
"Linus": "",
"Pierre": "",
"Caroline": "",
"Abigail": "",
"Alex": "",
"George": "",
"Evelyn": "",
"Lewis": "",
"Clint": "",
"Penny": "",
"Pam": "",
"Emily": "",
"Haley": "",
"Jas": "",
"Vincent": "",
"Jodi": "",
"Kent": "",
"Sam": "",
"Leah": "",
"Shane": "",
"Marnie": "",
"Elliott": "",
"Gus": "",
"Dwarf": "",
"Wizard": "",
"Harvey": "",
"Sandy": "",
"Willy": "",
"Krobus": ""
}

View File

@ -0,0 +1,14 @@
{
"Alex": "",
"Elliott": "",
"Harvey": "",
"Sam": "",
"Sebastian": "",
"Shane": "",
"Abigail": "",
"Emily": "",
"Haley": "",
"Leah": "",
"Maru": "",
"Penny": ""
}

View File

@ -0,0 +1,6 @@
{
"Mail:birthdayMom": "",
"Mail:birthdayDad": "",
"Happy Birthday: Star Message": "",
"Happy Birthday: Farmhand Birthday Message": ""
}

View File

@ -0,0 +1,35 @@
{
"Robin": "",
"Demetrius": "",
"Maru": "",
"Sebastian": "",
"Linus": "",
"Pierre": "",
"Caroline": "",
"Abigail": "",
"Alex": "",
"George": "",
"Evelyn": "",
"Lewis": "",
"Clint": "",
"Penny": "",
"Pam": "",
"Emily": "",
"Haley": "",
"Jas": "",
"Vincent": "",
"Jodi": "",
"Kent": "",
"Sam": "",
"Leah": "",
"Shane": "",
"Marnie": "",
"Elliott": "",
"Gus": "",
"Dwarf": "",
"Wizard": "",
"Harvey": "",
"Sandy": "",
"Willy": "",
"Krobus": ""
}

Some files were not shown because too many files have changed in this diff Show More