narejeno
This commit is contained in:
407
src/systems/MiningDungeonsSystem.js
Normal file
407
src/systems/MiningDungeonsSystem.js
Normal file
@@ -0,0 +1,407 @@
|
||||
/**
|
||||
* MINING & DUNGEONS SYSTEM
|
||||
* Underground cave generation, mining, and dungeon exploration
|
||||
*/
|
||||
class MiningDungeonsSystem {
|
||||
constructor(scene) {
|
||||
this.scene = scene;
|
||||
this.enabled = true;
|
||||
|
||||
// Caves & dungeons
|
||||
this.caves = new Map();
|
||||
this.currentCave = null;
|
||||
|
||||
// Mining
|
||||
this.oreVeins = new Map();
|
||||
this.minedOres = [];
|
||||
|
||||
// Elevators
|
||||
this.elevators = new Map();
|
||||
|
||||
// Enemies
|
||||
this.caveEnemies = [];
|
||||
|
||||
// Bosses
|
||||
this.dungeonBosses = new Map();
|
||||
|
||||
// Settings
|
||||
this.settings = {
|
||||
maxDepth: 50,
|
||||
roomSize: { min: 5, max: 15 },
|
||||
tunnelWidth: 2,
|
||||
oreChance: 0.1
|
||||
};
|
||||
|
||||
this.loadProgress();
|
||||
this.init();
|
||||
|
||||
console.log('✅ Mining & Dungeons System initialized');
|
||||
}
|
||||
|
||||
init() {
|
||||
this.defineOreTypes();
|
||||
this.defineEnemyTypes();
|
||||
console.log('⛏️ Mining & Dungeons ready');
|
||||
}
|
||||
|
||||
// ========== ORE TYPES ==========
|
||||
|
||||
defineOreTypes() {
|
||||
this.oreTypes = {
|
||||
// Depth 0-10
|
||||
copper: { depth: [0, 10], value: 5, rarity: 0.4 },
|
||||
tin: { depth: [0, 10], value: 5, rarity: 0.4 },
|
||||
|
||||
// Depth 10-20
|
||||
iron: { depth: [10, 20], value: 15, rarity: 0.3 },
|
||||
coal: { depth: [10, 20], value: 10, rarity: 0.35 },
|
||||
|
||||
// Depth 20-30
|
||||
gold: { depth: [20, 30], value: 50, rarity: 0.15 },
|
||||
silver: { depth: [20, 30], value: 30, rarity: 0.2 },
|
||||
|
||||
// Depth 30+
|
||||
diamond: { depth: [30, 50], value: 200, rarity: 0.05 },
|
||||
mythril: { depth: [30, 50], value: 500, rarity: 0.02 }
|
||||
};
|
||||
}
|
||||
|
||||
// ========== ENEMY TYPES ==========
|
||||
|
||||
defineEnemyTypes() {
|
||||
this.enemyTypes = {
|
||||
bat: {
|
||||
name: 'Cave Bat',
|
||||
hp: 20,
|
||||
damage: 5,
|
||||
speed: 1.5,
|
||||
xp: 10,
|
||||
loot: ['bat_wing', 'guano']
|
||||
},
|
||||
spider: {
|
||||
name: 'Giant Spider',
|
||||
hp: 50,
|
||||
damage: 15,
|
||||
speed: 1.0,
|
||||
xp: 25,
|
||||
loot: ['spider_silk', 'venom']
|
||||
},
|
||||
mole: {
|
||||
name: 'Mutant Mole',
|
||||
hp: 80,
|
||||
damage: 20,
|
||||
speed: 0.8,
|
||||
xp: 40,
|
||||
loot: ['mole_claw', 'earth_essence']
|
||||
},
|
||||
golem: {
|
||||
name: 'Stone Golem',
|
||||
hp: 200,
|
||||
damage: 40,
|
||||
speed: 0.5,
|
||||
xp: 100,
|
||||
loot: ['stone_core', 'ancient_rune']
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// ========== CAVE GENERATION ==========
|
||||
|
||||
generateCave(depth, seed) {
|
||||
const cave = {
|
||||
id: `cave_${depth}_${seed}`,
|
||||
depth,
|
||||
seed,
|
||||
rooms: [],
|
||||
tunnels: [],
|
||||
oreVeins: [],
|
||||
enemies: [],
|
||||
boss: null,
|
||||
explored: false
|
||||
};
|
||||
|
||||
// Generate rooms
|
||||
const numRooms = 5 + Math.floor(depth / 10);
|
||||
for (let i = 0; i < numRooms; i++) {
|
||||
cave.rooms.push(this.generateRoom(depth));
|
||||
}
|
||||
|
||||
// Connect rooms with tunnels
|
||||
cave.tunnels = this.connectRooms(cave.rooms);
|
||||
|
||||
// Place ore veins
|
||||
cave.oreVeins = this.placeOres(depth, cave.rooms);
|
||||
|
||||
// Spawn enemies
|
||||
cave.enemies = this.spawnEnemies(depth, cave.rooms);
|
||||
|
||||
// Boss every 10 levels
|
||||
if (depth % 10 === 0) {
|
||||
cave.boss = this.createBoss(depth);
|
||||
}
|
||||
|
||||
this.caves.set(cave.id, cave);
|
||||
return cave;
|
||||
}
|
||||
|
||||
generateRoom(depth) {
|
||||
const size = this.settings.roomSize;
|
||||
const width = size.min + Math.floor(Math.random() * (size.max - size.min));
|
||||
const height = size.min + Math.floor(Math.random() * (size.max - size.min));
|
||||
|
||||
return {
|
||||
x: Math.floor(Math.random() * 100),
|
||||
y: Math.floor(Math.random() * 100),
|
||||
width,
|
||||
height,
|
||||
type: this.getRoomType(depth)
|
||||
};
|
||||
}
|
||||
|
||||
getRoomType(depth) {
|
||||
const types = ['cave', 'crystal_cavern', 'lava_chamber', 'ice_cave', 'mushroom_grove'];
|
||||
const index = Math.floor(depth / 10) % types.length;
|
||||
return types[index];
|
||||
}
|
||||
|
||||
connectRooms(rooms) {
|
||||
const tunnels = [];
|
||||
|
||||
for (let i = 0; i < rooms.length - 1; i++) {
|
||||
const room1 = rooms[i];
|
||||
const room2 = rooms[i + 1];
|
||||
|
||||
tunnels.push({
|
||||
from: { x: room1.x + room1.width / 2, y: room1.y + room1.height / 2 },
|
||||
to: { x: room2.x + room2.width / 2, y: room2.y + room2.height / 2 },
|
||||
width: this.settings.tunnelWidth
|
||||
});
|
||||
}
|
||||
|
||||
return tunnels;
|
||||
}
|
||||
|
||||
// ========== ORE PLACEMENT ==========
|
||||
|
||||
placeOres(depth, rooms) {
|
||||
const oreVeins = [];
|
||||
|
||||
for (const room of rooms) {
|
||||
const numVeins = 2 + Math.floor(Math.random() * 5);
|
||||
|
||||
for (let i = 0; i < numVeins; i++) {
|
||||
const ore = this.selectOre(depth);
|
||||
if (!ore) continue;
|
||||
|
||||
oreVeins.push({
|
||||
type: ore,
|
||||
x: room.x + Math.floor(Math.random() * room.width),
|
||||
y: room.y + Math.floor(Math.random() * room.height),
|
||||
amount: 5 + Math.floor(Math.random() * 10),
|
||||
mined: false
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return oreVeins;
|
||||
}
|
||||
|
||||
selectOre(depth) {
|
||||
const validOres = Object.entries(this.oreTypes)
|
||||
.filter(([_, ore]) => depth >= ore.depth[0] && depth <= ore.depth[1]);
|
||||
|
||||
if (validOres.length === 0) return null;
|
||||
|
||||
// Weighted random selection
|
||||
const totalRarity = validOres.reduce((sum, [_, ore]) => sum + ore.rarity, 0);
|
||||
let roll = Math.random() * totalRarity;
|
||||
|
||||
for (const [oreName, ore] of validOres) {
|
||||
roll -= ore.rarity;
|
||||
if (roll <= 0) return oreName;
|
||||
}
|
||||
|
||||
return validOres[0][0];
|
||||
}
|
||||
|
||||
// ========== ENEMY SPAWNING ==========
|
||||
|
||||
spawnEnemies(depth, rooms) {
|
||||
const enemies = [];
|
||||
const enemiesPerRoom = 1 + Math.floor(depth / 5);
|
||||
|
||||
for (const room of rooms) {
|
||||
for (let i = 0; i < enemiesPerRoom; i++) {
|
||||
const enemyType = this.selectEnemy(depth);
|
||||
const enemyData = this.enemyTypes[enemyType];
|
||||
|
||||
enemies.push({
|
||||
type: enemyType,
|
||||
name: enemyData.name,
|
||||
hp: enemyData.hp * (1 + depth * 0.1),
|
||||
maxHp: enemyData.hp * (1 + depth * 0.1),
|
||||
damage: enemyData.damage * (1 + depth * 0.1),
|
||||
speed: enemyData.speed,
|
||||
x: room.x + Math.floor(Math.random() * room.width),
|
||||
y: room.y + Math.floor(Math.random() * room.height),
|
||||
xp: enemyData.xp,
|
||||
loot: enemyData.loot
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return enemies;
|
||||
}
|
||||
|
||||
selectEnemy(depth) {
|
||||
if (depth < 10) return 'bat';
|
||||
if (depth < 20) return Math.random() < 0.5 ? 'bat' : 'spider';
|
||||
if (depth < 30) return Math.random() < 0.3 ? 'spider' : 'mole';
|
||||
return Math.random() < 0.5 ? 'mole' : 'golem';
|
||||
}
|
||||
|
||||
// ========== BOSS CREATION ==========
|
||||
|
||||
createBoss(depth) {
|
||||
const bossTypes = {
|
||||
10: { name: 'Crystal Guardian', hp: 500, damage: 50 },
|
||||
20: { name: 'Lava Titan', hp: 1000, damage: 80 },
|
||||
30: { name: 'Ice Dragon', hp: 2000, damage: 120 },
|
||||
40: { name: 'Shadow Demon', hp: 3500, damage: 150 },
|
||||
50: { name: 'Ancient Wyrm', hp: 5000, damage: 200 }
|
||||
};
|
||||
|
||||
const bossData = bossTypes[depth] || bossTypes[50];
|
||||
|
||||
return {
|
||||
name: bossData.name,
|
||||
hp: bossData.hp,
|
||||
maxHp: bossData.hp,
|
||||
damage: bossData.damage,
|
||||
phase: 1,
|
||||
maxPhases: 3,
|
||||
defeated: false,
|
||||
loot: this.generateBossLoot(depth)
|
||||
};
|
||||
}
|
||||
|
||||
generateBossLoot(depth) {
|
||||
return [
|
||||
{ item: 'legendary_sword', chance: 0.1 },
|
||||
{ item: 'boss_trophy', chance: 1.0 },
|
||||
{ item: 'rare_gem', chance: 0.5 },
|
||||
{ item: 'gold', amount: depth * 100, chance: 1.0 }
|
||||
];
|
||||
}
|
||||
|
||||
// ========== MINING ==========
|
||||
|
||||
mineOre(oreVeinId) {
|
||||
const vein = this.oreVeins.get(oreVeinId);
|
||||
if (!vein || vein.mined) return null;
|
||||
|
||||
// Mine ore
|
||||
vein.amount--;
|
||||
|
||||
if (vein.amount <= 0) {
|
||||
vein.mined = true;
|
||||
}
|
||||
|
||||
// Add to inventory
|
||||
if (this.scene.inventorySystem) {
|
||||
this.scene.inventorySystem.addItem(vein.type, 1);
|
||||
}
|
||||
|
||||
// Track mined ores
|
||||
this.minedOres.push({
|
||||
type: vein.type,
|
||||
time: Date.now()
|
||||
});
|
||||
|
||||
console.log(`⛏️ Mined ${vein.type}!`);
|
||||
return vein.type;
|
||||
}
|
||||
|
||||
// ========== ELEVATOR ==========
|
||||
|
||||
buildElevator(x, y) {
|
||||
const elevator = {
|
||||
id: `elevator_${x}_${y}`,
|
||||
x, y,
|
||||
currentDepth: 0,
|
||||
maxDepth: 0,
|
||||
active: true
|
||||
};
|
||||
|
||||
this.elevators.set(elevator.id, elevator);
|
||||
console.log(`🛗 Built elevator at (${x}, ${y})`);
|
||||
return elevator;
|
||||
}
|
||||
|
||||
useElevator(elevatorId, targetDepth) {
|
||||
const elevator = this.elevators.get(elevatorId);
|
||||
if (!elevator) return false;
|
||||
|
||||
if (targetDepth > elevator.maxDepth) {
|
||||
console.log('❌ Depth not unlocked yet');
|
||||
return false;
|
||||
}
|
||||
|
||||
// Generate cave if not exists
|
||||
let cave = Array.from(this.caves.values()).find(c => c.depth === targetDepth);
|
||||
if (!cave) {
|
||||
cave = this.generateCave(targetDepth, Date.now());
|
||||
}
|
||||
|
||||
this.currentCave = cave;
|
||||
elevator.currentDepth = targetDepth;
|
||||
|
||||
console.log(`🛗 Descended to depth ${targetDepth}`);
|
||||
return true;
|
||||
}
|
||||
|
||||
// ========== MINE CART ==========
|
||||
|
||||
placeMinecart(x, y) {
|
||||
console.log(`🛤️ Placed minecart at (${x}, ${y})`);
|
||||
// Minecart for fast transport through tunnels
|
||||
}
|
||||
|
||||
// ========== UPDATE ==========
|
||||
|
||||
update(delta) {
|
||||
// Update cave enemies, etc.
|
||||
}
|
||||
|
||||
// ========== PERSISTENCE ==========
|
||||
|
||||
saveProgress() {
|
||||
const data = {
|
||||
caves: Array.from(this.caves.values()).map(c => ({
|
||||
id: c.id,
|
||||
depth: c.depth,
|
||||
explored: c.explored
|
||||
})),
|
||||
minedOres: this.minedOres.length
|
||||
};
|
||||
|
||||
localStorage.setItem('novafarma_mining', JSON.stringify(data));
|
||||
}
|
||||
|
||||
loadProgress() {
|
||||
const saved = localStorage.getItem('novafarma_mining');
|
||||
if (saved) {
|
||||
try {
|
||||
const data = JSON.parse(saved);
|
||||
console.log('✅ Mining progress loaded');
|
||||
} catch (error) {
|
||||
console.error('Failed to load mining progress:', error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
destroy() {
|
||||
this.saveProgress();
|
||||
console.log('⛏️ Mining & Dungeons System destroyed');
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user