Implement most jewels

This commit is contained in:
2026-02-12 02:36:25 -08:00
parent 230b47061d
commit b475df6f68
27 changed files with 681 additions and 162 deletions

View File

@@ -21,6 +21,8 @@ public interface IEquipmentComponent : IEntityComponent
public void UpdateEquipment(EquipableItem equipable);
public bool AugmentableEquipmentExists();
public int BonusAttack { get; }
public int BonusDefense { get; }

View File

@@ -1,9 +1,174 @@
public class Augment
using Zennysoft.Ma.Adapter;
public class Augment
{
public JewelTags AugmentTag;
public Augment(JewelTags tag)
public Augment(JewelTags tag, IAugmentType augment)
{
AugmentTag = tag;
AugmentType = augment;
}
public IAugmentType AugmentType { get; set; }
}
public interface IAugmentType
{
void Apply();
void Remove();
}
public class HPRecoverySpeedAugment : IAugmentType
{
private readonly IPlayer _player;
public HPRecoverySpeedAugment(IPlayer player)
{
_player = player;
}
public void Apply() => _player.HealthTimerHPRate += 2;
public void Remove() => _player.HealthTimerHPRate -= 2;
}
public class BasicAugment : IAugmentType
{
public void Apply()
{
// do nothing
}
public void Remove()
{
// do nothing
}
}
public class HastenVTAugment : IAugmentType
{
private readonly IPlayer _player;
public HastenVTAugment(IPlayer player)
{
_player = player;
}
public void Apply() => _player.ModifyHealthTimerSpeed(_player.HealthTimerSpeedModifier + 0.25f);
public void Remove() => _player.ModifyHealthTimerSpeed(_player.HealthTimerSpeedModifier - 0.25f);
}
public class SlowVTReductionAugment : IAugmentType
{
private readonly IPlayer _player;
public SlowVTReductionAugment(IPlayer player)
{
_player = player;
}
public void Apply() => _player.ModifyHealthTimerSpeed(_player.HealthTimerSpeedModifier - 0.25f);
public void Remove() => _player.ModifyHealthTimerSpeed(_player.HealthTimerSpeedModifier + 0.25f);
}
public class IncreaseEXPRateAugment : IAugmentType
{
private readonly IPlayer _player;
public IncreaseEXPRateAugment(IPlayer player)
{
_player = player;
}
public void Apply() => _player.ExperiencePointsComponent.ModifyExpGainRate(_player.ExperiencePointsComponent.ExpGainRate.Value + 0.25f);
public void Remove() => _player.ExperiencePointsComponent.ModifyExpGainRate(_player.ExperiencePointsComponent.ExpGainRate.Value - 0.25f);
}
public class LowerEXPRateAugment : IAugmentType
{
private readonly IPlayer _player;
public LowerEXPRateAugment(IPlayer player)
{
_player = player;
}
public void Apply() => _player.ExperiencePointsComponent.ModifyExpGainRate(_player.ExperiencePointsComponent.ExpGainRate.Value - 0.25f);
public void Remove() => _player.ExperiencePointsComponent.ModifyExpGainRate(_player.ExperiencePointsComponent.ExpGainRate.Value + 0.25f);
}
public class LowerHPRecoveryAugment : IAugmentType
{
private readonly IPlayer _player;
public LowerHPRecoveryAugment(IPlayer player)
{
_player = player;
}
public void Apply() => _player.HealthTimerHPRate -= 1;
public void Remove() => _player.HealthTimerHPRate += 1;
}
public class IdentifyAllItemsAugment : IAugmentType
{
private readonly IPlayer _player;
public IdentifyAllItemsAugment(IPlayer player)
{
_player = player;
}
public void Apply()
{
_player.AutoIdentifyItems = true;
foreach (var item in _player.Inventory.Items.ToList())
{
if (item.ItemTag == ItemTag.MysteryItem)
_player.IdentifyItem(item);
}
}
public void Remove()
{
var weaponAugment = _player.EquipmentComponent.EquippedWeapon.Value.Augment;
var armorAugment = _player.EquipmentComponent.EquippedArmor.Value.Augment;
var accessoryAugment = _player.EquipmentComponent.EquippedAccessory.Value.Augment;
var augments = new List<Augment?>() { weaponAugment, armorAugment, accessoryAugment };
if (augments.Count(x => x != null && x.AugmentTag == JewelTags.AutoIdentifyAllItems) > 1)
return;
else
_player.AutoIdentifyItems = false;
}
}
public class RevivePlayerAugment : IAugmentType
{
private readonly IPlayer _player;
public RevivePlayerAugment(IPlayer player)
{
_player = player;
}
public void Apply()
{
_player.AutoRevive = true;
}
public void Remove()
{
var weaponAugment = _player.EquipmentComponent.EquippedWeapon.Value.Augment;
var armorAugment = _player.EquipmentComponent.EquippedArmor.Value.Augment;
var accessoryAugment = _player.EquipmentComponent.EquippedAccessory.Value.Augment;
var augments = new List<Augment?>() { weaponAugment, armorAugment, accessoryAugment };
if (augments.Count(x => x != null && x.AugmentTag == JewelTags.ReviveUserOnce) > 1)
return;
else
_player.AutoRevive = false;
}
}

View File

@@ -15,5 +15,7 @@ public enum JewelTags
SlowVTReduction,
AutoIdentifyAllItems,
ReviveUserOnce,
TelluricElement
TelluricElement,
IncreaseAtkDefLuck,
IncreaseLuck
}

View File

@@ -26,7 +26,9 @@ public interface IPlayer : IKillable, ICharacterBody3D
public void PlayJumpScareAnimation();
//public void AugmentItem(IAugmentItem jewel, EquipableItem equipableItem);
public void ApplyNewAugment(IAugmentItem jewel, EquipableItem equipableItem);
public void IdentifyItem(InventoryItem unidentifiedItem);
public IInventory Inventory { get; }
@@ -46,12 +48,20 @@ public interface IPlayer : IKillable, ICharacterBody3D
public void SetHealthTimerStatus(bool isActive);
public bool CanEquipState { get; set; }
public void ModifyHealthTimerSpeed(float newModifier);
public bool AutoRevive { get; set; }
public int TotalAttack { get; }
public int TotalDefense { get; }
public int TotalLuck { get; }
public int HealthTimerHPRate { get; set; }
public float HealthTimerSpeedModifier { get; }
public bool AutoIdentifyItems { get; set; }
public event Action PlayerDied;
public delegate InventoryItem RerollItem(InventoryItem item);
}

View File

@@ -0,0 +1 @@
uid://bevfcpew3kket

View File

@@ -87,4 +87,9 @@ public class EquipmentComponent : IEquipmentComponent
}
public void UpdateEquipment(EquipableItem equipable) => EquipmentChanged?.Invoke(equipable);
public bool AugmentableEquipmentExists()
{
return (_equippedWeapon.Value.ItemName != null && _equippedWeapon.Value.Augment == null) || (_equippedArmor.Value.ItemName != null && _equippedArmor.Value.Augment == null) || (_equippedAccessory.Value.ItemName != null && _equippedAccessory.Value.Augment == null);
}
}

View File

@@ -5,7 +5,6 @@ using Godot;
using System;
using System.Collections.Generic;
using System.Linq;
using Zennysoft.Game.Abstractions;
using Zennysoft.Game.Implementation;
using Zennysoft.Ma.Adapter;
@@ -92,7 +91,9 @@ public partial class Inventory : Node, IInventory
var consumables = listToSort.Where(x => x is ConsumableItem).OrderBy(x => x as ConsumableItem, new ConsumableComparer());
var throwables = listToSort.Where(x => x is ThrowableItem).OrderBy(x => x as ThrowableItem, new ThrowableComparer());
var effectItems = listToSort.Where(x => x is EffectItem).OrderBy(x => x as EffectItem, new EffectComparer());
Items = [.. equippedItems, .. weapons, .. armor, .. accessories, .. ammo, .. consumables, .. throwables, .. effectItems];
var jewelItems = listToSort.Where(x => x is Jewel).OrderBy(x => x as Jewel, new JewelComparer());
var setItems = listToSort.Where(x => x is Plastique).OrderBy(x => x as Plastique, new SetItemComparer());
Items = [.. equippedItems, .. weapons, .. armor, .. accessories, .. ammo, .. consumables, .. throwables, .. effectItems, .. jewelItems, .. setItems];
var stackableItems = Items.OfType<IStackable>();
var itemsToStack = stackableItems.GroupBy(x => ((InventoryItem)x).ItemName).Where(x => x.Count() > 1);
@@ -146,6 +147,22 @@ public partial class Inventory : Node, IInventory
}
}
public class JewelComparer : IComparer<Jewel>
{
public int Compare(Jewel x, Jewel y)
{
return x.ItemName.CompareTo(y.ItemName);
}
}
public class SetItemComparer : IComparer<Plastique>
{
public int Compare(Plastique x, Plastique y)
{
return x.ItemName.CompareTo(y.ItemName);
}
}
public class ConsumableComparer : IComparer<ConsumableItem>
{
public int Compare(ConsumableItem x, ConsumableItem y)

View File

@@ -17,6 +17,9 @@ public partial class Accessory : EquipableItem
public override void _Ready()
{
_sprite.Texture = Stats.Texture;
_bonusDamage = Stats.BonusAttack;
_bonusDefense = Stats.BonusDefense;
_bonusLuck = Stats.BonusLuck;
}
public override string ItemName => Stats.Name;
@@ -28,16 +31,16 @@ public partial class Accessory : EquipableItem
public override float ThrowSpeed => Stats.ThrowSpeed;
public override int BonusAttack => Stats.BonusAttack;
public override int BonusAttack { get => _bonusDamage; }
public override int BonusDefense => Stats.BonusDefense;
public override int BonusDefense { get => _bonusDefense; }
public override int BonusLuck { get => _bonusLuck; }
public override int BonusHP => Stats.BonusHP;
public override int BonusVT => Stats.BonusVT;
public override int BonusLuck { get => Stats.BonusLuck + _bonusLuck; }
public override ElementalResistanceSet ElementalResistance => new ElementalResistanceSet(Stats.AeolicResistance, Stats.HydricResistance, Stats.IgneousResistance, Stats.FerrumResistance, Stats.TelluricResistance, Stats.HolyResistance, Stats.CurseResistance);
[Save("accessory_tag")]
@@ -45,6 +48,12 @@ public partial class Accessory : EquipableItem
public override ItemTag ItemTag => Stats.ItemTag;
[Save("accessory_bonus_damage")]
private int _bonusDamage { get; set; } = 0;
[Save("accessory_bonus_damage")]
private int _bonusDefense { get; set; } = 0;
[Save("accessory_bonus_luck")]
private int _bonusLuck { get; set; } = 0;

View File

@@ -17,6 +17,9 @@ public partial class Armor : EquipableItem
public override void _Ready()
{
_sprite.Texture = Stats.Texture;
_bonusDamage = Stats.BonusAttack;
_bonusDefense = Stats.BonusDefense;
_bonusLuck = Stats.BonusLuck;
}
public override string ItemName => Stats.Name;
@@ -29,11 +32,17 @@ public partial class Armor : EquipableItem
public override float ThrowSpeed => Stats.ThrowSpeed;
public override int BonusDefense => Stats.BonusDefense + _bonusDefense;
public override int BonusAttack { get => _bonusDamage; }
public override int BonusLuck { get => Stats.BonusLuck + _bonusLuck; }
public override int BonusDefense { get => _bonusDefense; }
[Save("bonus_defense")]
public override int BonusLuck { get => _bonusLuck; }
[Save("armor_bonus_damage")]
private int _bonusDamage { get; set; } = 0;
[Save("armor_bonus_damage")]
private int _bonusDefense { get; set; } = 0;
[Save("armor_bonus_luck")]

View File

@@ -36,40 +36,4 @@ public partial class Jewel : InventoryItem, IAugmentItem
public JewelStats Stats { get; set; } = new JewelStats();
public JewelTags Augment => Stats.JewelTag;
public void ApplyAugment(Weapon weapon)
{
weapon.Augment = new Augment(Stats.JewelTag);
switch (Stats.JewelTag)
{
case JewelTags.AeolicElement:
weapon.Stats.WeaponElement = ElementType.Aeolic;
break;
}
}
public void ApplyAugment(Armor armor)
{
armor.Augment = new Augment(Stats.JewelTag);
switch (Stats.JewelTag)
{
case JewelTags.AeolicElement:
armor.Stats.AeolicResistance += 25;
break;
case JewelTags.HydricElement:
armor.Stats.HydricResistance += 25;
break;
case JewelTags.IgneousElement:
armor.Stats.IgneousResistance += 25;
break;
case JewelTags.TelluricElement:
armor.Stats.TelluricResistance += 25;
break;
}
}
public void ApplyAugment(Accessory accessory)
{
accessory.Augment = new Augment(Stats.JewelTag);
}
}

View File

@@ -5,6 +5,7 @@
[resource]
script = ExtResource("1_dxj8h")
JewelTag = 15
Name = "Black Egg"
Description = "Increase Attack, Defense, and Luck."
SpawnRate = 0.5

View File

@@ -5,6 +5,7 @@
[resource]
script = ExtResource("1_vvfsu")
JewelTag = 16
Name = "Cat's Eye"
Description = "Dramatically increases Luck."
SpawnRate = 0.5

View File

@@ -5,6 +5,7 @@
[resource]
script = ExtResource("1_k60ln")
JewelTag = 3
Name = "Cinnabar Structure"
Description = "Hastens VT, adds or improves Rust."
SpawnRate = 0.5

View File

@@ -5,6 +5,7 @@
[resource]
script = ExtResource("1_pn071")
JewelTag = 4
Name = "Foolish Orb"
Description = "Lowers EXP gain."
SpawnRate = 0.5

View File

@@ -5,6 +5,7 @@
[resource]
script = ExtResource("1_c23yr")
JewelTag = 5
Name = "Glue Orb"
Description = "Prevents item from being unequipped."
SpawnRate = 0.5

View File

@@ -5,6 +5,7 @@
[resource]
script = ExtResource("1_7gwjj")
JewelTag = 6
Name = "Heirloom Stone"
Description = "Returns item to the surface world."
SpawnRate = 0.5

View File

@@ -5,6 +5,7 @@
[resource]
script = ExtResource("1_qh03l")
JewelTag = 8
Name = "Igneous Jewel"
Description = ""
SpawnRate = 0.5

View File

@@ -5,8 +5,9 @@
[resource]
script = ExtResource("1_ivvck")
JewelTag = 9
Name = "Mercury Prism"
Description = ""
Description = "Increases EXP Gain rate."
SpawnRate = 0.5
BonusAttack = 0
BonusDefense = 0

View File

@@ -5,8 +5,9 @@
[resource]
script = ExtResource("1_cabnq")
JewelTag = 11
Name = "Metabolic Jewel"
Description = ""
Description = "Slows VT Rate reduction."
SpawnRate = 0.5
BonusAttack = 0
BonusDefense = 0

View File

@@ -5,8 +5,9 @@
[resource]
script = ExtResource("1_75k4l")
JewelTag = 12
Name = "Ossified Cortex"
Description = ""
Description = "Identifes all items automatically."
SpawnRate = 0.5
BonusAttack = 0
BonusDefense = 0

View File

@@ -5,8 +5,9 @@
[resource]
script = ExtResource("1_fkhpb")
JewelTag = 13
Name = "Rejection Stone"
Description = ""
Description = "Revives the user once. Breaks item on use."
SpawnRate = 0.5
BonusAttack = 0
BonusDefense = 0

View File

@@ -5,8 +5,9 @@
[resource]
script = ExtResource("1_868vv")
JewelTag = 0
Name = "Tarnished Jewel"
Description = ""
Description = "No effect."
SpawnRate = 0.5
BonusAttack = 0
BonusDefense = 0

View File

@@ -5,6 +5,7 @@
[resource]
script = ExtResource("2_c8kww")
JewelTag = 14
Name = "Telluric Jewel"
Description = "Add Telluric damage to Weapon or Telluric resistance to Armor."
SpawnRate = 0.5

View File

@@ -4,6 +4,7 @@ using Chickensoft.Introspection;
using Godot;
using SimpleInjector;
using System;
using System.Linq;
using Zennysoft.Ma.Adapter;
using Zennysoft.Ma.Adapter.Entity;
@@ -100,7 +101,17 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
#endregion
public bool CanEquipState { get; set; } = true;
[Export]
public int HealthTimerHPRate { get; set; } = 2;
[Export]
public bool AutoIdentifyItems { get; set; } = false;
[Export]
public float HealthTimerSpeedModifier { get; set; } = 1f;
[Export]
public bool AutoRevive { get; set; } = false;
private bool flipAttack = false;
@@ -126,6 +137,7 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
PlayerLogic.Set(Settings);
Inventory = new Inventory();
Inventory.InventoryChanged += Inventory_InventoryChanged;
HealthComponent = new HealthComponent(InitialHP);
VTComponent = new VTComponent(InitialVT);
AttackComponent = new AttackComponent(InitialAttack);
@@ -208,6 +220,19 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
HealthTimer.Stop();
}
public void ModifyHealthTimerSpeed(float newSpeed)
{
HealthTimerSpeedModifier = newSpeed;
HealthTimer.Stop();
HealthTimer.WaitTime = _healthTimerWaitTime * newSpeed;
HealthTimer.Start();
}
public void ModifyHealthRecoveryAmount(int newAmount)
{
}
public void TeleportPlayer((Vector3 Rotation, Vector3 Position) newTransform)
{
Rotation = newTransform.Rotation;
@@ -231,6 +256,8 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
public void PlayJumpScareAnimation() => PlayerFXAnimations.Play("jump_scare");
public void IdentifyItem(InventoryItem unidentifiedItem) => _itemReroller.RerollItem(unidentifiedItem, Inventory);
public int TotalAttack => AttackComponent.CurrentAttack.Value + EquipmentComponent.BonusAttack;
public int TotalDefense => DefenseComponent.CurrentDefense.Value + EquipmentComponent.BonusDefense;
@@ -245,6 +272,10 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
public void Die()
{
PlayerFXAnimations.Play("death");
if (AutoRevive)
return;
HealthTimer.WaitTime = _healthTimerWaitTime;
HealthTimer.Timeout -= OnHealthTimerTimeout;
SetProcessInput(false);
@@ -279,8 +310,9 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
HealthComponent.RaiseMaximumHP(equipable.BonusHP, false);
VTComponent.RaiseMaximumVT(equipable.BonusVT, false);
//if (equipable.Augment != null)
// Augment(equipable.Augment, equipable);
if (equipable.Augment != null)
equipable.Augment.AugmentType.Apply();
EquipmentComponent.Equip(equipable);
SfxDatabase.Instance.Play(SoundEffect.Equip);
@@ -293,8 +325,8 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
HealthComponent.SetMaximumHealth(HealthComponent.MaximumHP.Value - equipable.BonusHP);
VTComponent.SetMaximumVT(VTComponent.MaximumVT.Value - equipable.BonusVT);
//if (equipable.Augment != null)
// Deaugment(equipable.Augment);
if (equipable.Augment != null)
equipable.Augment.AugmentType.Remove();
EquipmentComponent.Unequip(equipable);
SfxDatabase.Instance.Play(SoundEffect.Unequip);
@@ -303,35 +335,175 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
PersuaderCrosshair.Hide();
}
//public void ApplyNewAugment(Jewel jewel, EquipableItem equipableItem)
//{
// _player.Inventory.Remove(jewel);
// jewel.ApplyAugment((dynamic)equipableItem);
// if (!_player.EquipmentComponent.IsItemEquipped(equipableItem))
// return;
// if (jewel.Stats.JewelTag == JewelTags.IncreaseEXPGain)
// _player.ExperiencePointsComponent.ModifyExpGainRate(_player.ExperiencePointsComponent.ExpGainRate.Value + 0.25f);
//}
private void Augment(IAugmentItem augment, EquipableItem equipable)
public void ApplyNewAugment(IAugmentItem augmentItem, EquipableItem equipableItem)
{
var jewel = augment as Jewel;
switch (augment.Augment)
var jewel = augmentItem as Jewel;
Inventory.Remove(jewel);
ApplyNewAugment((dynamic)equipableItem, jewel.Augment);
if (EquipmentComponent.IsItemEquipped(equipableItem))
equipableItem.Augment.AugmentType.Apply();
}
private void ApplyNewAugment(Weapon weapon, JewelTags tag)
{
case JewelTags.IncreaseEXPGain:
ExperiencePointsComponent.ModifyExpGainRate(ExperiencePointsComponent.ExpGainRate.Value + 0.25f);
switch (tag)
{
case JewelTags.AeolicElement:
weapon.Stats.WeaponElement = ElementType.Aeolic;
weapon.Augment = new Augment(JewelTags.AeolicElement, new BasicAugment());
break;
case JewelTags.HydricElement:
weapon.Stats.WeaponElement = ElementType.Hydric;
weapon.Augment = new Augment(JewelTags.HydricElement, new BasicAugment());
break;
case JewelTags.SlowVTReduction:
weapon.Augment = new Augment(JewelTags.SlowVTReduction, new SlowVTReductionAugment(this));
break;
case JewelTags.HastenVT:
weapon.Augment = new Augment(JewelTags.HastenVT, new HastenVTAugment(this));
break;
case JewelTags.ReviveUserOnce:
weapon.Augment = new Augment(JewelTags.ReviveUserOnce, new RevivePlayerAugment(this));
break;
case JewelTags.IncreaseHPRecovery:
weapon.Augment = new Augment(JewelTags.IncreaseHPRecovery, new HPRecoverySpeedAugment(this));
break;
case JewelTags.LowerEXPGain:
weapon.Augment = new Augment(JewelTags.LowerEXPGain, new LowerEXPRateAugment(this));
break;
case JewelTags.ItemRescue:
Inventory.Remove(weapon);
break;
case JewelTags.Glue:
weapon.Glued = true;
weapon.Augment = new Augment(JewelTags.Glue, new BasicAugment());
break;
case JewelTags.TelluricElement:
weapon.Stats.WeaponElement = ElementType.Telluric;
weapon.Augment = new Augment(JewelTags.TelluricElement, new BasicAugment());
break;
case JewelTags.AutoIdentifyAllItems:
weapon.Augment = new Augment(JewelTags.AutoIdentifyAllItems, new IdentifyAllItemsAugment(this));
break;
case JewelTags.IncreaseAtkDefLuck:
weapon.Stats.BonusAttack += 2;
weapon.Stats.BonusDefense += 2;
weapon.Stats.BonusLuck += 10;
weapon.Augment = new Augment(JewelTags.IncreaseAtkDefLuck, new BasicAugment());
break;
case JewelTags.IncreaseLuck:
weapon.Stats.BonusLuck += 25;
weapon.Augment = new Augment(JewelTags.IncreaseLuck, new BasicAugment());
break;
}
}
private void Deaugment(Augment augment)
private void ApplyNewAugment(Armor armor, JewelTags tag)
{
switch (augment.AugmentTag)
switch (tag)
{
case JewelTags.IncreaseEXPGain:
ExperiencePointsComponent.ModifyExpGainRate(ExperiencePointsComponent.ExpGainRate.Value - 0.25f);
case JewelTags.AeolicElement:
armor.Stats.AeolicResistance += 25;
armor.Augment = new Augment(JewelTags.AeolicElement, new BasicAugment());
break;
case JewelTags.HydricElement:
armor.Stats.HydricResistance += 25;
armor.Augment = new Augment(JewelTags.HydricElement, new BasicAugment());
break;
case JewelTags.SlowVTReduction:
armor.Augment = new Augment(JewelTags.SlowVTReduction, new SlowVTReductionAugment(this));
break;
case JewelTags.HastenVT:
armor.Augment = new Augment(JewelTags.HastenVT, new HastenVTAugment(this));
break;
case JewelTags.ReviveUserOnce:
armor.Augment = new Augment(JewelTags.ReviveUserOnce, new RevivePlayerAugment(this));
break;
case JewelTags.IncreaseHPRecovery:
armor.Augment = new Augment(JewelTags.IncreaseHPRecovery, new HPRecoverySpeedAugment(this));
break;
case JewelTags.LowerEXPGain:
armor.Augment = new Augment(JewelTags.LowerEXPGain, new LowerEXPRateAugment(this));
break;
case JewelTags.ItemRescue:
Inventory.Remove(armor);
break;
case JewelTags.Glue:
armor.Glued = true;
armor.Augment = new Augment(JewelTags.Glue, new BasicAugment());
break;
case JewelTags.TelluricElement:
armor.Stats.TelluricResistance += 25;
armor.Augment = new Augment(JewelTags.TelluricElement, new BasicAugment());
break;
case JewelTags.AutoIdentifyAllItems:
armor.Augment = new Augment(JewelTags.AutoIdentifyAllItems, new IdentifyAllItemsAugment(this));
break;
case JewelTags.IncreaseAtkDefLuck:
armor.Stats.BonusAttack += 2;
armor.Stats.BonusDefense += 2;
armor.Stats.BonusLuck += 10;
armor.Augment = new Augment(JewelTags.IncreaseAtkDefLuck, new BasicAugment());
break;
case JewelTags.IncreaseLuck:
armor.Stats.BonusLuck += 25;
armor.Augment = new Augment(JewelTags.IncreaseLuck, new BasicAugment());
break;
}
}
private void ApplyNewAugment(Accessory accessory, JewelTags tag)
{
switch (tag)
{
case JewelTags.AeolicElement:
accessory.Stats.AeolicResistance += 25;
accessory.Augment = new Augment(JewelTags.AeolicElement, new BasicAugment());
break;
case JewelTags.HydricElement:
accessory.Stats.HydricResistance += 25;
accessory.Augment = new Augment(JewelTags.HydricElement, new BasicAugment());
break;
case JewelTags.SlowVTReduction:
accessory.Augment = new Augment(JewelTags.SlowVTReduction, new SlowVTReductionAugment(this));
break;
case JewelTags.HastenVT:
accessory.Augment = new Augment(JewelTags.HastenVT, new HastenVTAugment(this));
break;
case JewelTags.ReviveUserOnce:
accessory.Augment = new Augment(JewelTags.ReviveUserOnce, new RevivePlayerAugment(this));
break;
case JewelTags.IncreaseHPRecovery:
accessory.Augment = new Augment(JewelTags.IncreaseHPRecovery, new HPRecoverySpeedAugment(this));
break;
case JewelTags.LowerEXPGain:
accessory.Augment = new Augment(JewelTags.LowerEXPGain, new LowerEXPRateAugment(this));
break;
case JewelTags.ItemRescue:
Inventory.Remove(accessory);
break;
case JewelTags.Glue:
accessory.Glued = true;
accessory.Augment = new Augment(JewelTags.Glue, new BasicAugment());
break;
case JewelTags.TelluricElement:
accessory.Stats.TelluricResistance += 25;
accessory.Augment = new Augment(JewelTags.TelluricElement, new BasicAugment());
break;
case JewelTags.AutoIdentifyAllItems:
accessory.Augment = new Augment(JewelTags.AutoIdentifyAllItems, new IdentifyAllItemsAugment(this));
break;
case JewelTags.IncreaseAtkDefLuck:
accessory.Stats.BonusAttack += 2;
accessory.Stats.BonusDefense += 2;
accessory.Stats.BonusLuck += 10;
accessory.Augment = new Augment(JewelTags.IncreaseAtkDefLuck, new BasicAugment());
break;
case JewelTags.IncreaseLuck:
accessory.Stats.BonusLuck += 25;
accessory.Augment = new Augment(JewelTags.IncreaseLuck, new BasicAugment());
break;
}
}
@@ -456,8 +628,43 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
private void PlayerFXAnimations_AnimationFinished(StringName animName)
{
if (animName == "death")
{
if (AutoRevive)
PlayerFXAnimations.PlayBackwards("revive");
else
PlayerDied?.Invoke();
}
if (animName == "revive")
{
Revive();
}
}
private void Revive()
{
HealthComponent.SetCurrentHealth(HealthComponent.MaximumHP.Value);
VTComponent.SetVT(VTComponent.MaximumVT.Value);
if (EquipmentComponent.EquippedAccessory.Value.Augment?.AugmentTag == JewelTags.ReviveUserOnce)
{
var itemToBreak = EquipmentComponent.EquippedAccessory.Value;
Unequip(EquipmentComponent.EquippedAccessory.Value);
Inventory.Remove(itemToBreak);
}
else if (EquipmentComponent.EquippedArmor.Value.Augment?.AugmentTag == JewelTags.ReviveUserOnce)
{
var itemToBreak = EquipmentComponent.EquippedArmor.Value;
Unequip(EquipmentComponent.EquippedArmor.Value);
Inventory.Remove(itemToBreak);
}
else if (EquipmentComponent.EquippedWeapon.Value.Augment?.AugmentTag == JewelTags.ReviveUserOnce)
{
var itemToBreak = EquipmentComponent.EquippedWeapon.Value;
Unequip(EquipmentComponent.EquippedWeapon.Value);
Inventory.Remove(itemToBreak);
}
else
PlayJumpScareAnimation();
}
private void InverseHPToAttackPowerSync(int obj)
{
@@ -595,4 +802,16 @@ public partial class Player : CharacterBody3D, IPlayer, IProvide<IPlayer>
GD.Print("Hit wall");
WeaponAnimations.Stop();
}
private void Inventory_InventoryChanged()
{
if (AutoIdentifyItems)
{
foreach (var item in Inventory.Items.ToList())
{
if (item.ItemTag == ItemTag.MysteryItem)
IdentifyItem(item);
}
}
}
}

View File

@@ -1,4 +1,4 @@
[gd_scene load_steps=1585 format=3 uid="uid://cfecvvav8kkp6"]
[gd_scene load_steps=1586 format=3 uid="uid://cfecvvav8kkp6"]
[ext_resource type="Script" uid="uid://yxmiqy7i0t7r" path="res://src/player/Player.cs" id="1_xcol5"]
[ext_resource type="PackedScene" uid="uid://didc6vnf5ftlg" path="res://src/camera/ShakeCamera.tscn" id="2_jtmj1"]
@@ -780,70 +780,6 @@ tracks/12/keys = {
"values": [127]
}
[sub_resource type="Animation" id="Animation_es4xk"]
resource_name = "death"
length = 2.5
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("../Camera/Camera3D:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 2),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [Vector3(0.003, 2.1, -0.01), Vector3(0.003, 0, -1)]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("../Camera/Camera3D/MeshInstance3D:mesh:material:shader")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(3.35872e-05),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [ExtResource("4_v5qoq")]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("../Camera/Camera3D/MeshInstance3D:mesh:material:shader_parameter/colorCount")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(-0.266666, 0, 0.0333338),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 0,
"values": [Vector3(640.06, 1, 640), Vector3(640, 640, 640), Vector3(640.06, 1, 640)]
}
tracks/3/type = "value"
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/path = NodePath("../Camera/Camera3D/MeshInstance3D:mesh:material:shader_parameter/includeAlpha")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [true]
}
tracks/4/type = "value"
tracks/4/imported = false
tracks/4/enabled = true
tracks/4/path = NodePath("../Camera/Camera3D/MeshInstance3D:mesh:material:shader_parameter/colorShift")
tracks/4/interp = 1
tracks/4/loop_wrap = true
tracks/4/keys = {
"times": PackedFloat32Array(0, 2.5),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [Vector3(1, 1, 1), Vector3(1, 1, 0)]
}
[sub_resource type="Animation" id="Animation_ebyyx"]
resource_name = "hit_wall"
length = 0.453127
@@ -930,6 +866,134 @@ tracks/1/keys = {
"values": [0, 30]
}
[sub_resource type="Animation" id="Animation_es4xk"]
resource_name = "death"
length = 2.5
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("../Camera/Camera3D:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 2),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [Vector3(0.003, 2.1, -0.01), Vector3(0.003, 0, -1)]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("../Camera/Camera3D/MeshInstance3D:mesh:material:shader")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(3.35872e-05),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [ExtResource("4_v5qoq")]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("../Camera/Camera3D/MeshInstance3D:mesh:material:shader_parameter/colorCount")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(-0.266666, 0, 0.0333338),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 0,
"values": [Vector3(640.06, 1, 640), Vector3(640, 640, 640), Vector3(640.06, 1, 640)]
}
tracks/3/type = "value"
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/path = NodePath("../Camera/Camera3D/MeshInstance3D:mesh:material:shader_parameter/includeAlpha")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [true]
}
tracks/4/type = "value"
tracks/4/imported = false
tracks/4/enabled = true
tracks/4/path = NodePath("../Camera/Camera3D/MeshInstance3D:mesh:material:shader_parameter/colorShift")
tracks/4/interp = 1
tracks/4/loop_wrap = true
tracks/4/keys = {
"times": PackedFloat32Array(0, 2.5),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [Vector3(1, 1, 1), Vector3(1, 1, 0)]
}
[sub_resource type="Animation" id="Animation_sq73w"]
resource_name = "revive"
length = 2.5
tracks/0/type = "value"
tracks/0/imported = false
tracks/0/enabled = true
tracks/0/path = NodePath("../Camera/Camera3D:position")
tracks/0/interp = 1
tracks/0/loop_wrap = true
tracks/0/keys = {
"times": PackedFloat32Array(0, 2),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [Vector3(0.003, 2.1, -0.01), Vector3(0.003, 0, -1)]
}
tracks/1/type = "value"
tracks/1/imported = false
tracks/1/enabled = true
tracks/1/path = NodePath("../Camera/Camera3D/MeshInstance3D:mesh:material:shader")
tracks/1/interp = 1
tracks/1/loop_wrap = true
tracks/1/keys = {
"times": PackedFloat32Array(3.35872e-05),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [ExtResource("4_v5qoq")]
}
tracks/2/type = "value"
tracks/2/imported = false
tracks/2/enabled = true
tracks/2/path = NodePath("../Camera/Camera3D/MeshInstance3D:mesh:material:shader_parameter/colorCount")
tracks/2/interp = 1
tracks/2/loop_wrap = true
tracks/2/keys = {
"times": PackedFloat32Array(-0.266666, 0, 0.0333338),
"transitions": PackedFloat32Array(1, 1, 1),
"update": 0,
"values": [Vector3(640.06, 1, 640), Vector3(640, 640, 640), Vector3(640.06, 1, 640)]
}
tracks/3/type = "value"
tracks/3/imported = false
tracks/3/enabled = true
tracks/3/path = NodePath("../Camera/Camera3D/MeshInstance3D:mesh:material:shader_parameter/includeAlpha")
tracks/3/interp = 1
tracks/3/loop_wrap = true
tracks/3/keys = {
"times": PackedFloat32Array(0),
"transitions": PackedFloat32Array(1),
"update": 1,
"values": [true]
}
tracks/4/type = "value"
tracks/4/imported = false
tracks/4/enabled = true
tracks/4/path = NodePath("../Camera/Camera3D/MeshInstance3D:mesh:material:shader_parameter/colorShift")
tracks/4/interp = 1
tracks/4/loop_wrap = true
tracks/4/keys = {
"times": PackedFloat32Array(0, 2.5),
"transitions": PackedFloat32Array(1, 1),
"update": 0,
"values": [Vector3(1, 1, 1), Vector3(1, 1, 0)]
}
[sub_resource type="AnimationLibrary" id="AnimationLibrary_ebyyx"]
_data = {
&"Divinity_Recall": SubResource("Animation_j5wmh"),
@@ -939,7 +1003,8 @@ _data = {
&"death": SubResource("Animation_es4xk"),
&"hit_wall": SubResource("Animation_ebyyx"),
&"jump_scare": SubResource("Animation_wvcio"),
&"normal_attack": SubResource("Animation_v5qoq")
&"normal_attack": SubResource("Animation_v5qoq"),
&"revive": SubResource("Animation_sq73w")
}
[sub_resource type="Animation" id="Animation_74hqa"]
@@ -10273,6 +10338,7 @@ collision_layer = 802
collision_mask = 775
script = ExtResource("1_xcol5")
HealthTimerIsActive = true
AutoRevive = true
[node name="MainCollision" type="CollisionShape3D" parent="."]
unique_name_in_owner = true

View File

@@ -109,7 +109,8 @@ public partial class InventoryMenu2 : Control, IInventoryMenu
var item = _currentlySelected.Item.Value;
if (_augmentMode)
{
//_player.AugmentItem(_augmentingJewel, item as EquipableItem);
_player.ApplyNewAugment(_augmentingJewel, item as EquipableItem);
_augmentMode = false;
ResetInventoryState();
}
else if (item is EquipableItem equipable)
@@ -120,18 +121,23 @@ public partial class InventoryMenu2 : Control, IInventoryMenu
{
_player.Equip(equipable);
}
foreach (var slot in ItemSlots)
slot.SetItemEquipmentStatus(_player.EquipmentComponent.IsItemEquipped(slot.Item.Value));
ResetInventoryState();
}
else if (item is Plastique plastique)
{
_game.SetItem(plastique);
ResetInventoryState();
}
else if (item is Jewel jewel)
{
_augmentMode = true;
AugmentMode(jewel);
}
else
{
_game.UseItem(_currentlySelected.Item.Value);
ResetInventoryState();
}
CloseActionMenu();
}
@@ -143,7 +149,7 @@ public partial class InventoryMenu2 : Control, IInventoryMenu
_game.DropItem(_currentlySelected.Item.Value);
CloseActionMenu();
_gameRepo.CloseInventory();
if (!_player.Inventory.Items.Contains(_currentlySelected.Item.Value))
if (_currentlySelected != null && !_player.Inventory.Items.Contains(_currentlySelected.Item.Value))
_currentlySelected = ItemSlots[previousItemInList];
}
@@ -153,7 +159,7 @@ public partial class InventoryMenu2 : Control, IInventoryMenu
_game.ThrowItem(_currentlySelected.Item.Value);
CloseActionMenu();
_gameRepo.CloseInventory();
if (!_player.Inventory.Items.Contains(_currentlySelected.Item.Value))
if (_currentlySelected != null && !_player.Inventory.Items.Contains(_currentlySelected.Item.Value))
_currentlySelected = ItemSlots[previousItemInList];
}
@@ -162,10 +168,16 @@ public partial class InventoryMenu2 : Control, IInventoryMenu
if (ActionPanel.Visible && Input.IsActionJustPressed(GameInputs.Interact))
{
CloseActionMenu();
_augmentMode = false;
SfxDatabase.Instance.Play(SoundEffect.CancelUI);
GetViewport().SetInputAsHandled();
}
else if (_augmentMode && !ActionPanel.Visible && Input.IsActionJustPressed(GameInputs.Interact))
{
GetViewport().SetInputAsHandled();
_augmentMode = false;
SfxDatabase.Instance.Play(SoundEffect.CancelUI);
ResetInventoryState();
}
if (!ActionPanel.Visible && Input.IsActionJustPressed(GameInputs.MoveUp))
{
if (ItemSlots.First(x => x.Visible) != _currentlySelected)
@@ -216,12 +228,20 @@ public partial class InventoryMenu2 : Control, IInventoryMenu
{
var itemIsEquipped = _player.EquipmentComponent.IsItemEquipped(equipable);
InteractButton.Text = itemIsEquipped ? "Unequip" : "Equip";
InteractButton.Disabled = itemIsEquipped && equipable.Glued;
ThrowButton.Disabled = itemIsEquipped;
ThrowButton.FocusMode = itemIsEquipped ? FocusModeEnum.None : FocusModeEnum.All;
DropButton.Disabled = itemIsEquipped;
DropButton.FocusMode = itemIsEquipped ? FocusModeEnum.None : FocusModeEnum.All;
InteractButton.GrabFocus();
if ((item is Weapon weapon && _player.EquipmentComponent.EquippedWeapon.Value.Glued) ||
(item is Armor && _player.EquipmentComponent.EquippedArmor.Value.Glued) ||
(item is Accessory && _player.EquipmentComponent.EquippedAccessory.Value.Glued))
{
InteractButton.Disabled = true;
InteractButton.FocusMode = FocusModeEnum.None;
ThrowButton.GrabFocus();
}
}
else if (item is Plastique plastique)
{
@@ -250,8 +270,6 @@ public partial class InventoryMenu2 : Control, IInventoryMenu
private void ResetInventoryState()
{
_augmentMode = false;
foreach (var item in ItemSlots)
{
item.Hide();
@@ -271,18 +289,28 @@ public partial class InventoryMenu2 : Control, IInventoryMenu
{
var item = _player.Inventory.Items[i];
ItemSlots[i].Item.OnNext(item);
ItemSlots[i].FocusMode = FocusModeEnum.All;
ItemSlots[i].Disabled = false;
ItemSlots[i].Show();
ItemSlots[i].SetItemEquipmentStatus(_player.EquipmentComponent.IsItemEquipped(item));
if (item is IStackable stackable)
ItemCountLabels[i].Text = $"x{stackable.Count.Value:D2}";
if (item is EquipableItem equipable && equipable.Glued)
{
ItemSlots[i].FocusMode = FocusModeEnum.None;
ItemSlots[i].Disabled = true;
}
else
{
ItemSlots[i].FocusMode = FocusModeEnum.All;
ItemSlots[i].Disabled = false;
}
}
if (_currentlySelected == null || _currentlySelected.Disabled || _currentlySelected.FocusMode == FocusModeEnum.None)
_currentlySelected = ItemSlots.FirstOrDefault(x => !x.Disabled);
if (_currentlySelected != null)
_currentlySelected.GrabFocus();
else
_currentlySelected = ItemSlots.First();
}
private void Slot_FocusEntered(IItemSlot slot)
@@ -316,6 +344,7 @@ public partial class InventoryMenu2 : Control, IInventoryMenu
private void CloseActionMenu()
{
if (_currentlySelected != null)
_currentlySelected.GrabFocus();
ActionPanel.Hide();
}

View File

@@ -76,6 +76,14 @@ public partial class ItemRescueMenu : Control
InteractButton.Pressed += InteractButton_Pressed;
DropButton.Pressed += DropButton_Pressed;
_currentlySelected = ItemSlot01;
VisibilityChanged += ItemRescueMenu_VisibilityChanged;
}
private void ItemRescueMenu_VisibilityChanged()
{
ResetInventoryState();
_currentlySelected = ItemSlot01;
_currentlySelected.GrabFocus();
}
private void InteractButton_Pressed()