mirror of
https://github.com/Phantop/LADXHD.git
synced 2024-11-01 04:14:22 +00:00
571 lines
21 KiB
C#
571 lines
21 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.GameObjects.Enemies;
|
||
|
using ProjectZ.InGame.GameObjects.MidBoss;
|
||
|
using ProjectZ.InGame.GameObjects.Things;
|
||
|
using ProjectZ.InGame.Map;
|
||
|
using ProjectZ.InGame.SaveLoad;
|
||
|
using ProjectZ.InGame.Things;
|
||
|
|
||
|
namespace ProjectZ.InGame.GameObjects.Bosses
|
||
|
{
|
||
|
class BossEvilEagle : GameObject
|
||
|
{
|
||
|
private MBossGrimCreeper _grimCreeper;
|
||
|
private MBossGrimCreeperFly _creeperFly0;
|
||
|
private MBossGrimCreeperFly _creeperFly1;
|
||
|
|
||
|
private readonly CSprite _sprite;
|
||
|
private readonly BodyComponent _body;
|
||
|
private readonly AiComponent _aiComponent;
|
||
|
private readonly Animator _animator;
|
||
|
private readonly AiDamageState _damageState;
|
||
|
private readonly DamageFieldComponent _damageComponent;
|
||
|
private readonly HittableComponent _hittableComponent;
|
||
|
|
||
|
private readonly Vector2 _startPosition;
|
||
|
|
||
|
private readonly string _saveKey;
|
||
|
|
||
|
private Vector2 _slowStart;
|
||
|
private float _slowCounter;
|
||
|
private float _transparency = 0;
|
||
|
|
||
|
private int _spawnIndex;
|
||
|
private int _direction;
|
||
|
|
||
|
private const float FlySpeed = 2;
|
||
|
private const int Lives = 12;
|
||
|
|
||
|
private Vector2 _wingStartPosition;
|
||
|
private Vector2 _wingEndPosition;
|
||
|
private float _wingCounter;
|
||
|
private float _featherCounter;
|
||
|
private const float WingTime = 700;
|
||
|
|
||
|
private bool _featherAttack;
|
||
|
private bool _playedIntro;
|
||
|
private bool _introSound;
|
||
|
|
||
|
public BossEvilEagle() : base("evil eagle") { }
|
||
|
|
||
|
public BossEvilEagle(Map.Map map, int posX, int posY, string saveKey) : base(map)
|
||
|
{
|
||
|
Tags = Values.GameObjectTag.Enemy;
|
||
|
|
||
|
EntityPosition = new CPosition(posX, posY, 0);
|
||
|
EntitySize = new Rectangle(-32, -32, 64, 64);
|
||
|
|
||
|
_startPosition = EntityPosition.Position;
|
||
|
|
||
|
_saveKey = saveKey;
|
||
|
|
||
|
if (!string.IsNullOrWhiteSpace(_saveKey) && Game1.GameManager.SaveManager.GetString(_saveKey) == "1")
|
||
|
{
|
||
|
// respawn the heart if the player died after he killed the boss without collecting the heart
|
||
|
SpawnHeart();
|
||
|
|
||
|
IsDead = true;
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
_animator = AnimatorSaveLoad.LoadAnimator("Nightmares/evil eagle");
|
||
|
_animator.Play("glide_-1");
|
||
|
|
||
|
_sprite = new CSprite(EntityPosition) { Color = Color.Transparent };
|
||
|
|
||
|
var animationComponent = new AnimationComponent(_animator, _sprite, Vector2.Zero);
|
||
|
|
||
|
_body = new BodyComponent(EntityPosition, -8, -16, 16, 16, 8)
|
||
|
{
|
||
|
CollisionTypes = Values.CollisionTypes.None,
|
||
|
Bounciness = 0.25f,
|
||
|
Drag = 1.0f,
|
||
|
DragAir = 1.0f,
|
||
|
IgnoresZ = true,
|
||
|
IsGrounded = false
|
||
|
};
|
||
|
|
||
|
var hittableRectangle = new CBox(EntityPosition, -8, -16, 16, 16, 8);
|
||
|
var damageCollider = new CBox(EntityPosition, -8, -16, 16, 16, 8);
|
||
|
|
||
|
var stateIdle = new AiState(UpdateIdle) { Init = InitIdle };
|
||
|
var stateSpawnDelay = new AiState();
|
||
|
stateSpawnDelay.Trigger.Add(new AiTriggerCountdown(750, null, () => _aiComponent.ChangeState("spawning")));
|
||
|
var stateSpawning = new AiState(UpdateSpawning) { Init = InitSpawning };
|
||
|
var statePreJump = new AiState();
|
||
|
statePreJump.Trigger.Add(new AiTriggerCountdown(1000, null, () => _aiComponent.ChangeState("grimSaddle")));
|
||
|
var stateGrimSaddle = new AiState(UpdateGrimSaddle) { Init = InitGrimSaddle };
|
||
|
var stateSaddled = new AiState(UpdateSaddled);
|
||
|
var stateAttack = new AiState(UpdateAttack) { Init = InitAttack };
|
||
|
var stateDamaged = new AiState(UpdateDamaged);
|
||
|
stateDamaged.Trigger.Add(new AiTriggerCountdown(500, null, FlyUp));
|
||
|
var stateFlyUp = new AiState(UpdateFlyUp) { Init = InitFlyUp };
|
||
|
var stateAttackEnter = new AiState(UpdateWingAttackEnter) { Init = InitWingAttackEnter };
|
||
|
var stateFeatherAttack = new AiState(UpdateWingAttack) { Init = InitWingAttack };
|
||
|
var statePreAttack = new AiState() { Init = InitPreAttack };
|
||
|
statePreAttack.Trigger.Add(new AiTriggerCountdown(800, null, () => _aiComponent.ChangeState("grabAttack")));
|
||
|
var stateGrab = new AiState(UpdateAttackGrab) { Init = InitGrab };
|
||
|
var stateLeave = new AiState(UpdateLeave) { Init = InitLeave };
|
||
|
var stateGone = new AiState();
|
||
|
stateGone.Trigger.Add(new AiTriggerCountdown(100, null, ToAttack));
|
||
|
|
||
|
_aiComponent = new AiComponent();
|
||
|
_aiComponent.Trigger.Add(new AiTriggerUpdate(UpdateVisibility));
|
||
|
|
||
|
_aiComponent.States.Add("idle", stateIdle);
|
||
|
_aiComponent.States.Add("spawnDelay", stateSpawnDelay);
|
||
|
_aiComponent.States.Add("spawning", stateSpawning);
|
||
|
_aiComponent.States.Add("grimPreJump", statePreJump);
|
||
|
_aiComponent.States.Add("grimSaddle", stateGrimSaddle);
|
||
|
_aiComponent.States.Add("saddled", stateSaddled);
|
||
|
_aiComponent.States.Add("attack", stateAttack);
|
||
|
_aiComponent.States.Add("damaged", stateDamaged);
|
||
|
_aiComponent.States.Add("flyup", stateFlyUp);
|
||
|
_aiComponent.States.Add("attackEnter", stateAttackEnter);
|
||
|
_aiComponent.States.Add("featherAttack", stateFeatherAttack);
|
||
|
_aiComponent.States.Add("preAttack", statePreAttack);
|
||
|
_aiComponent.States.Add("grabAttack", stateGrab);
|
||
|
_aiComponent.States.Add("leave", stateLeave);
|
||
|
_aiComponent.States.Add("gone", stateGone);
|
||
|
|
||
|
_damageState = new AiDamageState(this, _body, _aiComponent, _sprite, Lives, false, false, AiDamageState.BlinkTime * 2 * 10) { ExplosionOffsetY = 8 };
|
||
|
_damageState.AddBossDamageState(OnDeath);
|
||
|
|
||
|
AddComponent(AiComponent.Index, _aiComponent);
|
||
|
AddComponent(DamageFieldComponent.Index, _damageComponent = new DamageFieldComponent(damageCollider, HitType.Enemy, 8));
|
||
|
AddComponent(HittableComponent.Index, _hittableComponent = new HittableComponent(hittableRectangle, OnHit));
|
||
|
AddComponent(BaseAnimationComponent.Index, animationComponent);
|
||
|
AddComponent(BodyComponent.Index, _body);
|
||
|
AddComponent(DrawComponent.Index, new DrawCSpriteComponent(_sprite, Values.LayerPlayer));
|
||
|
|
||
|
InitStartSequence();
|
||
|
_aiComponent.ChangeState("idle");
|
||
|
|
||
|
// spawn position
|
||
|
EntityPosition.Set(new Vector2(EntityPosition.X + 180, 24));
|
||
|
}
|
||
|
|
||
|
private void InitStartSequence()
|
||
|
{
|
||
|
_grimCreeper = new MBossGrimCreeper(Map, (int)EntityPosition.X - 32, (int)EntityPosition.Y + 32, null);
|
||
|
_grimCreeper.StartNightmareSequnece();
|
||
|
Map.Objects.SpawnObject(_grimCreeper);
|
||
|
|
||
|
_creeperFly0 = new MBossGrimCreeperFly(Map, new Vector2(EntityPosition.X - 41, EntityPosition.Y + 32), new Vector2(-24, 12));
|
||
|
_creeperFly0.StartSequenceMode();
|
||
|
Map.Objects.SpawnObject(_creeperFly0);
|
||
|
|
||
|
_creeperFly1 = new MBossGrimCreeperFly(Map, new Vector2(EntityPosition.X - 7, EntityPosition.Y + 32), new Vector2(-16, -8));
|
||
|
_creeperFly1.StartSequenceMode();
|
||
|
Map.Objects.SpawnObject(_creeperFly1);
|
||
|
}
|
||
|
|
||
|
private void UpdateVisibility()
|
||
|
{
|
||
|
var target = (_startPosition.X - 144 < EntityPosition.X && EntityPosition.X < _startPosition.X + 144 &&
|
||
|
EntityPosition.Y > -16 && EntityPosition.Y < 160) ? 1 : 0;
|
||
|
_transparency = AnimationHelper.MoveToTarget(_transparency, target, 0.175f * Game1.TimeMultiplier);
|
||
|
_sprite.Color = Color.White * _transparency;
|
||
|
}
|
||
|
|
||
|
private void InitIdle()
|
||
|
{
|
||
|
_body.Velocity = Vector3.Zero;
|
||
|
_body.VelocityTarget = Vector2.Zero;
|
||
|
_damageState.CurrentLives = Lives;
|
||
|
}
|
||
|
|
||
|
private void UpdateIdle()
|
||
|
{
|
||
|
if (MapManager.ObjLink.EntityPosition.Y > _startPosition.Y + 90 || !MapManager.ObjLink.IsClimbing())
|
||
|
return;
|
||
|
|
||
|
if (!_playedIntro)
|
||
|
{
|
||
|
Game1.GameManager.StartDialogPath("grim_creeper_3");
|
||
|
_aiComponent.ChangeState("spawnDelay");
|
||
|
}
|
||
|
else
|
||
|
ToAttack();
|
||
|
}
|
||
|
|
||
|
private void SpawnHeart()
|
||
|
{
|
||
|
Map.Objects.SpawnObject(new ObjItem(Map, (int)_startPosition.X - 8, (int)_startPosition.Y, null, _saveKey + "_heart", "heartMeterFull", null));
|
||
|
}
|
||
|
|
||
|
private void InitPreAttack()
|
||
|
{
|
||
|
_animator.SpeedMultiplier = 1.5f;
|
||
|
|
||
|
}
|
||
|
|
||
|
private void InitGrab()
|
||
|
{
|
||
|
_animator.Stop();
|
||
|
_animator.Play("cflap_" + _direction);
|
||
|
_animator.Stop();
|
||
|
|
||
|
// adjust the distance
|
||
|
var distance = MathF.Abs(MapManager.ObjLink.EntityPosition.X - EntityPosition.X);
|
||
|
var mult = Math.Clamp(distance / 40 * 1.45f, 0.35f, 1.5f);
|
||
|
var direction = new Vector2(_direction * mult, 1.45f);
|
||
|
direction.Normalize();
|
||
|
|
||
|
_body.VelocityTarget = direction * 4f;
|
||
|
}
|
||
|
|
||
|
private void UpdateAttackGrab()
|
||
|
{
|
||
|
if (EntityPosition.Y > _startPosition.Y + 180)
|
||
|
ToAttack();
|
||
|
}
|
||
|
|
||
|
private void InitLeave()
|
||
|
{
|
||
|
//_body.VelocityTarget = new Vector2(0, -1);
|
||
|
}
|
||
|
|
||
|
private void UpdateLeave()
|
||
|
{
|
||
|
if (_direction < 0 && _body.Velocity.X > -3)
|
||
|
_body.Velocity.X -= 0.15f * Game1.TimeMultiplier;
|
||
|
if (_direction > 0 && _body.Velocity.X < 3)
|
||
|
_body.Velocity.X += 0.15f * Game1.TimeMultiplier;
|
||
|
|
||
|
if (_body.Velocity.Y > -2)
|
||
|
_body.Velocity.Y -= 0.015f * Game1.TimeMultiplier;
|
||
|
|
||
|
// start playing the glide animation
|
||
|
if (_direction == -1 && EntityPosition.X < _startPosition.X ||
|
||
|
_direction == 1 && EntityPosition.X > _startPosition.X)
|
||
|
{
|
||
|
_animator.Play("cglide_" + _direction);
|
||
|
}
|
||
|
if (_direction == -1 && EntityPosition.X < _startPosition.X - 160 ||
|
||
|
_direction == 1 && EntityPosition.X > _startPosition.X + 160)
|
||
|
{
|
||
|
ToAttack();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void InitWingAttackEnter()
|
||
|
{
|
||
|
_direction = MapManager.ObjLink.EntityPosition.X < _startPosition.X ? -1 : 1;
|
||
|
|
||
|
// only show the first frame
|
||
|
_animator.Play("cflap_" + _direction);
|
||
|
_animator.Stop();
|
||
|
|
||
|
_body.Velocity = Vector3.Zero;
|
||
|
_body.VelocityTarget = Vector2.Zero;
|
||
|
|
||
|
_wingCounter = 0;
|
||
|
_wingStartPosition = new Vector2(_startPosition.X - _direction * 100, _startPosition.Y - 24);
|
||
|
_wingEndPosition = new Vector2(_startPosition.X - _direction * 28, _startPosition.Y + 8);
|
||
|
|
||
|
EntityPosition.Set(_wingStartPosition);
|
||
|
}
|
||
|
|
||
|
private void UpdateWingAttackEnter()
|
||
|
{
|
||
|
_wingCounter += Game1.DeltaTime;
|
||
|
var percentage = _wingCounter / WingTime;
|
||
|
|
||
|
// start flapping the wings
|
||
|
if (percentage > 0.80)
|
||
|
_animator.Continue();
|
||
|
|
||
|
if (percentage >= 1)
|
||
|
{
|
||
|
EntityPosition.Set(_wingEndPosition);
|
||
|
|
||
|
// feather attack
|
||
|
if (_featherAttack)
|
||
|
_aiComponent.ChangeState("featherAttack");
|
||
|
else
|
||
|
_aiComponent.ChangeState("preAttack");
|
||
|
|
||
|
_featherAttack = false;
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var lerpState = MathF.Sin(percentage * MathF.PI / 2);
|
||
|
var newPosition = Vector2.Lerp(_wingStartPosition, _wingEndPosition, lerpState);
|
||
|
EntityPosition.Set(newPosition);
|
||
|
}
|
||
|
|
||
|
private void InitWingAttack()
|
||
|
{
|
||
|
_wingCounter = 0;
|
||
|
}
|
||
|
|
||
|
private void UpdateWingAttack()
|
||
|
{
|
||
|
_wingCounter += Game1.DeltaTime;
|
||
|
|
||
|
// end state
|
||
|
if (_wingCounter > 275 * 11)
|
||
|
{
|
||
|
_aiComponent.ChangeState("leave");
|
||
|
}
|
||
|
|
||
|
// move up and down
|
||
|
var offset = MathF.Sin(_wingCounter / 1100 * MathF.PI * 2 + MathF.PI / 2) * 4 - 4;
|
||
|
var newPosition = new Vector2(_wingEndPosition.X, _wingEndPosition.Y + offset);
|
||
|
EntityPosition.Set(newPosition);
|
||
|
|
||
|
// push the playyer
|
||
|
if (MapManager.ObjLink.EntityPosition.Y < _startPosition.Y + 90)
|
||
|
MapManager.ObjLink._body.AdditionalMovementVT.X = _direction * 1.1f;
|
||
|
else
|
||
|
MapManager.ObjLink._body.AdditionalMovementVT.X = 0;
|
||
|
|
||
|
// shoot a feather
|
||
|
_featherCounter += Game1.DeltaTime;
|
||
|
if (_featherCounter > 275)
|
||
|
{
|
||
|
_featherCounter = 0;
|
||
|
|
||
|
var startPosition = new Vector2(EntityPosition.X - _direction * 4, EntityPosition.Y + 10);
|
||
|
var direction = MapManager.ObjLink.EntityPosition.Position - startPosition;
|
||
|
if (direction != Vector2.Zero)
|
||
|
direction.Normalize();
|
||
|
|
||
|
var radiants = MathF.Atan2(direction.Y, direction.X);
|
||
|
// randomly offset the direction a little bit
|
||
|
radiants += (Game1.RandomNumber.Next(0, 11) - 5) / 25f;
|
||
|
var aimDirection = new Vector2(MathF.Cos(radiants), MathF.Sin(radiants));
|
||
|
|
||
|
var eagleFeather = new BossEvilEagleFeather(Map, startPosition, aimDirection * 4);
|
||
|
Map.Objects.SpawnObject(eagleFeather);
|
||
|
|
||
|
Game1.GameManager.PlaySoundEffect("D378-50-32");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void UpdateDamaged()
|
||
|
{
|
||
|
if (!_damageState.IsInDamageState())
|
||
|
_aiComponent.ChangeState("flyup");
|
||
|
}
|
||
|
|
||
|
private void FlyUp()
|
||
|
{
|
||
|
Game1.GameManager.PlaySoundEffect("D378-49-31");
|
||
|
_animator.Play("cflap_" + _direction);
|
||
|
}
|
||
|
|
||
|
private void InitFlyUp()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
private void UpdateFlyUp()
|
||
|
{
|
||
|
if (_body.Velocity.Y > -2)
|
||
|
_body.Velocity.Y -= 0.1f * Game1.TimeMultiplier;
|
||
|
|
||
|
if (EntityPosition.Y < -48)
|
||
|
ToAttack();
|
||
|
}
|
||
|
|
||
|
private void ToAttack()
|
||
|
{
|
||
|
// reset the boss
|
||
|
if (MapManager.ObjLink.EntityPosition.Y > _startPosition.Y + 90)
|
||
|
{
|
||
|
_aiComponent.ChangeState("idle");
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
_body.VelocityTarget = Vector2.Zero;
|
||
|
_damageComponent.IsActive = true;
|
||
|
|
||
|
if (_damageState.CurrentLives == 4 || _damageState.CurrentLives == 5 || _featherAttack)
|
||
|
_aiComponent.ChangeState("attackEnter");
|
||
|
else
|
||
|
_aiComponent.ChangeState("attack");
|
||
|
}
|
||
|
|
||
|
private void InitAttack()
|
||
|
{
|
||
|
_direction = Game1.RandomNumber.Next(0, 2) * 2 - 1;
|
||
|
|
||
|
_body.Velocity = Vector3.Zero;
|
||
|
_body.VelocityTarget.X = _direction * FlySpeed;
|
||
|
|
||
|
var randomHeight = Game1.RandomNumber.Next(0, 28) * 2;
|
||
|
|
||
|
EntityPosition.Set(new Vector2(_startPosition.X - _direction * 160, (int)MapManager.ObjLink.EntityPosition.Y - randomHeight));
|
||
|
|
||
|
_animator.Play("cglide_" + _direction);
|
||
|
}
|
||
|
|
||
|
private void UpdateAttack()
|
||
|
{
|
||
|
if (EntityPosition.X < _startPosition.X - 180 || _startPosition.X + 180 < EntityPosition.X)
|
||
|
_aiComponent.ChangeState("gone");
|
||
|
}
|
||
|
|
||
|
private void UpdateSaddled()
|
||
|
{
|
||
|
if (_body.Velocity.X > -3)
|
||
|
_body.Velocity.X -= 0.15f * Game1.TimeMultiplier;
|
||
|
if (_body.Velocity.Y > -2)
|
||
|
_body.Velocity.Y -= 0.01f * Game1.TimeMultiplier;
|
||
|
|
||
|
if (EntityPosition.X < _startPosition.X - 23)
|
||
|
{
|
||
|
_animator.Play("cglide_-1");
|
||
|
}
|
||
|
if (EntityPosition.X < _startPosition.X - 180)
|
||
|
{
|
||
|
// start attacking
|
||
|
ToAttack();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void InitGrimSaddle()
|
||
|
{
|
||
|
_grimCreeper.StartSaddleJump();
|
||
|
}
|
||
|
|
||
|
private void UpdateGrimSaddle()
|
||
|
{
|
||
|
if (_grimCreeper.Map == null)
|
||
|
{
|
||
|
_aiComponent.ChangeState("saddled");
|
||
|
_animator.Play("cflap");
|
||
|
_animator.SpeedMultiplier = 0.5f;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private void InitSpawning()
|
||
|
{
|
||
|
_playedIntro = true;
|
||
|
_body.VelocityTarget.X = -FlySpeed;
|
||
|
_spawnIndex = 0;
|
||
|
}
|
||
|
|
||
|
private void UpdateSpawning()
|
||
|
{
|
||
|
MapManager.ObjLink.FreezePlayer();
|
||
|
|
||
|
if (_spawnIndex == 0)
|
||
|
{
|
||
|
if (EntityPosition.X < _startPosition.X - 180)
|
||
|
{
|
||
|
_animator.Play("glide_1");
|
||
|
_body.VelocityTarget.X = FlySpeed;
|
||
|
EntityPosition.Y += 20;
|
||
|
_spawnIndex = 1;
|
||
|
}
|
||
|
}
|
||
|
else if (_spawnIndex == 1)
|
||
|
{
|
||
|
if (!_introSound && EntityPosition.X > _startPosition.X - 130)
|
||
|
{
|
||
|
_introSound = true;
|
||
|
Game1.GameManager.PlaySoundEffect("D378-34-22");
|
||
|
}
|
||
|
|
||
|
if (EntityPosition.X > _startPosition.X + 180)
|
||
|
{
|
||
|
_introSound = false;
|
||
|
_animator.Play("glide_-1");
|
||
|
_body.VelocityTarget.X = -FlySpeed;
|
||
|
_spawnIndex = 2;
|
||
|
EntityPosition.Y += 20;
|
||
|
}
|
||
|
}
|
||
|
else if (_spawnIndex == 2)
|
||
|
{
|
||
|
if (!_introSound && EntityPosition.X < _startPosition.X + 110)
|
||
|
{
|
||
|
_introSound = true;
|
||
|
Game1.GameManager.PlaySoundEffect("D378-48-30");
|
||
|
}
|
||
|
|
||
|
if (EntityPosition.X < _startPosition.X + 40)
|
||
|
{
|
||
|
Game1.GameManager.PlaySoundEffect("D360-48-30");
|
||
|
_animator.Play("flap");
|
||
|
_slowStart = EntityPosition.Position;
|
||
|
_body.VelocityTarget.X = 0;
|
||
|
_spawnIndex = 3;
|
||
|
}
|
||
|
}
|
||
|
else if (_spawnIndex == 3)
|
||
|
{
|
||
|
_slowCounter += Game1.DeltaTime;
|
||
|
if (_slowCounter > 500)
|
||
|
{
|
||
|
_aiComponent.ChangeState("grimSaddle");
|
||
|
_slowCounter = 500;
|
||
|
|
||
|
_creeperFly0.ToLeave();
|
||
|
_creeperFly1.ToLeave();
|
||
|
}
|
||
|
|
||
|
var percentage = MathF.Sin(_slowCounter / 500 * MathF.PI / 2);
|
||
|
var newPositionX = MathHelper.Lerp(_slowStart.X, _startPosition.X + 6, percentage);
|
||
|
EntityPosition.Set(new Vector2(newPositionX, EntityPosition.Y));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
private Values.HitCollision OnHit(GameObject originObject, Vector2 direction, HitType damageType, int damage, bool pieceOfPower)
|
||
|
{
|
||
|
if (_damageState.IsInDamageState() || _aiComponent.CurrentStateId == "flyup")
|
||
|
return Values.HitCollision.None;
|
||
|
|
||
|
if (damageType == HitType.MagicRod || damageType == HitType.Boomerang)
|
||
|
damage = 4;
|
||
|
|
||
|
_damageComponent.IsActive = false;
|
||
|
_damageState.SetDamageState(true);
|
||
|
_damageState.CurrentLives -= damage;
|
||
|
|
||
|
Game1.GameManager.PlaySoundEffect("D370-07-07");
|
||
|
|
||
|
// dead?
|
||
|
if (_damageState.CurrentLives <= 0)
|
||
|
{
|
||
|
_body.IsActive = false;
|
||
|
_hittableComponent.IsActive = false;
|
||
|
|
||
|
Game1.GameManager.StartDialogPath("grim_creeper_4");
|
||
|
|
||
|
_damageState.OnDeathBoss(pieceOfPower);
|
||
|
|
||
|
return Values.HitCollision.Enemy;
|
||
|
}
|
||
|
|
||
|
// next move will be the wing attack; not sure how this works in the original
|
||
|
if (Game1.RandomNumber.Next(0, 2) == 0)
|
||
|
_featherAttack = true;
|
||
|
|
||
|
_aiComponent.ChangeState("damaged");
|
||
|
_body.VelocityTarget = Vector2.Zero;
|
||
|
|
||
|
return Values.HitCollision.Enemy;
|
||
|
}
|
||
|
|
||
|
private void OnDeath()
|
||
|
{
|
||
|
if (!string.IsNullOrEmpty(_saveKey))
|
||
|
Game1.GameManager.SaveManager.SetString(_saveKey, "1");
|
||
|
|
||
|
Game1.GameManager.PlaySoundEffect("D378-26-1A");
|
||
|
|
||
|
SpawnHeart();
|
||
|
|
||
|
Map.Objects.DeleteObjects.Add(this);
|
||
|
}
|
||
|
}
|
||
|
}
|