Files
novafarma/EMERGENCY_SYSTEMS_RECOVERY/BarberShopSystem.js
2026-01-16 02:43:46 +01:00

664 lines
19 KiB
JavaScript

/**
* BARBER SHOP SYSTEM - Character Customization & Styling
* Part of: New Town Buildings
* Created: January 4, 2026
*
* Features:
* - Hairstyle changes (dreadlocks, mohawk, long hair, ponytail, bald)
* - Piercings & body modifications (ear gauges, nose ring, eyebrow, lip)
* - Color customization (hair dye, clothing)
* - Zombie makeover (cosmetic for workers)
* - NPC customization (change other characters)
* - Save/load favorite looks
*/
class BarberShopSystem {
constructor(game) {
this.game = game;
this.player = game.player;
// Barber shop status
this.isUnlocked = false;
this.isOpen = false;
this.barber = null;
// Hairstyle catalog
this.hairstyles = this.initializeHairstyles();
// Piercing catalog
this.piercings = this.initializePiercings();
// Hair dye colors
this.dyeColors = this.initializeDyeColors();
// Player's current appearance
this.playerAppearance = {
hairstyle: 'default',
hairColor: 'brown',
piercings: [],
clothing: {
shirt: 'default',
pants: 'default',
colorShirt: 'blue',
colorPants: 'brown'
}
};
// Saved looks (5 slots)
this.savedLooks = [null, null, null, null, null];
// Visit counter (for discounts)
this.visitCount = 0;
this.lastVisitDate = null;
}
/**
* Initialize hairstyle catalog
*/
initializeHairstyles() {
return {
default: {
id: 'default',
name: 'Default Hair',
price: 0,
unlocked: true,
sprite: 'hair_default',
description: 'Your natural hair.'
},
dreadlocks_pink_green: {
id: 'dreadlocks_pink_green',
name: 'Pink & Green Dreadlocks',
price: 500,
unlocked: true,
signature: 'kai', // Kai's signature style
sprite: 'hair_dreadlocks_pg',
description: 'Kai\'s iconic pink and green dreads!'
},
mohawk_blue: {
id: 'mohawk_blue',
name: 'Blue Mohawk',
price: 300,
unlocked: true,
sprite: 'hair_mohawk_blue',
description: 'Stand tall with this punk mohawk.'
},
mohawk_purple: {
id: 'mohawk_purple',
name: 'Purple Mohawk',
price: 300,
unlocked: true,
sprite: 'hair_mohawk_purple',
description: 'Purple power!'
},
mohawk_red: {
id: 'mohawk_red',
name: 'Red Mohawk',
price: 300,
unlocked: true,
sprite: 'hair_mohawk_red',
description: 'Fiery red mohawk.'
},
long_hair: {
id: 'long_hair',
name: 'Long Hair',
price: 400,
unlocked: true,
dyeable: true,
sprite: 'hair_long',
description: 'Flowing long hair, can be dyed any color.'
},
ponytail: {
id: 'ponytail',
name: 'Ponytail',
price: 250,
unlocked: true,
dyeable: true,
sprite: 'hair_ponytail',
description: 'Practical and stylish.'
},
bald: {
id: 'bald',
name: 'Bald',
price: 100,
unlocked: true,
reversible: true, // Can revert for free
sprite: 'hair_none',
description: 'Clean shaven head. Can reverse for FREE!'
}
};
}
/**
* Initialize piercing catalog
*/
initializePiercings() {
return {
ear_gauges: {
id: 'ear_gauges',
name: 'Ear Gauges',
price: 200,
unlocked: true,
signature: 'kai', // Kai's trademark
sprite: 'piercing_gauges',
description: 'Large ear gauges like Kai\'s!'
},
nose_ring: {
id: 'nose_ring',
name: 'Nose Ring',
price: 150,
unlocked: true,
sprite: 'piercing_nose',
description: 'Simple nose ring.'
},
eyebrow_piercing: {
id: 'eyebrow_piercing',
name: 'Eyebrow Piercing',
price: 100,
unlocked: true,
sprite: 'piercing_eyebrow',
description: 'Edgy eyebrow piercing.'
},
lip_ring: {
id: 'lip_ring',
name: 'Lip Ring',
price: 150,
unlocked: true,
sprite: 'piercing_lip',
description: 'Lip ring for that punk look.'
},
multiple_ear: {
id: 'multiple_ear',
name: 'Multiple Ear Piercings',
price: 50,
stackable: true, // Can have multiple
sprite: 'piercing_ear_multiple',
description: 'Each additional piercing costs 50g.'
}
};
}
/**
* Initialize hair dye colors
*/
initializeDyeColors() {
return {
brown: { name: 'Brown', price: 0, hex: '#654321' },
black: { name: 'Black', price: 100, hex: '#000000' },
blonde: { name: 'Blonde', price: 150, hex: '#FFD700' },
red: { name: 'Red', price: 200, hex: '#FF0000' },
blue: { name: 'Blue', price: 200, hex: '#0000FF' },
purple: { name: 'Purple', price: 200, hex: '#800080' },
pink: { name: 'Pink', price: 200, hex: '#FF69B4' },
green: { name: 'Green', price: 200, hex: '#00FF00' },
white: { name: 'White', price: 250, hex: '#FFFFFF' }
};
}
/**
* Unlock barber shop
*/
unlockBarberShop() {
// Check requirements
const npcCount = this.game.npcs.getPopulationCount();
if (npcCount < 3) {
return {
success: false,
message: 'Need at least 3 NPCs in town first!'
};
}
if (!this.player.hasCompletedQuest('style_matters')) {
return {
success: false,
message: 'Complete "Style Matters" quest first!'
};
}
if (!this.player.hasMaterials({ wood: 75, iron: 25 })) {
return {
success: false,
message: 'Need 75 Wood + 25 Iron to build barber shop!'
};
}
if (this.player.money < 6000) {
return {
success: false,
message: 'Need 6,000g to build barber shop!'
};
}
// Build barber shop
this.player.removeMaterials({ wood: 75, iron: 25 });
this.player.money -= 6000;
this.isUnlocked = true;
this.isOpen = true;
// Spawn barber NPC
this.barber = this.game.npcs.spawn('barber', {
name: 'Razor',
position: { x: 1400, y: 900 },
appearance: {
hairstyle: 'mohawk_purple',
piercings: ['ear_gauges', 'nose_ring', 'lip_ring']
}
});
this.game.showMessage('💇 Barber Shop is now open!');
return { success: true };
}
/**
* Change hairstyle
*/
changeHairstyle(hairstyleId) {
const hairstyle = this.hairstyles[hairstyleId];
if (!hairstyle) {
return { success: false, message: 'Hairstyle not found!' };
}
// Check if shop is open
if (!this.isOpen) {
return { success: false, message: 'Barber shop is closed!' };
}
// Check price (with discount)
const discount = this.getVisitDiscount();
const price = Math.floor(hairstyle.price * (1 - discount));
// Free reversal from bald
if (hairstyle.reversible && this.playerAppearance.hairstyle === 'bald') {
// Revert to previous hairstyle for free
this.playerAppearance.hairstyle = this.previousHairstyle || 'default';
this.game.showMessage('Hair restored for FREE!');
return { success: true, price: 0 };
}
// Check money
if (this.player.money < price) {
return {
success: false,
message: `Not enough money! Need ${price}g`
};
}
// Save previous hairstyle (for bald reversal)
this.previousHairstyle = this.playerAppearance.hairstyle;
// Change hairstyle
this.player.money -= price;
this.playerAppearance.hairstyle = hairstyleId;
// Update sprite
this.updatePlayerSprite();
// Track visit
this.incrementVisitCount();
let message = `Changed to ${hairstyle.name}! ${price}g`;
if (discount > 0) {
message += ` (${Math.floor(discount * 100)}% repeat customer discount!)`;
}
this.game.showMessage(message);
return { success: true, price: price, discount: discount };
}
/**
* Add piercing
*/
addPiercing(piercingId) {
const piercing = this.piercings[piercingId];
if (!piercing) {
return { success: false, message: 'Piercing not found!' };
}
// Check if already have (unless stackable)
if (!piercing.stackable && this.playerAppearance.piercings.includes(piercingId)) {
return {
success: false,
message: 'You already have this piercing!'
};
}
// Check price
const price = piercing.price;
if (this.player.money < price) {
return {
success: false,
message: `Not enough money! Need ${price}g`
};
}
// Add piercing
this.player.money -= price;
if (piercing.stackable) {
// Count how many of this type
const count = this.playerAppearance.piercings.filter(p => p === piercingId).length;
this.playerAppearance.piercings.push(`${piercingId}_${count + 1}`);
} else {
this.playerAppearance.piercings.push(piercingId);
}
// Update sprite
this.updatePlayerSprite();
// Track visit
this.incrementVisitCount();
this.game.showMessage(`Added ${piercing.name}! ${price}g`);
return { success: true, price: price };
}
/**
* Remove piercing
*/
removePiercing(piercingId) {
const index = this.playerAppearance.piercings.indexOf(piercingId);
if (index === -1) {
return { success: false, message: 'You don\'t have this piercing!' };
}
// Remove free of charge
this.playerAppearance.piercings.splice(index, 1);
// Update sprite
this.updatePlayerSprite();
this.game.showMessage('Piercing removed (free).');
return { success: true };
}
/**
* Dye hair color
*/
dyeHair(colorId) {
const color = this.dyeColors[colorId];
if (!color) {
return { success: false, message: 'Color not found!' };
}
// Check if current hairstyle is dyeable
const currentHairstyle = this.hairstyles[this.playerAppearance.hairstyle];
if (!currentHairstyle.dyeable && currentHairstyle.id !== 'default') {
return {
success: false,
message: 'This hairstyle cannot be dyed!'
};
}
// Check price
if (this.player.money < color.price) {
return {
success: false,
message: `Not enough money! Need ${color.price}g`
};
}
// Dye hair
this.player.money -= color.price;
this.playerAppearance.hairColor = colorId;
// Update sprite
this.updatePlayerSprite();
// Track visit
this.incrementVisitCount();
this.game.showMessage(`Hair dyed ${color.name}! ${color.price}g`);
return { success: true, price: color.price };
}
/**
* Dye clothing
*/
dyeClothing(clothingPart, colorId) {
const color = this.dyeColors[colorId];
if (!color) {
return { success: false, message: 'Color not found!' };
}
// Clothing dye is cheaper (half price)
const price = Math.floor(color.price / 2);
if (this.player.money < price) {
return {
success: false,
message: `Not enough money! Need ${price}g`
};
}
// Dye clothing
this.player.money -= price;
if (clothingPart === 'shirt') {
this.playerAppearance.clothing.colorShirt = colorId;
} else if (clothingPart === 'pants') {
this.playerAppearance.clothing.colorPants = colorId;
}
// Update sprite
this.updatePlayerSprite();
this.game.showMessage(`${clothingPart} dyed ${color.name}! ${price}g`);
return { success: true, price: price };
}
/**
* Zombie makeover (cosmetic for workers)
*/
zombieMakeover(zombieId) {
const zombie = this.game.zombieWorkers.get(zombieId);
if (!zombie) {
return { success: false, message: 'Zombie not found!' };
}
const price = 1000;
if (this.player.money < price) {
return {
success: false,
message: 'Zombie makeover costs 1,000g!'
};
}
// Apply makeover
this.player.money -= price;
// Random fancy appearance for zombie
const fancyStyles = ['mohawk_blue', 'mohawk_purple', 'dreadlocks_pink_green'];
const style = Phaser.Utils.Array.GetRandom(fancyStyles);
zombie.appearance = {
hairstyle: style,
accessories: ['fancy_bow_tie', 'top_hat']
};
// Update zombie sprite
this.game.zombieWorkers.updateZombieSprite(zombieId);
// Loyalty bonus (zombies appreciate looking good!)
zombie.addLoyalty(20);
this.game.showMessage(`${zombie.name} looks fabulous! +20 Loyalty! 1,000g`);
return { success: true, price: price };
}
/**
* Customize NPC appearance
*/
customizeNPC(npcId, changes) {
const npc = this.game.npcs.get(npcId);
if (!npc) {
return { success: false, message: 'NPC not found!' };
}
// Check relationship (need 5+ hearts)
if (this.player.getRelationshipLevel(npcId) < 5) {
return {
success: false,
message: `Need 5+ hearts with ${npc.name} first!`
};
}
const price = 500;
if (this.player.money < price) {
return {
success: false,
message: 'NPC customization costs 500g!'
};
}
// Apply changes
this.player.money -= price;
if (changes.hairstyle) {
npc.appearance.hairstyle = changes.hairstyle;
}
if (changes.hairColor) {
npc.appearance.hairColor = changes.hairColor;
}
// Update NPC sprite
this.game.npcs.updateNPCSprite(npcId);
// NPC reaction
npc.addRelationshipPoints(10);
this.game.showDialogue(npc.name, "Wow, I love it! Thank you!");
this.game.showMessage(`Styled ${npc.name}! +10 ❤️ 500g`);
return { success: true, price: price };
}
/**
* Save current look to slot
*/
saveLook(slotIndex) {
if (slotIndex < 0 || slotIndex >= 5) {
return { success: false, message: 'Invalid slot!' };
}
this.savedLooks[slotIndex] = {
hairstyle: this.playerAppearance.hairstyle,
hairColor: this.playerAppearance.hairColor,
piercings: [...this.playerAppearance.piercings],
clothing: { ...this.playerAppearance.clothing },
name: `Look ${slotIndex + 1}`
};
this.game.showMessage(`Saved look to slot ${slotIndex + 1}!`);
return { success: true };
}
/**
* Load saved look from slot
*/
loadLook(slotIndex) {
if (slotIndex < 0 || slotIndex >= 5) {
return { success: false, message: 'Invalid slot!' };
}
const savedLook = this.savedLooks[slotIndex];
if (!savedLook) {
return { success: false, message: 'No look saved in this slot!' };
}
// Apply saved look (free!)
this.playerAppearance = {
hairstyle: savedLook.hairstyle,
hairColor: savedLook.hairColor,
piercings: [...savedLook.piercings],
clothing: { ...savedLook.clothing }
};
// Update sprite
this.updatePlayerSprite();
this.game.showMessage(`Loaded ${savedLook.name}!`);
return { success: true };
}
/**
* Get visit discount (repeat customers)
*/
getVisitDiscount() {
// 5+ visits = 10% off
if (this.visitCount >= 5) {
return 0.10;
}
return 0;
}
/**
* Increment visit count
*/
incrementVisitCount() {
const today = this.game.time.currentDate;
// Only count once per day
if (this.lastVisitDate !== today) {
this.visitCount++;
this.lastVisitDate = today;
}
}
/**
* Update player sprite with new appearance
*/
updatePlayerSprite() {
// Emit event for sprite manager to update
this.game.emit('playerAppearanceChanged', {
appearance: this.playerAppearance
});
// Rebuild player sprite
this.player.rebuildSprite(this.playerAppearance);
}
/**
* Get preview of appearance change
*/
getPreview(changes) {
return {
...this.playerAppearance,
...changes
};
}
/**
* Get shop UI data
*/
getShopUIData() {
return {
isUnlocked: this.isUnlocked,
isOpen: this.isOpen,
hairstyles: this.hairstyles,
piercings: this.piercings,
dyeColors: this.dyeColors,
currentAppearance: this.playerAppearance,
savedLooks: this.savedLooks,
visitDiscount: this.getVisitDiscount(),
barber: this.barber
};
}
}