Implementation of saving inventory items (had to resturcture texture loading)
This commit is contained in:
219
src/items/EffectService.cs
Normal file
219
src/items/EffectService.cs
Normal file
@@ -0,0 +1,219 @@
|
||||
using Godot;
|
||||
using System.Linq;
|
||||
using System;
|
||||
|
||||
namespace GameJamDungeon.src.items
|
||||
{
|
||||
public class EffectService
|
||||
{
|
||||
private readonly IGame _game;
|
||||
private readonly IPlayer _player;
|
||||
|
||||
public EffectService(IGame game, IPlayer player)
|
||||
{
|
||||
_game = game;
|
||||
_player = player;
|
||||
}
|
||||
|
||||
public void TeleportEnemiesToCurrentRoom()
|
||||
{
|
||||
var currentFloor = _game.CurrentFloor;
|
||||
var rooms = currentFloor.Rooms;
|
||||
var currentRoom = _player.GetCurrentRoom();
|
||||
|
||||
if (currentRoom is not MonsterRoom)
|
||||
return;
|
||||
|
||||
var validRooms = rooms.OfType<MonsterRoom>().ToList();
|
||||
if (currentRoom is MonsterRoom monsterRoom)
|
||||
validRooms.Remove(monsterRoom);
|
||||
|
||||
var currentMonsterRoom = (MonsterRoom)currentRoom;
|
||||
|
||||
var enemyList = validRooms.SelectMany(x => x.GetEnemiesInCurrentRoom());
|
||||
|
||||
foreach (var enemy in enemyList)
|
||||
{
|
||||
var spawnPoints = currentMonsterRoom.EnemySpawnPoints.GetChildren().OfType<Marker3D>().ToList();
|
||||
var spawnPointsGodotCollection = new Godot.Collections.Array<Marker3D>(spawnPoints);
|
||||
var randomSpawnPoint = spawnPointsGodotCollection.PickRandom();
|
||||
enemy.SetEnemyGlobalPosition(randomSpawnPoint.GlobalPosition);
|
||||
}
|
||||
}
|
||||
|
||||
public void KillHalfEnemiesInRoom()
|
||||
{
|
||||
var currentRoom = _player.GetCurrentRoom();
|
||||
if (currentRoom is not MonsterRoom)
|
||||
return;
|
||||
|
||||
var currentMonsterRoom = (MonsterRoom)currentRoom;
|
||||
var enemyList = currentMonsterRoom.GetEnemiesInCurrentRoom().ToList();
|
||||
var enemiesToKill = enemyList.Count / 2;
|
||||
for (var i = 0; i < enemiesToKill; i++)
|
||||
enemyList[i].Die();
|
||||
}
|
||||
|
||||
public void TurnAllEnemiesInRoomIntoHealingItem()
|
||||
{
|
||||
var currentRoom = _player.GetCurrentRoom();
|
||||
var currentEnemies = currentRoom.EnemiesInRoom;
|
||||
foreach (var enemy in currentEnemies)
|
||||
{
|
||||
enemy.Die();
|
||||
DropHealingItem(enemy.GetEnemyGlobalPosition());
|
||||
}
|
||||
}
|
||||
|
||||
public void DropHealingItem(Vector3 vector)
|
||||
{
|
||||
var consumableFolder = "res://src/items/consumable";
|
||||
var restorativeScene = GD.Load<PackedScene>($"{consumableFolder}/ConsumableItem.tscn");
|
||||
var consumable = restorativeScene.Instantiate<ConsumableItem>();
|
||||
var resourceFiles = DirAccess.GetFilesAt($"{consumableFolder}/resources");
|
||||
var rng = new RandomNumberGenerator();
|
||||
rng.Randomize();
|
||||
var randomResource = resourceFiles[rng.RandiRange(0, resourceFiles.Length - 1)];
|
||||
var randomFile = ResourceLoader.Load<ConsumableItemStats>($"{consumableFolder}/resources/{randomResource}");
|
||||
consumable.ItemStats = randomFile;
|
||||
_game.AddChild(consumable);
|
||||
consumable.GlobalPosition = vector;
|
||||
}
|
||||
|
||||
public void HealAllEnemiesAndPlayerInRoomToFull()
|
||||
{
|
||||
var currentRoom = _player.GetCurrentRoom();
|
||||
var currentEnemies = currentRoom.EnemiesInRoom;
|
||||
foreach (var enemy in currentEnemies)
|
||||
enemy.SetCurrentHP(enemy.GetMaximumHP());
|
||||
_player.Stats.SetCurrentHP(_player.Stats.MaximumHP.Value);
|
||||
}
|
||||
|
||||
public void AbsorbHPFromAllEnemiesInRoom()
|
||||
{
|
||||
var currentRoom = _player.GetCurrentRoom();
|
||||
var currentEnemies = currentRoom.EnemiesInRoom;
|
||||
var hpToAbsorb = 0.0;
|
||||
foreach (var enemy in currentEnemies)
|
||||
hpToAbsorb += enemy.CurrentHP * 0.05;
|
||||
_player.Stats.SetCurrentHP(_player.Stats.CurrentHP.Value + (int)hpToAbsorb);
|
||||
GD.Print("HP to absorb: " + hpToAbsorb);
|
||||
}
|
||||
|
||||
public void DealElementalDamageToAllEnemiesInRoom(ElementType elementType)
|
||||
{
|
||||
var currentRoom = _player.GetCurrentRoom();
|
||||
var currentEnemies = currentRoom.EnemiesInRoom;
|
||||
foreach (var enemy in currentEnemies)
|
||||
enemy.TakeDamage(20, elementType);
|
||||
}
|
||||
|
||||
public void SwapHPandVT()
|
||||
{
|
||||
var oldHp = _player.Stats.CurrentHP.Value;
|
||||
var oldVt = _player.Stats.CurrentVT.Value;
|
||||
|
||||
_player.Stats.SetCurrentHP(oldVt);
|
||||
_player.Stats.SetCurrentVT(oldHp);
|
||||
}
|
||||
|
||||
public void RandomEffect(EffectItem item)
|
||||
{
|
||||
var itemEffects = Enum.GetValues<UsableItemTag>().ToList();
|
||||
itemEffects.Remove(UsableItemTag.RandomEffect);
|
||||
itemEffects.Remove(UsableItemTag.None);
|
||||
var randomEffect = new Godot.Collections.Array<UsableItemTag>(itemEffects).PickRandom();
|
||||
item.SetEffectTag(randomEffect);
|
||||
_game.UseItem(item);
|
||||
}
|
||||
|
||||
public void RaiseCurrentWeaponAttack()
|
||||
{
|
||||
if (_player.EquippedWeapon.Value.ItemName == string.Empty)
|
||||
return;
|
||||
|
||||
var currentWeapon = _player.EquippedWeapon.Value;
|
||||
currentWeapon.IncreaseWeaponAttack(1);
|
||||
}
|
||||
|
||||
public void RaiseCurrentArmorDefense()
|
||||
{
|
||||
if (_player.EquippedArmor.Value.ItemName == string.Empty)
|
||||
return;
|
||||
|
||||
var currentArmor = _player.EquippedArmor.Value;
|
||||
currentArmor.IncreaseArmorDefense(1);
|
||||
}
|
||||
|
||||
public void RaiseLevel()
|
||||
{
|
||||
_player.LevelUp();
|
||||
}
|
||||
|
||||
public void TeleportToRandomRoom(IEnemy enemy)
|
||||
{
|
||||
var currentFloor = _game.CurrentFloor;
|
||||
var rooms = currentFloor.Rooms;
|
||||
var currentRoom = enemy.GetCurrentRoom();
|
||||
var validRooms = rooms.OfType<MonsterRoom>().ToList();
|
||||
if (currentRoom is MonsterRoom currentMonsterRoom)
|
||||
validRooms.Remove(currentMonsterRoom);
|
||||
|
||||
if (validRooms.Count == 0)
|
||||
return;
|
||||
|
||||
var roomsGodotCollection = new Godot.Collections.Array<MonsterRoom>(validRooms);
|
||||
var randomRoom = roomsGodotCollection.PickRandom();
|
||||
var spawnPoints = randomRoom.EnemySpawnPoints.GetChildren().OfType<Marker3D>().ToList();
|
||||
var spawnPointsGodotCollection = new Godot.Collections.Array<Marker3D>(spawnPoints);
|
||||
var randomSpawnPoint = spawnPointsGodotCollection.PickRandom();
|
||||
|
||||
enemy.SetEnemyGlobalPosition(randomSpawnPoint.GlobalPosition);
|
||||
}
|
||||
|
||||
public void TeleportToRandomRoom(IPlayer player)
|
||||
{
|
||||
var currentFloor = _game.CurrentFloor;
|
||||
var rooms = currentFloor.Rooms;
|
||||
|
||||
var currentRoom = rooms.SingleOrDefault(x => x.IsPlayerInRoom);
|
||||
|
||||
var validRooms = rooms.OfType<MonsterRoom>().ToList();
|
||||
if (currentRoom is MonsterRoom currentMonsterRoom)
|
||||
validRooms.Remove(currentMonsterRoom);
|
||||
|
||||
if (validRooms.Count == 0)
|
||||
return;
|
||||
|
||||
var roomsGodotCollection = new Godot.Collections.Array<MonsterRoom>(validRooms);
|
||||
var randomRoom = roomsGodotCollection.PickRandom();
|
||||
var spawnPoint = randomRoom.PlayerSpawn;
|
||||
_game.ToggleInventory();
|
||||
player.TeleportPlayer(spawnPoint.GlobalPosition);
|
||||
}
|
||||
|
||||
public void ChangeAffinity(ThrowableItem throwableItem)
|
||||
{
|
||||
var maximumElements = Enum.GetNames(typeof(ElementType)).Length;
|
||||
throwableItem.SetElementType(throwableItem.ElementType + 1 % maximumElements);
|
||||
|
||||
// TODO: Make this an inventory animation to cycle through elements.
|
||||
throwableItem.SetDescription(
|
||||
$"Inflicts {throwableItem.ElementType} damage when thrown." +
|
||||
$"{System.Environment.NewLine}Use item to change Affinity.");
|
||||
}
|
||||
|
||||
public void WarpToExit(IPlayer player)
|
||||
{
|
||||
var exitRoom = _game.CurrentFloor.Rooms.OfType<ExitRoom>().Single();
|
||||
if (exitRoom.PlayerDiscoveredRoom)
|
||||
player.TeleportPlayer(exitRoom.PlayerSpawn.GlobalPosition);
|
||||
}
|
||||
|
||||
public void WarpToExit(IEnemy enemy)
|
||||
{
|
||||
var exitRoom = _game.CurrentFloor.Rooms.OfType<ExitRoom>().Single();
|
||||
enemy.SetEnemyGlobalPosition(exitRoom.PlayerSpawn.GlobalPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
1
src/items/EffectService.cs.uid
Normal file
1
src/items/EffectService.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cnvyubmj6u7qw
|
||||
13
src/items/EquipableItem.cs
Normal file
13
src/items/EquipableItem.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using Chickensoft.Introspection;
|
||||
using Chickensoft.Serialization;
|
||||
|
||||
namespace GameJamDungeon;
|
||||
|
||||
[Meta]
|
||||
public abstract partial class EquipableItem : InventoryItem
|
||||
{
|
||||
public abstract ItemTag ItemTag { get; }
|
||||
|
||||
[Save("equipable_item_is_equipped")]
|
||||
public bool IsEquipped { get; set; }
|
||||
}
|
||||
1
src/items/EquipableItem.cs.uid
Normal file
1
src/items/EquipableItem.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://cw8s4mjrde4no
|
||||
@@ -1,10 +0,0 @@
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace GameJamDungeon;
|
||||
|
||||
public interface IEquipableItem : IInventoryItem
|
||||
{
|
||||
public ImmutableList<ItemTag> ItemTags { get; }
|
||||
|
||||
public bool IsEquipped { get; }
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
using Chickensoft.AutoInject;
|
||||
using Chickensoft.GodotNodeInterfaces;
|
||||
using Chickensoft.Introspection;
|
||||
using Chickensoft.Serialization;
|
||||
using Godot;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@@ -8,11 +10,11 @@ namespace GameJamDungeon;
|
||||
|
||||
public interface IInventory : INode
|
||||
{
|
||||
public List<IInventoryItem> Items { get; }
|
||||
public List<InventoryItem> Items { get; }
|
||||
|
||||
public bool TryAdd(IInventoryItem inventoryItem);
|
||||
public bool TryAdd(InventoryItem inventoryItem);
|
||||
|
||||
public void Remove(IInventoryItem inventoryItem);
|
||||
public void Remove(InventoryItem inventoryItem);
|
||||
|
||||
public void Sort();
|
||||
|
||||
@@ -21,6 +23,7 @@ public interface IInventory : INode
|
||||
event Inventory.PickedUpItemEventHandler PickedUpItem;
|
||||
}
|
||||
|
||||
[Meta, Id("inventory")]
|
||||
public partial class Inventory : Node, IInventory
|
||||
{
|
||||
public override void _Notification(int what) => this.Notify(what);
|
||||
@@ -38,9 +41,10 @@ public partial class Inventory : Node, IInventory
|
||||
Items = [];
|
||||
}
|
||||
|
||||
public List<IInventoryItem> Items { get; private set; }
|
||||
[Save("inventory_items")]
|
||||
public List<InventoryItem> Items { get; private set; }
|
||||
|
||||
public bool TryAdd(IInventoryItem inventoryItem)
|
||||
public bool TryAdd(InventoryItem inventoryItem)
|
||||
{
|
||||
if (Items.Count >= _maxInventorySize)
|
||||
{
|
||||
@@ -53,7 +57,7 @@ public partial class Inventory : Node, IInventory
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Remove(IInventoryItem inventoryItem) => Items.Remove(inventoryItem);
|
||||
public void Remove(InventoryItem inventoryItem) => Items.Remove(inventoryItem);
|
||||
|
||||
|
||||
public void Sort()
|
||||
@@ -61,7 +65,7 @@ public partial class Inventory : Node, IInventory
|
||||
var equippedWeapon = Items.OfType<Weapon>().Where(x => x.IsEquipped);
|
||||
var equippedArmor = Items.OfType<Armor>().Where(x => x.IsEquipped);
|
||||
var equippedAccessory = Items.OfType<Accessory>().Where(x => x.IsEquipped);
|
||||
var equippedItems = new List<IInventoryItem>();
|
||||
var equippedItems = new List<InventoryItem>();
|
||||
equippedItems.AddRange(equippedWeapon);
|
||||
equippedItems.AddRange(equippedArmor);
|
||||
equippedItems.AddRange(equippedAccessory);
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
using Chickensoft.GodotNodeInterfaces;
|
||||
using Chickensoft.Introspection;
|
||||
using Chickensoft.Serialization;
|
||||
using Godot;
|
||||
using System;
|
||||
|
||||
@@ -17,13 +19,22 @@ public interface IInventoryItem : INode3D
|
||||
double ThrowDamage { get; }
|
||||
|
||||
float ThrowSpeed { get; }
|
||||
|
||||
Texture2D GetTexture();
|
||||
|
||||
public void SetItemStats(InventoryItemStats inventoryItemStats);
|
||||
}
|
||||
|
||||
public interface IUsableItem : IInventoryItem
|
||||
[Meta]
|
||||
public abstract partial class InventoryItem : Node3D, IInventoryItem
|
||||
{
|
||||
public void Use();
|
||||
[Save("inventory_item_id")]
|
||||
public Guid ID => Guid.NewGuid();
|
||||
public abstract string ItemName { get; }
|
||||
public abstract string Description { get; }
|
||||
[Save("inventory_item_spawn_rate")]
|
||||
public abstract float SpawnRate { get; }
|
||||
[Save("inventory_item_throw_damage")]
|
||||
public abstract double ThrowDamage { get; }
|
||||
[Save("inventory_item_throw_speed")]
|
||||
public abstract float ThrowSpeed { get; }
|
||||
|
||||
[Save("inventory_item_stats")]
|
||||
public abstract InventoryItemStats ItemStats { get; set; }
|
||||
}
|
||||
|
||||
@@ -1,16 +1,22 @@
|
||||
using Chickensoft.Introspection;
|
||||
using Chickensoft.Serialization;
|
||||
using Godot;
|
||||
|
||||
namespace GameJamDungeon;
|
||||
|
||||
[Meta, Id("inventory_item_stats")]
|
||||
public partial class InventoryItemStats : Resource
|
||||
{
|
||||
[Export]
|
||||
public string Name = string.Empty;
|
||||
[Save("inventory_item_name")]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
[Export(PropertyHint.MultilineText)]
|
||||
public string Description = string.Empty;
|
||||
[Save("inventory_item_description")]
|
||||
public string Description { get; set; } = string.Empty;
|
||||
|
||||
[Export]
|
||||
public Texture2D Texture { get; set; }
|
||||
[Save("inventory_item_texture")]
|
||||
[Export] public Texture2D Texture { get; set; } = default!;
|
||||
|
||||
[Export(PropertyHint.Range, "0, 1, 0.01")]
|
||||
public float SpawnRate { get; set; } = 0.5f;
|
||||
@@ -28,5 +34,5 @@ public partial class InventoryItemStats : Resource
|
||||
public int ThrowDamage { get; set; } = 5;
|
||||
|
||||
[Export]
|
||||
public Godot.Collections.Array<ItemTag> ItemTags { get; set; } = new Godot.Collections.Array<ItemTag>();
|
||||
public ItemTag ItemTag { get; set; } = ItemTag.None;
|
||||
}
|
||||
67
src/items/InventoryItemTextureExtensions.cs
Normal file
67
src/items/InventoryItemTextureExtensions.cs
Normal file
@@ -0,0 +1,67 @@
|
||||
using Godot;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
using System.Text.Json;
|
||||
using System;
|
||||
|
||||
/// <summary>Basis JSON converter.</summary>
|
||||
public class Texture2DConverter : JsonConverter<Texture2D>
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public override bool CanConvert(Type typeToConvert) =>
|
||||
typeToConvert == typeof(Texture2D);
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Texture2D Read(
|
||||
ref Utf8JsonReader reader,
|
||||
Type typeToConvert,
|
||||
JsonSerializerOptions options)
|
||||
{
|
||||
var texture2D = new Texture2D();
|
||||
|
||||
while (reader.Read())
|
||||
{
|
||||
if (reader.TokenType == JsonTokenType.EndObject)
|
||||
{
|
||||
return texture2D;
|
||||
}
|
||||
|
||||
if (reader.TokenType != JsonTokenType.PropertyName)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var propertyName = reader.GetString();
|
||||
reader.Read();
|
||||
|
||||
switch (propertyName)
|
||||
{
|
||||
case "resource_path":
|
||||
var resourcePath = JsonSerializer.Deserialize<string>(ref reader, options);
|
||||
texture2D = GD.Load<Texture2D>(resourcePath);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
throw new JsonException("Unexpected end when reading Texture2D.");
|
||||
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void Write(
|
||||
Utf8JsonWriter writer,
|
||||
Texture2D value,
|
||||
JsonSerializerOptions options
|
||||
)
|
||||
{
|
||||
var resolver = options.TypeInfoResolver;
|
||||
var resourcePathType = resolver!.GetTypeInfo(typeof(string), options)!;
|
||||
|
||||
writer.WriteStartObject();
|
||||
writer.WritePropertyName("resource_path");
|
||||
JsonSerializer.Serialize(writer, value.ResourcePath, resourcePathType);
|
||||
writer.WriteEndObject();
|
||||
}
|
||||
}
|
||||
1
src/items/InventoryItemTextureExtensions.cs.uid
Normal file
1
src/items/InventoryItemTextureExtensions.cs.uid
Normal file
@@ -0,0 +1 @@
|
||||
uid://bdc3xwj2b1oog
|
||||
@@ -33,7 +33,7 @@ public partial class ItemDatabase : Node
|
||||
{
|
||||
var armorInfo = GD.Load<ArmorStats>($"res://src/items/armor/resources/{armor}");
|
||||
var armorScene = ArmorScene.Instantiate<Armor>();
|
||||
armorScene.SetItemStats(armorInfo);
|
||||
armorScene.ItemStats = armorInfo;
|
||||
database.Add(armorScene);
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ public partial class ItemDatabase : Node
|
||||
{
|
||||
var weaponInfo = GD.Load<WeaponStats>($"res://src/items/weapons/resources/{weapon}");
|
||||
var weaponScene = WeaponScene.Instantiate<Weapon>();
|
||||
weaponScene.SetItemStats(weaponInfo);
|
||||
weaponScene.ItemStats = weaponInfo;
|
||||
database.Add(weaponScene);
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ public partial class ItemDatabase : Node
|
||||
{
|
||||
var accessoryInfo = GD.Load<AccessoryStats>($"res://src/items/accessory/resources/{accessory}");
|
||||
var accessoryScene = AccessoryScene.Instantiate<Accessory>();
|
||||
accessoryScene.SetItemStats(accessoryInfo);
|
||||
accessoryScene.ItemStats = accessoryInfo;
|
||||
database.Add(accessoryScene);
|
||||
}
|
||||
|
||||
@@ -57,7 +57,7 @@ public partial class ItemDatabase : Node
|
||||
{
|
||||
var throwableItemInfo = GD.Load<ThrowableItemStats>($"res://src/items/throwable/resources/{throwable}");
|
||||
var throwableItemScene = ThrowableItemScene.Instantiate<ThrowableItem>();
|
||||
throwableItemScene.SetItemStats(throwableItemInfo);
|
||||
throwableItemScene.ItemStats = throwableItemInfo;
|
||||
database.Add(throwableItemScene);
|
||||
}
|
||||
|
||||
@@ -65,10 +65,10 @@ public partial class ItemDatabase : Node
|
||||
{
|
||||
var consumableItemInfo = GD.Load<ConsumableItemStats>($"res://src/items/consumable/resources/{consumable}");
|
||||
var consumableItemScene = ConsumableItemScene.Instantiate<ConsumableItem>();
|
||||
consumableItemScene.SetItemStats(consumableItemInfo);
|
||||
consumableItemScene.ItemStats = consumableItemInfo;
|
||||
database.Add(consumableItemScene);
|
||||
}
|
||||
|
||||
return database.ToArray();
|
||||
return [.. database];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,39 +1,24 @@
|
||||
using Chickensoft.AutoInject;
|
||||
using Chickensoft.Introspection;
|
||||
using Chickensoft.Serialization;
|
||||
using Godot;
|
||||
using System;
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace GameJamDungeon;
|
||||
|
||||
[Meta(typeof(IAutoNode))]
|
||||
public partial class Accessory : Node3D, IEquipableItem
|
||||
[Meta, Id("accessory")]
|
||||
public partial class Accessory : EquipableItem
|
||||
{
|
||||
public override void _Notification(int what) => this.Notify(what);
|
||||
|
||||
[Dependency] public IGameEventDepot GameEventDepot => this.DependOn<IGameEventDepot>();
|
||||
|
||||
[Dependency] public IPlayer Player => this.DependOn<IPlayer>();
|
||||
|
||||
[Export] private AccessoryStats _accessoryStats { get; set; } = new AccessoryStats();
|
||||
|
||||
[Node] private Sprite3D Sprite { get; set; } = new Sprite3D();
|
||||
public override string ItemName => _accessoryStats.Name;
|
||||
|
||||
[Node] public Area3D Pickup { get; set; } = default!;
|
||||
public override string Description => _accessoryStats.Description;
|
||||
|
||||
public Guid ID => Guid.NewGuid();
|
||||
public override float SpawnRate => _accessoryStats.SpawnRate;
|
||||
|
||||
public string ItemName => _accessoryStats.Name;
|
||||
public override double ThrowDamage => _accessoryStats.ThrowDamage;
|
||||
|
||||
public string Description => _accessoryStats.Description;
|
||||
|
||||
public float SpawnRate => _accessoryStats.SpawnRate;
|
||||
|
||||
public Texture2D GetTexture() => _accessoryStats.Texture;
|
||||
|
||||
public double ThrowDamage => _accessoryStats.ThrowDamage;
|
||||
|
||||
public float ThrowSpeed => _accessoryStats.ThrowSpeed;
|
||||
public override float ThrowSpeed => _accessoryStats.ThrowSpeed;
|
||||
|
||||
public int MaxHPUp => _accessoryStats.MaxHPUp;
|
||||
|
||||
@@ -45,32 +30,9 @@ public partial class Accessory : Node3D, IEquipableItem
|
||||
|
||||
public int DEFUp => _accessoryStats.DEFUp;
|
||||
|
||||
public ImmutableList<AccessoryTag> AccessoryTags => [.. _accessoryStats.AccessoryTags];
|
||||
public AccessoryTag AccessoryTag => _accessoryStats.AccessoryTag;
|
||||
|
||||
public ImmutableList<ItemTag> ItemTags => [.. _accessoryStats.ItemTags];
|
||||
public override ItemTag ItemTag => _accessoryStats.ItemTag;
|
||||
|
||||
public bool IsEquipped { get; set; }
|
||||
|
||||
public void OnReady()
|
||||
{
|
||||
Pickup.BodyEntered += OnEntered;
|
||||
Sprite.Texture = _accessoryStats.Texture;
|
||||
}
|
||||
|
||||
public void SetItemStats(InventoryItemStats inventoryItemStats)
|
||||
{
|
||||
_accessoryStats = (AccessoryStats)inventoryItemStats;
|
||||
}
|
||||
|
||||
public void Throw()
|
||||
{
|
||||
Player.Inventory.Remove(this);
|
||||
}
|
||||
|
||||
public void OnEntered(Node3D body)
|
||||
{
|
||||
var isAdded = Player.Inventory.TryAdd(this);
|
||||
if (isAdded)
|
||||
QueueFree();
|
||||
}
|
||||
public override InventoryItemStats ItemStats { get => _accessoryStats; set => _accessoryStats = (AccessoryStats)value; }
|
||||
}
|
||||
|
||||
@@ -6,13 +6,12 @@
|
||||
radius = 0.470016
|
||||
|
||||
[node name="Accessory" type="Node3D"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.75, 0)
|
||||
script = ExtResource("1_ikyk2")
|
||||
|
||||
[node name="Pickup" type="Area3D" parent="."]
|
||||
unique_name_in_owner = true
|
||||
collision_layer = 0
|
||||
collision_mask = 4
|
||||
collision_layer = 4
|
||||
collision_mask = 0
|
||||
|
||||
[node name="Sprite" type="Sprite3D" parent="Pickup"]
|
||||
unique_name_in_owner = true
|
||||
|
||||
@@ -1,31 +1,44 @@
|
||||
using Godot;
|
||||
using Chickensoft.Introspection;
|
||||
using Chickensoft.Serialization;
|
||||
using Godot;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace GameJamDungeon;
|
||||
|
||||
[GlobalClass]
|
||||
[Meta, Id("accessory_stat_type")]
|
||||
public partial class AccessoryStats : InventoryItemStats
|
||||
{
|
||||
[Export]
|
||||
[Save("accessory_atk_up")]
|
||||
public int ATKUp { get; set; } = 0;
|
||||
|
||||
[Export]
|
||||
[Save("accessory_def_up")]
|
||||
public int DEFUp { get; set; } = 0;
|
||||
|
||||
[Export]
|
||||
[Save("accessory_luck_up")]
|
||||
public double LuckUp { get; set; } = 0;
|
||||
|
||||
[Export]
|
||||
[Save("accessory_max_hp_up")]
|
||||
public int MaxHPUp { get; set; } = 0;
|
||||
|
||||
[Export]
|
||||
[Save("accessory_max_vt_up")]
|
||||
public int MaxVTUp { get; set; } = 0;
|
||||
|
||||
[Export]
|
||||
public Godot.Collections.Array<AccessoryTag> AccessoryTags { get; set; } = new Godot.Collections.Array<AccessoryTag>();
|
||||
[Save("accessory_tag")]
|
||||
public AccessoryTag AccessoryTag { get; set; } = AccessoryTag.None;
|
||||
}
|
||||
|
||||
public enum AccessoryTag
|
||||
{
|
||||
None,
|
||||
HalfVTConsumption,
|
||||
StatusEffectImmunity
|
||||
}
|
||||
|
||||
[JsonSerializable(typeof(AccessoryTag))]
|
||||
public partial class AccessoryTagEnumContext : JsonSerializerContext;
|
||||
|
||||
@@ -1,17 +1,22 @@
|
||||
[gd_resource type="Resource" script_class="AccessoryStats" load_steps=3 format=3 uid="uid://c3v6r8s8yruag"]
|
||||
|
||||
[ext_resource type="Script" path="res://src/items/accessory/AccessoryStats.cs" id="1_co7sc"]
|
||||
[ext_resource type="Script" uid="uid://b8arlmivk68b" path="res://src/items/accessory/AccessoryStats.cs" id="1_co7sc"]
|
||||
[ext_resource type="Texture2D" uid="uid://db7i7iy5gagae" path="res://src/items/accessory/textures/MASK 02.PNG" id="1_uwbei"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_co7sc")
|
||||
ATKUp = 0
|
||||
DEFUp = 0
|
||||
LUCKUp = 0.0
|
||||
LuckUp = 0.0
|
||||
MaxHPUp = 0
|
||||
MaxVTUp = 0
|
||||
AccessoryTags = [1]
|
||||
AccessoryTag = 2
|
||||
Name = "Mask of the Shunned Goddess"
|
||||
Description = "Status Effect Immunity"
|
||||
Texture = ExtResource("1_uwbei")
|
||||
SpawnRate = 0.1
|
||||
ThrowSpeed = 12.0
|
||||
HealHPAmount = 0
|
||||
HealVTAmount = 0
|
||||
ThrowDamage = 5
|
||||
ItemTags = Array[int]([])
|
||||
|
||||
@@ -1,17 +1,22 @@
|
||||
[gd_resource type="Resource" script_class="AccessoryStats" load_steps=3 format=3 uid="uid://ct8iply3dwssv"]
|
||||
|
||||
[ext_resource type="Texture2D" uid="uid://db7i7iy5gagae" path="res://src/items/accessory/textures/MASK 02.PNG" id="1_t16cd"]
|
||||
[ext_resource type="Script" path="res://src/items/accessory/AccessoryStats.cs" id="1_vdb56"]
|
||||
[ext_resource type="Script" uid="uid://b8arlmivk68b" path="res://src/items/accessory/AccessoryStats.cs" id="1_vdb56"]
|
||||
|
||||
[resource]
|
||||
script = ExtResource("1_vdb56")
|
||||
ATKUp = 0
|
||||
DEFUp = 0
|
||||
LUCKUp = 0.0
|
||||
LuckUp = 0.0
|
||||
MaxHPUp = 0
|
||||
MaxVTUp = 0
|
||||
AccessoryTags = [0]
|
||||
AccessoryTag = 1
|
||||
Name = "Mask of the Goddess of Sloth"
|
||||
Description = "Halves VT Depletion Rate"
|
||||
Texture = ExtResource("1_t16cd")
|
||||
SpawnRate = 0.1
|
||||
ThrowSpeed = 12.0
|
||||
HealHPAmount = 0
|
||||
HealVTAmount = 0
|
||||
ThrowDamage = 5
|
||||
ItemTags = Array[int]([])
|
||||
|
||||
@@ -1,72 +1,28 @@
|
||||
using Chickensoft.AutoInject;
|
||||
using Chickensoft.Introspection;
|
||||
using Godot;
|
||||
using System;
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace GameJamDungeon;
|
||||
|
||||
[Meta(typeof(IAutoNode))]
|
||||
public partial class Armor : Node3D, IEquipableItem
|
||||
[Meta, Id("armor")]
|
||||
public partial class Armor : EquipableItem
|
||||
{
|
||||
public override void _Notification(int what) => this.Notify(what);
|
||||
public override InventoryItemStats ItemStats { get => _armorStats; set => _armorStats = (ArmorStats)value; }
|
||||
|
||||
[Dependency] public IPlayer Player => this.DependOn<IPlayer>();
|
||||
private ArmorStats _armorStats { get; set; } = new ArmorStats();
|
||||
|
||||
[Export] private ArmorStats _armorStats { get; set; } = new ArmorStats();
|
||||
public override string ItemName => _armorStats.Name;
|
||||
|
||||
[Node] private Sprite3D Sprite { get; set; } = new Sprite3D();
|
||||
public override string Description => _armorStats.Description;
|
||||
|
||||
[Node] private Area3D Pickup { get; set; } = default!;
|
||||
public override float SpawnRate => _armorStats.SpawnRate;
|
||||
|
||||
public Guid ID => Guid.NewGuid();
|
||||
public override double ThrowDamage => _armorStats.ThrowDamage;
|
||||
|
||||
public string ItemName => _armorStats.Name;
|
||||
|
||||
public string Description => _armorStats.Description;
|
||||
|
||||
public float SpawnRate => _armorStats.SpawnRate;
|
||||
|
||||
public Texture2D GetTexture() => _armorStats.Texture;
|
||||
|
||||
public double ThrowDamage => _armorStats.ThrowDamage;
|
||||
|
||||
public float ThrowSpeed => _armorStats.ThrowSpeed;
|
||||
public override float ThrowSpeed => _armorStats.ThrowSpeed;
|
||||
|
||||
public int Defense => _armorStats.Defense;
|
||||
|
||||
public void IncreaseArmorDefense(int bonus) => _armorStats.Defense += bonus;
|
||||
|
||||
|
||||
public ImmutableList<ItemTag> ItemTags => [.. _armorStats.ItemTags];
|
||||
|
||||
public bool IsEquipped { get; set; }
|
||||
|
||||
public void OnReady()
|
||||
{
|
||||
Pickup.BodyEntered += OnEntered;
|
||||
Sprite.Texture = _armorStats.Texture;
|
||||
}
|
||||
|
||||
public void SetItemStats(InventoryItemStats inventoryItemStats)
|
||||
{
|
||||
_armorStats = (ArmorStats)inventoryItemStats;
|
||||
}
|
||||
|
||||
public void Throw()
|
||||
{
|
||||
Player.Inventory.Remove(this);
|
||||
}
|
||||
|
||||
public void Drop()
|
||||
{
|
||||
Player.Inventory.Remove(this);
|
||||
}
|
||||
|
||||
public void OnEntered(Node3D body)
|
||||
{
|
||||
var isAdded = Player.Inventory.TryAdd(this);
|
||||
if (isAdded)
|
||||
QueueFree();
|
||||
}
|
||||
public override ItemTag ItemTag => _armorStats.ItemTag;
|
||||
}
|
||||
|
||||
@@ -6,13 +6,12 @@
|
||||
size = Vector3(0.778381, 0.929947, 0.731567)
|
||||
|
||||
[node name="Armor" type="Node3D"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, -1.75, 0)
|
||||
script = ExtResource("1_cmjpq")
|
||||
|
||||
[node name="Pickup" type="Area3D" parent="."]
|
||||
unique_name_in_owner = true
|
||||
collision_layer = 0
|
||||
collision_mask = 4
|
||||
collision_layer = 4
|
||||
collision_mask = 0
|
||||
|
||||
[node name="Sprite" type="Sprite3D" parent="Pickup"]
|
||||
unique_name_in_owner = true
|
||||
|
||||
@@ -1,25 +1,34 @@
|
||||
using Godot;
|
||||
using Chickensoft.Introspection;
|
||||
using Chickensoft.Serialization;
|
||||
using Godot;
|
||||
|
||||
namespace GameJamDungeon;
|
||||
|
||||
[GlobalClass]
|
||||
[Meta, Id("armor_stats")]
|
||||
public partial class ArmorStats : InventoryItemStats
|
||||
{
|
||||
[Export]
|
||||
[Save("armor_defense")]
|
||||
public int Defense { get; set; } = 0;
|
||||
|
||||
[Export]
|
||||
[Save("armor_telluric_resistance")]
|
||||
public double TelluricResistance { get; set; } = 0;
|
||||
|
||||
[Export]
|
||||
[Save("armor_aeolic_resistance")]
|
||||
public double AeolicResistance { get; set; } = 0;
|
||||
|
||||
[Export]
|
||||
[Save("armor_hydric_resistance")]
|
||||
public double HydricResistance { get; set; } = 0;
|
||||
|
||||
[Export]
|
||||
[Save("armor_igneous_resistance")]
|
||||
public double IgneousResistance { get; set; } = 0;
|
||||
|
||||
[Export]
|
||||
[Save("armor_ferrum_resistance")]
|
||||
public double FerrumResistance { get; set; } = 0;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[gd_resource type="Resource" script_class="ArmorStats" load_steps=3 format=3 uid="uid://ce2vfa2t3io67"]
|
||||
|
||||
[ext_resource type="Script" path="res://src/items/armor/ArmorStats.cs" id="1_6r2bl"]
|
||||
[ext_resource type="Script" uid="uid://dqtp6ewvttoyu" path="res://src/items/armor/ArmorStats.cs" id="1_6r2bl"]
|
||||
[ext_resource type="Texture2D" uid="uid://ckcn67d64mgke" path="res://src/items/armor/textures/atoners adornment.PNG" id="1_588l8"]
|
||||
|
||||
[resource]
|
||||
@@ -15,3 +15,8 @@ Name = "Atoner's Adornments"
|
||||
Description = "+1 DEF"
|
||||
Texture = ExtResource("1_588l8")
|
||||
SpawnRate = 0.25
|
||||
ThrowSpeed = 12.0
|
||||
HealHPAmount = 0
|
||||
HealVTAmount = 0
|
||||
ThrowDamage = 5
|
||||
ItemTag = 0
|
||||
|
||||
@@ -1,68 +1,31 @@
|
||||
using Chickensoft.AutoInject;
|
||||
using Chickensoft.Introspection;
|
||||
using Godot;
|
||||
using System;
|
||||
|
||||
namespace GameJamDungeon;
|
||||
|
||||
[Meta(typeof(IAutoNode))]
|
||||
public partial class ConsumableItem : Node3D, IUsableItem
|
||||
[Meta, Id("consumable_item")]
|
||||
public partial class ConsumableItem : InventoryItem
|
||||
{
|
||||
public override void _Notification(int what) => this.Notify(what);
|
||||
|
||||
[Dependency] public IGame Game => this.DependOn<IGame>();
|
||||
|
||||
[Dependency] public IPlayer Player => this.DependOn<IPlayer>();
|
||||
|
||||
[Export]
|
||||
private ConsumableItemStats _consumableItemStats { get; set; }
|
||||
private ConsumableItemStats _consumableItemStats { get; set; } = new ConsumableItemStats();
|
||||
|
||||
[Node] private Sprite3D Sprite { get; set; } = new Sprite3D();
|
||||
public override string ItemName => _consumableItemStats.Name;
|
||||
|
||||
[Node] private Area3D Pickup { get; set; } = default!;
|
||||
public override string Description => _consumableItemStats.Description;
|
||||
|
||||
public Guid ID => Guid.NewGuid();
|
||||
public override float SpawnRate => _consumableItemStats.SpawnRate;
|
||||
|
||||
public string ItemName => _consumableItemStats.Name;
|
||||
public override double ThrowDamage => _consumableItemStats.ThrowDamage;
|
||||
|
||||
public string Description => _consumableItemStats.Description;
|
||||
public override float ThrowSpeed => _consumableItemStats.ThrowSpeed;
|
||||
|
||||
public float SpawnRate => _consumableItemStats.SpawnRate;
|
||||
public int HealHPAmount => _consumableItemStats.HealHPAmount;
|
||||
|
||||
public Texture2D GetTexture() => _consumableItemStats.Texture;
|
||||
public int HealVTAmount => _consumableItemStats.HealVTAmount;
|
||||
|
||||
public double ThrowDamage => _consumableItemStats.ThrowDamage;
|
||||
public int RaiseHPAmount => _consumableItemStats.RaiseHPAmount;
|
||||
|
||||
public float ThrowSpeed => _consumableItemStats.ThrowSpeed;
|
||||
public int RaiseVTAmount => _consumableItemStats.RaiseVTAmount;
|
||||
|
||||
public void Use()
|
||||
{
|
||||
if (Player.Stats.CurrentHP == Player.Stats.MaximumHP && _consumableItemStats.RaiseHPAmount > 0)
|
||||
Player.RaiseHP(_consumableItemStats.RaiseHPAmount);
|
||||
if (Player.Stats.CurrentVT == Player.Stats.MaximumVT && _consumableItemStats.RaiseVTAmount > 0)
|
||||
Player.RaiseVT(_consumableItemStats.RaiseVTAmount);
|
||||
|
||||
if (_consumableItemStats.HealHPAmount > 0 && Player.Stats.CurrentHP != Player.Stats.MaximumHP)
|
||||
Player.HealHP(_consumableItemStats.HealHPAmount);
|
||||
if (_consumableItemStats.HealVTAmount > 0 && Player.Stats.CurrentVT != Player.Stats.MaximumVT)
|
||||
Player.HealVT(_consumableItemStats.HealVTAmount);
|
||||
}
|
||||
|
||||
public void SetItemStats(InventoryItemStats inventoryItemStats)
|
||||
{
|
||||
_consumableItemStats = (ConsumableItemStats)inventoryItemStats;
|
||||
}
|
||||
|
||||
public void OnReady()
|
||||
{
|
||||
Pickup.BodyEntered += OnEntered;
|
||||
Sprite.Texture = _consumableItemStats.Texture;
|
||||
}
|
||||
|
||||
public void OnEntered(Node3D body)
|
||||
{
|
||||
var isAdded = Player.Inventory.TryAdd(this);
|
||||
if (isAdded)
|
||||
QueueFree();
|
||||
}
|
||||
public override InventoryItemStats ItemStats { get => _consumableItemStats; set => _consumableItemStats = (ConsumableItemStats)value; }
|
||||
}
|
||||
|
||||
@@ -10,8 +10,8 @@ script = ExtResource("1_26bad")
|
||||
|
||||
[node name="Pickup" type="Area3D" parent="."]
|
||||
unique_name_in_owner = true
|
||||
collision_layer = 0
|
||||
collision_mask = 4
|
||||
collision_layer = 4
|
||||
collision_mask = 0
|
||||
|
||||
[node name="Sprite" type="Sprite3D" parent="Pickup"]
|
||||
unique_name_in_owner = true
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
using Godot;
|
||||
using Chickensoft.Introspection;
|
||||
using Chickensoft.Serialization;
|
||||
using Godot;
|
||||
|
||||
namespace GameJamDungeon;
|
||||
|
||||
[GlobalClass]
|
||||
[Meta, Id("consumable_item_stats")]
|
||||
public partial class ConsumableItemStats : InventoryItemStats
|
||||
{
|
||||
[Export]
|
||||
[Save("consumable_item_raise_hp")]
|
||||
public int RaiseHPAmount { get; set; } = 0;
|
||||
|
||||
[Export]
|
||||
[Save("consumable_item_raise_vt")]
|
||||
public int RaiseVTAmount { get; set; } = 0;
|
||||
}
|
||||
|
||||
@@ -21,13 +21,13 @@ public partial class DroppedItem : RigidBody3D, IDroppedItem
|
||||
|
||||
[Node] private Sprite2D Sprite { get; set; } = default!;
|
||||
|
||||
public IInventoryItem Item { get; set; }
|
||||
public InventoryItem Item { get; set; }
|
||||
|
||||
public void OnResolved()
|
||||
{
|
||||
ContactMonitor = true;
|
||||
BodyEntered += DroppedItem_BodyEntered;
|
||||
Sprite.Texture = Item.GetTexture();
|
||||
Sprite.Texture = Item.ItemStats.Texture;
|
||||
}
|
||||
|
||||
public async void Drop()
|
||||
|
||||
@@ -1,221 +1,27 @@
|
||||
using Chickensoft.AutoInject;
|
||||
using Chickensoft.Introspection;
|
||||
using Chickensoft.Introspection;
|
||||
using Godot;
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace GameJamDungeon;
|
||||
|
||||
[Meta(typeof(IAutoNode))]
|
||||
public partial class EffectItem : Node3D, IUsableItem
|
||||
[Meta, Id("effect_item")]
|
||||
public partial class EffectItem : InventoryItem
|
||||
{
|
||||
public override void _Notification(int what) => this.Notify(what);
|
||||
|
||||
[Dependency] public IGame Game => this.DependOn<IGame>();
|
||||
|
||||
[Dependency] public IPlayer Player => this.DependOn<IPlayer>();
|
||||
|
||||
[Export]
|
||||
private EffectItemStats _effectItemStats { get; set; }
|
||||
private EffectItemStats _effectItemStats { get; set; } = new EffectItemStats();
|
||||
|
||||
[Node] private Sprite3D Sprite { get; set; } = new Sprite3D();
|
||||
public override string ItemName => _effectItemStats.Name;
|
||||
|
||||
[Node] private Area3D Pickup { get; set; } = default!;
|
||||
public override string Description => _effectItemStats.Description;
|
||||
|
||||
public Guid ID => Guid.NewGuid();
|
||||
public override float SpawnRate => _effectItemStats.SpawnRate;
|
||||
|
||||
public string ItemName => _effectItemStats.Name;
|
||||
public override double ThrowDamage => _effectItemStats.ThrowDamage;
|
||||
|
||||
public string Description => _effectItemStats.Description;
|
||||
public override float ThrowSpeed => _effectItemStats.ThrowSpeed;
|
||||
|
||||
public float SpawnRate => _effectItemStats.SpawnRate;
|
||||
public UsableItemTag UsableItemTag => _effectItemStats.UsableItemTag;
|
||||
|
||||
public Texture2D GetTexture() => _effectItemStats.Texture;
|
||||
public void SetEffectTag(UsableItemTag effect) => _effectItemStats.UsableItemTag = effect;
|
||||
|
||||
public double ThrowDamage => _effectItemStats.ThrowDamage;
|
||||
|
||||
public float ThrowSpeed => _effectItemStats.ThrowSpeed;
|
||||
|
||||
public void Use()
|
||||
{
|
||||
if (_effectItemStats.UsableItemTags.Contains(UsableItemTag.DoubleEXP))
|
||||
Game.DoubleEXP(TimeSpan.FromSeconds(30));
|
||||
if (_effectItemStats.UsableItemTags.Contains(UsableItemTag.TeleportAllEnemiesToRoom))
|
||||
TeleportEnemiesToCurrentRoom();
|
||||
if (_effectItemStats.UsableItemTags.Contains(UsableItemTag.KillHalfEnemiesInRoom))
|
||||
KillHalfEnemiesInRoom();
|
||||
if (_effectItemStats.UsableItemTags.Contains(UsableItemTag.TurnAllEnemiesIntoHealingItem))
|
||||
TurnAllEnemiesInRoomIntoHealingItem();
|
||||
if (_effectItemStats.UsableItemTags.Contains(UsableItemTag.HealsAllInRoomToMaxHP))
|
||||
HealAllEnemiesAndPlayerInRoomToFull();
|
||||
if (_effectItemStats.UsableItemTags.Contains(UsableItemTag.AbsorbHPFromAllEnemiesInRoom))
|
||||
AbsorbHPFromAllEnemiesInRoom();
|
||||
if (_effectItemStats.UsableItemTags.Contains(UsableItemTag.DealElementalDamageToAllEnemiesInRoom))
|
||||
DealElementalDamageToAllEnemiesInRoom(ElementType.Hydric);
|
||||
if (_effectItemStats.UsableItemTags.Contains(UsableItemTag.SwapHPAndVT))
|
||||
SwapHPandVT();
|
||||
if (_effectItemStats.UsableItemTags.Contains(UsableItemTag.RaiseCurrentWeaponAttack))
|
||||
RaiseCurrentWeaponAttack();
|
||||
if (_effectItemStats.UsableItemTags.Contains(UsableItemTag.RaiseCurrentDefenseArmor))
|
||||
RaiseCurrentArmorDefense();
|
||||
if (_effectItemStats.UsableItemTags.Contains(UsableItemTag.RaiseLevel))
|
||||
RaiseLevel();
|
||||
|
||||
if (_effectItemStats.UsableItemTags.Contains(UsableItemTag.RandomEffect))
|
||||
RandomEffect();
|
||||
|
||||
}
|
||||
|
||||
public void SetItemStats(InventoryItemStats inventoryItemStats)
|
||||
{
|
||||
_effectItemStats = (EffectItemStats)inventoryItemStats;
|
||||
}
|
||||
|
||||
public void OnReady()
|
||||
{
|
||||
Pickup.BodyEntered += OnEntered;
|
||||
Sprite.Texture = _effectItemStats.Texture;
|
||||
}
|
||||
|
||||
public void OnEntered(Node3D body)
|
||||
{
|
||||
var isAdded = Player.Inventory.TryAdd(this);
|
||||
if (isAdded)
|
||||
QueueFree();
|
||||
}
|
||||
|
||||
private void TeleportEnemiesToCurrentRoom()
|
||||
{
|
||||
var currentFloor = Game.CurrentFloor;
|
||||
var rooms = currentFloor.Rooms;
|
||||
var currentRoom = Player.GetCurrentRoom();
|
||||
|
||||
if (currentRoom is not MonsterRoom)
|
||||
return;
|
||||
|
||||
var validRooms = rooms.OfType<MonsterRoom>().ToList();
|
||||
if (currentRoom is MonsterRoom monsterRoom)
|
||||
validRooms.Remove(monsterRoom);
|
||||
|
||||
var currentMonsterRoom = (MonsterRoom)currentRoom;
|
||||
|
||||
var enemyList = validRooms.SelectMany(x => x.GetEnemiesInCurrentRoom());
|
||||
|
||||
foreach (var enemy in enemyList)
|
||||
{
|
||||
var spawnPoints = currentMonsterRoom.EnemySpawnPoints.GetChildren().OfType<Marker3D>().ToList();
|
||||
var spawnPointsGodotCollection = new Godot.Collections.Array<Marker3D>(spawnPoints);
|
||||
var randomSpawnPoint = spawnPointsGodotCollection.PickRandom();
|
||||
enemy.SetEnemyGlobalPosition(randomSpawnPoint.GlobalPosition);
|
||||
}
|
||||
}
|
||||
|
||||
private void KillHalfEnemiesInRoom()
|
||||
{
|
||||
var currentRoom = Player.GetCurrentRoom();
|
||||
if (currentRoom is not MonsterRoom)
|
||||
return;
|
||||
|
||||
var currentMonsterRoom = (MonsterRoom)currentRoom;
|
||||
var enemyList = currentMonsterRoom.GetEnemiesInCurrentRoom().ToList();
|
||||
var enemiesToKill = enemyList.Count / 2;
|
||||
for (var i = 0; i < enemiesToKill; i++)
|
||||
enemyList[i].Die();
|
||||
}
|
||||
|
||||
private void TurnAllEnemiesInRoomIntoHealingItem()
|
||||
{
|
||||
var currentRoom = Player.GetCurrentRoom();
|
||||
var currentEnemies = currentRoom.EnemiesInRoom;
|
||||
foreach (var enemy in currentEnemies)
|
||||
{
|
||||
enemy.Die();
|
||||
DropHealingItem(enemy.GetEnemyGlobalPosition());
|
||||
}
|
||||
}
|
||||
|
||||
private void DropHealingItem(Vector3 vector)
|
||||
{
|
||||
var consumableFolder = "res://src/items/consumable";
|
||||
var restorativeScene = GD.Load<PackedScene>($"{consumableFolder}/ConsumableItem.tscn");
|
||||
var consumable = restorativeScene.Instantiate<ConsumableItem>();
|
||||
var resourceFiles = DirAccess.GetFilesAt($"{consumableFolder}/resources");
|
||||
var rng = new RandomNumberGenerator();
|
||||
rng.Randomize();
|
||||
var randomResource = resourceFiles[rng.RandiRange(0, resourceFiles.Length - 1)];
|
||||
var randomFile = ResourceLoader.Load<ConsumableItemStats>($"{consumableFolder}/resources/{randomResource}");
|
||||
consumable.SetItemStats(randomFile);
|
||||
Game.AddChild(consumable);
|
||||
consumable.GlobalPosition = vector;
|
||||
}
|
||||
|
||||
private void HealAllEnemiesAndPlayerInRoomToFull()
|
||||
{
|
||||
var currentRoom = Player.GetCurrentRoom();
|
||||
var currentEnemies = currentRoom.EnemiesInRoom;
|
||||
foreach (var enemy in currentEnemies)
|
||||
enemy.SetCurrentHP(enemy.GetMaximumHP());
|
||||
Player.Stats.SetCurrentHP(Player.Stats.MaximumHP.Value);
|
||||
}
|
||||
|
||||
private void AbsorbHPFromAllEnemiesInRoom()
|
||||
{
|
||||
var currentRoom = Player.GetCurrentRoom();
|
||||
var currentEnemies = currentRoom.EnemiesInRoom;
|
||||
var hpToAbsorb = 0.0;
|
||||
foreach (var enemy in currentEnemies)
|
||||
hpToAbsorb += enemy.CurrentHP * 0.05;
|
||||
Player.Stats.SetCurrentHP(Player.Stats.CurrentHP.Value + (int)hpToAbsorb);
|
||||
GD.Print("HP to absorb: " + hpToAbsorb);
|
||||
}
|
||||
|
||||
private void DealElementalDamageToAllEnemiesInRoom(ElementType elementType)
|
||||
{
|
||||
var currentRoom = Player.GetCurrentRoom();
|
||||
var currentEnemies = currentRoom.EnemiesInRoom;
|
||||
foreach (var enemy in currentEnemies)
|
||||
enemy.TakeDamage(20, elementType);
|
||||
}
|
||||
|
||||
private void SwapHPandVT()
|
||||
{
|
||||
var oldHp = Player.Stats.CurrentHP.Value;
|
||||
var oldVt = Player.Stats.CurrentVT.Value;
|
||||
|
||||
Player.Stats.SetCurrentHP(oldVt);
|
||||
Player.Stats.SetCurrentVT(oldHp);
|
||||
}
|
||||
|
||||
private void RandomEffect()
|
||||
{
|
||||
var itemEffects = Enum.GetValues<UsableItemTag>().ToList();
|
||||
itemEffects.Remove(UsableItemTag.RandomEffect);
|
||||
var randomEffect = new Godot.Collections.Array<UsableItemTag>(itemEffects).PickRandom();
|
||||
_effectItemStats.UsableItemTags.Clear();
|
||||
_effectItemStats.UsableItemTags.Add(randomEffect);
|
||||
Use();
|
||||
}
|
||||
|
||||
private void RaiseCurrentWeaponAttack()
|
||||
{
|
||||
if (Player.EquippedWeapon.Value.ItemName == string.Empty)
|
||||
return;
|
||||
|
||||
var currentWeapon = Player.EquippedWeapon.Value;
|
||||
currentWeapon.IncreaseWeaponAttack(1);
|
||||
}
|
||||
|
||||
private void RaiseCurrentArmorDefense()
|
||||
{
|
||||
if (Player.EquippedArmor.Value.ItemName == string.Empty)
|
||||
return;
|
||||
|
||||
var currentArmor = Player.EquippedArmor.Value;
|
||||
currentArmor.IncreaseArmorDefense(1);
|
||||
}
|
||||
|
||||
private void RaiseLevel()
|
||||
{
|
||||
Player.LevelUp();
|
||||
}
|
||||
public override InventoryItemStats ItemStats { get => _effectItemStats; set => _effectItemStats = (EffectItemStats)value; }
|
||||
}
|
||||
|
||||
@@ -10,8 +10,8 @@ script = ExtResource("1_yw2rj")
|
||||
|
||||
[node name="Pickup" type="Area3D" parent="."]
|
||||
unique_name_in_owner = true
|
||||
collision_layer = 0
|
||||
collision_mask = 4
|
||||
collision_layer = 4
|
||||
collision_mask = 0
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="Pickup"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0600509, 0.26725, 0.180481)
|
||||
|
||||
@@ -1,13 +1,18 @@
|
||||
using Godot;
|
||||
using Chickensoft.Introspection;
|
||||
using Chickensoft.Serialization;
|
||||
using Godot;
|
||||
|
||||
namespace GameJamDungeon;
|
||||
|
||||
[GlobalClass]
|
||||
[Meta, Id("effect_item_stats")]
|
||||
public partial class EffectItemStats : InventoryItemStats
|
||||
{
|
||||
[Export]
|
||||
public Godot.Collections.Array<UsableItemTag> UsableItemTags { get; set; } = new Godot.Collections.Array<UsableItemTag>();
|
||||
[Save("effect_item_tag")]
|
||||
public UsableItemTag UsableItemTag { get; set; } = UsableItemTag.None;
|
||||
|
||||
[Export]
|
||||
[Save("effect_item_element")]
|
||||
public ElementType ElementalDamageType { get; set; }
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ texture = ExtResource("1_1rwq6")
|
||||
[node name="Pickup" type="Area3D" parent="."]
|
||||
unique_name_in_owner = true
|
||||
collision_layer = 4
|
||||
collision_mask = 4
|
||||
collision_mask = 0
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="Pickup"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.348749, 0)
|
||||
|
||||
@@ -1,146 +1,37 @@
|
||||
using Chickensoft.AutoInject;
|
||||
using Chickensoft.Introspection;
|
||||
using Godot;
|
||||
using System;
|
||||
using System.Collections.Immutable;
|
||||
using System.Linq;
|
||||
|
||||
namespace GameJamDungeon;
|
||||
|
||||
[Meta(typeof(IAutoNode))]
|
||||
public partial class ThrowableItem : Node3D, IUsableItem
|
||||
[Meta, Id("throwable_item")]
|
||||
public partial class ThrowableItem : InventoryItem
|
||||
{
|
||||
public override void _Notification(int what) => this.Notify(what);
|
||||
|
||||
[Dependency] public IGame Game => this.DependOn<IGame>();
|
||||
|
||||
[Dependency] public IPlayer Player => this.DependOn<IPlayer>();
|
||||
|
||||
public Guid ID => Guid.NewGuid();
|
||||
|
||||
public string ItemName => _throwableItemStats.Name;
|
||||
|
||||
public string Description => _throwableItemStats.Description;
|
||||
|
||||
public float SpawnRate => _throwableItemStats.SpawnRate;
|
||||
|
||||
public Texture2D GetTexture() => _throwableItemStats.Texture;
|
||||
|
||||
public double ThrowDamage => _throwableItemStats.ThrowDamage;
|
||||
|
||||
public float ThrowSpeed => _throwableItemStats.ThrowSpeed;
|
||||
|
||||
public ElementType ElementType => _throwableItemStats.ElementType;
|
||||
|
||||
public ImmutableList<ThrowableItemTag> ThrowableItemTags => [.. _throwableItemStats.ThrowableItemTags];
|
||||
|
||||
public int Count { get; }
|
||||
|
||||
public void SetItemStats(InventoryItemStats inventoryItemStats)
|
||||
{
|
||||
_throwableItemStats = (ThrowableItemStats)inventoryItemStats;
|
||||
}
|
||||
|
||||
public void OnEntered(Node3D body)
|
||||
{
|
||||
var isAdded = Player.Inventory.TryAdd(this);
|
||||
if (isAdded)
|
||||
QueueFree();
|
||||
}
|
||||
|
||||
[Export]
|
||||
private ThrowableItemStats _throwableItemStats { get; set; }
|
||||
|
||||
[Node] private Sprite3D Sprite { get; set; } = new Sprite3D();
|
||||
public override string ItemName => _throwableItemStats.Name;
|
||||
|
||||
[Node] private Area3D Pickup { get; set; } = default!;
|
||||
public override string Description => _throwableItemStats.Description;
|
||||
|
||||
public void OnResolved()
|
||||
{
|
||||
Pickup.BodyEntered += OnEntered;
|
||||
Sprite.Texture = _throwableItemStats.Texture;
|
||||
}
|
||||
public override float SpawnRate => _throwableItemStats.SpawnRate;
|
||||
|
||||
public void Use()
|
||||
{
|
||||
if (_throwableItemStats.HealHPAmount > 0)
|
||||
Player.HealHP(_throwableItemStats.HealHPAmount);
|
||||
if (_throwableItemStats.HealVTAmount > 0)
|
||||
Player.HealVT(_throwableItemStats.HealVTAmount);
|
||||
public override double ThrowDamage => _throwableItemStats.ThrowDamage;
|
||||
|
||||
if (_throwableItemStats.ThrowableItemTags.Contains(ThrowableItemTag.TeleportToRandomLocation))
|
||||
TeleportToRandomRoom(Player);
|
||||
public override float ThrowSpeed => _throwableItemStats.ThrowSpeed;
|
||||
|
||||
if (_throwableItemStats.ThrowableItemTags.Contains(ThrowableItemTag.CanChangeAffinity))
|
||||
ChangeAffinity();
|
||||
public ElementType ElementType => _throwableItemStats.ElementType;
|
||||
|
||||
if (_throwableItemStats.ThrowableItemTags.Contains(ThrowableItemTag.WarpToExitIfFound))
|
||||
WarpToExit(Player);
|
||||
}
|
||||
public ThrowableItemTag ThrowableItemTag => _throwableItemStats.ThrowableItemTag;
|
||||
|
||||
public void TeleportToRandomRoom(IEnemy enemy)
|
||||
{
|
||||
var currentFloor = Game.CurrentFloor;
|
||||
var rooms = currentFloor.Rooms;
|
||||
var currentRoom = enemy.GetCurrentRoom();
|
||||
var validRooms = rooms.OfType<MonsterRoom>().ToList();
|
||||
if (currentRoom is MonsterRoom currentMonsterRoom)
|
||||
validRooms.Remove(currentMonsterRoom);
|
||||
public int HealHPAmount => _throwableItemStats.HealHPAmount;
|
||||
|
||||
if (validRooms.Count == 0)
|
||||
return;
|
||||
public int HealVTAmount => _throwableItemStats.HealVTAmount;
|
||||
|
||||
var roomsGodotCollection = new Godot.Collections.Array<MonsterRoom>(validRooms);
|
||||
var randomRoom = roomsGodotCollection.PickRandom();
|
||||
var spawnPoints = randomRoom.EnemySpawnPoints.GetChildren().OfType<Marker3D>().ToList();
|
||||
var spawnPointsGodotCollection = new Godot.Collections.Array<Marker3D>(spawnPoints);
|
||||
var randomSpawnPoint = spawnPointsGodotCollection.PickRandom();
|
||||
public void SetElementType(ElementType elementType) => _throwableItemStats.ElementType = elementType;
|
||||
|
||||
enemy.SetEnemyGlobalPosition(randomSpawnPoint.GlobalPosition);
|
||||
}
|
||||
public void SetDescription(string description) => _throwableItemStats.Description = description;
|
||||
|
||||
private void TeleportToRandomRoom(IPlayer player)
|
||||
{
|
||||
var currentFloor = Game.CurrentFloor;
|
||||
var rooms = currentFloor.Rooms;
|
||||
public int Count { get; }
|
||||
|
||||
var currentRoom = rooms.SingleOrDefault(x => x.IsPlayerInRoom);
|
||||
|
||||
var validRooms = rooms.OfType<MonsterRoom>().ToList();
|
||||
if (currentRoom is MonsterRoom currentMonsterRoom)
|
||||
validRooms.Remove(currentMonsterRoom);
|
||||
|
||||
if (validRooms.Count == 0)
|
||||
return;
|
||||
|
||||
var roomsGodotCollection = new Godot.Collections.Array<MonsterRoom>(validRooms);
|
||||
var randomRoom = roomsGodotCollection.PickRandom();
|
||||
var spawnPoint = randomRoom.PlayerSpawn;
|
||||
Game.ToggleInventory();
|
||||
player.TeleportPlayer(spawnPoint.GlobalPosition);
|
||||
}
|
||||
|
||||
private void ChangeAffinity()
|
||||
{
|
||||
var maximumElements = Enum.GetNames(typeof(ElementType)).Length;
|
||||
_throwableItemStats.ElementType = _throwableItemStats.ElementType + 1 % maximumElements;
|
||||
|
||||
// TODO: Make this an inventory animation to cycle through elements.
|
||||
_throwableItemStats.Description =
|
||||
$"Inflicts {_throwableItemStats.ElementType} damage when thrown." +
|
||||
$"{System.Environment.NewLine}Use item to change Affinity.";
|
||||
}
|
||||
|
||||
private void WarpToExit(IPlayer player)
|
||||
{
|
||||
var exitRoom = Game.CurrentFloor.Rooms.OfType<ExitRoom>().Single();
|
||||
if (exitRoom.PlayerDiscoveredRoom)
|
||||
player.TeleportPlayer(exitRoom.PlayerSpawn.GlobalPosition);
|
||||
}
|
||||
|
||||
public void WarpToExit(IEnemy enemy)
|
||||
{
|
||||
var exitRoom = Game.CurrentFloor.Rooms.OfType<ExitRoom>().Single();
|
||||
enemy.SetEnemyGlobalPosition(exitRoom.PlayerSpawn.GlobalPosition);
|
||||
}
|
||||
public override InventoryItemStats ItemStats { get => _throwableItemStats; set => _throwableItemStats = (ThrowableItemStats)value; }
|
||||
}
|
||||
|
||||
@@ -10,8 +10,8 @@ script = ExtResource("1_nac2l")
|
||||
|
||||
[node name="Pickup" type="Area3D" parent="."]
|
||||
unique_name_in_owner = true
|
||||
collision_layer = 0
|
||||
collision_mask = 4
|
||||
collision_layer = 4
|
||||
collision_mask = 0
|
||||
|
||||
[node name="CollisionShape3D" type="CollisionShape3D" parent="Pickup"]
|
||||
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.0600509, 0.26725, 0.180481)
|
||||
|
||||
@@ -1,16 +1,22 @@
|
||||
using Godot;
|
||||
using Chickensoft.Introspection;
|
||||
using Chickensoft.Serialization;
|
||||
using Godot;
|
||||
|
||||
namespace GameJamDungeon;
|
||||
|
||||
[GlobalClass]
|
||||
[Meta, Id("throwable_item_stats")]
|
||||
public partial class ThrowableItemStats : InventoryItemStats
|
||||
{
|
||||
[Export]
|
||||
public Godot.Collections.Array<ThrowableItemTag> ThrowableItemTags { get; set; } = new Godot.Collections.Array<ThrowableItemTag>();
|
||||
[Save("throwable_item_tag")]
|
||||
public ThrowableItemTag ThrowableItemTag { get; set; } = ThrowableItemTag.None;
|
||||
|
||||
[Export]
|
||||
[Save("throwable_item_element")]
|
||||
public ElementType ElementType { get; set; } = ElementType.None;
|
||||
|
||||
[Export]
|
||||
public Godot.Collections.Array<UsableItemTag> UsableItemTags { get; set; } = new Godot.Collections.Array<UsableItemTag>();
|
||||
[Save("throwable_item_usable_tag")]
|
||||
public UsableItemTag UsableItemTag { get; set; } = UsableItemTag.None;
|
||||
}
|
||||
|
||||
@@ -1,15 +1,22 @@
|
||||
namespace GameJamDungeon;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace GameJamDungeon;
|
||||
|
||||
public enum ThrowableItemTag
|
||||
{
|
||||
None,
|
||||
LowerTargetTo1HP,
|
||||
CanChangeAffinity,
|
||||
TeleportToRandomLocation,
|
||||
WarpToExitIfFound
|
||||
}
|
||||
|
||||
[JsonSerializable(typeof(ThrowableItemTag))]
|
||||
public partial class ThrowableItemTagEnumContext : JsonSerializerContext;
|
||||
|
||||
public enum UsableItemTag
|
||||
{
|
||||
None,
|
||||
DoubleEXP,
|
||||
IdentifyAllItemsCostHP,
|
||||
BriefImmunity,
|
||||
@@ -26,14 +33,13 @@ public enum UsableItemTag
|
||||
RandomEffect,
|
||||
}
|
||||
|
||||
public enum EnhancingItemTag
|
||||
{
|
||||
Add1ATK,
|
||||
Add1DEF,
|
||||
RaiseLevelBy1,
|
||||
}
|
||||
[JsonSerializable(typeof(UsableItemTag))]
|
||||
public partial class UsableItemTagEnumContext : JsonSerializerContext;
|
||||
|
||||
public enum BoxItemTag
|
||||
{
|
||||
RandomNewItem,
|
||||
}
|
||||
}
|
||||
|
||||
[JsonSerializable(typeof(BoxItemTag))]
|
||||
public partial class BoxItemTagEnumContext : JsonSerializerContext;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
using Chickensoft.AutoInject;
|
||||
using Chickensoft.Introspection;
|
||||
using GameJamDungeon.src.items;
|
||||
using Godot;
|
||||
using System.Linq;
|
||||
|
||||
namespace GameJamDungeon;
|
||||
|
||||
@@ -14,15 +14,16 @@ public partial class ThrownItem : RigidBody3D
|
||||
|
||||
[Dependency] public IGame Game => this.DependOn<IGame>();
|
||||
|
||||
public IInventoryItem ItemThatIsThrown;
|
||||
public InventoryItem ItemThatIsThrown;
|
||||
|
||||
private EffectService _effectService;
|
||||
|
||||
[Node] public Sprite2D Sprite { get; set; } = default!;
|
||||
|
||||
public void OnResolved()
|
||||
{
|
||||
BodyEntered += ThrownItem_BodyEntered;
|
||||
GlobalPosition = Player.CurrentPosition;
|
||||
Sprite.Texture = ItemThatIsThrown.GetTexture();
|
||||
Sprite.Texture = ItemThatIsThrown.ItemStats.Texture;
|
||||
AddCollisionExceptionWith((Node)Player);
|
||||
}
|
||||
|
||||
@@ -33,8 +34,9 @@ public partial class ThrownItem : RigidBody3D
|
||||
QueueFree();
|
||||
}
|
||||
|
||||
public void Throw()
|
||||
public void Throw(EffectService effectService)
|
||||
{
|
||||
_effectService = effectService;
|
||||
ApplyCentralImpulse(-Player.CurrentBasis.Z.Normalized() * ItemThatIsThrown.ThrowSpeed);
|
||||
}
|
||||
|
||||
@@ -79,16 +81,16 @@ public partial class ThrownItem : RigidBody3D
|
||||
{
|
||||
if (ItemThatIsThrown is ThrowableItem throwableItem)
|
||||
{
|
||||
switch (throwableItem.ThrowableItemTags.Single())
|
||||
switch (throwableItem.ThrowableItemTag)
|
||||
{
|
||||
case ThrowableItemTag.LowerTargetTo1HP:
|
||||
enemy.TakeDamage(enemy.CurrentHP - 1, ignoreDefense: true, ignoreElementalResistance: true);
|
||||
break;
|
||||
case ThrowableItemTag.TeleportToRandomLocation:
|
||||
throwableItem.TeleportToRandomRoom(enemy);
|
||||
_effectService.TeleportToRandomRoom(enemy);
|
||||
break;
|
||||
case ThrowableItemTag.WarpToExitIfFound:
|
||||
throwableItem.WarpToExit(enemy);
|
||||
_effectService.WarpToExit(enemy);
|
||||
break;
|
||||
default:
|
||||
enemy.TakeDamage(throwableItem.ThrowDamage, throwableItem.ElementType);
|
||||
|
||||
@@ -1,51 +1,38 @@
|
||||
using Chickensoft.AutoInject;
|
||||
using Chickensoft.Introspection;
|
||||
using Chickensoft.Serialization;
|
||||
using Godot;
|
||||
using System;
|
||||
using System.Collections.Immutable;
|
||||
|
||||
namespace GameJamDungeon;
|
||||
|
||||
[Meta(typeof(IAutoNode))]
|
||||
public partial class Weapon : Node3D, IInventoryItem, IEquipableItem
|
||||
[Meta, Id("weapon")]
|
||||
public partial class Weapon : EquipableItem
|
||||
{
|
||||
public override void _Notification(int what) => this.Notify(what);
|
||||
|
||||
[Dependency] public IPlayer Player => this.DependOn<IPlayer>();
|
||||
|
||||
[Signal]
|
||||
public delegate void EquippedItemEventHandler(Weapon equippedWeapon);
|
||||
|
||||
[Export]
|
||||
private WeaponStats _weaponStats { get; set; } = new WeaponStats();
|
||||
|
||||
[Node] public Sprite3D Sprite { get; set; } = new Sprite3D();
|
||||
public override string ItemName => _weaponStats.Name;
|
||||
|
||||
[Node] public Area3D Pickup { get; set; } = default!;
|
||||
public override string Description => _weaponStats.Description;
|
||||
|
||||
public Texture2D GetTexture() => _weaponStats.Texture;
|
||||
|
||||
public Guid ID => Guid.NewGuid();
|
||||
|
||||
public string ItemName => _weaponStats.Name;
|
||||
|
||||
public string Description => _weaponStats.Description;
|
||||
|
||||
public float SpawnRate => _weaponStats.SpawnRate;
|
||||
public override float SpawnRate => _weaponStats.SpawnRate;
|
||||
|
||||
public int Damage => _weaponStats.Damage;
|
||||
|
||||
public double ThrowDamage => _weaponStats.ThrowDamage;
|
||||
public override double ThrowDamage => _weaponStats.ThrowDamage;
|
||||
|
||||
public float ThrowSpeed => _weaponStats.ThrowSpeed;
|
||||
public override float ThrowSpeed => _weaponStats.ThrowSpeed;
|
||||
|
||||
public double Luck => _weaponStats.Luck;
|
||||
|
||||
public double AttackSpeed => _weaponStats.AttackSpeed;
|
||||
|
||||
public ImmutableList<WeaponTag> WeaponTags => [.. _weaponStats.WeaponTags];
|
||||
public WeaponTag WeaponTag => _weaponStats.WeaponTag;
|
||||
|
||||
public ImmutableList<ItemTag> ItemTags => [.. _weaponStats.ItemTags];
|
||||
public override ItemTag ItemTag => _weaponStats.ItemTag;
|
||||
|
||||
public ElementType WeaponElement => _weaponStats.WeaponElement;
|
||||
|
||||
@@ -53,38 +40,5 @@ public partial class Weapon : Node3D, IInventoryItem, IEquipableItem
|
||||
|
||||
public void IncreaseWeaponAttack(int bonus) => _weaponStats.Damage += bonus;
|
||||
|
||||
public bool IsEquipped { get; set; }
|
||||
|
||||
public void OnReady()
|
||||
{
|
||||
Pickup.BodyEntered += OnEntered;
|
||||
Sprite.Texture = _weaponStats.Texture;
|
||||
}
|
||||
|
||||
public void SetItemStats(InventoryItemStats inventoryItemStats)
|
||||
{
|
||||
_weaponStats = (WeaponStats)inventoryItemStats;
|
||||
if (inventoryItemStats.Texture != null)
|
||||
{
|
||||
var texture = ResourceLoader.Load(inventoryItemStats.Texture.ResourcePath) as Texture2D;
|
||||
Sprite.Texture = texture;
|
||||
}
|
||||
}
|
||||
|
||||
public void Throw()
|
||||
{
|
||||
Player.Inventory.Remove(this);
|
||||
}
|
||||
|
||||
public void Drop()
|
||||
{
|
||||
Player.Inventory.Remove(this);
|
||||
}
|
||||
|
||||
public void OnEntered(Node3D body)
|
||||
{
|
||||
var isAdded = Player.Inventory.TryAdd(this);
|
||||
if (isAdded)
|
||||
QueueFree();
|
||||
}
|
||||
public override InventoryItemStats ItemStats { get => _weaponStats; set => _weaponStats = (WeaponStats)value; }
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ script = ExtResource("1_7pkyf")
|
||||
[node name="Pickup" type="Area3D" parent="."]
|
||||
unique_name_in_owner = true
|
||||
collision_layer = 4
|
||||
collision_mask = 4
|
||||
collision_mask = 0
|
||||
|
||||
[node name="Sprite" type="Sprite3D" parent="Pickup"]
|
||||
unique_name_in_owner = true
|
||||
|
||||
@@ -1,25 +1,34 @@
|
||||
using Chickensoft.Introspection;
|
||||
using Chickensoft.Serialization;
|
||||
using Godot;
|
||||
|
||||
namespace GameJamDungeon;
|
||||
|
||||
[GlobalClass]
|
||||
[Meta, Id("weapon_stat_type")]
|
||||
public partial class WeaponStats : InventoryItemStats
|
||||
{
|
||||
[Export]
|
||||
[Save("weapon_damage")]
|
||||
public int Damage { get; set; } = 0;
|
||||
|
||||
[Export]
|
||||
[Save("weapon_luck")]
|
||||
public double Luck { get; set; } = 0.05;
|
||||
|
||||
[Export]
|
||||
[Save("weapon_atk_speed")]
|
||||
public double AttackSpeed { get; set; } = 1;
|
||||
|
||||
[Export]
|
||||
[Save("weapon_element")]
|
||||
public ElementType WeaponElement { get; set; } = ElementType.None;
|
||||
|
||||
[Export]
|
||||
[Save("weapon_elemental_damage_bonus")]
|
||||
public double ElementalDamageBonus { get; set; } = 1.0;
|
||||
|
||||
[Export]
|
||||
public Godot.Collections.Array<WeaponTag> WeaponTags { get; set; } = new Godot.Collections.Array<WeaponTag>();
|
||||
[Save("weapon_tag")]
|
||||
public WeaponTag WeaponTag { get; set; } = WeaponTag.None;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user