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

152 lines
5.8 KiB
C#

using System;
using Microsoft.Xna.Framework;
using ProjectZ.InGame.GameObjects.Base;
using ProjectZ.InGame.GameObjects.Base.CObjects;
using ProjectZ.InGame.GameObjects.Base.Components;
using ProjectZ.InGame.GameObjects.Base.Components.AI;
using ProjectZ.InGame.Things;
namespace ProjectZ.InGame.GameObjects.NPCs
{
internal class ObjBallGame : GameObject
{
private readonly Rectangle _shadowSourceRectangle = new Rectangle(0, 0, 65, 66);
private readonly DrawShadowSpriteComponent _shadowComponent;
private readonly AiComponent _aiComponent;
private readonly ObjPersonNew _firstPerson;
private readonly ObjPersonNew _secondPerson;
private readonly Vector2 _ballStart;
private readonly Vector2 _ballEnd;
private float _throwCount;
private int _throwTime = 650;
private int _throwHeight = 12;
private int _throwDirection = 1;
public ObjBallGame() : base("green_child") { }
public ObjBallGame(Map.Map map, int posX, int posY, string spawnCondition) : base(map)
{
// check if the entity should get spawned
if (!string.IsNullOrEmpty(spawnCondition))
{
var condition = SaveLoad.SaveCondition.GetConditionNode(spawnCondition);
if (!condition.Check())
{
IsDead = true;
return;
}
}
EntityPosition = new CPosition(posX, posY + 16, 0);
EntitySize = new Rectangle(-8, -16, 16, 16);
_firstPerson = new ObjPersonNew(Map, posX, posY, null, "npc_boy_left", "npc_boy_ball_left", null, new Rectangle(0, 0, 14, 10));
Map.Objects.SpawnObject(_firstPerson);
_secondPerson = new ObjPersonNew(Map, posX + 48, posY, null, "npc_boy_right", "npc_boy_ball_right", null, new Rectangle(0, 0, 14, 10));
Map.Objects.SpawnObject(_secondPerson);
var sourceRectangle = new Rectangle(338, 10, 6, 6);
_ballStart = new Vector2(posX + 13, posY + 15);
_ballEnd = new Vector2(posX + 64 - 13, posY + 15);
var statePreThrow = new AiState();
statePreThrow.Trigger.Add(new AiTriggerRandomTime(() => _aiComponent.ChangeState("jumping"), 100, 200));
var stateJump = new AiState(UpdateJump);
stateJump.Trigger.Add(new AiTriggerRandomTime(ToThrowJump, 500, 750));
var stateJumpThrow = new AiState(UpdateJumpingThrowing);
stateJumpThrow.Trigger.Add(new AiTriggerRandomTime(ToThrow, 50, 200));
var stateThrow = new AiState(UpdateThrow);
_aiComponent = new AiComponent();
_aiComponent.States.Add("preThrow", statePreThrow);
_aiComponent.States.Add("jumping", stateJump);
_aiComponent.States.Add("throwJump", stateJumpThrow);
_aiComponent.States.Add("throw", stateThrow);
_aiComponent.ChangeState("throw");
AddComponent(AiComponent.Index, _aiComponent);
var sprite = new CSprite(Resources.SprNpCs, EntityPosition,
sourceRectangle, new Vector2(-sourceRectangle.Width / 2, -sourceRectangle.Height));
AddComponent(DrawComponent.Index, new DrawCSpriteComponent(sprite, Values.LayerPlayer));
_shadowComponent = new DrawShadowSpriteComponent(
Resources.SprShadow, EntityPosition, _shadowSourceRectangle,
new Vector2(-4, -2), 1.0f, 0.0f);
_shadowComponent.Width = 8;
_shadowComponent.Height = 4;
AddComponent(DrawShadowComponent.Index, _shadowComponent);
}
private void UpdateJump()
{
if (_throwDirection < 0 && _firstPerson.Body.IsGrounded)
_firstPerson.Body.Velocity.Z = 1f;
if (_throwDirection > 0 && _secondPerson.Body.IsGrounded)
_secondPerson.Body.Velocity.Z = 1f;
}
private void UpdateJumpingThrowing()
{
UpdateJump();
UpdateThrow();
}
private void UpdateThrow()
{
_throwCount += Game1.DeltaTime * _throwDirection;
if (_throwCount > _throwTime)
{
_throwDirection = -_throwDirection;
_throwCount = _throwTime;
_aiComponent.ChangeState("preThrow");
}
else if (_throwCount < 0)
{
_throwDirection = -_throwDirection;
_throwCount = 0;
_aiComponent.ChangeState("preThrow");
}
var throwState = _throwCount / (float)_throwTime;
var newPosition = Vector2.Lerp(_ballStart, _ballEnd, throwState);
EntityPosition.Set(newPosition);
EntityPosition.Z = 3 + (float)Math.Sin(throwState * Math.PI) * _throwHeight;
_shadowComponent.Color = Color.White * (1 - (float)Math.Sin(throwState * Math.PI) * 0.5f);
}
private void ToThrowJump()
{
if (_throwDirection < 0)
{
_secondPerson.Animator.Play("throw");
StartThrow();
}
else
{
_firstPerson.Animator.Play("throw");
StartThrow();
}
_aiComponent.ChangeState("throwJump");
}
private void ToThrow()
{
_aiComponent.ChangeState("throw");
}
private void StartThrow()
{
var random = Game1.RandomNumber.Next(100, 200) / 100f;
_throwTime = (int)(random * 300);
_throwHeight = (int)(random * 6);
_throwCount = _throwCount > 0 ? _throwTime : 0;
}
}
}