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

142 lines
5.7 KiB
C#

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.GameObjects.Base.Components.AI;
using ProjectZ.InGame.GameObjects.Things;
using ProjectZ.InGame.Things;
namespace ProjectZ.InGame.GameObjects.Dungeon
{
class ObjDungeonPillar : GameObject
{
private readonly BoxCollisionComponent _collisionComponent;
private readonly AiComponent _aiComponent;
private readonly CSprite[] _sprites = new CSprite[5];
private readonly string[] _spriteIds = { "pillar_bottom", "pillar_middle", "pillar_middle", "pillar_middle", "pillar_top" };
private string _saveKey;
private int _pillarIndex = 5;
private float _fallCount;
private float _particleCounter;
private float _stoneCounter;
private Vector2 _basePosition;
public ObjDungeonPillar() : base("pillar_bottom") { }
public ObjDungeonPillar(Map.Map map, int posX, int posY, string saveKey) : base(map)
{
_saveKey = saveKey;
if (!string.IsNullOrEmpty(_saveKey))
{
var strKeyState = Game1.GameManager.SaveManager.GetString(_saveKey);
if (strKeyState != null && strKeyState == "1")
{
IsDead = true;
return;
}
}
for (var i = 0; i < 5; i++)
_sprites[i] = new CSprite(_spriteIds[i], new CPosition(posX, posY - i * 16, 0), Vector2.Zero);
_basePosition = new Vector2(posX, posY);
EntityPosition = new CPosition(posX + 8, posY + 14, 0);
EntitySize = new Rectangle(-8, -78, 16, 80);
var stateIdle = new AiState();
var stateShaking = new AiState { Init = InitShake };
stateShaking.Trigger.Add(new AiTriggerCountdown(1300, null, () => _aiComponent.ChangeState("falling")));
var stateFalling = new AiState(UpdateFalling);
_aiComponent = new AiComponent();
_aiComponent.States.Add("idle", stateIdle);
_aiComponent.States.Add("shaking", stateShaking);
_aiComponent.States.Add("falling", stateFalling);
_aiComponent.ChangeState("idle");
var collisionBox = new CBox(posX + 1, posY + 4, 0, 14, 12, 16);
var hitBox = new CBox(posX, posY - 8, 0, 16, 24, 16);
AddComponent(AiComponent.Index, _aiComponent);
AddComponent(HittableComponent.Index, new HittableComponent(hitBox, OnHit));
AddComponent(CollisionComponent.Index, _collisionComponent = new BoxCollisionComponent(collisionBox, Values.CollisionTypes.Normal));
AddComponent(DrawComponent.Index, new DrawComponent(Draw, Values.LayerPlayer, EntityPosition));
}
private void InitShake()
{
Game1.GameManager.ShakeScreen(1300 + 5 * 500, 3, 2, 5, 2.5f);
Game1.GameManager.PlaySoundEffect("D360-11-0B");
Game1.GameManager.PlaySoundEffect("D378-37-25");
}
private void UpdateFalling()
{
_fallCount += Game1.DeltaTime;
_particleCounter += Game1.DeltaTime;
_stoneCounter -= Game1.DeltaTime;
if (_fallCount > 500)
{
_fallCount -= 500;
_pillarIndex--;
// remove the pillar?
if (_pillarIndex <= 0)
{
// we set the key here so that the collapse sequence will be shown after the pillar is gone
// this can lead to situations where the player changes the map while the pillar is collapsing and the state will not get saved
Game1.GameManager.SaveManager.SetString(_saveKey, "1");
Map.Objects.DeleteObjects.Add(this);
}
}
if (_stoneCounter < 0)
{
_stoneCounter = 850;
var stonePosX = (int)_basePosition.X + Game1.RandomNumber.Next(0, 48) - 24;
var stonePosY = (int)_basePosition.Y + Game1.RandomNumber.Next(0, 48) - 24;
Map.Objects.SpawnObject(new ObjSmallStone(Map, stonePosX, stonePosY, 64, new Vector3(0, 0, 0), true));
}
// spawn particles
if (_particleCounter > 100)
{
_particleCounter -= 100;
var positionX = (int)_basePosition.X + Game1.RandomNumber.Next(0, 28) - 14;
var positionY = (int)_basePosition.Y + Game1.RandomNumber.Next(0, 8) - 2;
Map.Objects.SpawnObject(new ObjAnimator(Map, positionX, positionY, Values.LayerTop, "Particles/spawn", "run", true));
}
}
private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType type, int damage, bool pieceOfPower)
{
if (originObject.GetType() == typeof(ObjBall) && _aiComponent.CurrentStateId == "idle")
{
_aiComponent.ChangeState("shaking");
return Values.HitCollision.Blocking;
}
return Values.HitCollision.None;
}
private void Draw(SpriteBatch spriteBatch)
{
for (var i = 0; i < _pillarIndex; i++)
{
_sprites[5 - _pillarIndex + i].Position.Set(new Vector2(_basePosition.X, _basePosition.Y - i * 16));
_sprites[5 - _pillarIndex + i].Draw(spriteBatch);
}
}
}
}