113 lines
3.2 KiB
Dart
113 lines
3.2 KiB
Dart
import '../enums.dart';
|
|
|
|
/// Defines an effect that an item can apply (e.g., 10% chance to Stun for 1 turn)
|
|
class ItemEffect {
|
|
final StatusEffectType type;
|
|
final int probability; // 0 to 100
|
|
final int duration;
|
|
final int value; // e.g., bleed damage amount
|
|
|
|
ItemEffect({
|
|
required this.type,
|
|
required this.probability,
|
|
required this.duration,
|
|
this.value = 0,
|
|
});
|
|
|
|
factory ItemEffect.fromJson(Map<String, dynamic> json) {
|
|
return ItemEffect(
|
|
type: StatusEffectType.values.firstWhere((e) => e.name == json['type']),
|
|
probability: json['probability'] ?? 0,
|
|
duration: json['duration'] ?? 0,
|
|
value: json['value'] ?? 0,
|
|
);
|
|
}
|
|
|
|
String get description {
|
|
String typeStr = type.name.toUpperCase();
|
|
// Customize names if needed
|
|
if (type == StatusEffectType.defenseForbidden) typeStr = "UNBLOCKABLE";
|
|
if (type == StatusEffectType.disarmed) typeStr = "DISARM";
|
|
|
|
String durationStr = "${duration}t";
|
|
String valStr = value > 0 ? " ($value dmg)" : "";
|
|
|
|
return "$typeStr $probability% ($durationStr)$valStr";
|
|
}
|
|
}
|
|
|
|
class Item {
|
|
final String id; // Unique identifier
|
|
final String name;
|
|
final String description;
|
|
final int atkBonus;
|
|
final int hpBonus;
|
|
final int armorBonus; // New stat for defense
|
|
final int dodge; // New: Dodge chance bonus
|
|
final EquipmentSlot slot;
|
|
final List<ItemEffect> effects; // Status effects this item can inflict
|
|
final int price; // New: Sell/Buy value
|
|
final String? image; // New: Image path
|
|
final int luck; // Success rate bonus (e.g. 5 = 5%)
|
|
final ItemRarity rarity;
|
|
final ItemTier tier;
|
|
final WeaponType? weaponType; // New: oneHanded or twoHanded
|
|
|
|
const Item({
|
|
required this.id,
|
|
required this.name,
|
|
required this.description,
|
|
required this.atkBonus,
|
|
required this.hpBonus,
|
|
this.armorBonus = 0, // Default to 0 for backward compatibility
|
|
this.dodge = 0, // Default to 0
|
|
required this.slot,
|
|
this.effects = const [], // Default to no effects
|
|
this.price = 0,
|
|
this.image,
|
|
this.luck = 0,
|
|
this.rarity = ItemRarity.magic,
|
|
this.tier = ItemTier.tier1,
|
|
this.weaponType,
|
|
});
|
|
|
|
String get typeName {
|
|
switch (slot) {
|
|
case EquipmentSlot.weapon:
|
|
return "Weapon";
|
|
case EquipmentSlot.armor:
|
|
return "Armor";
|
|
case EquipmentSlot.shield:
|
|
return "Subweapon";
|
|
case EquipmentSlot.accessory:
|
|
return "Accessory";
|
|
case EquipmentSlot.consumable:
|
|
return "Potion";
|
|
}
|
|
}
|
|
|
|
EquipmentSlot get defaultEquipSlot => slot;
|
|
|
|
List<EquipmentSlot> get compatibleEquipSlots {
|
|
switch (slot) {
|
|
case EquipmentSlot.weapon:
|
|
if (weaponType == WeaponType.oneHanded) {
|
|
return const [EquipmentSlot.weapon, EquipmentSlot.shield];
|
|
} else if (weaponType == WeaponType.twoHanded) {
|
|
return const [EquipmentSlot.weapon];
|
|
}
|
|
return const [EquipmentSlot.weapon]; // Default fallback
|
|
case EquipmentSlot.armor:
|
|
case EquipmentSlot.shield:
|
|
case EquipmentSlot.accessory:
|
|
return [slot];
|
|
case EquipmentSlot.consumable:
|
|
return const [];
|
|
}
|
|
}
|
|
|
|
bool canEquipTo(EquipmentSlot targetSlot) {
|
|
return compatibleEquipSlots.contains(targetSlot);
|
|
}
|
|
}
|