Fixed npc movment, npcs now correctly animate when moving, need to fix graphics for it though.

This commit is contained in:
2018-03-18 16:06:49 -07:00
parent 5c1f09b266
commit 9834bbcf28
10 changed files with 238 additions and 31 deletions

View File

@ -92,7 +92,11 @@ namespace CustomNPCFramework
if (Game1.player.currentLocation == null) return;
foreach (var v in Game1.player.currentLocation.characters)
{
v.speed = 5;
v.speed = 1;
if(v is ExtendedNPC)
{
(v as ExtendedNPC).SetMovingAndMove(Game1.currentGameTime, Game1.viewport, Game1.player.currentLocation, Direction.right, true);
}
//v.MovePosition(Game1.currentGameTime, Game1.viewport, Game1.player.currentLocation);
//ModMonitor.Log(v.sprite.spriteHeight.ToString());
}
@ -116,7 +120,7 @@ namespace CustomNPCFramework
{
new StardewValley.Object(475,999)
}, myNpc3);
npcTracker.addNewNPCToLocation(Game1.getLocationFromName("BusStop", false), merch);
npcTracker.addNewNPCToLocation(Game1.getLocationFromName("BusStop", false), merch,new Vector2(2,23));
}
public void initializeExamples()

View File

@ -5,6 +5,7 @@ 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;
@ -152,7 +153,7 @@ namespace CustomNPCFramework.Framework.Graphics
/// <param name="gender"></param>
/// <param name="minNumOfAccessories"></param>
/// <param name="maxNumOfAccessories"></param>
public ExtendedNPC generateNPC(Genders gender, int minNumOfAccessories, int maxNumOfAccessories, StandardColorCollection DrawColors=null)
public ExtendedNPC generateNPC(Genders gender, int minNumOfAccessories, int maxNumOfAccessories ,StandardColorCollection DrawColors=null)
{
Seasons myseason=Seasons.spring;
@ -295,7 +296,7 @@ namespace CustomNPCFramework.Framework.Graphics
}
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(13, 15) * Game1.tileSize, 2, NPCNames.getRandomNPCName(gender));
ExtendedNPC npc = new ExtendedNPC(new Sprite(getDefaultSpriteImage(bodySheet)), render, new Microsoft.Xna.Framework.Vector2(0,0) * Game1.tileSize, 2, NPCNames.getRandomNPCName(gender));
return npc;
}

View File

@ -132,7 +132,7 @@ namespace CustomNPCFramework.Framework.ModularNPCS
{
//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);
b.Draw(this.currentSprite.sprite.Texture,position,sourceRectangle, color, 0.0f, origin,scale,effects,layerDepth);
b.Draw(this.currentSprite.sprite.Texture,position,this.currentSprite.sprite.sourceRect, color, 0.0f, origin,scale,effects,layerDepth);
//b.Draw(this.Sprite.Texture, npc.getLocalPosition(Game1.viewport) + new Vector2((float)(this.sprite.spriteWidth * Game1.pixelZoom / 2), (float)(this.GetBoundingBox().Height / 2)) + (this.shakeTimer > 0 ? new Vector2((float)Game1.random.Next(-1, 2), (float)Game1.random.Next(-1, 2)) : Vector2.Zero), new Microsoft.Xna.Framework.Rectangle?(this.Sprite.SourceRect), Color.White * alpha, this.rotation, new Vector2((float)(this.sprite.spriteWidth / 2), (float)((double)this.sprite.spriteHeight * 3.0 / 4.0)), Math.Max(0.2f, this.scale) * (float)Game1.pixelZoom, this.flip || this.sprite.currentAnimation != null && this.sprite.currentAnimation[this.sprite.currentAnimationIndex].flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, Math.Max(0.0f, this.drawOnTop ? 0.991f : (float)this.getStandingY() / 10000f));
}
@ -141,17 +141,54 @@ namespace CustomNPCFramework.Framework.ModularNPCS
/// Animate the current sprite. Theoreticlly works from index offset to how many frames
/// </summary>
/// <param name="intervalFromCharacter"></param>
public void Animate(float intervalFromCharacter)
public void Animate(float intervalFromCharacter,bool loop=true)
{
this.currentSprite.sprite.Animate(Game1.currentGameTime, 0,3, intervalFromCharacter);
//ANIMATE AND UPDATE SOURCE RECTANGLE NOT WORKING!!!! FIGURE THIS OUT!!!!
//Class1.ModMonitor.Log("Current sprite frame:"+this.currentSprite.sprite.currentFrame.ToString());
//Class1.ModMonitor.Log("Am I ignoring something??: " + this.currentSprite.sprite.ignoreSourceRectUpdates);
//Class1.ModMonitor.Log("Current Sprite Source Rect:" + this.currentSprite.sprite.sourceRect);
//Class1.ModMonitor.Log("Sprite width: " + this.currentSprite.sprite.spriteWidth);
//Class1.ModMonitor.Log("Sprite width: " + this.currentSprite.sprite.spriteHeight);
this.Animate(Game1.currentGameTime, 0,2, intervalFromCharacter,this.currentSprite.sprite,loop);
}
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)
sprite.CurrentFrame = startFrame + sprite.CurrentFrame % numberOfFrames;
sprite.timer = sprite.timer + (float)gameTime.ElapsedGameTime.TotalMilliseconds;
if ((double)sprite.timer > (double)interval)
{
sprite.CurrentFrame = sprite.CurrentFrame + 1;
sprite.timer = 0.0f;
if (sprite.CurrentFrame == startFrame + numberOfFrames + 1 || sprite.currentFrame * sprite.spriteWidth >= sprite.Texture.Width)
{
if (loop)
sprite.CurrentFrame = startFrame;
sprite.UpdateSourceRect();
return true;
}
}
this.UpdateSourceRect(sprite);
return false;
}
public virtual void UpdateSourceRect(AnimatedSprite sprite)
{
if (sprite.ignoreSourceRectUpdates)
return;
sprite.sourceRect.X = sprite.CurrentFrame * sprite.spriteWidth;
sprite.sourceRect.Y = 0;
//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>
public void Animate(float intervalFromCharacter,int startFrame,int endFrame)
public void Animate(float intervalFromCharacter,int startFrame,int endFrame, bool loop)
{
this.currentSprite.sprite.loop = loop;
this.currentSprite.sprite.Animate(Game1.currentGameTime, startFrame, endFrame, intervalFromCharacter);
}
}

View File

@ -41,6 +41,12 @@ namespace CustomNPCFramework.Framework.ModularNPCS
}
public virtual void Animate(float animationInterval, bool loop=true)
{
}
/// <summary>
/// Used to draw the sprite to the screen.
/// </summary>

View File

@ -101,17 +101,17 @@ namespace CustomNPCFramework.Framework.ModularNPCS.CharacterAnimationBases
this.shoes.reload();
}
public override void Animate(float animationInterval)
public override void Animate(float animationInterval,bool loop=true)
{
this.body.Animate(animationInterval);
this.hair.Animate(animationInterval);
this.eyes.Animate(animationInterval);
this.shirt.Animate(animationInterval);
this.pants.Animate(animationInterval);
this.shoes.Animate(animationInterval);
this.body.Animate(animationInterval,loop);
this.hair.Animate(animationInterval,loop);
this.eyes.Animate(animationInterval,loop);
this.shirt.Animate(animationInterval,loop);
this.pants.Animate(animationInterval,loop);
this.shoes.Animate(animationInterval,loop);
foreach(var accessory in this.accessories)
{
accessory.Animate(animationInterval);
accessory.Animate(animationInterval,loop);
}
}
@ -184,6 +184,7 @@ namespace CustomNPCFramework.Framework.ModularNPCS.CharacterAnimationBases
{
//Class1.ModMonitor.Log(sourceRectangle.ToString());
Vector2 generalOffset = new Vector2(0, 1*Game1.tileSize); //Puts the sprite at the correct positioning.
position -= new Vector2(0, 0.25f * Game1.tileSize);
float smallOffset = 0.001f;
float tinyOffset = 0.0001f;
//Class1.ModMonitor.Log((position - generalOffset).ToString());

View File

@ -32,7 +32,11 @@ namespace CustomNPCFramework.Framework.ModularNPCS.ModularRenderers
public virtual void setAnimation(string key)
{
this.currentAnimation = animationList[key];
if (this.currentAnimation == null) this.setAnimation(AnimationKeys.standingKey);
if (this.currentAnimation == null)
{
Class1.ModMonitor.Log("ERROR SETTING AN ANIMATION: "+key);
this.setAnimation(AnimationKeys.standingKey);
}
}
public virtual void setDirection(int facingDirection)
@ -120,9 +124,9 @@ namespace CustomNPCFramework.Framework.ModularNPCS.ModularRenderers
}
public virtual void Animate(float interval)
public virtual void Animate(float interval, bool loop=true)
{
this.currentAnimation.Animate(interval);
this.currentAnimation.Animate(interval,loop);
}

View File

@ -1,4 +1,5 @@
using CustomNPCFramework.Framework.NPCS;
using CustomNPCFramework.Framework.ModularNPCS.ModularRenderers;
using CustomNPCFramework.Framework.NPCS;
using Microsoft.Xna.Framework.Graphics;
using StardewValley;
using System;
@ -69,5 +70,57 @@ namespace CustomNPCFramework.Framework.ModularNPCS
{
this.sprite.Texture = Class1.ModHelper.Content.Load<Texture2D>(this.relativePath);
}
/// <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)
{
if (npc.characterRenderer == null)
{
return;
}
else 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)
{
if (npc.characterRenderer == null)
{
return;
}
else 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)
{
if (npc.characterRenderer == null)
{
return;
}
else 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)
{
if (npc.characterRenderer == null)
{
return;
}
else npc.characterRenderer.setUp();
}
}
}

View File

@ -1,4 +1,5 @@
using CustomNPCFramework.Framework.ModularNPCS;
using CustomNPCFramework.Framework.Enums;
using CustomNPCFramework.Framework.ModularNPCS;
using CustomNPCFramework.Framework.ModularNPCS.ModularRenderers;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
@ -158,8 +159,75 @@ namespace CustomNPCFramework.Framework.NPCS
//ERROR NEED FIXING
public override void MovePosition(GameTime time, xTile.Dimensions.Rectangle viewport, GameLocation currentLocation)
{
base.MovePosition(time,viewport,currentLocation);
if (this.characterRenderer != null)
{
ModularMovement(time,viewport,currentLocation);
}
else
{
NonModularMovement(time,viewport,currentLocation);
}
return;
}
/// <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>
/// <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)
{
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);
this.MovePosition(time, viewport, currentLocation);
}
public virtual void NonModularMovement(GameTime time, xTile.Dimensions.Rectangle viewport, GameLocation location)
{
base.MovePosition(time, viewport, currentLocation);
return;
}
public virtual bool canMovePastNextLocation(xTile.Dimensions.Rectangle viewport)
{
//Up
if (!currentLocation.isTilePassable(this.nextPosition(0), viewport) || !this.willDestroyObjectsUnderfoot)
{
return false;
}
//Right
if (!currentLocation.isTilePassable(this.nextPosition(1), viewport) || !this.willDestroyObjectsUnderfoot)
{
return false;
}
//Down
if (!currentLocation.isTilePassable(this.nextPosition(2), viewport) || !this.willDestroyObjectsUnderfoot)
{
return false;
}
//Left
if (!currentLocation.isTilePassable(this.nextPosition(3), viewport) || !this.willDestroyObjectsUnderfoot)
{
return false;
}
return true;
}
public virtual void ModularMovement(GameTime time, xTile.Dimensions.Rectangle viewport, GameLocation location, float interval = 1000f)
{
interval /= 2;
this.characterRenderer.setAnimation(AnimationKeys.walkingKey);
if (this.canMovePastNextLocation(viewport) == false)
{
this.Halt();
return;
}
if (this.GetType() == typeof(FarmAnimal))
this.willDestroyObjectsUnderfoot = false;
if ((double)this.xVelocity != 0.0 || (double)this.yVelocity != 0.0)
@ -182,7 +250,9 @@ namespace CustomNPCFramework.Framework.NPCS
this.position.Y -= (float)(this.speed + this.addedSpeed);
if (!this.ignoreMovementAnimation)
{
this.sprite.AnimateUp(time, (this.speed - 2 + this.addedSpeed) * -25, Utility.isOnScreen(this.getTileLocationPoint(), 1, currentLocation) ? "Cowboy_Footstep" : "");
this.spriteInformation.setUp(this);
this.characterRenderer.Animate(interval,true);
//this.sprite.AnimateUp(time, (this.speed - 2 + this.addedSpeed) * -25, Utility.isOnScreen(this.getTileLocationPoint(), 1, currentLocation) ? "Cowboy_Footstep" : "");
this.faceDirection(0);
}
}
@ -207,7 +277,10 @@ namespace CustomNPCFramework.Framework.NPCS
this.position.X += (float)(this.speed + this.addedSpeed);
if (!this.ignoreMovementAnimation)
{
this.sprite.AnimateRight(time, (this.speed - 2 + this.addedSpeed) * -25, Utility.isOnScreen(this.getTileLocationPoint(), 1, currentLocation) ? "Cowboy_Footstep" : "");
this.spriteInformation.setRight(this);
this.characterRenderer.Animate(interval,true);
//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);
}
}
@ -232,7 +305,10 @@ namespace CustomNPCFramework.Framework.NPCS
this.position.Y += (float)(this.speed + this.addedSpeed);
if (!this.ignoreMovementAnimation)
{
this.sprite.AnimateDown(time, (this.speed - 2 + this.addedSpeed) * -25, Utility.isOnScreen(this.getTileLocationPoint(), 1, currentLocation) ? "Cowboy_Footstep" : "");
this.spriteInformation.setDown(this);
this.characterRenderer.Animate(interval,true);
//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);
}
}
@ -257,7 +333,10 @@ namespace CustomNPCFramework.Framework.NPCS
this.position.X -= (float)(this.speed + this.addedSpeed);
if (!this.ignoreMovementAnimation)
{
this.sprite.AnimateLeft(time, (this.speed - 2 + this.addedSpeed) * -25, Utility.isOnScreen(this.getTileLocationPoint(), 1, currentLocation) ? "Cowboy_Footstep" : "");
this.spriteInformation.setLeft(this);
this.characterRenderer.Animate(interval,true);
//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);
}
}
@ -290,6 +369,12 @@ namespace CustomNPCFramework.Framework.NPCS
}
}
public override void Halt()
{
this.characterRenderer.setAnimation(AnimationKeys.standingKey);
base.Halt();
}
public override void update(GameTime time, GameLocation location)
{
base.update(time, location);
@ -425,7 +510,7 @@ namespace CustomNPCFramework.Framework.NPCS
{
this.characterRenderer.setAnimation(AnimationKeys.swimmingKey);
this.characterRenderer.setDirection(this.facingDirection);
this.characterRenderer.draw(b,this,this.getLocalPosition(Game1.viewport) + new Vector2((float)(Game1.tileSize / 2), (float)(Game1.tileSize + Game1.tileSize / 4 + this.yJumpOffset * 2)) + (this.shakeTimer > 0 ? new Vector2((float)Game1.random.Next(-1, 2), (float)Game1.random.Next(-1, 2)) : Vector2.Zero) - new Vector2(0.0f, this.yOffset), new Microsoft.Xna.Framework.Rectangle?(new Microsoft.Xna.Framework.Rectangle(this.sprite.SourceRect.X, this.sprite.SourceRect.Y, this.sprite.SourceRect.Width, this.sprite.SourceRect.Height / 2 - (int)((double)this.yOffset / (double)Game1.pixelZoom))), Color.White, this.rotation, new Vector2((float)(Game1.tileSize / 2), (float)(Game1.tileSize * 3 / 2)) / 4f, Math.Max(0.2f, this.scale) * (float)Game1.pixelZoom, this.flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, Math.Max(0.0f, this.drawOnTop ? 0.991f : (float)this.getStandingY() / 10000f));
this.characterRenderer.draw(b,this,this.getLocalPosition(Game1.viewport) + new Vector2((float)(Game1.tileSize / 2), (float)(Game1.tileSize + Game1.tileSize / 4 + this.yJumpOffset * 2)) + (this.shakeTimer > 0 ? new Vector2((float)Game1.random.Next(-1, 2), (float)Game1.random.Next(-1, 2)) : Vector2.Zero) - new Vector2(0.0f, this.yOffset), new Microsoft.Xna.Framework.Rectangle?(new Microsoft.Xna.Framework.Rectangle(this.sprite.SourceRect.X, this.sprite.SourceRect.Y, this.sprite.SourceRect.Width, this.sprite.SourceRect.Height / 2 - (int)((double)this.yOffset / (double)Game1.pixelZoom))), Color.White, this.rotation, new Vector2((float)(Game1.tileSize / 2), (float)(Game1.tileSize * 3 / 2)) / 4f, Math.Max(0.2f, this.scale) * (float)Game1.pixelZoom, this.flip ? SpriteEffects.FlipHorizontally : SpriteEffects.None, Math.Max(0.0f, (float)this.getStandingY() / 10000f));
//Vector2 localPosition = this.getLocalPosition(Game1.viewport);
//b.Draw(Game1.staminaRect, new Microsoft.Xna.Framework.Rectangle((int)localPosition.X + (int)this.yOffset + Game1.pixelZoom * 2, (int)localPosition.Y - 32 * Game1.pixelZoom + this.sprite.SourceRect.Height * Game1.pixelZoom + Game1.tileSize * 3 / 4 + this.yJumpOffset * 2 - (int)this.yOffset, this.sprite.SourceRect.Width * Game1.pixelZoom - (int)this.yOffset * 2 - Game1.pixelZoom * 4, Game1.pixelZoom), new Microsoft.Xna.Framework.Rectangle?(Game1.staminaRect.Bounds), Color.White * 0.75f, 0.0f, Vector2.Zero, SpriteEffects.None, (float)((double)this.getStandingY() / 10000.0 + 1.0 / 1000.0));
}
@ -530,6 +615,11 @@ 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>
/// <param name="b"></param>
/// <param name="alpha"></param>
public override void draw(SpriteBatch b, float alpha = 1f)
{
if (this.characterRenderer == null)

View File

@ -1,4 +1,5 @@
using CustomNPCFramework.Framework.NPCS;
using Microsoft.Xna.Framework;
using StardewValley;
using System;
using System.Collections.Generic;
@ -32,6 +33,16 @@ namespace CustomNPCFramework.Framework.Utilities
{
this.moddedNPCS.Add(npc);
npc.defaultLocation = loc;
npc.currentLocation = loc;
loc.addCharacter(npc);
}
public void addNewNPCToLocation(GameLocation loc, ExtendedNPC npc, Vector2 tilePosition)
{
this.moddedNPCS.Add(npc);
npc.defaultLocation = loc;
npc.currentLocation = loc;
npc.position = tilePosition*Game1.tileSize;
loc.addCharacter(npc);
}

View File

@ -21,10 +21,10 @@
"downString": "FBodyBaseDown"
},
"movingAssetPaths": {
"leftString": "FBodyBaseLeft",
"rightString": "FBodyBaseRight",
"upString": "FBodyBaseUp",
"downString": "FBodyBaseDown"
"leftString": "FBodyBaseMovingLeft",
"rightString": "FBodyBaseMovingRight",
"upString": "FBodyBaseMovingUp",
"downString": "FBodyBaseMovingDown"
},
"sittingAssetPaths": {
"leftString": "FBodyBaseLeft",