Files
Mana-Loop/src/lib/game/data/loot-drops.ts
T
n8n-gitea 3f20991d2d
Build and Publish Mana Loop Docker Image / build-and-publish (push) Successful in 4m25s
feat: add material crafting recipes to Fabricator
2026-05-27 14:13:46 +02:00

347 lines
7.8 KiB
TypeScript
Executable File

// ─── Loot Drop Definitions ─────────────────────────────────────────────────────
import type { LootDrop } from '../types/game';
export const LOOT_DROPS: Record<string, LootDrop> = {
// ─── Materials (used for crafting) ───
manaCrystalDust: {
id: 'manaCrystalDust',
name: 'Mana Crystal Dust',
rarity: 'common',
type: 'material',
minFloor: 1,
dropChance: 0.15,
},
arcaneShard: {
id: 'arcaneShard',
name: 'Arcane Shard',
rarity: 'uncommon',
type: 'material',
minFloor: 10,
dropChance: 0.10,
},
earthShard: {
id: 'earthShard',
name: 'Earth Attuned Shard',
rarity: 'uncommon',
type: 'material',
minFloor: 10,
dropChance: 0.08,
},
metalShard: {
id: 'metalShard',
name: 'Metal Attuned Shard',
rarity: 'rare',
type: 'material',
minFloor: 20,
dropChance: 0.06,
},
crystalShard: {
id: 'crystalShard',
name: 'Crystal Attuned Shard',
rarity: 'rare',
type: 'material',
minFloor: 30,
dropChance: 0.05,
},
sandShard: {
id: 'sandShard',
name: 'Sand Attuned Shard',
rarity: 'uncommon',
type: 'material',
minFloor: 15,
dropChance: 0.07,
},
manaCrystal: {
id: 'manaCrystal',
name: 'Mana Crystal',
rarity: 'uncommon',
type: 'material',
minFloor: 5,
dropChance: 0.10,
},
fireCrystal: {
id: 'fireCrystal',
name: 'Fire Attuned Crystal',
rarity: 'rare',
type: 'material',
minFloor: 15,
dropChance: 0.06,
},
waterCrystal: {
id: 'waterCrystal',
name: 'Water Attuned Crystal',
rarity: 'rare',
type: 'material',
minFloor: 15,
dropChance: 0.06,
},
airCrystal: {
id: 'airCrystal',
name: 'Air Attuned Crystal',
rarity: 'rare',
type: 'material',
minFloor: 15,
dropChance: 0.06,
},
earthCrystal: {
id: 'earthCrystal',
name: 'Earth Attuned Crystal',
rarity: 'rare',
type: 'material',
minFloor: 15,
dropChance: 0.06,
},
lightCrystal: {
id: 'lightCrystal',
name: 'Light Attuned Crystal',
rarity: 'rare',
type: 'material',
minFloor: 25,
dropChance: 0.05,
},
darkCrystal: {
id: 'darkCrystal',
name: 'Dark Attuned Crystal',
rarity: 'rare',
type: 'material',
minFloor: 25,
dropChance: 0.05,
},
metalCrystal: {
id: 'metalCrystal',
name: 'Metal Attuned Crystal',
rarity: 'rare',
type: 'material',
minFloor: 30,
dropChance: 0.05,
},
crystalCrystal: {
id: 'crystalCrystal',
name: 'Crystal Attuned Crystal',
rarity: 'epic',
type: 'material',
minFloor: 40,
dropChance: 0.03,
},
elementalCore: {
id: 'elementalCore',
name: 'Elemental Core',
rarity: 'rare',
type: 'material',
minFloor: 25,
dropChance: 0.08,
},
voidEssence: {
id: 'voidEssence',
name: 'Void Essence',
rarity: 'epic',
type: 'material',
minFloor: 50,
dropChance: 0.05,
guardianOnly: true,
},
celestialFragment: {
id: 'celestialFragment',
name: 'Celestial Fragment',
rarity: 'legendary',
type: 'material',
minFloor: 75,
dropChance: 0.02,
guardianOnly: true,
},
// ─── Elemental Essence (grants elemental mana) ───
fireEssenceDrop: {
id: 'fireEssenceDrop',
name: 'Fire Essence',
rarity: 'uncommon',
type: 'essence',
minFloor: 5,
dropChance: 0.12,
amount: { min: 5, max: 15 },
},
waterEssenceDrop: {
id: 'waterEssenceDrop',
name: 'Water Essence',
rarity: 'uncommon',
type: 'essence',
minFloor: 5,
dropChance: 0.12,
amount: { min: 5, max: 15 },
},
airEssenceDrop: {
id: 'airEssenceDrop',
name: 'Air Essence',
rarity: 'uncommon',
type: 'essence',
minFloor: 5,
dropChance: 0.12,
amount: { min: 5, max: 15 },
},
earthEssenceDrop: {
id: 'earthEssenceDrop',
name: 'Earth Essence',
rarity: 'uncommon',
type: 'essence',
minFloor: 5,
dropChance: 0.12,
amount: { min: 5, max: 15 },
},
lightEssenceDrop: {
id: 'lightEssenceDrop',
name: 'Light Essence',
rarity: 'rare',
type: 'essence',
minFloor: 20,
dropChance: 0.08,
amount: { min: 3, max: 10 },
},
darkEssenceDrop: {
id: 'darkEssenceDrop',
name: 'Dark Essence',
rarity: 'rare',
type: 'essence',
minFloor: 20,
dropChance: 0.08,
amount: { min: 3, max: 10 },
},
vitalityEssenceDrop: {
id: 'vitalityEssenceDrop',
name: 'Vitality Essence',
rarity: 'epic',
type: 'essence',
minFloor: 40,
dropChance: 0.05,
amount: { min: 2, max: 8 },
},
deathEssenceDrop: {
id: 'deathEssenceDrop',
name: 'Death Essence',
rarity: 'epic',
type: 'essence',
minFloor: 40,
dropChance: 0.05,
amount: { min: 2, max: 8 },
},
// ─── Raw Mana Drops ───
manaOrb: {
id: 'manaOrb',
name: 'Mana Orb',
rarity: 'common',
type: 'gold', // Uses gold type but gives raw mana
minFloor: 1,
dropChance: 0.20,
amount: { min: 10, max: 50 },
},
greaterManaOrb: {
id: 'greaterManaOrb',
name: 'Greater Mana Orb',
rarity: 'uncommon',
type: 'gold',
minFloor: 15,
dropChance: 0.10,
amount: { min: 50, max: 150 },
},
supremeManaOrb: {
id: 'supremeManaOrb',
name: 'Supreme Mana Orb',
rarity: 'rare',
type: 'gold',
minFloor: 35,
dropChance: 0.05,
amount: { min: 100, max: 500 },
},
// ─── Equipment Blueprints ───
staffBlueprint: {
id: 'staffBlueprint',
name: 'Staff Blueprint',
rarity: 'uncommon',
type: 'blueprint',
minFloor: 10,
dropChance: 0.03,
},
wandBlueprint: {
id: 'wandBlueprint',
name: 'Wand Blueprint',
rarity: 'rare',
type: 'blueprint',
minFloor: 20,
dropChance: 0.02,
},
robeBlueprint: {
id: 'robeBlueprint',
name: 'Mage Robe Blueprint',
rarity: 'rare',
type: 'blueprint',
minFloor: 25,
dropChance: 0.02,
},
artifactBlueprint: {
id: 'artifactBlueprint',
name: 'Artifact Blueprint',
rarity: 'legendary',
type: 'blueprint',
minFloor: 60,
dropChance: 0.01,
guardianOnly: true,
},
};
// Rarity colors for UI
export const LOOT_RARITY_COLORS: Record<string, { color: string; glow: string }> = {
common: { color: '#9CA3AF', glow: '#9CA3AF40' },
uncommon: { color: '#22C55E', glow: '#22C55E40' },
rare: { color: '#3B82F6', glow: '#3B82F640' },
epic: { color: '#A855F7', glow: '#A855F740' },
legendary: { color: '#F59E0B', glow: '#F59E0B60' },
};
// Get loot drops available at a given floor
export function getAvailableDrops(floor: number, isGuardian: boolean): LootDrop[] {
return Object.values(LOOT_DROPS).filter(drop => {
if (drop.minFloor > floor) return false;
if (drop.guardianOnly && !isGuardian) return false;
return true;
});
}
// Roll for loot drops
export function rollLootDrops(
floor: number,
isGuardian: boolean,
luckBonus: number = 0
): Array<{ drop: LootDrop; amount: number }> {
const available = getAvailableDrops(floor, isGuardian);
const drops: Array<{ drop: LootDrop; amount: number }> = [];
for (const drop of available) {
// Calculate adjusted drop chance
let chance = drop.dropChance;
chance *= (1 + luckBonus); // Apply luck bonus
// Guardian floors have 2x drop rate
if (isGuardian) chance *= 2;
// Cap at 50% for any single drop
chance = Math.min(0.5, chance);
if (Math.random() < chance) {
let amount = 1;
// For gold/essence types, roll amount
if (drop.amount) {
amount = Math.floor(
Math.random() * (drop.amount.max - drop.amount.min + 1) + drop.amount.min
);
}
drops.push({ drop, amount });
}
}
return drops;
}