Initial commit: 3D Hommie RPG game

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Maxim Dolgolyov
2026-02-25 01:04:09 +03:00
commit fb5f09212b
34 changed files with 14550 additions and 0 deletions

184
js/game/SaveSystem.js Normal file
View File

@@ -0,0 +1,184 @@
export class SaveSystem {
constructor(game) {
this.game = game;
this.key = 'bomzh_rpg_save';
}
save() {
const data = {
version: 5,
timestamp: Date.now(),
gameTime: this.game.gameTime,
gameDay: this.game.gameDay,
player: {
stats: { ...this.game.player.stats },
position: {
x: this.game.player.position.x,
y: this.game.player.position.y,
z: this.game.player.position.z
},
stamina: this.game.player.stamina,
isDiseased: this.game.player.isDiseased,
diseaseTimer: this.game.player.diseaseTimer,
addictionLevel: this.game.player.addictionLevel,
lastDrinkTime: this.game.player.lastDrinkTime
},
inventory: { ...this.game.inventory.items },
inventoryMaxSlots: this.game.inventory.maxSlots,
quests: this.game.questSystem.quests.map(q => ({
id: q.id,
progress: q.progress,
completed: q.completed || false
})),
weather: this.game.weather.current,
temperature: this.game.weather.temperature,
skills: this.game.skills.getSaveData(),
dog: {
adopted: this.game.dog.adopted
},
reputation: this.game.reputation.getSaveData(),
seasons: this.game.seasons.getSaveData(),
jobSystem: this.game.jobSystem.getSaveData(),
equipment: this.game.equipment.getSaveData(),
achievements: this.game.achievements.getSaveData(),
housing: this.game.housing.getSaveData(),
gameStats: {
totalJobsCompleted: this.game.totalJobsCompleted,
totalBottlesSold: this.game.totalBottlesSold,
totalCrafted: this.game.totalCrafted,
talkedNPCs: [...this.game.talkedNPCs],
visitedLocations: [...this.game.visitedLocations],
enemiesDefeated: this.game.enemiesDefeated,
consecutiveFights: this.game.consecutiveFights
}
};
try {
localStorage.setItem(this.key, JSON.stringify(data));
this.game.notify('Игра сохранена!');
return true;
} catch (e) {
this.game.notify('Ошибка сохранения!');
return false;
}
}
load() {
try {
const raw = localStorage.getItem(this.key);
if (!raw) return false;
const data = JSON.parse(raw);
if (!data || data.version < 2) return false;
this.game.gameTime = data.gameTime;
this.game.gameDay = data.gameDay;
// Восстановление игрока
Object.assign(this.game.player.stats, data.player.stats);
this.game.player.position.set(
data.player.position.x,
data.player.position.y,
data.player.position.z
);
if (data.player.stamina !== undefined) {
this.game.player.stamina = data.player.stamina;
}
if (data.player.isDiseased) {
this.game.player.isDiseased = data.player.isDiseased;
this.game.player.diseaseTimer = data.player.diseaseTimer || 0;
}
if (data.player.addictionLevel) {
this.game.player.addictionLevel = data.player.addictionLevel;
this.game.player.lastDrinkTime = data.player.lastDrinkTime || 0;
}
// Инвентарь
this.game.inventory.items = { ...data.inventory };
if (data.inventoryMaxSlots) {
this.game.inventory.maxSlots = data.inventoryMaxSlots;
}
// Квесты
data.quests.forEach(saved => {
const quest = this.game.questSystem.quests.find(q => q.id === saved.id);
if (quest) {
quest.progress = saved.progress;
quest.completed = saved.completed;
}
});
// Погода
if (data.weather) {
this.game.weather.current = data.weather;
this.game.weather.temperature = data.temperature || 15;
this.game.particles.setWeather(data.weather);
}
// Навыки
if (data.skills) {
this.game.skills.loadSaveData(data.skills);
}
// Пёс
if (data.dog && data.dog.adopted) {
this.game.dog.adopt();
}
// Репутация
if (data.reputation) {
this.game.reputation.loadSaveData(data.reputation);
}
// Сезоны
if (data.seasons) {
this.game.seasons.loadSaveData(data.seasons);
}
// Работа
if (data.jobSystem) {
this.game.jobSystem.loadSaveData(data.jobSystem);
}
// Экипировка
if (data.equipment) {
this.game.equipment.loadSaveData(data.equipment);
}
// Достижения
if (data.achievements) {
this.game.achievements.loadSaveData(data.achievements);
}
// Укрытие
if (data.housing) {
this.game.housing.loadSaveData(data.housing);
}
// Статистика
if (data.gameStats) {
this.game.totalJobsCompleted = data.gameStats.totalJobsCompleted || 0;
this.game.totalBottlesSold = data.gameStats.totalBottlesSold || 0;
this.game.totalCrafted = data.gameStats.totalCrafted || 0;
this.game.talkedNPCs = new Set(data.gameStats.talkedNPCs || []);
this.game.visitedLocations = new Set(data.gameStats.visitedLocations || []);
this.game.enemiesDefeated = data.gameStats.enemiesDefeated || 0;
this.game.consecutiveFights = data.gameStats.consecutiveFights || 0;
}
this.game.notify('Игра загружена!');
return true;
} catch (e) {
this.game.notify('Ошибка загрузки!');
return false;
}
}
hasSave() {
return !!localStorage.getItem(this.key);
}
deleteSave() {
localStorage.removeItem(this.key);
}
}