LADXHD/InGame/GameObjects/Things/ObjCrystal.cs

103 lines
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.Things;
namespace ProjectZ.InGame.GameObjects.Things
{
internal class ObjCrystal : GameObject
{
private readonly CBox _hittableBoxSmall;
private readonly Color _lightColor;
private readonly string _dialogPath;
private readonly bool _isHardCrystal;
public ObjCrystal(Map.Map map, int posX, int posY, string spriteId, int color, bool hardCrystal, string dialogPath) : base(map, spriteId)
{
var sprite = Resources.GetSprite(spriteId);
EntityPosition = new CPosition(posX + 8, posY + 16, 0);
EntitySize = new Rectangle(-40, -8 - 40, 80, 80);
if (color == 0)
_lightColor = new Color(240, 100, 255);
else if (color == 1)
_lightColor = new Color(255, 255, 255) * 0.25f;
_isHardCrystal = hardCrystal;
_dialogPath = dialogPath;
var box = new CBox(posX, posY + 16 - 12, 0, 16, 12, 16);
var hittableBox = new CBox(EntityPosition, -7, -15, 0, 14, 13, 8);
_hittableBoxSmall = new CBox(EntityPosition, -6, -13, 0, 12, 10, 8, true);
if (!string.IsNullOrEmpty(_dialogPath))
AddComponent(PushableComponent.Index, new PushableComponent(box, OnPush) { InertiaTime = 50 });
AddComponent(CollisionComponent.Index, new BoxCollisionComponent(box, Values.CollisionTypes.Normal));
AddComponent(HittableComponent.Index, new HittableComponent(hittableBox, OnHit));
AddComponent(DrawComponent.Index, new DrawSpriteComponent(spriteId, EntityPosition, new Vector2(-8, -16), Values.LayerPlayer));
AddComponent(LightDrawComponent.Index, new LightDrawComponent(DrawLight));
}
private bool OnPush(Vector2 direction, PushableComponent.PushType pushType)
{
if (pushType == PushableComponent.PushType.Impact)
return false;
Game1.GameManager.StartDialogPath(_dialogPath);
return false;
}
private void DrawLight(SpriteBatch spriteBatch)
{
DrawHelper.DrawLight(spriteBatch, new Rectangle((int)EntityPosition.X - 40, (int)EntityPosition.Y - 8 - 40, 80, 80), _lightColor);
}
private Values.HitCollision OnHit(GameObject gameObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower)
{
if ((_isHardCrystal && damageType != HitType.PegasusBootsSword) || (damageType & HitType.SwordHold) != 0 || damageType == HitType.Hookshot)
return Values.HitCollision.None;
// this is really stupid
// for the sword attacks a smaller hitbox is used
if ((damageType & HitType.Sword) != 0 &&
gameObject is ObjLink player && !player.IsPoking)
{
var collidingRec = player.SwordDamageBox.Rectangle().GetIntersection(_hittableBoxSmall.Box.Rectangle());
var collidingArea = collidingRec.Width * collidingRec.Height;
if (collidingArea < 16)
return Values.HitCollision.None;
}
Game1.GameManager.PlaySoundEffect("D378-09-09");
// remove this object from the map
Map.Objects.DeleteObjects.Add(this);
// spawn small particle stones
var mult = damageType == HitType.PegasusBootsSword ? 1.0f : 0.25f;
var velZ = 0.5f;
var diff = 200f;
var vector0 = new Vector3(-1, -1, 0) * Game1.RandomNumber.Next(50, 75) / diff + new Vector3(direction * mult, velZ);
var vector1 = new Vector3(-1, 0, 0) * Game1.RandomNumber.Next(50, 75) / diff + new Vector3(direction * mult, velZ);
var vector2 = new Vector3(1, -1, 0) * Game1.RandomNumber.Next(50, 75) / diff + new Vector3(direction * mult, velZ);
var vector3 = new Vector3(1, 0, 0) * Game1.RandomNumber.Next(50, 75) / diff + new Vector3(direction * mult, velZ);
var stone0 = new ObjSmallStone(Map, (int)EntityPosition.X + 2, (int)EntityPosition.Y - 10, Game1.RandomNumber.Next(4, 8), vector0);
var stone1 = new ObjSmallStone(Map, (int)EntityPosition.X + 2, (int)EntityPosition.Y - 6, Game1.RandomNumber.Next(4, 8), vector1);
var stone2 = new ObjSmallStone(Map, (int)EntityPosition.X + 6, (int)EntityPosition.Y - 10, Game1.RandomNumber.Next(4, 8), vector2);
var stone3 = new ObjSmallStone(Map, (int)EntityPosition.X + 6, (int)EntityPosition.Y - 6, Game1.RandomNumber.Next(4, 8), vector3);
Map.Objects.SpawnObject(stone0);
Map.Objects.SpawnObject(stone1);
Map.Objects.SpawnObject(stone2);
Map.Objects.SpawnObject(stone3);
return Values.HitCollision.Blocking;
}
}
}