This commit is contained in:
2025-12-02 17:52:01 +09:00
parent 457eed4d3e
commit 0e96aa4f7c
10 changed files with 314 additions and 128 deletions
+4
View File
@@ -7,12 +7,14 @@ class EnemyTemplate {
final int baseHp;
final int baseAtk;
final int baseDefense;
final String? image;
const EnemyTemplate({
required this.name,
required this.baseHp,
required this.baseAtk,
required this.baseDefense,
this.image,
});
factory EnemyTemplate.fromJson(Map<String, dynamic> json) {
@@ -21,6 +23,7 @@ class EnemyTemplate {
baseHp: json['baseHp'] ?? 10,
baseAtk: json['baseAtk'] ?? 1,
baseDefense: json['baseDefense'] ?? 0,
image: json['image'],
);
}
@@ -36,6 +39,7 @@ class EnemyTemplate {
atk: scaledAtk,
baseDefense: scaledDefense,
armor: 0,
image: image,
);
}
}
+30 -12
View File
@@ -11,6 +11,8 @@ class ItemTemplate {
final int baseArmor;
final EquipmentSlot slot;
final List<ItemEffect> effects;
final int price;
final String? image;
const ItemTemplate({
required this.name,
@@ -20,6 +22,8 @@ class ItemTemplate {
this.baseArmor = 0,
required this.slot,
this.effects = const [],
this.price = 0,
this.image,
});
factory ItemTemplate.fromJson(Map<String, dynamic> json) {
@@ -30,10 +34,13 @@ class ItemTemplate {
baseHp: json['baseHp'] ?? 0,
baseArmor: json['baseArmor'] ?? 0,
slot: EquipmentSlot.values.firstWhere((e) => e.name == json['slot']),
effects: (json['effects'] as List<dynamic>?)
effects:
(json['effects'] as List<dynamic>?)
?.map((e) => ItemEffect.fromJson(e))
.toList() ??
[],
price: json['price'] ?? 0,
image: json['image'],
);
}
@@ -45,12 +52,12 @@ class ItemTemplate {
int scaledHp = baseHp > 0 ? baseHp + (stage - 1) * 5 : 0;
int scaledArmor = baseArmor > 0 ? baseArmor + (stage - 1) : 0;
// Calculate price based on stats
int calculatedPrice = (scaledAtk * 10) + (scaledHp * 2) + (scaledArmor * 5);
if (effects.isNotEmpty) {
calculatedPrice += effects.length * 50; // Bonus value for special effects
// Use fixed price from template
int finalPrice = price;
// Optional: Increase price if stage > 1 (e.g. +10% per stage)
if (stage > 1) {
finalPrice = (price * (1 + (stage - 1) * 0.1)).toInt();
}
if (calculatedPrice < 10) calculatedPrice = 10; // Minimum price
return Item(
name: "$name${stage > 1 ? ' +${stage - 1}' : ''}", // Append +1, +2 etc.
@@ -60,7 +67,8 @@ class ItemTemplate {
armorBonus: scaledArmor,
slot: slot,
effects: effects, // Pass the effects to the Item
price: calculatedPrice,
price: finalPrice,
image: image,
);
}
}
@@ -72,13 +80,23 @@ class ItemTable {
static List<ItemTemplate> accessories = [];
static Future<void> load() async {
final String jsonString = await rootBundle.loadString('assets/data/items.json');
final String jsonString = await rootBundle.loadString(
'assets/data/items.json',
);
final Map<String, dynamic> data = jsonDecode(jsonString);
weapons = (data['weapons'] as List).map((e) => ItemTemplate.fromJson(e)).toList();
armors = (data['armors'] as List).map((e) => ItemTemplate.fromJson(e)).toList();
shields = (data['shields'] as List).map((e) => ItemTemplate.fromJson(e)).toList();
accessories = (data['accessories'] as List).map((e) => ItemTemplate.fromJson(e)).toList();
weapons = (data['weapons'] as List)
.map((e) => ItemTemplate.fromJson(e))
.toList();
armors = (data['armors'] as List)
.map((e) => ItemTemplate.fromJson(e))
.toList();
shields = (data['shields'] as List)
.map((e) => ItemTemplate.fromJson(e))
.toList();
accessories = (data['accessories'] as List)
.map((e) => ItemTemplate.fromJson(e))
.toList();
}
static List<ItemTemplate> get allItems => [
+18 -9
View File
@@ -8,7 +8,9 @@ class Character {
int armor; // Current temporary shield/armor points in battle
int baseAtk;
int baseDefense; // Base defense stat
int gold; // New: Currency
String? image; // New: Image path
Map<EquipmentSlot, Item> equipment = {};
List<Item> inventory = [];
final int maxInventorySize = 16;
@@ -24,9 +26,10 @@ class Character {
required int atk,
this.baseDefense = 0,
this.gold = 0,
}) : baseMaxHp = maxHp,
baseAtk = atk,
hp = hp ?? maxHp;
this.image,
}) : baseMaxHp = maxHp,
baseAtk = atk,
hp = hp ?? maxHp;
/// Adds a status effect. If it already exists, it refreshes duration or stacks based on logic.
/// For now, we'll implement a simple refresh/overwrite logic.
@@ -99,7 +102,9 @@ class Character {
if (!inventory.contains(newItem)) return false;
// 1. Calculate current HP ratio before any changes
double hpRatio = totalMaxHp > 0 ? hp / totalMaxHp : 0.0; // Avoid division by zero
double hpRatio = totalMaxHp > 0
? hp / totalMaxHp
: 0.0; // Avoid division by zero
// 2. Handle Swap: If slot is occupied, unequip the old item first
if (equipment.containsKey(newItem.slot)) {
@@ -116,9 +121,10 @@ class Character {
hp = (totalMaxHp * hpRatio).toInt();
if (hp < 0) hp = 0; // Ensure HP does not go below zero
if (hp > totalMaxHp) {
hp = totalMaxHp; // Final Safety Clamp, though hpRatio <= 1.0 should prevent this
hp =
totalMaxHp; // Final Safety Clamp, though hpRatio <= 1.0 should prevent this
}
return true;
}
@@ -128,7 +134,9 @@ class Character {
if (!equipment.containsValue(item)) return false;
// 1. Calculate current HP ratio before any changes
double hpRatio = totalMaxHp > 0 ? hp / totalMaxHp : 0.0; // Avoid division by zero
double hpRatio = totalMaxHp > 0
? hp / totalMaxHp
: 0.0; // Avoid division by zero
if (inventory.length < maxInventorySize) {
equipment.remove(item.slot);
@@ -138,11 +146,12 @@ class Character {
hp = (totalMaxHp * hpRatio).toInt();
if (hp < 0) hp = 0; // Ensure HP does not go below zero
if (hp > totalMaxHp) {
hp = totalMaxHp; // Final Safety Clamp, though hpRatio <= 1.0 should prevent this
hp =
totalMaxHp; // Final Safety Clamp, though hpRatio <= 1.0 should prevent this
}
return true;
}
return false;
}
+3 -1
View File
@@ -46,6 +46,7 @@ class Item {
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
Item({
required this.name,
@@ -56,6 +57,7 @@ class Item {
required this.slot,
this.effects = const [], // Default to no effects
this.price = 0,
this.image,
});
String get typeName {
@@ -70,4 +72,4 @@ class Item {
return "Accessory";
}
}
}
}
+3 -2
View File
@@ -515,8 +515,9 @@ class BattleProvider with ChangeNotifier {
void sellItem(Item item) {
if (player.inventory.remove(item)) {
player.gold += item.price;
_addLog("Sold ${item.name} for ${item.price} G.");
int sellPrice = GameMath.floor(item.price * 0.6);
player.gold += sellPrice;
_addLog("Sold ${item.name} for $sellPrice G.");
notifyListeners();
}
}