173 lines
4.6 KiB
JavaScript
173 lines
4.6 KiB
JavaScript
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
// Load ladder configuration
|
|
const ladderConfig = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'ladder-config.json')));
|
|
|
|
class LadderService {
|
|
constructor() {
|
|
this.rankConfigs = new Map();
|
|
this.initConfig();
|
|
}
|
|
|
|
initConfig() {
|
|
ladderConfig.forEach(config => {
|
|
this.rankConfigs.set(config.Id, config);
|
|
});
|
|
}
|
|
|
|
// Get rank configuration by ID
|
|
getRankConfig(rankId) {
|
|
return this.rankConfigs.get(rankId);
|
|
}
|
|
|
|
// Get all rank configurations
|
|
getAllRankConfigs() {
|
|
return Array.from(this.rankConfigs.values());
|
|
}
|
|
|
|
// Handle player win
|
|
async handleWin(player, opponent) {
|
|
const config = this.getRankConfig(player.rankId);
|
|
|
|
if (config.RankScore === 1) {
|
|
// King rank score mechanism
|
|
this.updateRankScore(player, opponent, true);
|
|
} else {
|
|
// Star-based mechanism
|
|
this.updateStars(player, config, true);
|
|
}
|
|
|
|
player.totalWins++;
|
|
player.winStreak++;
|
|
|
|
return player;
|
|
}
|
|
|
|
// Handle player loss
|
|
async handleLoss(player, opponent) {
|
|
const config = this.getRankConfig(player.rankId);
|
|
|
|
if (config.RankScore === 1) {
|
|
// King rank score mechanism
|
|
this.updateRankScore(player, opponent, false);
|
|
} else {
|
|
// Star-based mechanism
|
|
this.updateStars(player, config, false);
|
|
}
|
|
|
|
player.winStreak = 0;
|
|
|
|
return player;
|
|
}
|
|
|
|
updateStars(player, config, isWin) {
|
|
if (isWin) {
|
|
let starsToAdd = config.WinGetStar;
|
|
// Add extra stars for win streak (3+ wins)
|
|
if (player.winStreak >= 2) { // Streak starts at 2 (after 2 wins)
|
|
starsToAdd += config.ExtraGetStar;
|
|
}
|
|
player.stars += starsToAdd;
|
|
|
|
// Level up check
|
|
if (player.stars > config.MaxStar) {
|
|
this.levelUp(player);
|
|
}
|
|
} else {
|
|
if (config.LoseLostStar === 1) {
|
|
player.stars = Math.max(0, player.stars - 1);
|
|
|
|
// Level down check
|
|
if (player.stars === 0 && config.LoseRankDown === 1) {
|
|
this.levelDown(player, config);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
updateRankScore(player, opponent, isWin) {
|
|
const config = this.getRankConfig(player.rankId);
|
|
|
|
if (isWin) {
|
|
// Initialize rank score if not already set
|
|
if (player.rankScore === 0) {
|
|
player.rankScore = config.InitialRankScore || 1100;
|
|
}
|
|
|
|
// Calculate score to add based on opponent's rank
|
|
let scoreToAdd = config.WinScoreMin || 80;
|
|
|
|
// If opponent has a higher rank score, calculate bonus
|
|
if (opponent.rankScore > player.rankScore) {
|
|
// Calculate bonus based on rank difference (simplified)
|
|
const ratio = Math.min((opponent.rankScore - player.rankScore) / 100, 1);
|
|
scoreToAdd = Math.round(config.WinScoreMin + ratio * (config.WinScoreMax - config.WinScoreMin));
|
|
}
|
|
|
|
player.rankScore += scoreToAdd;
|
|
} else {
|
|
// Deduct points on loss
|
|
const scoreToDeduct = config.LoseScore || 20;
|
|
if (player.rankScore > 0) {
|
|
player.rankScore = Math.max(0, player.rankScore - scoreToDeduct);
|
|
}
|
|
|
|
// Check for level down if score is too low
|
|
if (player.rankScore < 1000 && config.LoseRankDown === 1) {
|
|
this.levelDown(player, config);
|
|
}
|
|
}
|
|
}
|
|
|
|
levelUp(player) {
|
|
const nextConfig = this.getRankConfig(player.rankId + 1);
|
|
if (nextConfig) {
|
|
player.rankId++;
|
|
player.stars = nextConfig.BeginStar;
|
|
|
|
// Initialize rank score for King rank
|
|
if (nextConfig.RankScore === 1) {
|
|
player.rankScore = nextConfig.InitialRankScore || 1100;
|
|
}
|
|
}
|
|
}
|
|
|
|
levelDown(player, currentConfig) {
|
|
if (currentConfig.LoseRankDown === 1 && player.rankId > 1) {
|
|
player.rankId--;
|
|
const prevConfig = this.getRankConfig(player.rankId);
|
|
if (prevConfig.RankScore === 1) {
|
|
// Stay in rank score system
|
|
player.rankScore = Math.max(prevConfig.InitialRankScore || 1100, player.rankScore - (prevConfig.LoseScore || 20));
|
|
} else {
|
|
// Back to star system
|
|
player.stars = prevConfig.RankDownStar;
|
|
player.rankScore = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Get player's rank display info
|
|
getPlayerRankInfo(player) {
|
|
const config = this.getRankConfig(player.rankId);
|
|
if (config.RankScore === 1) {
|
|
return {
|
|
rankName: config.RankName,
|
|
level: config.Level,
|
|
score: player.rankScore,
|
|
isRankScore: true
|
|
};
|
|
} else {
|
|
return {
|
|
rankName: config.RankName,
|
|
level: config.Level,
|
|
stars: player.stars,
|
|
maxStars: config.MaxStar,
|
|
isRankScore: false
|
|
};
|
|
}
|
|
}
|
|
}
|
|
|
|
module.exports = new LadderService(); |