913 lines
34 KiB
JavaScript
913 lines
34 KiB
JavaScript
/**
|
|
* Galaxy Strike Online - Player System
|
|
* Manages player stats, levels, and progression
|
|
*/
|
|
|
|
class Player {
|
|
constructor(gameEngine) {
|
|
const debugLogger = window.debugLogger;
|
|
if (debugLogger) debugLogger.log('Player constructor called');
|
|
|
|
this.game = gameEngine;
|
|
|
|
// Player stats
|
|
this.stats = {
|
|
level: 1,
|
|
experience: 0,
|
|
totalXP: 0, // Total accumulated XP across all levels
|
|
experienceToNext: window.XPProgression ? window.XPProgression.calculateXPToNextLevel(1, 0) : 100,
|
|
skillPoints: 0,
|
|
totalKills: 0,
|
|
dungeonsCleared: 0,
|
|
playTime: 0,
|
|
lastLogin: Date.now()
|
|
};
|
|
|
|
// Base attributes
|
|
this.attributes = {
|
|
health: 100,
|
|
maxHealth: 100,
|
|
energy: 100,
|
|
maxEnergy: 100,
|
|
attack: 10,
|
|
defense: 5,
|
|
speed: 10,
|
|
criticalChance: 0.05,
|
|
criticalDamage: 1.5
|
|
};
|
|
|
|
// Player info
|
|
this.info = {
|
|
name: 'Commander',
|
|
title: 'Rookie Pilot',
|
|
guild: null,
|
|
rank: 'Cadet'
|
|
};
|
|
|
|
// Ship info
|
|
this.ship = {
|
|
name: 'Starter Cruiser',
|
|
class: 'Cruiser',
|
|
health: 100,
|
|
maxHealth: 100,
|
|
attack: 10,
|
|
defense: 5,
|
|
speed: 10,
|
|
criticalChance: 0.05,
|
|
criticalDamage: 1.5,
|
|
level: 1,
|
|
upgrades: []
|
|
};
|
|
|
|
// Settings
|
|
this.settings = {
|
|
autoSave: true,
|
|
notifications: true,
|
|
soundEffects: true,
|
|
music: false,
|
|
discordIntegration: false
|
|
};
|
|
|
|
if (debugLogger) debugLogger.log('Player constructor completed', {
|
|
initialLevel: this.stats.level,
|
|
initialHealth: this.attributes.health,
|
|
shipName: this.ship.name,
|
|
shipClass: this.ship.class
|
|
});
|
|
}
|
|
|
|
async initialize() {
|
|
const debugLogger = window.debugLogger;
|
|
console.log('[PLAYER] Player system initializing');
|
|
if (debugLogger) await debugLogger.startStep('playerInitialize');
|
|
|
|
try {
|
|
if (debugLogger) await debugLogger.logStep('Player initialization started');
|
|
// Player initialization is handled by GameEngine
|
|
// This method is kept for compatibility but doesn't load game data
|
|
console.log('[PLAYER] Player system initialization completed');
|
|
if (debugLogger) await debugLogger.endStep('playerInitialize');
|
|
} catch (error) {
|
|
console.error('[PLAYER] Error during initialization:', error);
|
|
if (debugLogger) await debugLogger.errorEvent(error, 'Player Initialize');
|
|
}
|
|
}
|
|
|
|
setupNewPlayer() {
|
|
const debugLogger = window.debugLogger;
|
|
console.log('[PLAYER] Setting up new player');
|
|
if (debugLogger) debugLogger.logStep('Setting up new player', {
|
|
currentLevel: this.stats.level,
|
|
currentTitle: this.info.title
|
|
});
|
|
|
|
this.game.showNotification('Welcome to Galaxy Strike Online, Commander!', 'success', 5000);
|
|
this.game.showNotification('Complete quests and explore dungeons to progress!', 'info', 4000);
|
|
|
|
if (debugLogger) debugLogger.logStep('New player setup completed', {
|
|
notificationsShown: 2
|
|
});
|
|
}
|
|
|
|
// Experience and leveling
|
|
addExperience(amount) {
|
|
const debugLogger = window.debugLogger;
|
|
const oldExperience = this.stats.experience;
|
|
const oldLevel = this.stats.level;
|
|
const oldTotalXP = this.stats.totalXP;
|
|
|
|
// Add to total accumulated XP
|
|
this.stats.totalXP += amount;
|
|
|
|
// Calculate new level based on total XP
|
|
if (window.XPProgression) {
|
|
const levelInfo = window.XPProgression.getLevelFromXP(this.stats.totalXP);
|
|
this.stats.level = levelInfo.level;
|
|
this.stats.experience = levelInfo.xpIntoLevel;
|
|
this.stats.experienceToNext = levelInfo.xpToNext;
|
|
} else {
|
|
// Fallback to old system
|
|
this.stats.experience += amount;
|
|
}
|
|
|
|
if (debugLogger) debugLogger.logStep('Experience added', {
|
|
amount: amount,
|
|
oldExperience: oldExperience,
|
|
newExperience: this.stats.experience,
|
|
oldTotalXP: oldTotalXP,
|
|
newTotalXP: this.stats.totalXP,
|
|
experienceToNext: this.stats.experienceToNext,
|
|
currentLevel: oldLevel,
|
|
newLevel: this.stats.level
|
|
});
|
|
|
|
// Check for level up
|
|
const levelsGained = this.stats.level - oldLevel;
|
|
if (levelsGained > 0) {
|
|
for (let i = 0; i < levelsGained; i++) {
|
|
this.levelUp();
|
|
}
|
|
}
|
|
|
|
if (debugLogger && levelsGained > 0) {
|
|
debugLogger.logStep('Level up(s) occurred', {
|
|
levelsGained: levelsGained,
|
|
newLevel: this.stats.level,
|
|
remainingExperience: this.stats.experience,
|
|
totalXP: this.stats.totalXP
|
|
});
|
|
}
|
|
|
|
this.game.showNotification(`+${this.game.formatNumber(amount)} XP`, 'success', 2000);
|
|
}
|
|
|
|
levelUp() {
|
|
const debugLogger = window.debugLogger;
|
|
const oldLevel = this.stats.level;
|
|
const oldSkillPoints = this.stats.skillPoints;
|
|
const oldMaxHealth = this.attributes.maxHealth;
|
|
const oldMaxEnergy = this.attributes.maxEnergy;
|
|
const oldAttack = this.attributes.attack;
|
|
const oldDefense = this.attributes.defense;
|
|
const oldShipMaxHealth = this.ship.maxHealth;
|
|
const oldTitle = this.info.title;
|
|
|
|
console.log(`[PLAYER] Level up! New level: ${this.stats.level}`);
|
|
if (debugLogger) debugLogger.logStep('Level up initiated', {
|
|
oldLevel: oldLevel,
|
|
newLevel: this.stats.level,
|
|
skillPointsGained: 2,
|
|
totalSkillPoints: this.stats.skillPoints + 2,
|
|
currentXP: this.stats.experience,
|
|
totalXP: this.stats.totalXP
|
|
});
|
|
|
|
// Update quest progress for level objectives
|
|
if (this.game.systems.questSystem) {
|
|
this.game.systems.questSystem.updateLevelProgress(this.stats.level);
|
|
if (debugLogger) debugLogger.logStep('Quest progress updated for new level');
|
|
}
|
|
|
|
// Update experience requirement for next level
|
|
if (window.XPProgression) {
|
|
const levelInfo = window.XPProgression.getLevelFromXP(this.stats.totalXP);
|
|
this.stats.experienceToNext = levelInfo.xpToNext;
|
|
} else {
|
|
// Fallback to old system
|
|
this.stats.experienceToNext = Math.floor(this.stats.experienceToNext * 1.5);
|
|
}
|
|
|
|
if (debugLogger) debugLogger.logStep('Experience requirement updated', {
|
|
newRequirement: this.stats.experienceToNext,
|
|
usingNewSystem: !!window.XPProgression
|
|
});
|
|
|
|
// Improve base stats
|
|
this.attributes.maxHealth += 10;
|
|
this.attributes.health = this.attributes.maxHealth;
|
|
|
|
// Update UI to show new level
|
|
if (this.game && this.game.systems && this.game.systems.ui) {
|
|
this.game.systems.ui.updateUI();
|
|
if (debugLogger) debugLogger.logStep('UI updated for new level');
|
|
}
|
|
|
|
this.game.showNotification(`Level Up! You are now level ${this.stats.level}!`, 'success', 3000);
|
|
this.attributes.maxEnergy += 5;
|
|
this.attributes.energy = this.attributes.maxEnergy;
|
|
this.attributes.attack += 2;
|
|
this.attributes.defense += 1;
|
|
|
|
// Update ship health
|
|
this.ship.maxHealth += 15;
|
|
this.ship.health = this.ship.maxHealth;
|
|
|
|
// Update title based on level
|
|
this.updateTitle();
|
|
|
|
this.game.showNotification(`Level Up! You are now level ${this.stats.level}!`, 'success', 5000);
|
|
this.game.showNotification(`+2 Skill Points available`, 'info', 3000);
|
|
|
|
if (debugLogger) debugLogger.logStep('Level up completed', {
|
|
levelChange: `${oldLevel} → ${this.stats.level}`,
|
|
healthChange: `${oldMaxHealth} → ${this.attributes.maxHealth}`,
|
|
energyChange: `${oldMaxEnergy} → ${this.attributes.maxEnergy}`,
|
|
attackChange: `${oldAttack} → ${this.attributes.attack}`,
|
|
defenseChange: `${oldDefense} → ${this.attributes.defense}`,
|
|
shipHealthChange: `${oldShipMaxHealth} → ${this.ship.maxHealth}`,
|
|
titleChange: `${oldTitle} → ${this.info.title}`,
|
|
skillPointsChange: `${oldSkillPoints} → ${this.stats.skillPoints + 2}`
|
|
});
|
|
|
|
// Add skill points after logging the changes
|
|
this.stats.skillPoints += 2;
|
|
}
|
|
|
|
updateTitle() {
|
|
const debugLogger = window.debugLogger;
|
|
const oldTitle = this.info.title;
|
|
|
|
const titles = {
|
|
1: 'Rookie Pilot',
|
|
5: 'Space Cadet',
|
|
10: 'Star Explorer',
|
|
15: 'Galaxy Ranger',
|
|
20: 'Space Captain',
|
|
25: 'Star Commander',
|
|
30: 'Galaxy Admiral',
|
|
40: 'Space Legend',
|
|
50: 'Cosmic Master'
|
|
};
|
|
|
|
for (const [level, title] of Object.entries(titles)) {
|
|
if (this.stats.level >= parseInt(level)) {
|
|
this.info.title = title;
|
|
}
|
|
}
|
|
|
|
if (debugLogger && oldTitle !== this.info.title) {
|
|
debugLogger.logStep('Player title updated', {
|
|
level: this.stats.level,
|
|
oldTitle: oldTitle,
|
|
newTitle: this.info.title
|
|
});
|
|
}
|
|
}
|
|
|
|
// Combat stats
|
|
takeDamage(amount) {
|
|
const debugLogger = window.debugLogger;
|
|
const oldHealth = this.attributes.health;
|
|
const actualDamage = Math.max(1, amount - this.attributes.defense);
|
|
this.attributes.health = Math.max(0, this.attributes.health - actualDamage);
|
|
|
|
if (debugLogger) debugLogger.logStep('Player took damage', {
|
|
damageAmount: amount,
|
|
playerDefense: this.attributes.defense,
|
|
actualDamage: actualDamage,
|
|
oldHealth: oldHealth,
|
|
newHealth: this.attributes.health,
|
|
healthRemaining: this.attributes.health > 0
|
|
});
|
|
|
|
if (this.attributes.health === 0) {
|
|
this.onDeath();
|
|
}
|
|
return actualDamage;
|
|
}
|
|
|
|
heal(amount) {
|
|
const debugLogger = window.debugLogger;
|
|
const oldHealth = this.attributes.health;
|
|
const healAmount = Math.min(amount, this.attributes.maxHealth - this.attributes.health);
|
|
this.attributes.health += healAmount;
|
|
|
|
if (debugLogger) debugLogger.logStep('Player healed', {
|
|
healAmount: amount,
|
|
actualHealAmount: healAmount,
|
|
oldHealth: oldHealth,
|
|
newHealth: this.attributes.health,
|
|
maxHealth: this.attributes.maxHealth,
|
|
healthPercent: Math.round((this.attributes.health / this.attributes.maxHealth) * 100)
|
|
});
|
|
|
|
return healAmount;
|
|
}
|
|
|
|
useEnergy(amount) {
|
|
const debugLogger = window.debugLogger;
|
|
const oldEnergy = this.attributes.energy;
|
|
|
|
if (this.attributes.energy < amount) {
|
|
if (debugLogger) debugLogger.logStep('Energy use failed - insufficient energy', {
|
|
requestedAmount: amount,
|
|
currentEnergy: oldEnergy,
|
|
deficit: amount - oldEnergy
|
|
});
|
|
return false;
|
|
}
|
|
|
|
this.attributes.energy -= amount;
|
|
|
|
if (debugLogger) debugLogger.logStep('Energy used', {
|
|
amountUsed: amount,
|
|
oldEnergy: oldEnergy,
|
|
newEnergy: this.attributes.energy,
|
|
maxEnergy: this.attributes.maxEnergy,
|
|
energyPercent: Math.round((this.attributes.energy / this.attributes.maxEnergy) * 100)
|
|
});
|
|
|
|
// Update UI to show energy change
|
|
this.updateUI();
|
|
|
|
return true;
|
|
}
|
|
|
|
restoreEnergy(amount) {
|
|
const debugLogger = window.debugLogger;
|
|
const oldEnergy = this.attributes.energy;
|
|
const restoreAmount = Math.min(amount, this.attributes.maxEnergy - this.attributes.energy);
|
|
this.attributes.energy += restoreAmount;
|
|
|
|
if (debugLogger) debugLogger.logStep('Energy restored', {
|
|
restoreAmount: amount,
|
|
actualRestoreAmount: restoreAmount,
|
|
oldEnergy: oldEnergy,
|
|
newEnergy: this.attributes.energy,
|
|
maxEnergy: this.attributes.maxEnergy,
|
|
energyPercent: Math.round((this.attributes.energy / this.attributes.maxEnergy) * 100)
|
|
});
|
|
|
|
// Update UI to show energy change
|
|
this.updateUI();
|
|
|
|
return restoreAmount;
|
|
}
|
|
|
|
// Energy regeneration
|
|
regenerateEnergy(deltaTime) {
|
|
const regenerationRate = this.getMaxEnergy() * 0.1; // 10% of max energy per second
|
|
const energyToRegen = (deltaTime / 1000) * regenerationRate;
|
|
|
|
if (this.attributes.energy < this.getMaxEnergy()) {
|
|
this.attributes.energy = Math.min(this.attributes.energy + energyToRegen, this.getMaxEnergy());
|
|
|
|
const debugLogger = window.debugLogger;
|
|
if (debugLogger) debugLogger.logStep('Energy regenerated', {
|
|
deltaTime: deltaTime,
|
|
energyRegenerated: energyToRegen,
|
|
currentEnergy: this.attributes.energy,
|
|
maxEnergy: this.getMaxEnergy()
|
|
});
|
|
}
|
|
}
|
|
|
|
// Combat calculations
|
|
calculateDamage(enemyDifficulty = 'normal') {
|
|
const debugLogger = window.debugLogger;
|
|
const baseDamage = this.ship.attack || this.attributes.attack;
|
|
|
|
// Adjust critical chance based on enemy difficulty
|
|
let criticalChance = this.ship.criticalChance || this.attributes.criticalChance;
|
|
const difficultyMultipliers = {
|
|
'tutorial': 1.5, // Higher chance against easy enemies
|
|
'easy': 1.2,
|
|
'normal': 1.0,
|
|
'medium': 0.9,
|
|
'hard': 0.7, // Lower chance against hard enemies
|
|
'extreme': 0.5 // Much lower chance against extreme enemies
|
|
};
|
|
|
|
const originalCriticalChance = criticalChance;
|
|
criticalChance *= (difficultyMultipliers[enemyDifficulty] || 1.0);
|
|
|
|
const criticalRoll = Math.random();
|
|
|
|
let damage = baseDamage;
|
|
let isCritical = false;
|
|
|
|
if (criticalRoll < criticalChance) {
|
|
damage *= (this.ship.criticalDamage || this.attributes.criticalDamage);
|
|
isCritical = true;
|
|
}
|
|
|
|
// Add some randomness
|
|
const randomMultiplier = this.game.getRandomFloat(0.9, 1.1);
|
|
damage *= randomMultiplier;
|
|
|
|
const finalDamage = Math.floor(damage);
|
|
|
|
if (debugLogger) debugLogger.logStep('Damage calculation completed', {
|
|
enemyDifficulty: enemyDifficulty,
|
|
baseDamage: baseDamage,
|
|
originalCriticalChance: originalCriticalChance,
|
|
adjustedCriticalChance: criticalChance,
|
|
criticalRoll: criticalRoll,
|
|
criticalDamageMultiplier: this.ship.criticalDamage || this.attributes.criticalDamage,
|
|
randomMultiplier: randomMultiplier,
|
|
isCritical: isCritical,
|
|
finalDamage: finalDamage
|
|
});
|
|
|
|
return {
|
|
damage: finalDamage,
|
|
isCritical
|
|
};
|
|
}
|
|
|
|
onDeath() {
|
|
const debugLogger = window.debugLogger;
|
|
const oldCredits = this.game.systems.economy?.credits || 0;
|
|
|
|
console.log('[PLAYER] Player death occurred');
|
|
if (debugLogger) debugLogger.logStep('Player death triggered', {
|
|
currentLevel: this.stats.level,
|
|
oldCredits: oldCredits,
|
|
totalKills: this.stats.totalKills,
|
|
dungeonsCleared: this.stats.dungeonsCleared
|
|
});
|
|
|
|
this.game.showNotification('Your ship was destroyed! Respawning...', 'error', 3000);
|
|
|
|
// Reset health and energy
|
|
this.attributes.health = this.attributes.maxHealth;
|
|
this.attributes.energy = this.attributes.maxEnergy;
|
|
this.ship.health = this.ship.maxHealth;
|
|
|
|
// Apply death penalty
|
|
const lostCredits = Math.floor(this.game.systems.economy.credits * 0.1);
|
|
this.game.systems.economy.removeCredits(lostCredits);
|
|
|
|
const newCredits = this.game.systems.economy?.credits || 0;
|
|
|
|
this.game.showNotification(`Death penalty: -${this.game.formatNumber(lostCredits)} credits`, 'warning', 3000);
|
|
|
|
if (debugLogger) debugLogger.logStep('Player death completed', {
|
|
healthRestored: this.attributes.health,
|
|
energyRestored: this.attributes.energy,
|
|
shipHealthRestored: this.ship.health,
|
|
creditsLost: lostCredits,
|
|
oldCredits: oldCredits,
|
|
newCredits: newCredits,
|
|
penaltyPercentage: 10
|
|
});
|
|
}
|
|
|
|
resetToLevel1() {
|
|
const debugLogger = window.debugLogger;
|
|
const oldStats = { ...this.stats };
|
|
const oldAttributes = { ...this.attributes };
|
|
const oldInfo = { ...this.info };
|
|
const oldShip = { ...this.ship };
|
|
|
|
console.log('[PLAYER] Resetting player to level 1');
|
|
if (debugLogger) debugLogger.logStep('Player reset to level 1 initiated', {
|
|
oldLevel: oldStats.level,
|
|
oldExperience: oldStats.experience,
|
|
oldKills: oldStats.totalKills
|
|
});
|
|
|
|
// Reset stats to initial values
|
|
this.stats = {
|
|
level: 1,
|
|
experience: 0,
|
|
totalXP: 0, // Total accumulated XP across all levels
|
|
experienceToNext: window.XPProgression ? window.XPProgression.calculateXPToNextLevel(1, 0) : 100,
|
|
skillPoints: 0,
|
|
totalKills: 0,
|
|
dungeonsCleared: 0,
|
|
playTime: 0,
|
|
lastLogin: Date.now(),
|
|
tutorialDungeonCompleted: false
|
|
};
|
|
|
|
// Reset attributes to base values
|
|
this.attributes = {
|
|
health: 100,
|
|
maxHealth: 100,
|
|
energy: 100,
|
|
maxEnergy: 100,
|
|
attack: 10,
|
|
defense: 5,
|
|
speed: 10,
|
|
criticalChance: 0.05,
|
|
criticalDamage: 1.5
|
|
};
|
|
|
|
// Reset info
|
|
this.info = {
|
|
name: 'Commander',
|
|
title: 'Rookie Pilot',
|
|
guild: null,
|
|
rank: 'Cadet'
|
|
};
|
|
|
|
// Reset ship
|
|
this.ship = {
|
|
name: 'Starter Cruiser',
|
|
class: 'Cruiser',
|
|
health: 1000,
|
|
maxHealth: 1000,
|
|
attack: 10,
|
|
defense: 5,
|
|
speed: 10,
|
|
criticalChance: 0.05,
|
|
criticalDamage: 1.5,
|
|
level: 1,
|
|
upgrades: []
|
|
};
|
|
|
|
console.log('=== DEBUG: Character Reset ===');
|
|
console.log('Player health reset to:', this.attributes.health, '/', this.attributes.maxHealth);
|
|
console.log('Ship health reset to:', this.ship.health, '/', this.ship.maxHealth);
|
|
|
|
// Reset skills
|
|
this.skills = {};
|
|
|
|
// Reset settings to defaults
|
|
this.settings = {
|
|
autoSave: true,
|
|
notifications: true,
|
|
soundEffects: true,
|
|
music: false,
|
|
theme: 'dark'
|
|
};
|
|
|
|
if (debugLogger) debugLogger.logStep('Player reset to level 1 completed', {
|
|
newLevel: this.stats.level,
|
|
newHealth: this.attributes.health,
|
|
newShipHealth: this.ship.health,
|
|
skillsCleared: true,
|
|
settingsReset: true
|
|
});
|
|
}
|
|
|
|
// Ship management
|
|
upgradeShip(upgradeType) {
|
|
const debugLogger = window.debugLogger;
|
|
const upgradeCosts = {
|
|
health: 100,
|
|
attack: 150,
|
|
defense: 120,
|
|
speed: 80,
|
|
critical: 200
|
|
};
|
|
|
|
const cost = upgradeCosts[upgradeType];
|
|
const oldCredits = this.game.systems.economy?.credits || 0;
|
|
|
|
if (debugLogger) debugLogger.logStep('Ship upgrade attempted', {
|
|
upgradeType: upgradeType,
|
|
cost: cost,
|
|
currentCredits: oldCredits,
|
|
canAfford: oldCredits >= cost
|
|
});
|
|
|
|
if (!cost || !this.game.systems.economy || this.game.systems.economy.credits < cost) {
|
|
if (debugLogger) debugLogger.logStep('Ship upgrade failed - insufficient funds or invalid type', {
|
|
upgradeType: upgradeType,
|
|
cost: cost,
|
|
currentCredits: oldCredits,
|
|
deficit: cost - oldCredits,
|
|
economySystemAvailable: !!this.game.systems.economy
|
|
});
|
|
return false;
|
|
}
|
|
|
|
const oldShipStats = { ...this.ship };
|
|
const oldPlayerStats = { ...this.attributes };
|
|
|
|
if (this.game.systems.economy) {
|
|
this.game.systems.economy.removeCredits(cost);
|
|
} else {
|
|
if (debugLogger) debugLogger.log('Economy system not available during ship upgrade');
|
|
return false;
|
|
}
|
|
|
|
switch (upgradeType) {
|
|
case 'health':
|
|
this.ship.maxHealth += 20;
|
|
this.ship.health = this.ship.maxHealth;
|
|
this.attributes.maxHealth += 10;
|
|
this.attributes.health = this.attributes.maxHealth;
|
|
break;
|
|
case 'attack':
|
|
this.ship.attack += 3;
|
|
break;
|
|
case 'defense':
|
|
this.ship.defense += 2;
|
|
break;
|
|
case 'speed':
|
|
this.ship.speed += 2;
|
|
break;
|
|
case 'critical':
|
|
this.ship.criticalChance = Math.min(0.5, this.ship.criticalChance + 0.02);
|
|
this.ship.criticalDamage += 0.1;
|
|
break;
|
|
}
|
|
|
|
this.ship.upgrades.push(upgradeType);
|
|
this.game.showNotification(`Ship upgraded: ${upgradeType}!`, 'success', 3000);
|
|
|
|
if (debugLogger) debugLogger.logStep('Ship upgrade completed', {
|
|
upgradeType: upgradeType,
|
|
cost: cost,
|
|
oldCredits: oldCredits,
|
|
newCredits: this.game.systems.economy?.credits || 0,
|
|
shipChanges: {
|
|
oldMaxHealth: oldShipStats.maxHealth,
|
|
newMaxHealth: this.ship.maxHealth,
|
|
oldAttack: oldShipStats.attack,
|
|
newAttack: this.ship.attack,
|
|
oldDefense: oldShipStats.defense,
|
|
newDefense: this.ship.defense,
|
|
oldSpeed: oldShipStats.speed,
|
|
newSpeed: this.ship.speed,
|
|
oldCriticalChance: oldShipStats.criticalChance,
|
|
newCriticalChance: this.ship.criticalChance,
|
|
oldCriticalDamage: oldShipStats.criticalDamage,
|
|
newCriticalDamage: this.ship.criticalDamage
|
|
},
|
|
playerChanges: {
|
|
oldMaxHealth: oldPlayerStats.maxHealth,
|
|
newMaxHealth: this.attributes.maxHealth,
|
|
oldHealth: oldPlayerStats.health,
|
|
newHealth: this.attributes.health
|
|
},
|
|
totalUpgrades: this.ship.upgrades.length
|
|
});
|
|
|
|
return true;
|
|
}
|
|
|
|
// Statistics tracking
|
|
incrementKills() {
|
|
const debugLogger = window.debugLogger;
|
|
const oldKills = this.stats.totalKills;
|
|
this.stats.totalKills++;
|
|
|
|
if (debugLogger) debugLogger.logStep('Kill count incremented', {
|
|
oldKills: oldKills,
|
|
newKills: this.stats.totalKills,
|
|
currentLevel: this.stats.level
|
|
});
|
|
|
|
// Update quest progress for combat objectives
|
|
if (this.game && this.game.systems && this.game.systems.questSystem) {
|
|
this.game.systems.questSystem.onEnemyDefeated();
|
|
if (debugLogger) debugLogger.logStep('Quest system notified of enemy defeat');
|
|
}
|
|
}
|
|
|
|
incrementDungeonsCleared() {
|
|
const debugLogger = window.debugLogger;
|
|
const oldDungeons = this.stats.dungeonsCleared;
|
|
this.stats.dungeonsCleared++;
|
|
|
|
if (debugLogger) debugLogger.logStep('Dungeons cleared incremented', {
|
|
oldDungeons: oldDungeons,
|
|
newDungeons: this.stats.dungeonsCleared,
|
|
currentLevel: this.stats.level
|
|
});
|
|
}
|
|
|
|
updatePlayTime(deltaTime) {
|
|
console.log('[PLAYER] updatePlayTime called with deltaTime:', deltaTime, 'ms');
|
|
console.log('[PLAYER] Before update - playTime:', this.stats.playTime, 'ms');
|
|
|
|
// Use real computer time delta
|
|
this.stats.playTime += deltaTime;
|
|
|
|
console.log('[PLAYER] After update - playTime:', this.stats.playTime, 'ms');
|
|
console.log('[PLAYER] PlayTime in seconds:', this.stats.playTime / 1000, 'seconds');
|
|
console.log('[PLAYER] PlayTime in minutes:', this.stats.playTime / 60000, 'minutes');
|
|
console.log('[PLAYER] PlayTime in hours:', this.stats.playTime / 3600000, 'hours');
|
|
}
|
|
|
|
// UI updates
|
|
updateUI() {
|
|
const debugLogger = window.debugLogger;
|
|
|
|
if (debugLogger) debugLogger.logStep('Player UI update started', {
|
|
currentLevel: this.stats.level,
|
|
currentHealth: this.attributes.health,
|
|
currentEnergy: this.attributes.energy,
|
|
totalKills: this.stats.totalKills
|
|
});
|
|
|
|
// Update player info
|
|
const playerNameElement = document.getElementById('playerName');
|
|
const playerLevelElement = document.getElementById('playerLevel');
|
|
|
|
if (playerNameElement) {
|
|
playerNameElement.textContent = `${this.info.name} - ${this.info.title}`;
|
|
}
|
|
|
|
if (playerLevelElement) {
|
|
playerLevelElement.textContent = `Lv. ${this.stats.level}`;
|
|
}
|
|
|
|
// Update health and energy only if in multiplayer mode or game is actively running
|
|
const shouldUpdateUI = window.smartSaveManager?.isMultiplayer || this.game?.isRunning;
|
|
|
|
if (shouldUpdateUI && this.game && this.game.systems && this.game.systems.ui) {
|
|
this.game.systems.ui.updateResourceDisplay();
|
|
}
|
|
|
|
// Update stats
|
|
const totalKillsElement = document.getElementById('totalKills');
|
|
const dungeonsClearedElement = document.getElementById('dungeonsCleared');
|
|
const playTimeElement = document.getElementById('playTime');
|
|
|
|
if (totalKillsElement) {
|
|
totalKillsElement.textContent = this.game.formatNumber(this.stats.totalKills);
|
|
}
|
|
|
|
if (dungeonsClearedElement) {
|
|
dungeonsClearedElement.textContent = this.game.formatNumber(this.stats.dungeonsCleared);
|
|
}
|
|
|
|
if (playTimeElement) {
|
|
playTimeElement.textContent = this.game.formatTime(this.stats.playTime / 1000);
|
|
}
|
|
|
|
// Update ship info
|
|
const flagshipNameElement = document.getElementById('flagshipName');
|
|
const shipHealthElement = document.getElementById('shipHealth');
|
|
|
|
if (flagshipNameElement) {
|
|
flagshipNameElement.textContent = this.ship.name;
|
|
}
|
|
|
|
if (shipHealthElement) {
|
|
const healthPercent = Math.round((this.ship.health / this.ship.maxHealth) * 100);
|
|
shipHealthElement.textContent = `${healthPercent}%`;
|
|
}
|
|
|
|
if (debugLogger) debugLogger.logStep('Player UI update completed', {
|
|
elementsUpdated: {
|
|
playerName: !!playerNameElement,
|
|
playerLevel: !!playerLevelElement,
|
|
totalKills: !!totalKillsElement,
|
|
dungeonsCleared: !!dungeonsClearedElement,
|
|
playTime: !!playTimeElement,
|
|
flagshipName: !!flagshipNameElement,
|
|
shipHealth: !!shipHealthElement
|
|
}
|
|
});
|
|
}
|
|
|
|
// Save/Load
|
|
save() {
|
|
const debugLogger = window.debugLogger;
|
|
|
|
const saveData = {
|
|
stats: this.stats,
|
|
attributes: this.attributes,
|
|
info: this.info,
|
|
ship: this.ship,
|
|
settings: this.settings
|
|
};
|
|
|
|
// if (debugLogger) debugLogger.logStep('Player save data prepared', {
|
|
// level: this.stats.level,
|
|
// experience: this.stats.experience,
|
|
// totalKills: this.stats.totalKills,
|
|
// dungeonsCleared: this.stats.dungeonsCleared,
|
|
// playTime: this.stats.playTime,
|
|
// shipName: this.ship.name,
|
|
// shipLevel: this.ship.level,
|
|
// upgradesCount: this.ship.upgrades.length,
|
|
// dataSize: JSON.stringify(saveData).length
|
|
// });
|
|
|
|
return saveData;
|
|
}
|
|
|
|
load(data) {
|
|
const debugLogger = window.debugLogger;
|
|
console.log('[PLAYER] Loading player data:', data);
|
|
console.log('[PLAYER] Current level before load:', this.stats.level);
|
|
|
|
if (debugLogger) debugLogger.logStep('Player load initiated', {
|
|
hasData: !!data,
|
|
dataKeys: data ? Object.keys(data) : [],
|
|
currentLevel: this.stats.level,
|
|
currentExperience: this.stats.experience
|
|
});
|
|
|
|
try {
|
|
if (data.stats) {
|
|
console.log('[PLAYER] Loading stats:', data.stats);
|
|
const oldStats = { ...this.stats };
|
|
this.stats = { ...this.stats, ...data.stats };
|
|
console.log('[PLAYER] Level after stats load:', this.stats.level);
|
|
|
|
if (debugLogger) debugLogger.logStep('Player stats loaded', {
|
|
oldLevel: oldStats.level,
|
|
newLevel: this.stats.level,
|
|
oldExperience: oldStats.experience,
|
|
newExperience: this.stats.experience,
|
|
oldKills: oldStats.totalKills,
|
|
newKills: this.stats.totalKills
|
|
});
|
|
}
|
|
|
|
if (data.attributes) {
|
|
console.log('[PLAYER] Loading attributes:', data.attributes);
|
|
const oldAttributes = { ...this.attributes };
|
|
this.attributes = { ...this.attributes, ...data.attributes };
|
|
|
|
if (debugLogger) debugLogger.logStep('Player attributes loaded', {
|
|
oldHealth: oldAttributes.health,
|
|
newHealth: this.attributes.health,
|
|
oldMaxHealth: oldAttributes.maxHealth,
|
|
newMaxHealth: this.attributes.maxHealth,
|
|
oldAttack: oldAttributes.attack,
|
|
newAttack: this.attributes.attack,
|
|
oldDefense: oldAttributes.defense,
|
|
newDefense: this.attributes.defense
|
|
});
|
|
}
|
|
|
|
if (data.info) {
|
|
console.log('[PLAYER] Loading info:', data.info);
|
|
const oldInfo = { ...this.info };
|
|
this.info = { ...this.info, ...data.info };
|
|
|
|
if (debugLogger) debugLogger.logStep('Player info loaded', {
|
|
oldName: oldInfo.name,
|
|
newName: this.info.name,
|
|
oldTitle: oldInfo.title,
|
|
newTitle: this.info.title,
|
|
oldGuild: oldInfo.guild,
|
|
newGuild: this.info.guild
|
|
});
|
|
}
|
|
|
|
if (data.ship) {
|
|
console.log('[PLAYER] Loading ship:', data.ship);
|
|
const oldShip = { ...this.ship };
|
|
this.ship = { ...this.ship, ...data.ship };
|
|
|
|
if (debugLogger) debugLogger.logStep('Player ship loaded', {
|
|
oldShipName: oldShip.name,
|
|
newShipName: this.ship.name,
|
|
oldShipLevel: oldShip.level,
|
|
newShipLevel: this.ship.level,
|
|
oldUpgrades: oldShip.upgrades.length,
|
|
newUpgrades: this.ship.upgrades.length
|
|
});
|
|
}
|
|
|
|
if (data.settings) {
|
|
console.log('[PLAYER] Loading settings:', data.settings);
|
|
const oldSettings = { ...this.settings };
|
|
this.settings = { ...this.settings, ...data.settings };
|
|
|
|
if (debugLogger) debugLogger.logStep('Player settings loaded', {
|
|
oldAutoSave: oldSettings.autoSave,
|
|
newAutoSave: this.settings.autoSave,
|
|
oldNotifications: oldSettings.notifications,
|
|
newNotifications: this.settings.notifications
|
|
});
|
|
}
|
|
|
|
console.log('[PLAYER] Final level after load:', this.stats.level);
|
|
|
|
if (debugLogger) debugLogger.logStep('Player load completed successfully', {
|
|
finalLevel: this.stats.level,
|
|
finalExperience: this.stats.experience,
|
|
finalHealth: this.attributes.health,
|
|
finalShipHealth: this.ship.health,
|
|
totalDataSections: ['stats', 'attributes', 'info', 'ship', 'settings'].filter(key => data[key]).length
|
|
});
|
|
|
|
} catch (error) {
|
|
console.error('[PLAYER] Error loading player data:', error);
|
|
if (debugLogger) debugLogger.errorEvent(error, 'Player Load');
|
|
throw error;
|
|
}
|
|
}
|
|
}
|