💻 GAME SYSTEMS CODE - Sleep, Crafting, Bakery
Implemented 3 major game systems in JavaScript
This commit is contained in:
384
src/systems/SleepSystem.js
Normal file
384
src/systems/SleepSystem.js
Normal file
@@ -0,0 +1,384 @@
|
||||
/**
|
||||
* SLEEP SYSTEM - Energy Regeneration & Bed Upgrades
|
||||
* Part of: Home Upgrade & Customization System
|
||||
* Created: January 4, 2026
|
||||
*
|
||||
* Features:
|
||||
* - 3-tier bed system (sleeping bag → wooden → king-size)
|
||||
* - Energy regeneration based on bed quality
|
||||
* - Time skip mechanics (8 hours sleep)
|
||||
* - Partner bonuses for married players
|
||||
* - Dream sequences and nightmares
|
||||
*/
|
||||
|
||||
export class SleepSystem {
|
||||
constructor(game) {
|
||||
this.game = game;
|
||||
this.player = game.player;
|
||||
this.isSleeping = false;
|
||||
this.currentBed = null;
|
||||
|
||||
// Bed types configuration
|
||||
this.bedTypes = {
|
||||
SLEEPING_BAG: {
|
||||
id: 'sleeping_bag',
|
||||
name: 'Sleeping Bag',
|
||||
cost: 0,
|
||||
unlocked: true,
|
||||
energyRegen: 50, // Restores 50% energy
|
||||
sleepDuration: 8, // hours
|
||||
dreamChance: 0, // No dreams
|
||||
nightmareChance: 0.1, // 10% nightmare chance
|
||||
partnerBonus: false,
|
||||
sprite: 'interior_bed_sleepingbag.png',
|
||||
description: 'A basic sleeping bag. Uncomfortable but functional.'
|
||||
},
|
||||
WOODEN_BED: {
|
||||
id: 'wooden_bed',
|
||||
name: 'Wooden Bed',
|
||||
cost: 2000,
|
||||
requirements: {
|
||||
farmhouseLevel: 1
|
||||
},
|
||||
unlocked: false,
|
||||
energyRegen: 90, // Restores 90% energy
|
||||
sleepDuration: 8,
|
||||
dreamChance: 0.2, // 20% dream chance
|
||||
nightmareChance: 0.05, // 5% nightmare chance
|
||||
partnerBonus: false,
|
||||
sprite: 'interior_bed_wooden.png',
|
||||
description: 'A comfortable wooden bed. Much better than the floor!'
|
||||
},
|
||||
KING_SIZE_BED: {
|
||||
id: 'king_size',
|
||||
name: 'King-size Bed',
|
||||
cost: 10000,
|
||||
requirements: {
|
||||
farmhouseLevel: 2,
|
||||
married: true
|
||||
},
|
||||
unlocked: false,
|
||||
energyRegen: 100, // Restores 100% energy
|
||||
sleepDuration: 8,
|
||||
dreamChance: 0.3, // 30% dream chance
|
||||
nightmareChance: 0, // No nightmares!
|
||||
partnerBonus: true, // +50 relationship points
|
||||
spousePresent: false,
|
||||
sprite: 'interior_bed_kingsize.png',
|
||||
description: 'A luxurious king-size bed. Perfect for two!'
|
||||
}
|
||||
};
|
||||
|
||||
// Current player's bed (starts with sleeping bag)
|
||||
this.playerBed = { ...this.bedTypes.SLEEPING_BAG };
|
||||
|
||||
// Sleep state
|
||||
this.sleepStartTime = null;
|
||||
this.sleepEndTime = null;
|
||||
this.dreamSequence = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if player can use a specific bed type
|
||||
*/
|
||||
canUseBed(bedType) {
|
||||
const bed = this.bedTypes[bedType];
|
||||
|
||||
// Check if unlocked
|
||||
if (!bed.unlocked && bedType !== 'SLEEPING_BAG') {
|
||||
return { canUse: false, reason: 'Bed not purchased yet' };
|
||||
}
|
||||
|
||||
// Check requirements
|
||||
if (bed.requirements) {
|
||||
if (bed.requirements.farmhouseLevel &&
|
||||
this.player.farmhouseLevel < bed.requirements.farmhouseLevel) {
|
||||
return {
|
||||
canUse: false,
|
||||
reason: `Requires Farmhouse Level ${bed.requirements.farmhouseLevel}`
|
||||
};
|
||||
}
|
||||
|
||||
if (bed.requirements.married && !this.player.isMarried) {
|
||||
return {
|
||||
canUse: false,
|
||||
reason: 'Requires marriage'
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
return { canUse: true };
|
||||
}
|
||||
|
||||
/**
|
||||
* Purchase a bed upgrade
|
||||
*/
|
||||
purchaseBed(bedType) {
|
||||
const bed = this.bedTypes[bedType];
|
||||
|
||||
// Check if can purchase
|
||||
if (bed.unlocked) {
|
||||
return { success: false, message: 'You already own this bed!' };
|
||||
}
|
||||
|
||||
// Check cost
|
||||
if (this.player.money < bed.cost) {
|
||||
return {
|
||||
success: false,
|
||||
message: `Not enough money! Need ${bed.cost}g`
|
||||
};
|
||||
}
|
||||
|
||||
// Check requirements
|
||||
const canUse = this.canUseBed(bedType);
|
||||
if (!canUse.canUse) {
|
||||
return { success: false, message: canUse.reason };
|
||||
}
|
||||
|
||||
// Purchase bed
|
||||
this.player.money -= bed.cost;
|
||||
bed.unlocked = true;
|
||||
this.playerBed = { ...bed };
|
||||
|
||||
// Trigger furniture placement
|
||||
this.game.emit('bedPurchased', {
|
||||
bedType: bedType,
|
||||
bed: bed
|
||||
});
|
||||
|
||||
return {
|
||||
success: true,
|
||||
message: `Purchased ${bed.name} for ${bed.cost}g!`
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Initiate sleep sequence
|
||||
*/
|
||||
sleep() {
|
||||
// Check if already sleeping
|
||||
if (this.isSleeping) {
|
||||
return { success: false, message: 'Already sleeping!' };
|
||||
}
|
||||
|
||||
// Check if tired enough (energy < 50%)
|
||||
if (this.player.energy > this.player.maxEnergy * 0.5) {
|
||||
return {
|
||||
success: false,
|
||||
message: "You're not tired enough to sleep yet."
|
||||
};
|
||||
}
|
||||
|
||||
// Start sleep
|
||||
this.isSleeping = true;
|
||||
this.sleepStartTime = this.game.time.currentTime;
|
||||
this.sleepEndTime = this.game.time.currentTime + (this.playerBed.sleepDuration * 3600); // Convert to seconds
|
||||
|
||||
// Roll for dream/nightmare
|
||||
this.dreamSequence = this.rollForDream();
|
||||
|
||||
// Trigger sleep animation
|
||||
this.game.emit('sleepStarted', {
|
||||
bed: this.playerBed,
|
||||
duration: this.playerBed.sleepDuration,
|
||||
dreamSequence: this.dreamSequence
|
||||
});
|
||||
|
||||
// Fast-forward time
|
||||
this.game.time.skipTime(this.playerBed.sleepDuration);
|
||||
|
||||
// Wake up after duration
|
||||
setTimeout(() => {
|
||||
this.wakeUp();
|
||||
}, 100); // Instant wake-up after time skip
|
||||
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
/**
|
||||
* Roll for dream or nightmare
|
||||
*/
|
||||
rollForDream() {
|
||||
const rand = Math.random();
|
||||
|
||||
// Check nightmare first
|
||||
if (rand < this.playerBed.nightmareChance) {
|
||||
return {
|
||||
type: 'nightmare',
|
||||
sequence: this.getRandomNightmare()
|
||||
};
|
||||
}
|
||||
|
||||
// Check dream
|
||||
if (rand < this.playerBed.dreamChance + this.playerBed.nightmareChance) {
|
||||
return {
|
||||
type: 'dream',
|
||||
sequence: this.getRandomDream()
|
||||
};
|
||||
}
|
||||
|
||||
return null; // No dream
|
||||
}
|
||||
|
||||
/**
|
||||
* Get random dream sequence
|
||||
*/
|
||||
getRandomDream() {
|
||||
const dreams = [
|
||||
{
|
||||
id: 'memory_ana',
|
||||
title: 'Memory of Ana',
|
||||
description: 'You dream of Ana, smiling in the sunlight...',
|
||||
effect: { mood: +10 }
|
||||
},
|
||||
{
|
||||
id: 'farming_success',
|
||||
title: 'Bountiful Harvest',
|
||||
description: 'You dream of your crops growing tall and strong.',
|
||||
effect: { farming_xp: 50 }
|
||||
},
|
||||
{
|
||||
id: 'zombie_peace',
|
||||
title: 'Peaceful Workers',
|
||||
description: 'Your zombie workers are happy and productive.',
|
||||
effect: { loyalty: +5 }
|
||||
}
|
||||
];
|
||||
|
||||
return dreams[Math.floor(Math.random() * dreams.length)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get random nightmare sequence
|
||||
*/
|
||||
getRandomNightmare() {
|
||||
const nightmares = [
|
||||
{
|
||||
id: 'ana_loss',
|
||||
title: 'The Loss',
|
||||
description: 'Fragments of that terrible day flash before you...',
|
||||
effect: { mood: -20 }
|
||||
},
|
||||
{
|
||||
id: 'zombie_attack',
|
||||
title: 'Undead Uprising',
|
||||
description: 'Your workers turn hostile, advancing slowly...',
|
||||
effect: { energy: -10 }
|
||||
},
|
||||
{
|
||||
id: 'crop_failure',
|
||||
title: 'Withered Fields',
|
||||
description: 'Your entire farm crumbles to dust.',
|
||||
effect: { mood: -10 }
|
||||
}
|
||||
];
|
||||
|
||||
return nightmares[Math.floor(Math.random() * nightmares.length)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Wake up from sleep
|
||||
*/
|
||||
wakeUp() {
|
||||
if (!this.isSleeping) return;
|
||||
|
||||
// Calculate energy restoration
|
||||
const energyRestored = (this.player.maxEnergy * this.playerBed.energyRegen) / 100;
|
||||
this.player.energy = Math.min(
|
||||
this.player.maxEnergy,
|
||||
this.player.energy + energyRestored
|
||||
);
|
||||
|
||||
// Partner bonus (if married & king-size bed)
|
||||
if (this.playerBed.partnerBonus && this.player.isMarried) {
|
||||
const spouse = this.game.npcs.getSpouse();
|
||||
if (spouse) {
|
||||
spouse.addRelationshipPoints(50);
|
||||
this.game.showMessage(`${spouse.name} cuddles closer. +50 ❤️`);
|
||||
}
|
||||
}
|
||||
|
||||
// Apply dream/nightmare effects
|
||||
if (this.dreamSequence) {
|
||||
this.applyDreamEffects(this.dreamSequence);
|
||||
}
|
||||
|
||||
// Update state
|
||||
this.isSleeping = false;
|
||||
this.currentBed = null;
|
||||
this.dreamSequence = null;
|
||||
|
||||
// Trigger wake-up event
|
||||
this.game.emit('wakeUp', {
|
||||
energyRestored: energyRestored,
|
||||
newEnergy: this.player.energy,
|
||||
time: this.game.time.currentTime
|
||||
});
|
||||
|
||||
// New day announcements
|
||||
this.game.showMessage(`Good morning! Energy restored: ${Math.floor(energyRestored)}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply dream/nightmare effects
|
||||
*/
|
||||
applyDreamEffects(dreamSequence) {
|
||||
const sequence = dreamSequence.sequence;
|
||||
|
||||
// Show dream/nightmare message
|
||||
const typeIcon = dreamSequence.type === 'dream' ? '✨' : '💀';
|
||||
this.game.showMessage(`${typeIcon} ${sequence.title}: ${sequence.description}`);
|
||||
|
||||
// Apply effects
|
||||
if (sequence.effect.mood) {
|
||||
this.player.mood += sequence.effect.mood;
|
||||
}
|
||||
if (sequence.effect.energy) {
|
||||
this.player.energy += sequence.effect.energy;
|
||||
}
|
||||
if (sequence.effect.farming_xp) {
|
||||
this.player.addXP('farming', sequence.effect.farming_xp);
|
||||
}
|
||||
if (sequence.effect.loyalty && this.game.zombieWorkers) {
|
||||
this.game.zombieWorkers.addGlobalLoyalty(sequence.effect.loyalty);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if it's a good time to sleep
|
||||
*/
|
||||
canSleepNow() {
|
||||
const hour = this.game.time.getHour();
|
||||
|
||||
// Can sleep between 8 PM (20:00) and 2 AM (02:00)
|
||||
if ((hour >= 20 && hour <= 23) || (hour >= 0 && hour <= 2)) {
|
||||
return { canSleep: true };
|
||||
}
|
||||
|
||||
return {
|
||||
canSleep: false,
|
||||
message: "It's not nighttime yet. Sleep between 8 PM - 2 AM."
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Get current bed info for UI
|
||||
*/
|
||||
getCurrentBedInfo() {
|
||||
return {
|
||||
...this.playerBed,
|
||||
isSleeping: this.isSleeping,
|
||||
canSleep: this.canSleepNow().canSleep
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Update (called every frame)
|
||||
*/
|
||||
update(deltaTime) {
|
||||
// Sleep system update logic (if needed)
|
||||
// Currently handled by events and timers
|
||||
}
|
||||
}
|
||||
|
||||
export default SleepSystem;
|
||||
Reference in New Issue
Block a user