642 lines
20 KiB
JavaScript
642 lines
20 KiB
JavaScript
/**
|
||
* SLIMES & DOGS SYSTEM
|
||
* Manages 8 slime types, King Slime boss, slime gel crafting, and dog companion.
|
||
*
|
||
* Features:
|
||
* - 8 Slime Types: Green, Blue, Red, Yellow, Purple, Black, Rainbow, King Slime
|
||
* - Slime Gel Crafting: 8 unique gel uses (potions, coatings, weapons)
|
||
* - Dog Companion: 6 abilities (item detection, combat, tracking, album helper, pathfinding, revive)
|
||
* - Dog Loyalty: 10-heart system, equipment (armor, backpack +10 slots)
|
||
*/
|
||
class SlimesDogsSystem {
|
||
constructor(scene) {
|
||
this.scene = scene;
|
||
|
||
// Slime types
|
||
this.slimeTypes = {
|
||
green: {
|
||
name: 'Green Slime',
|
||
health: 50,
|
||
damage: 5,
|
||
speed: 0.5,
|
||
drops: { green_gel: { min: 1, max: 3, chance: 1.0 } },
|
||
color: '#00FF00',
|
||
abilities: ['bounce'],
|
||
spawns: ['forest', 'swamp']
|
||
},
|
||
blue: {
|
||
name: 'Blue Slime',
|
||
health: 70,
|
||
damage: 8,
|
||
speed: 0.6,
|
||
drops: { blue_gel: { min: 1, max: 3, chance: 1.0 } },
|
||
color: '#0088FF',
|
||
abilities: ['freeze_touch'],
|
||
spawns: ['ice_biome', 'crystal_caves']
|
||
},
|
||
red: {
|
||
name: 'Red Slime',
|
||
health: 80,
|
||
damage: 12,
|
||
speed: 0.7,
|
||
drops: { red_gel: { min: 1, max: 3, chance: 1.0 } },
|
||
color: '#FF0000',
|
||
abilities: ['fire_trail'],
|
||
spawns: ['volcano', 'wasteland']
|
||
},
|
||
yellow: {
|
||
name: 'Yellow Slime',
|
||
health: 60,
|
||
damage: 10,
|
||
speed: 0.8,
|
||
drops: { yellow_gel: { min: 1, max: 3, chance: 1.0 } },
|
||
color: '#FFFF00',
|
||
abilities: ['electric_shock'],
|
||
spawns: ['plains', 'desert']
|
||
},
|
||
purple: {
|
||
name: 'Purple Slime',
|
||
health: 90,
|
||
damage: 15,
|
||
speed: 0.5,
|
||
drops: { purple_gel: { min: 2, max: 4, chance: 0.8 } },
|
||
color: '#AA00FF',
|
||
abilities: ['poison_cloud'],
|
||
spawns: ['swamp', 'dark_forest']
|
||
},
|
||
black: {
|
||
name: 'Black Slime',
|
||
health: 120,
|
||
damage: 20,
|
||
speed: 0.6,
|
||
drops: { black_gel: { min: 2, max: 5, chance: 0.6 } },
|
||
color: '#000000',
|
||
abilities: ['shadow_merge', 'darkness_aura'],
|
||
spawns: ['chernobyl', 'dark_fortress']
|
||
},
|
||
rainbow: {
|
||
name: 'Rainbow Slime',
|
||
health: 150,
|
||
damage: 25,
|
||
speed: 0.9,
|
||
drops: { rainbow_gel: { min: 3, max: 6, chance: 0.3 } },
|
||
color: '#FF00FF',
|
||
abilities: ['color_shift', 'prism_blast'],
|
||
spawns: ['atlantis', 'crystal_caves'],
|
||
rare: true
|
||
},
|
||
king: {
|
||
name: 'King Slime',
|
||
health: 3000,
|
||
damage: 50,
|
||
speed: 0.4,
|
||
drops: {
|
||
king_gel: { min: 10, max: 20, chance: 1.0 },
|
||
crown: { min: 1, max: 1, chance: 1.0 }
|
||
},
|
||
color: '#FFD700',
|
||
abilities: ['split', 'summon_slimes', 'giant_bounce', 'gel_wave'],
|
||
spawns: ['slime_cavern'],
|
||
boss: true,
|
||
splitCount: 4 // Splits into 4 smaller slimes
|
||
}
|
||
};
|
||
|
||
// Slime gel uses
|
||
this.gelUses = {
|
||
green_gel: [
|
||
{ type: 'potion', name: 'Healing Potion', effect: 'heal_50hp' },
|
||
{ type: 'coating', name: 'Sticky Coating', effect: 'slow_enemies' },
|
||
{ type: 'fertilizer', name: 'Slime Fertilizer', effect: 'crop_growth_2x' }
|
||
],
|
||
blue_gel: [
|
||
{ type: 'potion', name: 'Ice Resistance Potion', effect: 'ice_immunity_5min' },
|
||
{ type: 'coating', name: 'Freeze Coating', effect: 'freeze_on_hit' },
|
||
{ type: 'weapon', name: 'Frost Bomb', effect: 'freeze_area' }
|
||
],
|
||
red_gel: [
|
||
{ type: 'potion', name: 'Fire Resistance Potion', effect: 'fire_immunity_5min' },
|
||
{ type: 'coating', name: 'Flame Coating', effect: 'burn_on_hit' },
|
||
{ type: 'weapon', name: 'Molotov', effect: 'fire_area' }
|
||
],
|
||
yellow_gel: [
|
||
{ type: 'potion', name: 'Energy Potion', effect: 'speed_boost_20%' },
|
||
{ type: 'coating', name: 'Shock Coating', effect: 'stun_on_hit' },
|
||
{ type: 'light', name: 'Glowstick', effect: 'light_source' }
|
||
],
|
||
purple_gel: [
|
||
{ type: 'potion', name: 'Antidote', effect: 'cure_poison' },
|
||
{ type: 'coating', name: 'Poison Coating', effect: 'poison_on_hit' },
|
||
{ type: 'weapon', name: 'Poison Bomb', effect: 'poison_area' }
|
||
],
|
||
black_gel: [
|
||
{ type: 'potion', name: 'Shadow Potion', effect: 'invisibility_30sec' },
|
||
{ type: 'coating', name: 'Shadow Coating', effect: 'dark_damage' },
|
||
{ type: 'weapon', name: 'Void Bomb', effect: 'damage_absorb' }
|
||
],
|
||
rainbow_gel: [
|
||
{ type: 'potion', name: 'Rainbow Elixir', effect: 'all_stats_boost' },
|
||
{ type: 'coating', name: 'Prismatic Coating', effect: 'random_elemental' },
|
||
{ type: 'weapon', name: 'Spectrum Bomb', effect: 'multi_elemental' }
|
||
],
|
||
king_gel: [
|
||
{ type: 'potion', name: 'King\'s Blessing', effect: 'invincibility_10sec' },
|
||
{ type: 'coating', name: 'Royal Coating', effect: 'triple_damage' },
|
||
{ type: 'vehicle_fuel', name: 'Slime Fuel', effect: 'infinite_fuel_1hr' }
|
||
]
|
||
};
|
||
|
||
// Dog companion
|
||
this.dog = null;
|
||
|
||
// Dog breeds
|
||
this.dogBreeds = {
|
||
retriever: { name: 'Golden Retriever', bonus: 'item_detection_range_2x' },
|
||
shepherd: { name: 'German Shepherd', bonus: 'combat_damage_50%' },
|
||
husky: { name: 'Siberian Husky', bonus: 'cold_immunity' },
|
||
corgi: { name: 'Corgi', bonus: 'loyalty_gain_2x' },
|
||
dalmatian: { name: 'Dalmatian', bonus: 'speed_20%' },
|
||
custom: { name: 'Custom Dog', bonus: 'balanced' }
|
||
};
|
||
|
||
// Active slimes in world
|
||
this.activeSlimes = new Map();
|
||
|
||
console.log('🟢🐶 Slimes & Dogs System initialized!');
|
||
}
|
||
|
||
/**
|
||
* Spawn a slime
|
||
*/
|
||
spawnSlime(type, position) {
|
||
const slimeData = this.slimeTypes[type];
|
||
if (!slimeData) {
|
||
console.log(`❌ Unknown slime type: ${type}`);
|
||
return null;
|
||
}
|
||
|
||
const slimeId = `slime_${type}_${Date.now()}`;
|
||
|
||
const slime = {
|
||
id: slimeId,
|
||
type: type,
|
||
name: slimeData.name,
|
||
health: slimeData.health,
|
||
maxHealth: slimeData.health,
|
||
damage: slimeData.damage,
|
||
speed: slimeData.speed,
|
||
position: position,
|
||
color: slimeData.color,
|
||
abilities: slimeData.abilities,
|
||
alive: true,
|
||
boss: slimeData.boss || false
|
||
};
|
||
|
||
this.activeSlimes.set(slimeId, slime);
|
||
|
||
console.log(`🟢 Spawned ${slimeData.name} at (${position.x}, ${position.y})`);
|
||
|
||
return slimeId;
|
||
}
|
||
|
||
/**
|
||
* Fight King Slime boss
|
||
*/
|
||
fightKingSlime(position) {
|
||
const kingId = this.spawnSlime('king', position);
|
||
|
||
console.log('👑 BOSS FIGHT: King Slime!');
|
||
|
||
this.scene.events.emit('start-boss-fight', {
|
||
boss: this.activeSlimes.get(kingId),
|
||
arena: 'slime_cavern',
|
||
music: 'epic_slime',
|
||
mechanic: 'split'
|
||
});
|
||
|
||
return kingId;
|
||
}
|
||
|
||
/**
|
||
* King Slime split mechanic
|
||
*/
|
||
splitKingSlime(kingId, position) {
|
||
const king = this.activeSlimes.get(kingId);
|
||
if (!king || king.type !== 'king') return [];
|
||
|
||
console.log('💥 King Slime SPLITS!');
|
||
|
||
const spawnedSlimes = [];
|
||
const splitCount = this.slimeTypes.king.splitCount;
|
||
|
||
// Spawn smaller slimes in circle around king
|
||
for (let i = 0; i < splitCount; i++) {
|
||
const angle = (Math.PI * 2 / splitCount) * i;
|
||
const spawnPos = {
|
||
x: position.x + Math.cos(angle) * 100,
|
||
y: position.y + Math.sin(angle) * 100
|
||
};
|
||
|
||
// Spawn random colored slime
|
||
const slimeTypes = ['green', 'blue', 'red', 'yellow'];
|
||
const randomType = slimeTypes[Math.floor(Math.random() * slimeTypes.length)];
|
||
|
||
const slimeId = this.spawnSlime(randomType, spawnPos);
|
||
spawnedSlimes.push(slimeId);
|
||
}
|
||
|
||
this.scene.events.emit('notification', {
|
||
title: 'King Slime Split!',
|
||
message: `${splitCount} slimes spawned!`,
|
||
icon: '💥'
|
||
});
|
||
|
||
return spawnedSlimes;
|
||
}
|
||
|
||
/**
|
||
* Defeat a slime and get drops
|
||
*/
|
||
defeatSlime(slimeId) {
|
||
const slime = this.activeSlimes.get(slimeId);
|
||
if (!slime) return null;
|
||
|
||
slime.alive = false;
|
||
|
||
const slimeData = this.slimeTypes[slime.type];
|
||
const drops = this.rollDrops(slimeData.drops);
|
||
|
||
console.log(`💀 ${slime.name} defeated! Drops:`, drops);
|
||
|
||
// Spawn loot
|
||
drops.forEach(drop => {
|
||
if (this.scene.interactionSystem) {
|
||
this.scene.interactionSystem.spawnLoot(
|
||
slime.position.x,
|
||
slime.position.y,
|
||
drop.item,
|
||
drop.amount
|
||
);
|
||
}
|
||
});
|
||
|
||
// Remove from active slimes
|
||
this.activeSlimes.delete(slimeId);
|
||
|
||
return drops;
|
||
}
|
||
|
||
/**
|
||
* Roll for drops
|
||
*/
|
||
rollDrops(dropTable) {
|
||
const drops = [];
|
||
|
||
Object.keys(dropTable).forEach(item => {
|
||
const dropData = dropTable[item];
|
||
|
||
if (Math.random() < dropData.chance) {
|
||
const amount = Math.floor(
|
||
Math.random() * (dropData.max - dropData.min + 1) + dropData.min
|
||
);
|
||
|
||
drops.push({ item: item, amount: amount });
|
||
}
|
||
});
|
||
|
||
return drops;
|
||
}
|
||
|
||
/**
|
||
* Craft with slime gel
|
||
*/
|
||
craftWithGel(gelType, recipeIndex) {
|
||
const recipes = this.gelUses[gelType];
|
||
if (!recipes || !recipes[recipeIndex]) {
|
||
console.log(`❌ Invalid gel or recipe index!`);
|
||
return null;
|
||
}
|
||
|
||
const recipe = recipes[recipeIndex];
|
||
|
||
// Check if player has gel
|
||
if (this.scene.inventorySystem && !this.scene.inventorySystem.hasItem(gelType, 1)) {
|
||
console.log(`❌ Not enough ${gelType}!`);
|
||
return null;
|
||
}
|
||
|
||
// Consume gel
|
||
if (this.scene.inventorySystem) {
|
||
this.scene.inventorySystem.removeItem(gelType, 1);
|
||
}
|
||
|
||
// Create item
|
||
console.log(`🧪 Crafted ${recipe.name}!`);
|
||
|
||
this.scene.events.emit('notification', {
|
||
title: 'Crafted!',
|
||
message: `${recipe.name} created!`,
|
||
icon: '🧪'
|
||
});
|
||
|
||
return recipe;
|
||
}
|
||
|
||
/**
|
||
* Adopt a dog companion
|
||
*/
|
||
adoptDog(breed = 'retriever', name = 'Rex') {
|
||
if (this.dog) {
|
||
console.log('❌ You already have a dog companion!');
|
||
return null;
|
||
}
|
||
|
||
const breedData = this.dogBreeds[breed];
|
||
if (!breedData) {
|
||
console.log(`❌ Unknown breed: ${breed}`);
|
||
return null;
|
||
}
|
||
|
||
this.dog = {
|
||
name: name,
|
||
breed: breed,
|
||
breedName: breedData.name,
|
||
bonus: breedData.bonus,
|
||
loyalty: 0, // 0-10 hearts
|
||
abilities: {
|
||
item_detection: true,
|
||
combat: false, // Unlocks at 3 hearts
|
||
tracking: false, // Unlocks at 5 hearts
|
||
album_helper: false, // Unlocks at 7 hearts
|
||
pathfinding: false, // Unlocks at 8 hearts
|
||
revive: false // Unlocks at 10 hearts
|
||
},
|
||
equipment: {
|
||
armor: null,
|
||
backpack: null // +10 inventory slots when equipped
|
||
},
|
||
health: 100,
|
||
maxHealth: 100,
|
||
alive: true,
|
||
position: { x: 0, y: 0 }
|
||
};
|
||
|
||
console.log(`🐶 ${name} the ${breedData.name} joined you!`);
|
||
|
||
this.scene.events.emit('notification', {
|
||
title: 'Dog Companion!',
|
||
message: `${name} the ${breedData.name} joined your adventure!`,
|
||
icon: '🐶'
|
||
});
|
||
|
||
return this.dog;
|
||
}
|
||
|
||
/**
|
||
* Increase dog loyalty
|
||
*/
|
||
increaseLoyalty(amount = 1) {
|
||
if (!this.dog) return;
|
||
|
||
this.dog.loyalty = Math.min(10, this.dog.loyalty + amount);
|
||
|
||
console.log(`💕 ${this.dog.name}'s loyalty: ${this.dog.loyalty}/10 hearts`);
|
||
|
||
// Unlock abilities based on loyalty
|
||
this.unlockDogAbilities();
|
||
|
||
if (this.dog.loyalty === 10) {
|
||
this.scene.events.emit('notification', {
|
||
title: 'Maximum Loyalty!',
|
||
message: `${this.dog.name} can now REVIVE you!`,
|
||
icon: '💕'
|
||
});
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Unlock dog abilities based on loyalty
|
||
*/
|
||
unlockDogAbilities() {
|
||
if (!this.dog) return;
|
||
|
||
const loyalty = this.dog.loyalty;
|
||
|
||
if (loyalty >= 3 && !this.dog.abilities.combat) {
|
||
this.dog.abilities.combat = true;
|
||
console.log('⚔️ Combat ability unlocked!');
|
||
}
|
||
|
||
if (loyalty >= 5 && !this.dog.abilities.tracking) {
|
||
this.dog.abilities.tracking = true;
|
||
console.log('🔍 Tracking ability unlocked!');
|
||
}
|
||
|
||
if (loyalty >= 7 && !this.dog.abilities.album_helper) {
|
||
this.dog.abilities.album_helper = true;
|
||
console.log('📚 Album Helper ability unlocked!');
|
||
}
|
||
|
||
if (loyalty >= 8 && !this.dog.abilities.pathfinding) {
|
||
this.dog.abilities.pathfinding = true;
|
||
console.log('🗺️ Pathfinding ability unlocked!');
|
||
}
|
||
|
||
if (loyalty >= 10 && !this.dog.abilities.revive) {
|
||
this.dog.abilities.revive = true;
|
||
console.log('💖 REVIVE ability unlocked!');
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Equip armor on dog
|
||
*/
|
||
equipDogArmor(armorType) {
|
||
if (!this.dog) return false;
|
||
|
||
const armors = {
|
||
leather: { defense: 10, name: 'Leather Armor' },
|
||
iron: { defense: 25, name: 'Iron Armor' },
|
||
diamond: { defense: 50, name: 'Diamond Armor' }
|
||
};
|
||
|
||
const armor = armors[armorType];
|
||
if (!armor) {
|
||
console.log(`❌ Unknown armor: ${armorType}`);
|
||
return false;
|
||
}
|
||
|
||
this.dog.equipment.armor = {
|
||
type: armorType,
|
||
defense: armor.defense,
|
||
name: armor.name
|
||
};
|
||
|
||
this.dog.maxHealth = 100 + armor.defense;
|
||
this.dog.health = Math.min(this.dog.health + armor.defense, this.dog.maxHealth);
|
||
|
||
console.log(`🛡️ ${this.dog.name} equipped ${armor.name}! Defense +${armor.defense}`);
|
||
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* Equip backpack on dog (+10 inventory slots)
|
||
*/
|
||
equipDogBackpack() {
|
||
if (!this.dog) return false;
|
||
|
||
if (this.dog.equipment.backpack) {
|
||
console.log('ℹ️ Dog already has a backpack!');
|
||
return false;
|
||
}
|
||
|
||
this.dog.equipment.backpack = {
|
||
slots: 10
|
||
};
|
||
|
||
// Add inventory slots
|
||
if (this.scene.inventorySystem) {
|
||
this.scene.inventorySystem.maxSlots += 10;
|
||
}
|
||
|
||
console.log(`🎒 ${this.dog.name} equipped backpack! +10 inventory slots!`);
|
||
|
||
this.scene.events.emit('notification', {
|
||
title: 'Dog Backpack!',
|
||
message: `${this.dog.name} can now carry items! +10 slots!`,
|
||
icon: '🎒'
|
||
});
|
||
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* Use dog's item detection ability
|
||
*/
|
||
detectItems(playerPosition, radius = 300) {
|
||
if (!this.dog || !this.dog.abilities.item_detection) return [];
|
||
|
||
// Simulate item detection (in real game, would scan for actual items)
|
||
const detectedItems = [];
|
||
|
||
console.log(`🔍 ${this.dog.name} is sniffing for items...`);
|
||
|
||
// Visual indicator
|
||
this.scene.events.emit('dog-sniff-animation', {
|
||
position: this.dog.position,
|
||
radius: radius
|
||
});
|
||
|
||
return detectedItems;
|
||
}
|
||
|
||
/**
|
||
* Use dog's combat ability
|
||
*/
|
||
dogAttack(targetId) {
|
||
if (!this.dog || !this.dog.abilities.combat) return 0;
|
||
|
||
const baseDamage = 20;
|
||
const loyaltyBonus = this.dog.loyalty * 2;
|
||
const totalDamage = baseDamage + loyaltyBonus;
|
||
|
||
console.log(`⚔️ ${this.dog.name} attacks for ${totalDamage} damage!`);
|
||
|
||
return totalDamage;
|
||
}
|
||
|
||
/**
|
||
* Use dog's tracking ability
|
||
*/
|
||
trackTarget(targetType) {
|
||
if (!this.dog || !this.dog.abilities.tracking) return null;
|
||
|
||
console.log(`🐾 ${this.dog.name} is tracking ${targetType}...`);
|
||
|
||
// Simulate tracking (in real game, would find actual targets)
|
||
const trackingResult = {
|
||
found: true,
|
||
direction: Math.random() * Math.PI * 2,
|
||
distance: Math.random() * 1000
|
||
};
|
||
|
||
this.scene.events.emit('dog-tracking', trackingResult);
|
||
|
||
return trackingResult;
|
||
}
|
||
|
||
/**
|
||
* Dog helps find album items
|
||
*/
|
||
albumHelp() {
|
||
if (!this.dog || !this.dog.abilities.album_helper) return null;
|
||
|
||
console.log(`📚 ${this.dog.name} is searching for collectibles...`);
|
||
|
||
// Simulate finding collectible hint
|
||
const hint = {
|
||
type: 'album_item',
|
||
direction: Math.random() * Math.PI * 2,
|
||
distance: Math.random() * 500
|
||
};
|
||
|
||
this.scene.events.emit('notification', {
|
||
title: 'Dog Found Something!',
|
||
message: `${this.dog.name} detects a collectible nearby!`,
|
||
icon: '🐶'
|
||
});
|
||
|
||
return hint;
|
||
}
|
||
|
||
/**
|
||
* Revive player (10 hearts required!)
|
||
*/
|
||
revivePlayer() {
|
||
if (!this.dog || !this.dog.abilities.revive) return false;
|
||
|
||
console.log(`💖 ${this.dog.name} revived you!`);
|
||
|
||
this.scene.events.emit('player-revived', {
|
||
revivedBy: this.dog.name,
|
||
health: 50 // Revive with 50% health
|
||
});
|
||
|
||
this.scene.events.emit('notification', {
|
||
title: 'You Were Revived!',
|
||
message: `${this.dog.name} saved your life!`,
|
||
icon: '💖'
|
||
});
|
||
|
||
// One-time use per day
|
||
this.dog.abilities.revive = false;
|
||
|
||
setTimeout(() => {
|
||
this.dog.abilities.revive = true;
|
||
console.log('💖 Revive ability recharged!');
|
||
}, 86400000); // 24 hours
|
||
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* Get dog stats
|
||
*/
|
||
getDogStats() {
|
||
if (!this.dog) return null;
|
||
|
||
return {
|
||
name: this.dog.name,
|
||
breed: this.dog.breedName,
|
||
loyalty: `${this.dog.loyalty}/10 hearts`,
|
||
health: `${this.dog.health}/${this.dog.maxHealth}`,
|
||
abilities: Object.keys(this.dog.abilities).filter(a => this.dog.abilities[a]),
|
||
equipment: {
|
||
armor: this.dog.equipment.armor?.name || 'None',
|
||
backpack: this.dog.equipment.backpack ? '+10 slots' : 'None'
|
||
}
|
||
};
|
||
}
|
||
}
|