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; namespace CustomNPCFramework.Framework.Graphics { /// /// Used to hold a collection of strings. /// 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; this.rightString = RightString; this.upString = UpString; this.downString = DownString; } } /// /// Used to contain all of the asset managers. /// public class AssetPool { /// /// A dictionary holding all of the asset managers. (Name, AssetManager) /// public Dictionary assetPool; /// /// Constructor. /// public AssetPool() { this.assetPool = new Dictionary(); } /// /// Adds an asset manager to the asset pool. /// /// A key value pair with the convention being (Manager Name, Asset Manager) public void addAssetManager(KeyValuePair pair) { this.assetPool.Add(pair.Key, pair.Value); } /// /// Adds an asset manager to the asset pool. /// /// The name of the asset manager to be added. /// The asset manager object to be added to the asset pool. public void addAssetManager(string assetManagerName, AssetManager assetManager) { this.assetPool.Add(assetManagerName, assetManager); } /// /// Get an asset manager from the asset pool from a name. /// /// The name of the asset manager to return. /// public AssetManager getAssetManager(string name) { assetPool.TryGetValue(name, out AssetManager asset); return asset; } /// /// Remove an asset manager from the asset pool. /// /// The name of the asset manager to remove. public void removeAssetManager(string key) { assetPool.Remove(key); } /// /// Go through all of the asset managers and load assets according to their respective paths. /// public void loadAllAssets() { foreach (KeyValuePair assetManager in this.assetPool) { assetManager.Value.loadAssets(); } } /// /// Creates an extended animated sprite object given the asset name in the asset manager. /// /// /// public AnimatedSpriteExtended getAnimatedSpriteFromAsset(string name) { 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); } /// /// Generates a new AnimatedSpriteCollection object from the data held in an asset sheet. /// /// An asset sheet that holds the data for textures. /// The type of asset to get from the sheet. Hair, eyes, shoes, etc. /// public AnimatedSpriteCollection getSpriteCollectionFromSheet(AssetSheet assetSheet, AnimationType type) { var left = new AnimatedSpriteExtended(assetSheet.clone().getTexture(Direction.left, type),assetSheet); var right = new AnimatedSpriteExtended(assetSheet.clone().getTexture(Direction.right, type), assetSheet); var up = new AnimatedSpriteExtended(assetSheet.clone().getTexture(Direction.up, type), assetSheet); var down = new AnimatedSpriteExtended(assetSheet.clone().getTexture(Direction.down, type), assetSheet); return new AnimatedSpriteCollection(left, right, up, down, Direction.down); } /// /// Gets an animated sprite collection (ie a hair style facing all four directions) from a list of asset names. /// /// The name of the asset for the left facing sprite. /// The name of the asset for the right facing sprite. /// The name of the asset for the up facing sprite. /// The name of the asset for the down facing sprite. /// /// 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); } /// /// Get an AnimatedSpriteCollection from a name pairing. /// /// A collection of strings that hold information on directional textures. /// The direction in which the sprite should face. /// public AnimatedSpriteCollection getAnimatedSpriteCollectionFromAssets(NamePairings pair, Direction startingDirection = Direction.down) { return getAnimatedSpriteCollectionFromAssets(pair.leftString, pair.rightString, pair.upString, pair.downString); } /// /// Get a collection of sprites to generate a collective animated sprite. /// /// The collection of sprites to be used for the boyd of the npc. /// The collection of sprites to be used for the eye of the npc. /// The collection of sprites to be used for the hair of the npc. /// The collection of sprites to be used for the shirts of the npc. /// The collection of sprites to be used for the pants of the npc. /// The collection of sprites to be used for the shoes of the npc. /// The collection of sprites to be used for the accessories of the npc. /// The collection of collors to be used for chaing the color of an individual asset. /// public StandardCharacterAnimation GetStandardCharacterAnimation(NamePairings BodySprites, NamePairings EyeSprites, NamePairings HairSprites, NamePairings ShirtsSprites, NamePairings PantsSprites, NamePairings ShoesSprites,List 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); List accessories = new List(); foreach(var v in AccessoriesSprites) { accessories.Add(getAnimatedSpriteCollectionFromAssets(v)); } if (DrawColors == null) DrawColors = new StandardColorCollection(); return new StandardCharacterAnimation(body,eyes,hair,shirts,pants,shoes,accessories,DrawColors); } /// /// Get a list of parts that can apply for this criteria. /// /// The name of the asset manager. /// The gender critera. /// The season critera. /// The part type critera. /// public List getListOfApplicableBodyParts(string assetManagerName,Genders gender, Seasons season, PartType type) { var parts = this.getAssetManager(assetManagerName).getListOfAssetsThatMatchThisCriteria(gender, season, type); return parts; } /// /// Generate a basic npc based off of all all of the NPC data here. /// /// /// /// public ExtendedNPC generateNPC(Genders gender, int minNumOfAccessories, int maxNumOfAccessories ,StandardColorCollection DrawColors=null) { Seasons myseason=Seasons.spring; if (Game1.currentSeason == "spring") myseason = Seasons.spring; if (Game1.currentSeason == "summer") myseason = Seasons.summer; if (Game1.currentSeason == "fall") myseason = Seasons.fall; if (Game1.currentSeason == "winter") myseason = Seasons.winter; List bodyList = new List(); List eyesList = new List(); List hairList = new List(); List shirtList = new List(); List shoesList = new List(); List pantsList = new List(); List accessoryList = new List(); //Get all applicable parts from this current asset manager foreach (var assetManager in this.assetPool) { var body = getListOfApplicableBodyParts(assetManager.Key, gender, myseason, PartType.body); foreach (var piece in body) bodyList.Add(piece); var eyes = getListOfApplicableBodyParts(assetManager.Key, gender, myseason, PartType.eyes); foreach (var piece in eyes) eyesList.Add(piece); var hair = getListOfApplicableBodyParts(assetManager.Key, gender, myseason, PartType.hair); foreach (var piece in hair) hairList.Add(piece); var shirt = getListOfApplicableBodyParts(assetManager.Key, gender, myseason, PartType.shirt); foreach (var piece in shirt) shirtList.Add(piece); var pants = getListOfApplicableBodyParts(assetManager.Key, gender, myseason, PartType.pants); foreach (var piece in pants) pantsList.Add(piece); var shoes = getListOfApplicableBodyParts(assetManager.Key, gender, myseason, PartType.shoes); foreach (var piece in shoes) shoesList.Add(piece); var accessory = 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; amount = r.Next(minNumOfAccessories,maxNumOfAccessories + 1); //Necessary since r.next returns a num between min and (max-1) int bodyIndex = 0; int eyesIndex = 0; int hairIndex = 0; int shirtIndex = 0; int pantsIndex = 0; int shoesIndex = 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) { 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) { 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) { 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) { 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) { 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 accIntList = new List(); if (accessoryList.Count != 0) { for (int i = 0; i < amount; i++) { int acc = r.Next(0, accessoryList.Count - 1); accIntList.Add(acc); } } //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); List accessorySheet = new List(); foreach (var 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; } /// /// Creates a character renderer (a collection of textures) from a bunch of different asset sheets. /// /// The textures for the npc's body. /// The textures for the npc's eyes. /// The textures for the npc's hair. /// The textures for the npc's shirt. /// The textures for the npc's pants. /// The textures for the npc's shoes. /// The textures for the npc's accessories. /// The colors for the npc's different assets. /// public virtual BasicRenderer generateBasicRenderer(AssetSheet bodySheet, AssetSheet eyesSheet, AssetSheet hairSheet, AssetSheet shirtSheet, AssetSheet pantsSheet, AssetSheet shoesSheet, List accessorySheet, StandardColorCollection DrawColors=null) { 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); BasicRenderer render = new BasicRenderer(standingAnimation, movingAnimation, swimmingAnimation); return render; } /// /// Generate a Standard Character Animation from some asset sheets. /// (collection of textures to animations) /// /// The textures for the npc's body. /// The textures for the npc's eyes. /// The textures for the npc's hair. /// The textures for the npc's shirt. /// The textures for the npc's pants. /// The textures for the npc's shoes. /// The textures for the npc's accessories. /// The colors for the npc's different assets. /// public virtual StandardCharacterAnimation generateCharacterAnimation(AssetSheet body, AssetSheet eyes, AssetSheet hair, AssetSheet shirt, AssetSheet pants, AssetSheet shoes,List 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); List accessoryCollection = new List(); foreach (var v in accessories) { AnimatedSpriteCollection acc = 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; } /// /// Get the string for the standard character sprite to be used from this asset sheet. /// /// The standard asset sheet to be used. /// public virtual string getDefaultSpriteImage(AssetSheet imageGraphics) { return Class1.getRelativeDirectory(Path.Combine(imageGraphics.path, imageGraphics.assetInfo.standingAssetPaths.downString)); } } }