97 lines
3.9 KiB
JavaScript
97 lines
3.9 KiB
JavaScript
/**
|
|
* Galaxy Strike Online — NPC Reputation System (GDD §15.3)
|
|
* Scale: -2000 to +2000 per faction
|
|
* Factions: Federation, Pirate Syndicate, Merchant Guild, Rogue AI, Void Cult
|
|
*/
|
|
|
|
const FACTIONS = {
|
|
federation: { name: 'Federation', icon: '🌐', color: '#42a5f5', desc: 'The governing body of settled space.' },
|
|
pirate_syndicate:{ name: 'Pirate Syndicate', icon: '💀', color: '#ef5350', desc: 'Organised raiders — hostile by default.' },
|
|
merchant_guild: { name: 'Merchant Guild', icon: '💼', color: '#ffd700', desc: 'Trade consortium controlling major routes.' },
|
|
rogue_ai: { name: 'Rogue AI Collective',icon: '🤖', color: '#ab47bc', desc: 'Autonomous machines of unknown origin.' },
|
|
void_cult: { name: 'Void Cult', icon: '🌑', color: '#78909c', desc: 'Enigmatic zealots from deep space.' },
|
|
};
|
|
|
|
const THRESHOLDS = [
|
|
{ min: 1500, label: 'Exalted', color: '#ffd700' },
|
|
{ min: 1000, label: 'Honored', color: '#4caf50' },
|
|
{ min: 500, label: 'Friendly', color: '#66bb6a' },
|
|
{ min: 1, label: 'Neutral', color: '#aaa' },
|
|
{ min: -499, label: 'Unfriendly',color: '#ff9800' },
|
|
{ min: -999, label: 'Hostile', color: '#f44336' },
|
|
{ min: -2000,label: 'Hated', color: '#b71c1c' },
|
|
];
|
|
|
|
function getStanding(rep) {
|
|
for (const t of THRESHOLDS) if (rep >= t.min) return t;
|
|
return THRESHOLDS[THRESHOLDS.length - 1];
|
|
}
|
|
|
|
class ReputationSystem {
|
|
initReputation(playerData) {
|
|
if (playerData.reputation) return;
|
|
const rep = {};
|
|
for (const id of Object.keys(FACTIONS)) {
|
|
rep[id] = id === 'pirate_syndicate' ? -500 : 0; // Pirates start hostile
|
|
}
|
|
playerData.reputation = rep;
|
|
}
|
|
|
|
adjustReputation(playerData, factionId, delta, seasonBonuses = {}) {
|
|
this.initReputation(playerData);
|
|
if (!FACTIONS[factionId]) return;
|
|
// Apply void cult season bonus
|
|
if (factionId === 'void_cult' && seasonBonuses.voidCultRepBonus) {
|
|
delta = Math.round(delta * (1 + seasonBonuses.voidCultRepBonus));
|
|
}
|
|
const current = playerData.reputation[factionId] || 0;
|
|
playerData.reputation[factionId] = Math.max(-2000, Math.min(2000, current + delta));
|
|
// Opposing factions lose rep when gaining with others
|
|
const opposites = { federation: 'pirate_syndicate', pirate_syndicate: 'federation' };
|
|
const opp = opposites[factionId];
|
|
if (opp && delta > 0) {
|
|
playerData.reputation[opp] = Math.max(-2000, (playerData.reputation[opp]||0) - Math.floor(delta * 0.5));
|
|
}
|
|
return playerData.reputation[factionId];
|
|
}
|
|
|
|
/**
|
|
* Get active reputation bonuses to apply in other systems.
|
|
* Returns { marketFeeDiscount, craftingSpeedBonus, pvpAttackBonus }
|
|
*/
|
|
getActiveEffects(playerData) {
|
|
this.initReputation(playerData);
|
|
const rep = playerData.reputation;
|
|
const effects = { marketFeeDiscount: 0, craftingSpeedBonus: 0, pvpAttackBonus: 0 };
|
|
|
|
// Merchant Guild: market fee reduction
|
|
const guildRep = rep['merchant_guild'] || 0;
|
|
if (guildRep >= 1500) effects.marketFeeDiscount = 0.01; // Exalted: fee 2%->1%
|
|
else if (guildRep >= 750) effects.marketFeeDiscount = 0.005; // Honored: fee 2%->1.5%
|
|
|
|
// Rogue AI: crafting speed bonus
|
|
const aiRep = rep['rogue_ai'] || 0;
|
|
if (aiRep >= 1500) effects.craftingSpeedBonus = 0.20; // Exalted: +20%
|
|
else if (aiRep >= 750) effects.craftingSpeedBonus = 0.10; // Honored: +10%
|
|
|
|
// Pirate Syndicate: PvP attack bonus
|
|
const pirateRep = rep['pirate_syndicate'] || 0;
|
|
if (pirateRep >= 750) effects.pvpAttackBonus = 0.05; // Honored+: +5%
|
|
|
|
return effects;
|
|
}
|
|
|
|
getReputationData(playerData) {
|
|
this.initReputation(playerData);
|
|
return Object.entries(FACTIONS).map(([id, f]) => {
|
|
const rep = playerData.reputation[id] || 0;
|
|
const standing = getStanding(rep);
|
|
return { id, ...f, reputation: rep, standing: standing.label, standingColor: standing.color };
|
|
});
|
|
}
|
|
|
|
getFactions() { return FACTIONS; }
|
|
}
|
|
|
|
module.exports = { ReputationSystem, FACTIONS };
|