2018-12-30 18:00:05 +08:00
using System ;
using System.Collections.Generic ;
using System.IO ;
2019-01-06 13:31:40 +08:00
using System.Linq ;
2018-12-30 18:00:05 +08:00
using CustomNPCFramework.Framework.Enums ;
2018-03-04 23:53:55 +08:00
using CustomNPCFramework.Framework.Graphics ;
2018-12-30 18:00:05 +08:00
using CustomNPCFramework.Framework.ModularNpcs.ColorCollections ;
2018-02-24 11:10:56 +08:00
using CustomNPCFramework.Framework.NPCS ;
2018-03-04 19:36:19 +08:00
using CustomNPCFramework.Framework.Utilities ;
2018-02-24 11:10:56 +08:00
using Microsoft.Xna.Framework ;
using StardewModdingAPI ;
2019-01-06 15:21:06 +08:00
using StardewModdingAPI.Events ;
2018-02-24 11:10:56 +08:00
using StardewValley ;
namespace CustomNPCFramework
{
2018-03-04 20:36:46 +08:00
/// <summary>
2018-03-20 18:10:02 +08:00
/// BETA VERSION 0.1.0: Lots of ways this can be improved upon.
2018-03-04 20:36:46 +08:00
/// TODO:
2018-03-20 18:10:02 +08:00
///
///
2018-03-04 20:36:46 +08:00
/// List all asset managers in use.
/// Have all asset managers list what assets they are using.
2018-03-05 05:23:40 +08:00
///
2018-03-05 07:21:39 +08:00
/// Have asset info have a var called age.
/// ...where
/// 0=adult
/// 1=child
///
/// /// Have asset info have a var called bodyType.
/// ...where
/// 0=thin
/// 1=normal
/// 2=muscular
/// 3=big
///
2018-03-05 05:23:40 +08:00
/// Load in the assets and go go go.
2018-03-05 06:44:52 +08:00
/// -Collect a bunch of assets together to test this thing.
2018-03-18 16:48:01 +08:00
///
/// Find way to make sideways shirts render correctly.
2018-03-20 18:10:02 +08:00
///
///Get suggestions from modding community on requests and ways to improve the mod.
2018-03-04 20:36:46 +08:00
/// </summary>
2018-02-24 11:10:56 +08:00
public class Class1 : Mod
{
2018-12-30 18:00:05 +08:00
/// <summary>The mod helper for the mod.</summary>
2018-02-24 11:10:56 +08:00
public static IModHelper ModHelper ;
2018-12-30 18:00:05 +08:00
/// <summary>The mod monitor for the mod.</summary>
2018-02-24 11:10:56 +08:00
public static IMonitor ModMonitor ;
2018-03-04 20:36:46 +08:00
2018-12-30 18:00:05 +08:00
/// <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>
2018-03-04 20:36:46 +08:00
public static AssetPool assetPool ;
2018-12-22 07:28:52 +08:00
public static IManifest Manifest ;
2018-12-30 18:00:05 +08:00
/// <summary>The mod entry point, called after the mod is first loaded.</summary>
/// <param name="helper">Provides simplified APIs for writing mods.</param>
2018-02-24 11:10:56 +08:00
public override void Entry ( IModHelper helper )
{
ModHelper = this . Helper ;
ModMonitor = this . Monitor ;
2018-12-30 18:00:05 +08:00
Manifest = this . ModManifest ;
2018-03-04 20:36:46 +08:00
2019-01-06 15:21:06 +08:00
helper . Events . GameLoop . SaveLoaded + = this . OnSaveLoaded ;
helper . Events . GameLoop . Saving + = this . OnSaving ;
helper . Events . GameLoop . Saved + = this . OnSaved ;
helper . Events . GameLoop . UpdateTicked + = this . OnUpdateTicked ;
2018-12-30 18:00:05 +08:00
npcTracker = new NpcTracker ( ) ;
2018-03-04 20:36:46 +08:00
assetPool = new AssetPool ( ) ;
var assetManager = new AssetManager ( ) ;
assetPool . addAssetManager ( new KeyValuePair < string , AssetManager > ( "testNPC" , assetManager ) ) ;
2018-12-30 18:00:05 +08:00
this . initializeExamples ( ) ;
this . initializeAssetPool ( ) ;
2018-03-04 20:36:46 +08:00
assetPool . loadAllAssets ( ) ;
}
2018-12-30 18:00:05 +08:00
/// <summary>Initialize the asset pool with some test variables.</summary>
2018-03-04 20:36:46 +08:00
public void initializeAssetPool ( )
{
2019-01-06 13:31:40 +08:00
string relativePath = Path . Combine ( "Content" , "Graphics" , "NPCS" ) ;
assetPool . getAssetManager ( "testNPC" ) . addPathCreateDirectory ( new KeyValuePair < string , string > ( "characters" , relativePath ) ) ;
2018-03-04 19:36:19 +08:00
}
2019-01-06 15:21:06 +08:00
/// <summary>Raised after the game finishes writing data to the save file (except the initial save creation).</summary>
2018-12-30 18:00:05 +08:00
/// <param name="sender">The event sender.</param>
/// <param name="e">The event arguments.</param>
2019-01-06 15:21:06 +08:00
private void OnSaved ( object sender , SavedEventArgs e )
2018-03-04 19:36:19 +08:00
{
npcTracker . afterSave ( ) ;
}
2019-01-06 15:21:06 +08:00
/// <summary>Raised before the game begins writes data to the save file (except the initial save creation).</summary>
2018-12-30 18:00:05 +08:00
/// <param name="sender">The event sender.</param>
/// <param name="e">The event arguments.</param>
2019-01-06 15:21:06 +08:00
private void OnSaving ( object sender , SavingEventArgs e )
2018-03-04 19:36:19 +08:00
{
2019-01-06 15:21:06 +08:00
// clean up all the npcs from the game world to prevent it from crashing
2018-03-04 19:36:19 +08:00
npcTracker . cleanUpBeforeSave ( ) ;
2018-02-24 11:10:56 +08:00
}
2019-01-06 15:21:06 +08:00
/// <summary>Raised after the game state is updated (≈60 times per second).</summary>
2018-12-30 18:00:05 +08:00
/// <param name="sender">The event sender.</param>
/// <param name="e">The event arguments.</param>
2019-01-06 15:21:06 +08:00
private void OnUpdateTicked ( object sender , UpdateTickedEventArgs e )
2018-02-24 11:10:56 +08:00
{
2019-01-06 15:21:06 +08:00
// TODO For testing purposes only. Will remove in future release.
2018-03-20 14:01:43 +08:00
/ *
2018-02-24 11:10:56 +08:00
if ( Game1 . player . currentLocation = = null ) return ;
2018-03-19 10:06:08 +08:00
if ( Game1 . activeClickableMenu ! = null ) return ;
2018-02-24 11:10:56 +08:00
foreach ( var v in Game1 . player . currentLocation . characters )
{
2018-03-19 07:06:49 +08:00
v . speed = 1 ;
if ( v is ExtendedNPC )
{
( v as ExtendedNPC ) . SetMovingAndMove ( Game1 . currentGameTime , Game1 . viewport , Game1 . player . currentLocation , Direction . right , true ) ;
}
2018-02-24 17:36:41 +08:00
//v.MovePosition(Game1.currentGameTime, Game1.viewport, Game1.player.currentLocation);
2018-03-04 20:36:46 +08:00
//ModMonitor.Log(v.sprite.spriteHeight.ToString());
2018-02-24 11:10:56 +08:00
}
2018-03-20 14:01:43 +08:00
* /
2018-02-24 11:10:56 +08:00
}
2019-01-06 15:21:06 +08:00
/// <summary>Raised after the player loads a save slot and the world is initialised.</summary>
2018-12-30 18:00:05 +08:00
/// <param name="sender">The event sender.</param>
/// <param name="e">The event arguments.</param>
2019-01-06 15:21:06 +08:00
private void OnSaveLoaded ( object sender , SaveLoadedEventArgs e )
2018-02-24 11:10:56 +08:00
{
2019-01-06 15:21:06 +08:00
// TODO Used to spawn a custom npc just as an example. Don't keep this code. GENERATE NPC AND CALL THE CODE
2018-12-30 18:00:05 +08:00
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 > ( )
2018-03-17 19:39:46 +08:00
{
new StardewValley . Object ( 475 , 999 )
} , myNpc3 ) ;
2018-12-30 18:00:05 +08:00
npcTracker . addNewNpcToLocation ( Game1 . getLocationFromName ( "BusStop" , false ) , merch , new Vector2 ( 2 , 23 ) ) ;
2018-02-24 11:10:56 +08:00
}
2018-12-30 18:00:05 +08:00
/// <summary>Used to initialize examples for other modders to look at as reference.</summary>
2018-02-24 11:10:56 +08:00
public void initializeExamples ( )
{
2018-03-18 16:48:01 +08:00
return ;
2019-01-06 13:31:40 +08:00
string relativeDirPath = Path . Combine ( "Content" , "Templates" ) ;
2018-12-30 18:00:05 +08:00
var aManager = assetPool . getAssetManager ( "testNPC" ) ;
2019-01-06 13:31:40 +08:00
aManager . addPathCreateDirectory ( new KeyValuePair < string , string > ( "templates" , relativeDirPath ) ) ;
2018-03-04 23:53:55 +08:00
2019-01-06 13:31:40 +08:00
// write example
2018-03-04 23:53:55 +08:00
{
2019-01-06 13:31:40 +08:00
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 ( relativeFilePath ) ;
2018-03-04 23:53:55 +08:00
2019-01-06 13:31:40 +08:00
}
2018-03-04 23:53:55 +08:00
}
2018-02-24 11:10:56 +08:00
2019-01-06 13:31:40 +08:00
// write advanced example
2018-03-17 19:04:04 +08:00
{
2019-01-06 13:31:40 +08:00
string relativeFilePath = Path . Combine ( relativeDirPath , "AdvancedExample.json" ) ;
if ( ! File . Exists ( Path . Combine ( this . Helper . DirectoryPath , relativeFilePath ) ) )
{
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 ) ;
}
2018-03-17 19:04:04 +08:00
}
2018-02-24 11:10:56 +08:00
}
2018-12-30 18:00:05 +08:00
/// <summary>Used to finish cleaning up absolute asset paths into a shortened relative path.</summary>
2018-02-24 11:10:56 +08:00
public static string getRelativeDirectory ( string path )
{
2019-01-06 13:31:40 +08:00
return path
. Split ( new [ ] { ModHelper . DirectoryPath } , 2 , StringSplitOptions . None )
. Last ( )
. TrimStart ( Path . DirectorySeparatorChar ) ;
2018-02-24 11:10:56 +08:00
}
}
}