LADXHD/InGame/GameObjects/NPCs/ObjPerson.cs
2023-12-14 17:21:22 -05:00

168 lines
6.3 KiB
C#

using System.Globalization;
using Microsoft.Xna.Framework;
using ProjectZ.InGame.GameObjects.Base;
using ProjectZ.InGame.GameObjects.Base.CObjects;
using ProjectZ.InGame.GameObjects.Base.Components;
using ProjectZ.InGame.Map;
using ProjectZ.InGame.SaveLoad;
using ProjectZ.InGame.Things;
namespace ProjectZ.InGame.GameObjects.NPCs
{
// @TODO: should probably be replaced with ObjPersonNew in most places
internal class ObjPerson : GameObject
{
public BodyComponent Body;
public readonly Animator Animator;
private readonly string _personId;
private string _currentAnimation;
private int _lastDirection = -1;
private bool _directionMode = true;
private bool _isMoving;
private float _movementSpeed;
private float _movementCounter;
private Vector2 _startPosition;
private Vector2 _endPosition;
public ObjPerson() : base("person") { }
public ObjPerson(Map.Map map, int posX, int posY, string personId, Rectangle bodyRectangle, Vector2 offset, string animationName) : base(map)
{
if (string.IsNullOrEmpty(personId))
{
IsDead = true;
return;
}
EntityPosition = new CPosition(posX + 8, posY + 16, 0);
EntitySize = new Rectangle(-bodyRectangle.Width / 2, -bodyRectangle.Height, bodyRectangle.Width, bodyRectangle.Height);
_personId = personId;
Animator = AnimatorSaveLoad.LoadAnimator("NPCs/" + _personId);
if (Animator == null)
{
IsDead = true;
return;
}
var sprite = new CSprite(EntityPosition);
var animationComponent = new AnimationComponent(Animator, sprite, new Vector2(
-Animator.CurrentAnimation.AnimationWidth / 2f + offset.X,
-Animator.CurrentAnimation.AnimationHeight + offset.Y));
Body = new BodyComponent(EntityPosition,
-bodyRectangle.Width / 2, -bodyRectangle.Height, bodyRectangle.Width, bodyRectangle.Height, bodyRectangle.Height)
{
Gravity = -0.15f
};
if (!string.IsNullOrEmpty(animationName))
{
_directionMode = false;
Animator.Play(animationName);
}
AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(KeyChanged));
AddComponent(BodyComponent.Index, Body);
AddComponent(CollisionComponent.Index, new BodyCollisionComponent(Body, Values.CollisionTypes.Normal | Values.CollisionTypes.PushIgnore));
AddComponent(InteractComponent.Index, new InteractComponent(Body.BodyBox, Interact));
AddComponent(AnimationComponent.Index, animationComponent);
AddComponent(UpdateComponent.Index, new UpdateComponent(Update));
AddComponent(DrawComponent.Index, new BodyDrawComponent(Body, sprite, Values.LayerPlayer));
AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite));
}
private void Update()
{
if (_isMoving)
{
_movementCounter += Game1.DeltaTime * _movementSpeed;
// finished moving?
if (_movementCounter >= 1000)
{
EntityPosition.Set(_endPosition);
_isMoving = false;
}
else
{
var newPosition = Vector2.Lerp(_startPosition, _endPosition, _movementCounter / 1000);
EntityPosition.Set(newPosition);
}
}
if (_directionMode)
{
var playerDistance = new Vector2(
MapManager.ObjLink.EntityPosition.X - (EntityPosition.X),
MapManager.ObjLink.EntityPosition.Y - (EntityPosition.Y - 4));
var dir = 3;
// rotate in the direction of the player
if (playerDistance.Length() < 32)
dir = AnimationHelper.GetDirection(playerDistance);
if (_lastDirection != dir)
{
// look at the player
Animator.Play("stand_" + dir);
_lastDirection = dir;
}
}
// finished playing
if (_currentAnimation != null && !Animator.IsPlaying)
{
_currentAnimation = null;
Game1.GameManager.SaveManager.SetString(_personId + "Finished", "1");
}
}
private bool Interact()
{
Game1.GameManager.StartDialogPath(_personId);
return true;
}
private void KeyChanged()
{
// start new animation?
var animationString = _personId + "Animation";
var animationValues = Game1.GameManager.SaveManager.GetString(animationString);
if (animationValues != null)
{
_currentAnimation = animationValues.ToLower();
Animator.Play(_currentAnimation);
Game1.GameManager.SaveManager.RemoveString(animationString);
}
// start moving?
var moveString = _personId + "Move";
var moveValue = Game1.GameManager.SaveManager.GetString(moveString);
if (moveValue != null)
{
// offsetX, offsetY, movementSpeed
var split = moveValue.Split(',');
if (split.Length == 3)
{
var offsetX = int.Parse(split[0]);
var offsetY = int.Parse(split[1]);
var speed = float.Parse(split[2], CultureInfo.InvariantCulture);
_startPosition = EntityPosition.Position;
_endPosition = _startPosition + new Vector2(offsetX, offsetY);
_movementSpeed = speed;
_isMoving = true;
_movementCounter = 0;
}
Game1.GameManager.SaveManager.RemoveString(moveString);
}
}
}
}