Merge branch 'main' of https://git.zenny.quest/zenayi/GameJamDungeon
This commit is contained in:
@@ -44,6 +44,8 @@ public interface IPlayer : IKillable
|
|||||||
|
|
||||||
public void ModifyBonusLuck(double amount);
|
public void ModifyBonusLuck(double amount);
|
||||||
|
|
||||||
|
public void SetHealthTimerStatus(bool isActive);
|
||||||
|
|
||||||
public IInventory Inventory { get; }
|
public IInventory Inventory { get; }
|
||||||
|
|
||||||
public PlayerStats Stats { get; }
|
public PlayerStats Stats { get; }
|
||||||
|
|||||||
@@ -62,6 +62,9 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<ISaveChunk<Play
|
|||||||
#region Exports
|
#region Exports
|
||||||
[Export]
|
[Export]
|
||||||
private PlayerStatResource _playerStatResource { get; set; } = default!;
|
private PlayerStatResource _playerStatResource { get; set; } = default!;
|
||||||
|
|
||||||
|
[Export]
|
||||||
|
private bool HealthTimerIsActive = false;
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Node Dependencies
|
#region Node Dependencies
|
||||||
@@ -93,547 +96,555 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<ISaveChunk<Play
|
|||||||
#region Initialization
|
#region Initialization
|
||||||
public void InitializePlayerState()
|
public void InitializePlayerState()
|
||||||
{
|
{
|
||||||
Inventory = new Inventory();
|
Inventory = new Inventory();
|
||||||
Stats = InitializePlayerStats();
|
Stats = InitializePlayerStats();
|
||||||
SetProcessInput(false);
|
SetProcessInput(false);
|
||||||
SetPhysicsProcess(false);
|
SetPhysicsProcess(false);
|
||||||
|
|
||||||
EquippedWeapon.Changed += EquippedWeapon_Sync;
|
EquippedWeapon.Changed += EquippedWeapon_Sync;
|
||||||
EquippedArmor.Changed += EquippedArmor_Sync;
|
EquippedArmor.Changed += EquippedArmor_Sync;
|
||||||
EquippedAccessory.Changed += EquippedAccessory_Sync;
|
EquippedAccessory.Changed += EquippedAccessory_Sync;
|
||||||
Stats.CurrentHP.Changed += CurrentHP_Sync;
|
Stats.CurrentHP.Changed += CurrentHP_Sync;
|
||||||
Stats.CurrentExp.Changed += CurrentEXP_Sync;
|
Stats.CurrentExp.Changed += CurrentEXP_Sync;
|
||||||
HealthTimer.WaitTime = _healthTimerWaitTime;
|
HealthTimer.WaitTime = _healthTimerWaitTime;
|
||||||
HealthTimer.Timeout += OnHealthTimerTimeout;
|
HealthTimer.Timeout += OnHealthTimerTimeout;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Setup()
|
public void Setup()
|
||||||
{
|
{
|
||||||
var container = new SimpleInjector.Container();
|
var container = new SimpleInjector.Container();
|
||||||
container.Register<IPlayerLogic, PlayerLogic>(Lifestyle.Singleton);
|
container.Register<IPlayerLogic, PlayerLogic>(Lifestyle.Singleton);
|
||||||
//container.Verify();
|
//container.Verify();
|
||||||
|
|
||||||
PlayerLogic = container.GetInstance<IPlayerLogic>();
|
PlayerLogic = container.GetInstance<IPlayerLogic>();
|
||||||
PlayerLogic.Set(this as IPlayer);
|
PlayerLogic.Set(this as IPlayer);
|
||||||
PlayerLogic.Set(Settings);
|
PlayerLogic.Set(Settings);
|
||||||
PlayerLogic.Set(Stats);
|
PlayerLogic.Set(Stats);
|
||||||
PlayerLogic.Set(_gameRepo);
|
PlayerLogic.Set(_gameRepo);
|
||||||
|
|
||||||
_damageCalculator = new DamageCalculator();
|
_damageCalculator = new DamageCalculator();
|
||||||
|
|
||||||
Hitbox.AreaEntered += Hitbox_AreaEntered;
|
Hitbox.AreaEntered += Hitbox_AreaEntered;
|
||||||
CollisionDetector.AreaEntered += CollisionDetector_AreaEntered;
|
CollisionDetector.AreaEntered += CollisionDetector_AreaEntered;
|
||||||
AnimationPlayer.AnimationFinished += OnAnimationFinished;
|
AnimationPlayer.AnimationFinished += OnAnimationFinished;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnResolved()
|
public void OnResolved()
|
||||||
{
|
{
|
||||||
Settings = new PlayerLogic.Settings() { RotationSpeed = _playerStatResource.RotationSpeed, MoveSpeed = _playerStatResource.MoveSpeed, Acceleration = _playerStatResource.Acceleration };
|
Settings = new PlayerLogic.Settings() { RotationSpeed = _playerStatResource.RotationSpeed, MoveSpeed = _playerStatResource.MoveSpeed, Acceleration = _playerStatResource.Acceleration };
|
||||||
|
|
||||||
PlayerChunk = new SaveChunk<PlayerData>(
|
PlayerChunk = new SaveChunk<PlayerData>(
|
||||||
onSave: (chunk) => new PlayerData()
|
onSave: (chunk) => new PlayerData()
|
||||||
{
|
{
|
||||||
PlayerStats = Stats,
|
PlayerStats = Stats,
|
||||||
Inventory = Inventory
|
Inventory = Inventory
|
||||||
},
|
},
|
||||||
onLoad: (chunk, data) =>
|
onLoad: (chunk, data) =>
|
||||||
{
|
{
|
||||||
Stats = new PlayerStats(
|
Stats = new PlayerStats(
|
||||||
data.PlayerStats.CurrentHP,
|
data.PlayerStats.CurrentHP,
|
||||||
data.PlayerStats.MaximumHP,
|
data.PlayerStats.MaximumHP,
|
||||||
data.PlayerStats.CurrentVT,
|
data.PlayerStats.CurrentVT,
|
||||||
data.PlayerStats.MaximumVT,
|
data.PlayerStats.MaximumVT,
|
||||||
data.PlayerStats.CurrentAttack,
|
data.PlayerStats.CurrentAttack,
|
||||||
data.PlayerStats.BonusAttack,
|
data.PlayerStats.BonusAttack,
|
||||||
data.PlayerStats.MaxAttack,
|
data.PlayerStats.MaxAttack,
|
||||||
data.PlayerStats.CurrentDefense,
|
data.PlayerStats.CurrentDefense,
|
||||||
data.PlayerStats.BonusDefense,
|
data.PlayerStats.BonusDefense,
|
||||||
data.PlayerStats.MaxDefense,
|
data.PlayerStats.MaxDefense,
|
||||||
data.PlayerStats.CurrentExp,
|
data.PlayerStats.CurrentExp,
|
||||||
data.PlayerStats.CurrentLevel,
|
data.PlayerStats.CurrentLevel,
|
||||||
data.PlayerStats.ExpToNextLevel,
|
data.PlayerStats.ExpToNextLevel,
|
||||||
data.PlayerStats.Luck);
|
data.PlayerStats.Luck);
|
||||||
Inventory = data.Inventory;
|
Inventory = data.Inventory;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
PlayerBinding = PlayerLogic.Bind();
|
PlayerBinding = PlayerLogic.Bind();
|
||||||
|
|
||||||
PlayerBinding
|
PlayerBinding
|
||||||
.Handle((in PlayerLogic.Output.Animations.Attack output) =>
|
.Handle((in PlayerLogic.Output.Animations.Attack output) =>
|
||||||
{
|
{
|
||||||
if (PlayerIsHittingGeometry())
|
if (PlayerIsHittingGeometry())
|
||||||
{
|
{
|
||||||
AnimationPlayer.Play("hit_wall");
|
AnimationPlayer.Play("hit_wall");
|
||||||
_gameRepo.OnPlayerAttackedWall();
|
_gameRepo.OnPlayerAttackedWall();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
PlayAttackAnimation();
|
PlayAttackAnimation();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.Handle((in PlayerLogic.Output.ThrowItem output) =>
|
.Handle((in PlayerLogic.Output.ThrowItem output) =>
|
||||||
{
|
{
|
||||||
})
|
})
|
||||||
.Handle((in PlayerLogic.Output.Move output) =>
|
.Handle((in PlayerLogic.Output.Move output) =>
|
||||||
{
|
{
|
||||||
Move(output.delta);
|
Move(output.delta);
|
||||||
});
|
});
|
||||||
|
|
||||||
GameChunk.AddChunk(PlayerChunk);
|
GameChunk.AddChunk(PlayerChunk);
|
||||||
|
|
||||||
PlayerLogic.Start();
|
PlayerLogic.Start();
|
||||||
this.Provide();
|
this.Provide();
|
||||||
|
|
||||||
SetProcessInput(false);
|
SetProcessInput(false);
|
||||||
SetPhysicsProcess(false);
|
SetPhysicsProcess(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnReady()
|
public void OnReady()
|
||||||
{
|
{
|
||||||
SwordSlashAnimation.Position = GetViewport().GetVisibleRect().Size / 2;
|
SwordSlashAnimation.Position = GetViewport().GetVisibleRect().Size / 2;
|
||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
public void Activate()
|
public void Activate()
|
||||||
{
|
{
|
||||||
SetProcessInput(true);
|
SetProcessInput(true);
|
||||||
SetPhysicsProcess(true);
|
SetPhysicsProcess(true);
|
||||||
HealthTimer.Start();
|
SetHealthTimerStatus(HealthTimerIsActive);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Deactivate()
|
public void Deactivate()
|
||||||
{
|
{
|
||||||
SetProcessInput(false);
|
SetProcessInput(false);
|
||||||
SetPhysicsProcess(false);
|
SetPhysicsProcess(false);
|
||||||
HealthTimer.Stop();
|
SetHealthTimerStatus(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Attack()
|
public void Attack()
|
||||||
{
|
{
|
||||||
PlayerLogic.Input(new PlayerLogic.Input.Attack());
|
PlayerLogic.Input(new PlayerLogic.Input.Attack());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RaiseHP(int amountToRaise)
|
public void RaiseHP(int amountToRaise)
|
||||||
{
|
{
|
||||||
Stats.SetMaximumHP(Stats.MaximumHP.Value + amountToRaise);
|
Stats.SetMaximumHP(Stats.MaximumHP.Value + amountToRaise);
|
||||||
Stats.SetCurrentHP(Stats.MaximumHP.Value);
|
Stats.SetCurrentHP(Stats.MaximumHP.Value);
|
||||||
_gameRepo.AnnounceMessageInInventory($"{amountToRaise}MAXHP Up.");
|
_gameRepo.AnnounceMessageInInventory($"{amountToRaise}MAXHP Up.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HealHP(int amountToRestore)
|
public void HealHP(int amountToRestore)
|
||||||
{
|
{
|
||||||
Stats.SetCurrentHP(Stats.CurrentHP.Value + amountToRestore);
|
Stats.SetCurrentHP(Stats.CurrentHP.Value + amountToRestore);
|
||||||
var raiseString = amountToRestore == 1000 ? "MAX" : $"{amountToRestore}";
|
var raiseString = amountToRestore == 1000 ? "MAX" : $"{amountToRestore}";
|
||||||
_gameRepo.AnnounceMessageInInventory($"{raiseString}HP Restored.");
|
_gameRepo.AnnounceMessageInInventory($"{raiseString}HP Restored.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RaiseVT(int amountToRaise)
|
public void RaiseVT(int amountToRaise)
|
||||||
{
|
{
|
||||||
if (Stats.CurrentVT == Stats.MaximumVT)
|
if (Stats.CurrentVT == Stats.MaximumVT)
|
||||||
{
|
{
|
||||||
Stats.SetMaximumVT(Stats.MaximumVT.Value + amountToRaise);
|
Stats.SetMaximumVT(Stats.MaximumVT.Value + amountToRaise);
|
||||||
Stats.SetCurrentVT(Stats.MaximumVT.Value);
|
Stats.SetCurrentVT(Stats.MaximumVT.Value);
|
||||||
_gameRepo.AnnounceMessageInInventory($"{amountToRaise}MAXVT Up.");
|
_gameRepo.AnnounceMessageInInventory($"{amountToRaise}MAXVT Up.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HealVT(int amountToRestore)
|
public void HealVT(int amountToRestore)
|
||||||
{
|
{
|
||||||
Stats.SetCurrentVT(Stats.CurrentVT.Value + amountToRestore);
|
Stats.SetCurrentVT(Stats.CurrentVT.Value + amountToRestore);
|
||||||
var raiseString = amountToRestore == 1000 ? "MAX" : $"{amountToRestore}";
|
var raiseString = amountToRestore == 1000 ? "MAX" : $"{amountToRestore}";
|
||||||
_gameRepo.AnnounceMessageInInventory($"{raiseString}VT Restored.");
|
_gameRepo.AnnounceMessageInInventory($"{raiseString}VT Restored.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ModifyBonusAttack(int amount)
|
public void ModifyBonusAttack(int amount)
|
||||||
{
|
{
|
||||||
Stats.SetBonusAttack(Stats.BonusAttack.Value + amount);
|
Stats.SetBonusAttack(Stats.BonusAttack.Value + amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ModifyBonusDefense(int amount)
|
public void ModifyBonusDefense(int amount)
|
||||||
{
|
{
|
||||||
Stats.SetBonusDefense(Stats.BonusDefense.Value + amount);
|
Stats.SetBonusDefense(Stats.BonusDefense.Value + amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ModifyMaximumHP(int amount)
|
public void ModifyMaximumHP(int amount)
|
||||||
{
|
{
|
||||||
Stats.SetMaximumHP(Stats.MaximumHP.Value + amount);
|
Stats.SetMaximumHP(Stats.MaximumHP.Value + amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ModifyMaximumVT(int amount)
|
public void ModifyMaximumVT(int amount)
|
||||||
{
|
{
|
||||||
Stats.SetMaximumVT(Stats.MaximumVT.Value + amount);
|
Stats.SetMaximumVT(Stats.MaximumVT.Value + amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ModifyBonusLuck(double amount)
|
public void ModifyBonusLuck(double amount)
|
||||||
{
|
{
|
||||||
Stats.SetLuck(Stats.Luck.Value + amount);
|
Stats.SetLuck(Stats.Luck.Value + amount);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetHealthTimerStatus(bool isActive)
|
||||||
|
{
|
||||||
|
if (isActive)
|
||||||
|
HealthTimer.Start();
|
||||||
|
else
|
||||||
|
HealthTimer.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Move(float delta)
|
public void Move(float delta)
|
||||||
{
|
{
|
||||||
var rawInput = GlobalInputVector;
|
var rawInput = GlobalInputVector;
|
||||||
var strafeLeftInput = LeftStrafeInputVector;
|
var strafeLeftInput = LeftStrafeInputVector;
|
||||||
var strafeRightInput = RightStrafeInputVector;
|
var strafeRightInput = RightStrafeInputVector;
|
||||||
|
|
||||||
var transform = Transform;
|
var transform = Transform;
|
||||||
transform.Basis = new Basis(Vector3.Up, Settings.RotationSpeed * -rawInput.X * delta) * transform.Basis;
|
transform.Basis = new Basis(Vector3.Up, Settings.RotationSpeed * -rawInput.X * delta) * transform.Basis;
|
||||||
var moveDirection = new Vector3(strafeRightInput - strafeLeftInput, 0, rawInput.Z).Normalized();
|
var moveDirection = new Vector3(strafeRightInput - strafeLeftInput, 0, rawInput.Z).Normalized();
|
||||||
var velocity = Basis * moveDirection * Settings.MoveSpeed * Settings.Acceleration;
|
var velocity = Basis * moveDirection * Settings.MoveSpeed * Settings.Acceleration;
|
||||||
_knockbackStrength *= 0.9f;
|
_knockbackStrength *= 0.9f;
|
||||||
Transform = Transform with { Basis = transform.Basis };
|
Transform = Transform with { Basis = transform.Basis };
|
||||||
Velocity = velocity + (_knockbackDirection * _knockbackStrength);
|
Velocity = velocity + (_knockbackDirection * _knockbackStrength);
|
||||||
MoveAndSlide();
|
MoveAndSlide();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TeleportPlayer(Transform3D newTransform)
|
public void TeleportPlayer(Transform3D newTransform)
|
||||||
{
|
{
|
||||||
Transform = newTransform;
|
Transform = newTransform;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void TakeDamage(double damage, ElementType elementType, bool isCriticalHit = false)
|
public void TakeDamage(double damage, ElementType elementType, bool isCriticalHit = false)
|
||||||
{
|
{
|
||||||
if (Stats.CurrentHP.Value > 0)
|
if (Stats.CurrentHP.Value > 0)
|
||||||
{
|
{
|
||||||
_damageCalculator.CalculateDamage(damage, elementType, Stats.CurrentDefense.Value + Stats.BonusDefense.Value, ((Armor)_equippedArmor.Value).Stats.ElementalResistanceSet);
|
_damageCalculator.CalculateDamage(damage, elementType, Stats.CurrentDefense.Value + Stats.BonusDefense.Value, ((Armor)_equippedArmor.Value).Stats.ElementalResistanceSet);
|
||||||
Stats.SetCurrentHP(Stats.CurrentHP.Value - (int)damage);
|
Stats.SetCurrentHP(Stats.CurrentHP.Value - (int)damage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Knockback(float impulse)
|
public void Knockback(float impulse)
|
||||||
{
|
{
|
||||||
_knockbackStrength = impulse;
|
_knockbackStrength = impulse;
|
||||||
_knockbackDirection = GlobalBasis.Z.Normalized();
|
_knockbackDirection = GlobalBasis.Z.Normalized();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GainExp(double expGained)
|
public void GainExp(double expGained)
|
||||||
{
|
{
|
||||||
Stats.SetCurrentExp(Stats.CurrentExp.Value + expGained);
|
Stats.SetCurrentExp(Stats.CurrentExp.Value + expGained);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void LevelUp()
|
public void LevelUp()
|
||||||
{
|
{
|
||||||
var rng = new RandomNumberGenerator();
|
var rng = new RandomNumberGenerator();
|
||||||
rng.Randomize();
|
rng.Randomize();
|
||||||
var hpIncrease = rng.RandiRange(3, 6);
|
var hpIncrease = rng.RandiRange(3, 6);
|
||||||
Stats.SetMaximumHP(Stats.MaximumHP.Value + hpIncrease);
|
Stats.SetMaximumHP(Stats.MaximumHP.Value + hpIncrease);
|
||||||
var nextLevel = Stats.CurrentLevel.Value + 1;
|
var nextLevel = Stats.CurrentLevel.Value + 1;
|
||||||
var expToNextLevel = (int)(6.5 * nextLevel + 4.5 * Mathf.Pow(nextLevel, 2) + Mathf.Pow(nextLevel, 3));
|
var expToNextLevel = (int)(6.5 * nextLevel + 4.5 * Mathf.Pow(nextLevel, 2) + Mathf.Pow(nextLevel, 3));
|
||||||
var newCurrentExp = Mathf.Max(Stats.CurrentExp.Value - Stats.ExpToNextLevel.Value, 0);
|
var newCurrentExp = Mathf.Max(Stats.CurrentExp.Value - Stats.ExpToNextLevel.Value, 0);
|
||||||
Stats.SetCurrentLevel(nextLevel);
|
Stats.SetCurrentLevel(nextLevel);
|
||||||
Stats.SetExpToNextLevel(expToNextLevel);
|
Stats.SetExpToNextLevel(expToNextLevel);
|
||||||
Stats.SetCurrentExp(newCurrentExp);
|
Stats.SetCurrentExp(newCurrentExp);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Die()
|
public void Die()
|
||||||
{
|
{
|
||||||
EquippedWeapon.Sync -= EquippedWeapon_Sync;
|
EquippedWeapon.Sync -= EquippedWeapon_Sync;
|
||||||
EquippedArmor.Sync -= EquippedArmor_Sync;
|
EquippedArmor.Sync -= EquippedArmor_Sync;
|
||||||
EquippedAccessory.Sync -= EquippedAccessory_Sync;
|
EquippedAccessory.Sync -= EquippedAccessory_Sync;
|
||||||
Stats.CurrentHP.Sync -= CurrentHP_Sync;
|
Stats.CurrentHP.Sync -= CurrentHP_Sync;
|
||||||
Stats.CurrentExp.Sync -= CurrentEXP_Sync;
|
Stats.CurrentExp.Sync -= CurrentEXP_Sync;
|
||||||
|
|
||||||
HealthTimer.WaitTime = _healthTimerWaitTime;
|
HealthTimer.WaitTime = _healthTimerWaitTime;
|
||||||
HealthTimer.Timeout -= OnHealthTimerTimeout;
|
HealthTimer.Timeout -= OnHealthTimerTimeout;
|
||||||
SwordSlashAnimation.Stop();
|
SwordSlashAnimation.Stop();
|
||||||
SetProcessInput(false);
|
SetProcessInput(false);
|
||||||
SetPhysicsProcess(false);
|
SetPhysicsProcess(false);
|
||||||
//Hitbox.AreaEntered -= Hitbox_AreaEntered;
|
//Hitbox.AreaEntered -= Hitbox_AreaEntered;
|
||||||
//CollisionDetector.AreaEntered -= CollisionDetector_AreaEntered;
|
//CollisionDetector.AreaEntered -= CollisionDetector_AreaEntered;
|
||||||
//AnimationPlayer.AnimationFinished -= OnAnimationFinished;
|
//AnimationPlayer.AnimationFinished -= OnAnimationFinished;
|
||||||
|
|
||||||
Game.GameOver();
|
Game.GameOver();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void _Input(InputEvent @event)
|
public override void _Input(InputEvent @event)
|
||||||
{
|
{
|
||||||
if (@event.IsActionPressed(GameInputs.Attack))
|
if (@event.IsActionPressed(GameInputs.Attack))
|
||||||
Attack();
|
Attack();
|
||||||
if (@event.IsActionPressed(GameInputs.Sprint))
|
if (@event.IsActionPressed(GameInputs.Sprint))
|
||||||
Settings.MoveSpeed *= 2;
|
Settings.MoveSpeed *= 2;
|
||||||
if (@event.IsActionReleased(GameInputs.Sprint))
|
if (@event.IsActionReleased(GameInputs.Sprint))
|
||||||
Settings.MoveSpeed /= 2;
|
Settings.MoveSpeed /= 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnPhysicsProcess(double delta)
|
public void OnPhysicsProcess(double delta)
|
||||||
{
|
{
|
||||||
PlayerLogic.Input(new PlayerLogic.Input.PhysicsTick(delta));
|
PlayerLogic.Input(new PlayerLogic.Input.PhysicsTick(delta));
|
||||||
PlayerLogic.Input(new PlayerLogic.Input.Moved(GlobalPosition, GlobalTransform));
|
PlayerLogic.Input(new PlayerLogic.Input.Moved(GlobalPosition, GlobalTransform));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Equip(EquipableItem equipable)
|
public void Equip(EquipableItem equipable)
|
||||||
{
|
{
|
||||||
if (equipable.ItemTag == ItemTag.MysteryItem)
|
if (equipable.ItemTag == ItemTag.MysteryItem)
|
||||||
{
|
{
|
||||||
var rerolledItem = Game.RerollItem(equipable) as EquipableItem;
|
var rerolledItem = Game.RerollItem(equipable) as EquipableItem;
|
||||||
Equip(rerolledItem);
|
Equip(rerolledItem);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (equipable is Weapon weapon)
|
if (equipable is Weapon weapon)
|
||||||
{
|
{
|
||||||
Unequip(_equippedWeapon.Value);
|
Unequip(_equippedWeapon.Value);
|
||||||
weapon.IsEquipped = true;
|
weapon.IsEquipped = true;
|
||||||
_equippedWeapon.OnNext(weapon);
|
_equippedWeapon.OnNext(weapon);
|
||||||
}
|
}
|
||||||
else if (equipable is Armor armor)
|
else if (equipable is Armor armor)
|
||||||
{
|
{
|
||||||
Unequip(_equippedArmor.Value);
|
Unequip(_equippedArmor.Value);
|
||||||
armor.IsEquipped = true;
|
armor.IsEquipped = true;
|
||||||
_equippedArmor.OnNext(armor);
|
_equippedArmor.OnNext(armor);
|
||||||
}
|
}
|
||||||
else if (equipable is Accessory accessory)
|
else if (equipable is Accessory accessory)
|
||||||
{
|
{
|
||||||
Unequip(_equippedAccessory.Value);
|
Unequip(_equippedAccessory.Value);
|
||||||
accessory.IsEquipped = true;
|
accessory.IsEquipped = true;
|
||||||
_equippedAccessory.OnNext(accessory);
|
_equippedAccessory.OnNext(accessory);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw new NotImplementedException("Item type is not supported.");
|
throw new NotImplementedException("Item type is not supported.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Unequip(EquipableItem equipable)
|
public void Unequip(EquipableItem equipable)
|
||||||
{
|
{
|
||||||
if (equipable is Weapon weapon)
|
if (equipable is Weapon weapon)
|
||||||
{
|
{
|
||||||
weapon.IsEquipped = false;
|
weapon.IsEquipped = false;
|
||||||
ModifyBonusAttack(-weapon.Damage);
|
ModifyBonusAttack(-weapon.Damage);
|
||||||
_equippedWeapon.OnNext(new Weapon());
|
_equippedWeapon.OnNext(new Weapon());
|
||||||
}
|
}
|
||||||
else if (equipable is Armor armor)
|
else if (equipable is Armor armor)
|
||||||
{
|
{
|
||||||
armor.IsEquipped = false;
|
armor.IsEquipped = false;
|
||||||
ModifyBonusDefense(-armor.Defense);
|
ModifyBonusDefense(-armor.Defense);
|
||||||
_equippedArmor.OnNext(new Armor());
|
_equippedArmor.OnNext(new Armor());
|
||||||
}
|
}
|
||||||
else if (equipable is Accessory accessory)
|
else if (equipable is Accessory accessory)
|
||||||
{
|
{
|
||||||
accessory.IsEquipped = false;
|
accessory.IsEquipped = false;
|
||||||
ModifyMaximumHP(-accessory.MaxHPUp);
|
ModifyMaximumHP(-accessory.MaxHPUp);
|
||||||
ModifyMaximumVT(-accessory.MaxVTUp);
|
ModifyMaximumVT(-accessory.MaxVTUp);
|
||||||
ModifyBonusAttack(-accessory.ATKUp);
|
ModifyBonusAttack(-accessory.ATKUp);
|
||||||
ModifyBonusDefense(-accessory.DEFUp);
|
ModifyBonusDefense(-accessory.DEFUp);
|
||||||
ModifyBonusLuck(-accessory.LuckUp);
|
ModifyBonusLuck(-accessory.LuckUp);
|
||||||
_equippedAccessory.OnNext(new Accessory());
|
_equippedAccessory.OnNext(new Accessory());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
throw new NotImplementedException("Item type is not supported.");
|
throw new NotImplementedException("Item type is not supported.");
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Vector3 GlobalInputVector
|
private static Vector3 GlobalInputVector
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var rawInput = Input.GetVector(GameInputs.MoveLeft, GameInputs.MoveRight, GameInputs.MoveUp, GameInputs.MoveDown);
|
var rawInput = Input.GetVector(GameInputs.MoveLeft, GameInputs.MoveRight, GameInputs.MoveUp, GameInputs.MoveDown);
|
||||||
var input = new Vector3
|
var input = new Vector3
|
||||||
{
|
{
|
||||||
X = rawInput.X,
|
X = rawInput.X,
|
||||||
Z = rawInput.Y
|
Z = rawInput.Y
|
||||||
};
|
};
|
||||||
return input with { Y = 0f };
|
return input with { Y = 0f };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float LeftStrafeInputVector
|
private static float LeftStrafeInputVector
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Input.GetActionStrength(GameInputs.StrafeLeft);
|
return Input.GetActionStrength(GameInputs.StrafeLeft);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static float RightStrafeInputVector
|
private static float RightStrafeInputVector
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
return Input.GetActionStrength(GameInputs.StrafeRight);
|
return Input.GetActionStrength(GameInputs.StrafeRight);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ThrowItem()
|
private void ThrowItem()
|
||||||
{
|
{
|
||||||
var itemScene = GD.Load<PackedScene>("res://src/items/throwable/ThrowableItem.tscn");
|
var itemScene = GD.Load<PackedScene>("res://src/items/throwable/ThrowableItem.tscn");
|
||||||
var throwItem = itemScene.Instantiate<ThrowableItem>();
|
var throwItem = itemScene.Instantiate<ThrowableItem>();
|
||||||
GetTree().Root.AddChildEx(throwItem);
|
GetTree().Root.AddChildEx(throwItem);
|
||||||
throwItem.GlobalPosition = CurrentPosition + new Vector3(0, 3.5f, 0);
|
throwItem.GlobalPosition = CurrentPosition + new Vector3(0, 3.5f, 0);
|
||||||
throwItem.GlobalRotation = GlobalRotation;
|
throwItem.GlobalRotation = GlobalRotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PlayAttackAnimation()
|
private void PlayAttackAnimation()
|
||||||
{
|
{
|
||||||
var attackSpeed = ((Weapon)EquippedWeapon.Value).AttackSpeed;
|
var attackSpeed = ((Weapon)EquippedWeapon.Value).AttackSpeed;
|
||||||
AnimationPlayer.SetSpeedScale((float)attackSpeed);
|
AnimationPlayer.SetSpeedScale((float)attackSpeed);
|
||||||
if (EquippedWeapon.Value.ItemName == "Atonement")
|
if (EquippedWeapon.Value.ItemName == "Atonement")
|
||||||
AnimationPlayer.Play("atonement_attack");
|
AnimationPlayer.Play("atonement_attack");
|
||||||
else
|
else
|
||||||
AnimationPlayer.Play("attack");
|
AnimationPlayer.Play("attack");
|
||||||
_gameRepo.OnPlayerAttack();
|
_gameRepo.OnPlayerAttack();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnAnimationFinished(StringName animation)
|
private void OnAnimationFinished(StringName animation)
|
||||||
{
|
{
|
||||||
PlayerLogic.Input(new PlayerLogic.Input.AttackAnimationFinished());
|
PlayerLogic.Input(new PlayerLogic.Input.AttackAnimationFinished());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnExitTree()
|
private void OnExitTree()
|
||||||
{
|
{
|
||||||
PlayerLogic.Stop();
|
PlayerLogic.Stop();
|
||||||
PlayerBinding.Dispose();
|
PlayerBinding.Dispose();
|
||||||
AnimationPlayer.AnimationFinished -= OnAnimationFinished;
|
AnimationPlayer.AnimationFinished -= OnAnimationFinished;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnPlayerPositionUpdated(Vector3 globalPosition) => GlobalPosition = globalPosition;
|
private void OnPlayerPositionUpdated(Vector3 globalPosition) => GlobalPosition = globalPosition;
|
||||||
|
|
||||||
private void OnHealthTimerTimeout()
|
private void OnHealthTimerTimeout()
|
||||||
{
|
{
|
||||||
if (Stats.CurrentHP.Value <= 0)
|
if (Stats.CurrentHP.Value <= 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (Stats.CurrentVT.Value > 0)
|
if (Stats.CurrentVT.Value > 0)
|
||||||
{
|
{
|
||||||
if (((Accessory)EquippedAccessory.Value).AccessoryTag == AccessoryTag.HalfVTConsumption)
|
if (((Accessory)EquippedAccessory.Value).AccessoryTag == AccessoryTag.HalfVTConsumption)
|
||||||
{
|
{
|
||||||
reduceOnTick = !reduceOnTick;
|
reduceOnTick = !reduceOnTick;
|
||||||
}
|
}
|
||||||
Stats.SetCurrentHP(Stats.CurrentHP.Value + 1);
|
Stats.SetCurrentHP(Stats.CurrentHP.Value + 1);
|
||||||
if (reduceOnTick)
|
if (reduceOnTick)
|
||||||
Stats.SetCurrentVT(Stats.CurrentVT.Value - 1);
|
Stats.SetCurrentVT(Stats.CurrentVT.Value - 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
Stats.SetCurrentHP(Stats.CurrentHP.Value - 1);
|
Stats.SetCurrentHP(Stats.CurrentHP.Value - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EquippedWeapon_Sync(EquipableItem obj)
|
private void EquippedWeapon_Sync(EquipableItem obj)
|
||||||
{
|
{
|
||||||
ModifyBonusAttack(((Weapon)obj).Damage);
|
ModifyBonusAttack(((Weapon)obj).Damage);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EquippedArmor_Sync(EquipableItem obj)
|
private void EquippedArmor_Sync(EquipableItem obj)
|
||||||
{
|
{
|
||||||
ModifyBonusDefense(((Armor)obj).Defense);
|
ModifyBonusDefense(((Armor)obj).Defense);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EquippedAccessory_Sync(EquipableItem accessory)
|
private void EquippedAccessory_Sync(EquipableItem accessory)
|
||||||
{
|
{
|
||||||
ModifyMaximumHP(((Accessory)accessory).MaxHPUp);
|
ModifyMaximumHP(((Accessory)accessory).MaxHPUp);
|
||||||
ModifyMaximumVT(((Accessory)accessory).MaxVTUp);
|
ModifyMaximumVT(((Accessory)accessory).MaxVTUp);
|
||||||
ModifyBonusAttack(((Accessory)accessory).ATKUp);
|
ModifyBonusAttack(((Accessory)accessory).ATKUp);
|
||||||
ModifyBonusDefense(((Accessory)accessory).DEFUp);
|
ModifyBonusDefense(((Accessory)accessory).DEFUp);
|
||||||
ModifyBonusLuck(((Accessory)accessory).LuckUp);
|
ModifyBonusLuck(((Accessory)accessory).LuckUp);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CurrentHP_Sync(int newHealth)
|
private void CurrentHP_Sync(int newHealth)
|
||||||
{
|
{
|
||||||
if (newHealth <= 0)
|
if (newHealth <= 0)
|
||||||
Die();
|
Die();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CurrentEXP_Sync(double newExp)
|
private void CurrentEXP_Sync(double newExp)
|
||||||
{
|
{
|
||||||
if (Stats.CurrentExp.Value >= Stats.ExpToNextLevel.Value)
|
if (Stats.CurrentExp.Value >= Stats.ExpToNextLevel.Value)
|
||||||
LevelUp();
|
LevelUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Hitbox_AreaEntered(Area3D area)
|
private void Hitbox_AreaEntered(Area3D area)
|
||||||
{
|
{
|
||||||
var target = area.GetOwner();
|
var target = area.GetOwner();
|
||||||
if (target is IEnemy enemy)
|
if (target is IEnemy enemy)
|
||||||
HitEnemy(enemy);
|
HitEnemy(enemy);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void HitEnemy(IEnemy enemy)
|
private void HitEnemy(IEnemy enemy)
|
||||||
{
|
{
|
||||||
var attackValue = Stats.CurrentAttack.Value + Stats.BonusAttack.Value;
|
var attackValue = Stats.CurrentAttack.Value + Stats.BonusAttack.Value;
|
||||||
var ignoreElementalResistance = ((Weapon)EquippedWeapon.Value).WeaponTag == WeaponTag.IgnoreAffinity;
|
var ignoreElementalResistance = ((Weapon)EquippedWeapon.Value).WeaponTag == WeaponTag.IgnoreAffinity;
|
||||||
var isCriticalHit = BattleExtensions.IsCriticalHit(Stats.Luck.Value);
|
var isCriticalHit = BattleExtensions.IsCriticalHit(Stats.Luck.Value);
|
||||||
var element = ((Weapon)EquippedWeapon.Value).WeaponElement;
|
var element = ((Weapon)EquippedWeapon.Value).WeaponElement;
|
||||||
|
|
||||||
enemy.TakeDamage(
|
enemy.TakeDamage(
|
||||||
attackValue * ((Weapon)EquippedWeapon.Value).ElementalDamageBonus,
|
attackValue * ((Weapon)EquippedWeapon.Value).ElementalDamageBonus,
|
||||||
element,
|
element,
|
||||||
isCriticalHit,
|
isCriticalHit,
|
||||||
false,
|
false,
|
||||||
ignoreElementalResistance);
|
ignoreElementalResistance);
|
||||||
|
|
||||||
if (((Weapon)EquippedWeapon.Value).WeaponTag == WeaponTag.Knockback)
|
if (((Weapon)EquippedWeapon.Value).WeaponTag == WeaponTag.Knockback)
|
||||||
enemy.Knockback(0.3f, -CurrentBasis.Z.Normalized());
|
enemy.Knockback(0.3f, -CurrentBasis.Z.Normalized());
|
||||||
|
|
||||||
_gameRepo.OnPlayerAttackedEnemy();
|
_gameRepo.OnPlayerAttackedEnemy();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CollisionDetector_AreaEntered(Area3D area)
|
private void CollisionDetector_AreaEntered(Area3D area)
|
||||||
{
|
{
|
||||||
if (area.GetParent() is InventoryItem inventoryItem)
|
if (area.GetParent() is InventoryItem inventoryItem)
|
||||||
{
|
{
|
||||||
var isAdded = Inventory.TryAdd(inventoryItem);
|
var isAdded = Inventory.TryAdd(inventoryItem);
|
||||||
if (isAdded)
|
if (isAdded)
|
||||||
{
|
{
|
||||||
_gameRepo.AnnounceMessageOnMainScreen($"{inventoryItem.ItemName} picked up.");
|
_gameRepo.AnnounceMessageOnMainScreen($"{inventoryItem.ItemName} picked up.");
|
||||||
inventoryItem.QueueFree();
|
inventoryItem.QueueFree();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
_gameRepo.AnnounceMessageOnMainScreen($"Could not pick up {inventoryItem.ItemName}.");
|
_gameRepo.AnnounceMessageOnMainScreen($"Could not pick up {inventoryItem.ItemName}.");
|
||||||
}
|
}
|
||||||
if (area.GetParent() is DroppedItem droppedItem)
|
if (area.GetParent() is DroppedItem droppedItem)
|
||||||
{
|
{
|
||||||
var isAdded = Inventory.TryAdd(droppedItem.Item);
|
var isAdded = Inventory.TryAdd(droppedItem.Item);
|
||||||
if (isAdded)
|
if (isAdded)
|
||||||
{
|
{
|
||||||
_gameRepo.AnnounceMessageOnMainScreen($"{droppedItem.Item.ItemName} picked up.");
|
_gameRepo.AnnounceMessageOnMainScreen($"{droppedItem.Item.ItemName} picked up.");
|
||||||
droppedItem.QueueFree();
|
droppedItem.QueueFree();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
_gameRepo.AnnounceMessageOnMainScreen($"Could not pick up {droppedItem.Item.ItemName}.");
|
_gameRepo.AnnounceMessageOnMainScreen($"Could not pick up {droppedItem.Item.ItemName}.");
|
||||||
}
|
}
|
||||||
if (area.GetParent() is ThrownItem thrownItem)
|
if (area.GetParent() is ThrownItem thrownItem)
|
||||||
{
|
{
|
||||||
var isAdded = Inventory.TryAdd(thrownItem.ItemThatIsThrown);
|
var isAdded = Inventory.TryAdd(thrownItem.ItemThatIsThrown);
|
||||||
if (isAdded)
|
if (isAdded)
|
||||||
{
|
{
|
||||||
_gameRepo.AnnounceMessageOnMainScreen($"{thrownItem.ItemThatIsThrown.ItemName} picked up.");
|
_gameRepo.AnnounceMessageOnMainScreen($"{thrownItem.ItemThatIsThrown.ItemName} picked up.");
|
||||||
thrownItem.QueueFree();
|
thrownItem.QueueFree();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
_gameRepo.AnnounceMessageOnMainScreen($"Could not pick up {thrownItem.ItemThatIsThrown.ItemName}.");
|
_gameRepo.AnnounceMessageOnMainScreen($"Could not pick up {thrownItem.ItemThatIsThrown.ItemName}.");
|
||||||
}
|
}
|
||||||
if (area.GetParent() is Restorative restorative)
|
if (area.GetParent() is Restorative restorative)
|
||||||
{
|
{
|
||||||
_gameRepo.OnRestorativePickedUp(restorative);
|
_gameRepo.OnRestorativePickedUp(restorative);
|
||||||
restorative.QueueFree();
|
restorative.QueueFree();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private PlayerStats InitializePlayerStats()
|
private PlayerStats InitializePlayerStats()
|
||||||
{
|
{
|
||||||
var playerStats = new PlayerStats(
|
var playerStats = new PlayerStats(
|
||||||
currentHP: new AutoProp<int>(_playerStatResource.CurrentHP),
|
currentHP: new AutoProp<int>(_playerStatResource.CurrentHP),
|
||||||
maximumHP: new AutoProp<int>(_playerStatResource.MaximumHP),
|
maximumHP: new AutoProp<int>(_playerStatResource.MaximumHP),
|
||||||
currentVT: new AutoProp<int>(_playerStatResource.CurrentVT),
|
currentVT: new AutoProp<int>(_playerStatResource.CurrentVT),
|
||||||
maximumVT: new AutoProp<int>(_playerStatResource.MaximumVT),
|
maximumVT: new AutoProp<int>(_playerStatResource.MaximumVT),
|
||||||
currentAttack: new AutoProp<int>(_playerStatResource.CurrentAttack),
|
currentAttack: new AutoProp<int>(_playerStatResource.CurrentAttack),
|
||||||
currentDefense: new AutoProp<int>(_playerStatResource.CurrentDefense),
|
currentDefense: new AutoProp<int>(_playerStatResource.CurrentDefense),
|
||||||
maxAttack: new AutoProp<int>(_playerStatResource.MaxAttack),
|
maxAttack: new AutoProp<int>(_playerStatResource.MaxAttack),
|
||||||
maxDefense: new AutoProp<int>(_playerStatResource.MaxDefense),
|
maxDefense: new AutoProp<int>(_playerStatResource.MaxDefense),
|
||||||
bonusAttack: new AutoProp<int>(_playerStatResource.BonusAttack),
|
bonusAttack: new AutoProp<int>(_playerStatResource.BonusAttack),
|
||||||
bonusDefense: new AutoProp<int>(_playerStatResource.BonusDefense),
|
bonusDefense: new AutoProp<int>(_playerStatResource.BonusDefense),
|
||||||
currentExp: new AutoProp<double>(_playerStatResource.CurrentExp),
|
currentExp: new AutoProp<double>(_playerStatResource.CurrentExp),
|
||||||
expToNextLevel: new AutoProp<int>(_playerStatResource.ExpToNextLevel),
|
expToNextLevel: new AutoProp<int>(_playerStatResource.ExpToNextLevel),
|
||||||
currentLevel: new AutoProp<int>(_playerStatResource.CurrentLevel),
|
currentLevel: new AutoProp<int>(_playerStatResource.CurrentLevel),
|
||||||
luck: new AutoProp<double>(_playerStatResource.Luck));
|
luck: new AutoProp<double>(_playerStatResource.Luck));
|
||||||
|
|
||||||
return playerStats;
|
return playerStats;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool PlayerIsHittingGeometry()
|
private bool PlayerIsHittingGeometry()
|
||||||
{
|
{
|
||||||
var collisions = WallCheck.GetCollidingBodies();
|
var collisions = WallCheck.GetCollidingBodies();
|
||||||
return collisions.Count > 0;
|
return collisions.Count > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void WallCheck_BodyEntered(Node body)
|
private void WallCheck_BodyEntered(Node body)
|
||||||
{
|
{
|
||||||
PlayerLogic.Input(new PlayerLogic.Input.AttackAnimationFinished());
|
PlayerLogic.Input(new PlayerLogic.Input.AttackAnimationFinished());
|
||||||
GD.Print("Hit wall");
|
GD.Print("Hit wall");
|
||||||
AnimationPlayer.Stop();
|
AnimationPlayer.Stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -376,7 +376,6 @@ shape = SubResource("CapsuleShape3D_dw45s")
|
|||||||
unique_name_in_owner = true
|
unique_name_in_owner = true
|
||||||
process_mode = 1
|
process_mode = 1
|
||||||
wait_time = 3.0
|
wait_time = 3.0
|
||||||
autostart = true
|
|
||||||
|
|
||||||
[node name="Animation" type="Node3D" parent="."]
|
[node name="Animation" type="Node3D" parent="."]
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user