Add reputation actions and localization updates: Implement getReputationActions method in FalukantService, enhancing reputation management. Update German and English localization files to include new reputation action terms and mood descriptions, improving user experience and clarity.

This commit is contained in:
Torsten Schulz (local)
2026-01-29 09:37:34 +01:00
parent eecd947377
commit 1ead06fd4f
5 changed files with 246 additions and 6 deletions

View File

@@ -70,6 +70,7 @@ import TownProductWorth from '../models/falukant/data/town_product_worth.js';
import ProductWeatherEffect from '../models/falukant/type/product_weather_effect.js';
import WeatherType from '../models/falukant/type/weather.js';
import ReputationActionType from '../models/falukant/type/reputation_action.js';
import ReputationActionLog from '../models/falukant/log/reputation_action.js';
function calcAge(birthdate) {
const b = new Date(birthdate); b.setHours(0, 0);
@@ -465,7 +466,7 @@ class FalukantService extends BaseService {
{
model: FalukantCharacter,
as: 'character',
attributes: ['id', 'birthdate', 'health'],
attributes: ['id', 'birthdate', 'health', 'reputation'],
include: [
{
model: Relationship,
@@ -3007,10 +3008,96 @@ class FalukantService extends BaseService {
return TitleOfNobility.findAll();
}
async getReputationActions() {
return ReputationActionType.findAll({
async getReputationActions(hashedUserId) {
const user = await getFalukantUserOrFail(hashedUserId);
// Lade alle Action-Typen
const actionTypes = await ReputationActionType.findAll({
order: [['cost', 'ASC']]
});
// Berechne tägliche Nutzung (heute)
const todayStart = new Date();
todayStart.setHours(0, 0, 0, 0);
const todayEnd = new Date();
todayEnd.setHours(23, 59, 59, 999);
const todayActions = await ReputationActionLog.count({
where: {
falukantUserId: user.id,
actionTimestamp: {
[Op.between]: [todayStart, todayEnd]
}
}
});
// Standard-Limits (können später konfigurierbar gemacht werden)
const dailyCap = 10; // Maximal 10 Actions pro Tag
const dailyUsed = todayActions;
const dailyRemaining = Math.max(0, dailyCap - dailyUsed);
// Cooldown: 60 Minuten zwischen Actions
const cooldownMinutes = 60;
const lastAction = await ReputationActionLog.findOne({
where: { falukantUserId: user.id },
order: [['actionTimestamp', 'DESC']],
attributes: ['actionTimestamp']
});
let cooldownRemainingSec = 0;
if (lastAction && lastAction.actionTimestamp) {
const now = new Date();
const lastActionTime = new Date(lastAction.actionTimestamp);
const secondsSinceLastAction = Math.floor((now - lastActionTime) / 1000);
const cooldownSec = cooldownMinutes * 60;
cooldownRemainingSec = Math.max(0, cooldownSec - secondsSinceLastAction);
}
// Berechne timesUsed für jede Action (basierend auf decay_window_days)
const actionsWithUsage = await Promise.all(actionTypes.map(async (actionType) => {
const windowStart = new Date();
windowStart.setDate(windowStart.getDate() - actionType.decayWindowDays);
const usageCount = await ReputationActionLog.count({
where: {
falukantUserId: user.id,
actionTypeId: actionType.id,
actionTimestamp: {
[Op.gte]: windowStart
}
}
});
// Berechne aktuellen Gewinn basierend auf decay
let currentGain = actionType.baseGain;
for (let i = 0; i < usageCount; i++) {
currentGain = Math.max(
actionType.minGain,
Math.floor(currentGain * actionType.decayFactor)
);
}
return {
id: actionType.id,
tr: actionType.tr,
cost: actionType.cost,
baseGain: actionType.baseGain,
currentGain: currentGain,
timesUsed: usageCount,
decayFactor: actionType.decayFactor,
minGain: actionType.minGain,
decayWindowDays: actionType.decayWindowDays
};
}));
return {
actions: actionsWithUsage,
dailyCap,
dailyUsed,
dailyRemaining,
cooldownMinutes,
cooldownRemainingSec
};
}
async getHouseTypes() {