LADXHD/InGame/GameObjects/NPCs/ObjShopKeeper.cs

187 lines
7.5 KiB
C#
Raw Normal View History

2023-12-14 22:21:22 +00:00
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
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
{
internal class ObjShopkeeper : GameObject
{
private readonly BodyComponent _body;
private readonly BodyDrawComponent _bodyDrawComponent;
private readonly Animator _animator;
private readonly Rectangle _thunderTop = new Rectangle(444, 118, 14, 16);
private readonly Rectangle _thunderBottom = new Rectangle(476, 107, 32, 32);
private float _directionChange;
private int _lastDirection = -1;
private bool _isHoldingItem;
private float _punishCount;
private bool _punishMode;
private bool _punishDialog;
private bool _isPunishing = true;
private bool _showThunder;
private bool _soundEffect;
public ObjShopkeeper() : base("shopkeeper") { }
public ObjShopkeeper(Map.Map map, int posX, int posY) : base(map)
{
EntityPosition = new CPosition(posX + 8, posY + 16, 0);
EntitySize = new Rectangle(-8, -16, 16, 16);
_animator = AnimatorSaveLoad.LoadAnimator("NPCs/shopkeeper");
// player stole from the shop the last time?
_punishMode = Game1.GameManager.SaveManager.GetString("stoleItem") == "1";
if (_punishMode)
{
EntityPosition = new CPosition(posX + 8 - 39, posY + 16 - 32, 0);
_animator.Play("stand_3");
}
var sprite = new CSprite(EntityPosition);
var animationComponent = new AnimationComponent(_animator, sprite, new Vector2(-8, -16));
_body = new BodyComponent(EntityPosition, -7, -10, 14, 10, 8);
_bodyDrawComponent = new BodyDrawComponent(_body, sprite, 1);
var interactionBox = new CBox(EntityPosition, -7, -14, 14, 14, 8);
AddComponent(KeyChangeListenerComponent.Index, new KeyChangeListenerComponent(OnKeyChange));
AddComponent(BodyComponent.Index, _body);
AddComponent(CollisionComponent.Index, new BodyCollisionComponent(_body, Values.CollisionTypes.Normal));
AddComponent(InteractComponent.Index, new InteractComponent(interactionBox, OnInteract));
AddComponent(BaseAnimationComponent.Index, animationComponent);
AddComponent(UpdateComponent.Index, new UpdateComponent(Update));
AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerPlayer, EntityPosition));
AddComponent(DrawShadowComponent.Index, new DrawShadowCSpriteComponent(sprite));
}
public override void Init()
{
if (_punishMode)
MapManager.ObjLink.NextMapPositionEnd =
new Vector2(MapManager.ObjLink.NextMapPositionEnd.Value.X, MapManager.ObjLink.NextMapPositionEnd.Value.Y - 5);
}
private void Update()
{
if (!_punishMode)
UpdateNormal();
else
UpdatePunishMode();
}
private void UpdateNormal()
{
var playerDistance = new Vector2(
MapManager.ObjLink.EntityPosition.X - (EntityPosition.X),
MapManager.ObjLink.EntityPosition.Y - (EntityPosition.Y - 4));
// rotate in the direction of the player
var dir = AnimationHelper.GetDirection(playerDistance);
if (_lastDirection != dir)
{
_directionChange -= Game1.DeltaTime;
if (_directionChange <= 0)
{
// 50/50 chance of making the next direction change be fast or slow
_directionChange = Game1.RandomNumber.Next(0, 2) == 0 ?
Game1.RandomNumber.Next(0, 250) : Game1.RandomNumber.Next(1500, 2500);
// look at the player
_animator.Play("stand_" + dir);
_lastDirection = dir;
}
}
var blockPath = _isHoldingItem && (_lastDirection == 0 || _lastDirection == 3);
Game1.GameManager.SaveManager.SetString("isWatched", blockPath ? "1" : "0");
}
private void UpdatePunishMode()
{
if (Game1.GameManager.InGameOverlay.TextboxOverlay.IsOpen)
return;
if (_showThunder)
{
_punishCount += Game1.DeltaTime;
Game1.GameManager.UseShockEffect = _punishCount % 200 < 100;
if (!_soundEffect)
{
_soundEffect = true;
Game1.GameManager.PlaySoundEffect("D378-38-26");
}
}
// show the dialog
if (!_punishDialog && !MapManager.ObjLink.IsTransitioning)
{
Game1.GameManager.StartDialogPath("itemShop_revenge");
_punishDialog = true;
_showThunder = true;
}
if (_punishCount >= 3200 && _isPunishing)
{
_isPunishing = false;
_showThunder = false;
Game1.GameManager.SaveManager.SetString("stoleItem", "0");
Game1.GameManager.UseShockEffect = false;
// make sure the player actually dies
Game1.GameManager.InflictDamage(Game1.GameManager.MaxHearths * 4 * 2);
Game1.GameManager.RemoveItem("potion", 1);
}
if (MapManager.ObjLink.IsTransitioning || _showThunder)
MapManager.ObjLink.UpdatePlayer = false;
}
private void Draw(SpriteBatch spriteBatch)
{
// draw the shopkeeper
_bodyDrawComponent.Draw(spriteBatch);
// draw the thunder effect
if (!_showThunder)
return;
var offsetY = -5;
var animationOffset = _punishCount % 133 < 66;
if (_punishCount > 0)
spriteBatch.Draw(Resources.SprNpCs, new Vector2(EntityPosition.X - 8, EntityPosition.Y + offsetY),
new Rectangle(_thunderTop.X + (animationOffset ? _thunderTop.Width + 1 : 0), _thunderTop.Y, _thunderTop.Width, _thunderTop.Height), Color.White);
if (_punishCount > 66)
spriteBatch.Draw(Resources.SprNpCs, new Vector2(EntityPosition.X - 8, EntityPosition.Y + offsetY + 16),
new Rectangle(_thunderTop.X + (animationOffset ? _thunderTop.Width + 1 : 0), _thunderTop.Y, _thunderTop.Width, _thunderTop.Height), Color.White);
if (_punishCount > 133)
spriteBatch.Draw(Resources.SprNpCs, new Vector2(EntityPosition.X - 17, EntityPosition.Y + offsetY + 32),
new Rectangle(_thunderBottom.X + (animationOffset ? _thunderBottom.Width + 1 : 0), _thunderBottom.Y, _thunderBottom.Width, _thunderBottom.Height), Color.White);
}
private void OnKeyChange()
{
var value = Game1.GameManager.SaveManager.GetString("holdItem");
_isHoldingItem = value == "1";
}
private bool OnInteract()
{
Game1.GameManager.StartDialogPath("shopkeeper");
return true;
}
}
}