feat(falukant): add improve lover affection feature and localization updates
All checks were successful
Deploy to production / deploy (push) Successful in 2m49s
All checks were successful
Deploy to production / deploy (push) Successful in 2m49s
- Introduced the `improveLoverAffection` method in FalukantService to enhance relationship dynamics by allowing users to boost affection at a cost. - Updated FalukantController and FalukantRouter to include the new endpoint for improving lover affection. - Enhanced FamilyView component to provide a button for users to trigger the affection improvement action. - Added localization entries for the new feature in multiple languages, ensuring clarity in user interactions regarding affection improvements.
This commit is contained in:
@@ -119,6 +119,8 @@ class FalukantController {
|
|||||||
});
|
});
|
||||||
this.setLoverMaintenance = this._wrapWithUser((userId, req) =>
|
this.setLoverMaintenance = this._wrapWithUser((userId, req) =>
|
||||||
this.service.setLoverMaintenance(userId, req.params.relationshipId, req.body?.maintenanceLevel), { blockInDebtorsPrison: true });
|
this.service.setLoverMaintenance(userId, req.params.relationshipId, req.body?.maintenanceLevel), { blockInDebtorsPrison: true });
|
||||||
|
this.improveLoverAffection = this._wrapWithUser((userId, req) =>
|
||||||
|
this.service.improveLoverAffection(userId, req.params.relationshipId), { blockInDebtorsPrison: true });
|
||||||
this.createLoverRelationship = this._wrapWithUser((userId, req) =>
|
this.createLoverRelationship = this._wrapWithUser((userId, req) =>
|
||||||
this.service.createLoverRelationship(userId, req.body?.targetCharacterId, req.body?.loverRole), { successStatus: 201, blockInDebtorsPrison: true });
|
this.service.createLoverRelationship(userId, req.body?.targetCharacterId, req.body?.loverRole), { successStatus: 201, blockInDebtorsPrison: true });
|
||||||
this.spendTimeWithSpouse = this._wrapWithUser((userId) =>
|
this.spendTimeWithSpouse = this._wrapWithUser((userId) =>
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ router.post('/family/marriage/spend-time', falukantController.spendTimeWithSpous
|
|||||||
router.post('/family/marriage/gift', falukantController.giftToSpouse);
|
router.post('/family/marriage/gift', falukantController.giftToSpouse);
|
||||||
router.post('/family/marriage/reconcile', falukantController.reconcileMarriage);
|
router.post('/family/marriage/reconcile', falukantController.reconcileMarriage);
|
||||||
router.post('/family/lover/:relationshipId/maintenance', falukantController.setLoverMaintenance);
|
router.post('/family/lover/:relationshipId/maintenance', falukantController.setLoverMaintenance);
|
||||||
|
router.post('/family/lover/:relationshipId/improve-affection', falukantController.improveLoverAffection);
|
||||||
router.post('/family/lover/:relationshipId/acknowledge', falukantController.acknowledgeLover);
|
router.post('/family/lover/:relationshipId/acknowledge', falukantController.acknowledgeLover);
|
||||||
router.post('/family/lover/:relationshipId/end', falukantController.endLoverRelationship);
|
router.post('/family/lover/:relationshipId/end', falukantController.endLoverRelationship);
|
||||||
router.get('/heirs/potential', falukantController.getPotentialHeirs);
|
router.get('/heirs/potential', falukantController.getPotentialHeirs);
|
||||||
|
|||||||
@@ -3880,6 +3880,91 @@ class FalukantService extends BaseService {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async improveLoverAffection(hashedUserId, relationshipId) {
|
||||||
|
const parsedRelationshipId = Number.parseInt(relationshipId, 10);
|
||||||
|
if (Number.isNaN(parsedRelationshipId)) {
|
||||||
|
throw { status: 400, message: 'relationshipId is required' };
|
||||||
|
}
|
||||||
|
|
||||||
|
const action = {
|
||||||
|
cost: 60,
|
||||||
|
affectionDelta: 6,
|
||||||
|
visibilityDelta: 3,
|
||||||
|
discretionDelta: -2,
|
||||||
|
householdOrderDelta: -3,
|
||||||
|
marriageSatisfactionDelta: -1
|
||||||
|
};
|
||||||
|
|
||||||
|
const { user, state } = await this.getOwnedLoverRelationState(hashedUserId, parsedRelationshipId);
|
||||||
|
if (Number(user.money || 0) < action.cost) {
|
||||||
|
throw new Error('notenoughmoney.');
|
||||||
|
}
|
||||||
|
|
||||||
|
const userHouse = await UserHouse.findOne({
|
||||||
|
where: { userId: user.id },
|
||||||
|
attributes: ['householdOrder']
|
||||||
|
});
|
||||||
|
|
||||||
|
const marriage = await Relationship.findOne({
|
||||||
|
where: { character1Id: user.character.id },
|
||||||
|
include: [
|
||||||
|
{ model: RelationshipType, as: 'relationshipType', where: { tr: 'married' } },
|
||||||
|
{ model: RelationshipState, as: 'state', required: false }
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
let marriageState = marriage?.state || null;
|
||||||
|
if (marriage && !marriageState) {
|
||||||
|
marriageState = await RelationshipState.create({
|
||||||
|
relationshipId: marriage.id,
|
||||||
|
...this.buildDefaultRelationshipState('married')
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const nextAffection = this.clampScore((state.affection ?? 50) + action.affectionDelta);
|
||||||
|
const nextVisibility = this.clampScore((state.visibility ?? 15) + action.visibilityDelta);
|
||||||
|
const nextDiscretion = this.clampScore((state.discretion ?? 50) + action.discretionDelta);
|
||||||
|
const nextHouseholdOrder = userHouse
|
||||||
|
? this.clampScore((userHouse.householdOrder ?? 55) + action.householdOrderDelta)
|
||||||
|
: null;
|
||||||
|
const nextMarriageSatisfaction = marriageState
|
||||||
|
? this.clampScore((marriageState.marriageSatisfaction ?? 55) + action.marriageSatisfactionDelta)
|
||||||
|
: null;
|
||||||
|
|
||||||
|
await sequelize.transaction(async (t) => {
|
||||||
|
await state.update(
|
||||||
|
{
|
||||||
|
affection: nextAffection,
|
||||||
|
visibility: nextVisibility,
|
||||||
|
discretion: nextDiscretion,
|
||||||
|
},
|
||||||
|
{ transaction: t }
|
||||||
|
);
|
||||||
|
if (userHouse && nextHouseholdOrder != null) {
|
||||||
|
await userHouse.update({ householdOrder: nextHouseholdOrder }, { transaction: t });
|
||||||
|
}
|
||||||
|
if (marriageState && nextMarriageSatisfaction != null) {
|
||||||
|
await marriageState.update({ marriageSatisfaction: nextMarriageSatisfaction }, { transaction: t });
|
||||||
|
}
|
||||||
|
await updateFalukantUserMoney(user.id, -action.cost, 'lover_affection_boost', user.id);
|
||||||
|
});
|
||||||
|
|
||||||
|
await this.refreshHouseholdTensionState(user, user.character);
|
||||||
|
await notifyUser(hashedUserId, 'falukantUpdateFamily', { reason: 'daily' });
|
||||||
|
await notifyUser(hashedUserId, 'falukantUpdateStatus', {});
|
||||||
|
|
||||||
|
return {
|
||||||
|
success: true,
|
||||||
|
relationshipId: parsedRelationshipId,
|
||||||
|
cost: action.cost,
|
||||||
|
affection: nextAffection,
|
||||||
|
visibility: nextVisibility,
|
||||||
|
discretion: nextDiscretion,
|
||||||
|
householdOrder: nextHouseholdOrder,
|
||||||
|
marriageSatisfaction: nextMarriageSatisfaction,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
async spendTimeWithSpouse(hashedUserId) {
|
async spendTimeWithSpouse(hashedUserId) {
|
||||||
const user = await this.getFalukantUserByHashedId(hashedUserId);
|
const user = await this.getFalukantUserByHashedId(hashedUserId);
|
||||||
if (!user?.character?.id) throw new Error('User or character not found');
|
if (!user?.character?.id) throw new Error('User or character not found');
|
||||||
|
|||||||
@@ -831,6 +831,10 @@
|
|||||||
"maintenanceHigh": "Suporta 75",
|
"maintenanceHigh": "Suporta 75",
|
||||||
"maintenanceSuccess": "Na-update ang suporta.",
|
"maintenanceSuccess": "Na-update ang suporta.",
|
||||||
"maintenanceError": "Dili ma-update ang suporta.",
|
"maintenanceError": "Dili ma-update ang suporta.",
|
||||||
|
"improveAffection": "Pauswaga ang pagmahal ({cost})",
|
||||||
|
"improveAffectionHint": "Mopataas sa pagmahal, mogasto og kwarta, ug mopataas usab sa visibility.",
|
||||||
|
"improveAffectionSuccess": "Napalig-on ang pagmahal ({cost}). Bag-ong bili: pagmahal {affection}, visibility {visibility}, discretion {discretion}.",
|
||||||
|
"improveAffectionError": "Dili mapaayo ang pagmahal.",
|
||||||
"acknowledge": "Iila",
|
"acknowledge": "Iila",
|
||||||
"acknowledgeSuccess": "Giila na ang relasyon.",
|
"acknowledgeSuccess": "Giila na ang relasyon.",
|
||||||
"acknowledgeError": "Dili ma-ila ang relasyon.",
|
"acknowledgeError": "Dili ma-ila ang relasyon.",
|
||||||
|
|||||||
@@ -805,6 +805,10 @@
|
|||||||
"maintenanceHigh": "Unterhalt 75",
|
"maintenanceHigh": "Unterhalt 75",
|
||||||
"maintenanceSuccess": "Der Unterhalt wurde angepasst.",
|
"maintenanceSuccess": "Der Unterhalt wurde angepasst.",
|
||||||
"maintenanceError": "Der Unterhalt konnte nicht angepasst werden.",
|
"maintenanceError": "Der Unterhalt konnte nicht angepasst werden.",
|
||||||
|
"improveAffection": "Zuneigung steigern ({cost})",
|
||||||
|
"improveAffectionHint": "Erhöht Zuneigung, kostet Geld und erhöht zugleich Sichtbarkeit.",
|
||||||
|
"improveAffectionSuccess": "Die Zuneigung wurde gestärkt ({cost}). Neuer Stand: Zuneigung {affection}, Sichtbarkeit {visibility}, Diskretion {discretion}.",
|
||||||
|
"improveAffectionError": "Die Zuneigung konnte nicht gesteigert werden.",
|
||||||
"acknowledge": "Anerkennen",
|
"acknowledge": "Anerkennen",
|
||||||
"acknowledgeSuccess": "Die Beziehung wurde offiziell anerkannt.",
|
"acknowledgeSuccess": "Die Beziehung wurde offiziell anerkannt.",
|
||||||
"acknowledgeError": "Die Beziehung konnte nicht anerkannt werden.",
|
"acknowledgeError": "Die Beziehung konnte nicht anerkannt werden.",
|
||||||
|
|||||||
@@ -942,6 +942,10 @@
|
|||||||
"maintenanceHigh": "Maintenance 75",
|
"maintenanceHigh": "Maintenance 75",
|
||||||
"maintenanceSuccess": "Maintenance has been updated.",
|
"maintenanceSuccess": "Maintenance has been updated.",
|
||||||
"maintenanceError": "Maintenance could not be updated.",
|
"maintenanceError": "Maintenance could not be updated.",
|
||||||
|
"improveAffection": "Boost affection ({cost})",
|
||||||
|
"improveAffectionHint": "Raises affection, costs money, and also increases visibility.",
|
||||||
|
"improveAffectionSuccess": "Affection has been strengthened ({cost}). New values: affection {affection}, visibility {visibility}, discretion {discretion}.",
|
||||||
|
"improveAffectionError": "Affection could not be improved.",
|
||||||
"acknowledge": "Acknowledge",
|
"acknowledge": "Acknowledge",
|
||||||
"acknowledgeSuccess": "The relationship has been officially acknowledged.",
|
"acknowledgeSuccess": "The relationship has been officially acknowledged.",
|
||||||
"acknowledgeError": "The relationship could not be acknowledged.",
|
"acknowledgeError": "The relationship could not be acknowledged.",
|
||||||
|
|||||||
@@ -796,6 +796,10 @@
|
|||||||
"maintenanceHigh": "Mantenimiento 75",
|
"maintenanceHigh": "Mantenimiento 75",
|
||||||
"maintenanceSuccess": "Se ha ajustado el mantenimiento.",
|
"maintenanceSuccess": "Se ha ajustado el mantenimiento.",
|
||||||
"maintenanceError": "No se pudo ajustar el mantenimiento.",
|
"maintenanceError": "No se pudo ajustar el mantenimiento.",
|
||||||
|
"improveAffection": "Mejorar afecto ({cost})",
|
||||||
|
"improveAffectionHint": "Aumenta el afecto, cuesta dinero y también sube la visibilidad.",
|
||||||
|
"improveAffectionSuccess": "El afecto ha mejorado ({cost}). Nuevos valores: afecto {affection}, visibilidad {visibility}, discreción {discretion}.",
|
||||||
|
"improveAffectionError": "No se pudo mejorar el afecto.",
|
||||||
"acknowledge": "Reconocer",
|
"acknowledge": "Reconocer",
|
||||||
"acknowledgeSuccess": "La relación ha sido reconocida oficialmente.",
|
"acknowledgeSuccess": "La relación ha sido reconocida oficialmente.",
|
||||||
"acknowledgeError": "No se pudo reconocer la relación.",
|
"acknowledgeError": "No se pudo reconocer la relación.",
|
||||||
|
|||||||
@@ -794,6 +794,10 @@
|
|||||||
"maintenanceHigh": "Entretien 75",
|
"maintenanceHigh": "Entretien 75",
|
||||||
"maintenanceSuccess": "L'entretien a été ajusté.",
|
"maintenanceSuccess": "L'entretien a été ajusté.",
|
||||||
"maintenanceError": "La maintenance n'a pas pu être ajustée.",
|
"maintenanceError": "La maintenance n'a pas pu être ajustée.",
|
||||||
|
"improveAffection": "Renforcer l’affection ({cost})",
|
||||||
|
"improveAffectionHint": "Augmente l’affection, coûte de l’argent et augmente aussi la visibilité.",
|
||||||
|
"improveAffectionSuccess": "L’affection a été renforcée ({cost}). Nouvelles valeurs : affection {affection}, visibilité {visibility}, discrétion {discretion}.",
|
||||||
|
"improveAffectionError": "L’affection n’a pas pu être améliorée.",
|
||||||
"acknowledge": "Reconnaître",
|
"acknowledge": "Reconnaître",
|
||||||
"acknowledgeSuccess": "La relation a été officiellement reconnue.",
|
"acknowledgeSuccess": "La relation a été officiellement reconnue.",
|
||||||
"acknowledgeError": "La relation n'a pas pu être reconnue.",
|
"acknowledgeError": "La relation n'a pas pu être reconnue.",
|
||||||
|
|||||||
@@ -437,6 +437,13 @@
|
|||||||
<button class="button button--secondary" @click="setLoverMaintenance(lover, 75)">
|
<button class="button button--secondary" @click="setLoverMaintenance(lover, 75)">
|
||||||
{{ $t('falukant.family.lovers.actions.maintenanceHigh') }}
|
{{ $t('falukant.family.lovers.actions.maintenanceHigh') }}
|
||||||
</button>
|
</button>
|
||||||
|
<button
|
||||||
|
class="button button--secondary"
|
||||||
|
@click="improveLoverAffection(lover)"
|
||||||
|
:title="$t('falukant.family.lovers.actions.improveAffectionHint', { cost: formatCost(loverAffectionActionCost) })"
|
||||||
|
>
|
||||||
|
{{ $t('falukant.family.lovers.actions.improveAffection', { cost: formatCost(loverAffectionActionCost) }) }}
|
||||||
|
</button>
|
||||||
<button
|
<button
|
||||||
v-if="!lover.acknowledged"
|
v-if="!lover.acknowledged"
|
||||||
class="button button--secondary"
|
class="button button--secondary"
|
||||||
@@ -504,6 +511,7 @@ const MARRIAGE_GIFT_COSTS = {
|
|||||||
decent: 80,
|
decent: 80,
|
||||||
lavish: 180
|
lavish: 180
|
||||||
}
|
}
|
||||||
|
const LOVER_AFFECTION_ACTION_COST = 60
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'FamilyView',
|
name: 'FamilyView',
|
||||||
@@ -548,6 +556,9 @@ export default {
|
|||||||
marriageGiftCosts() {
|
marriageGiftCosts() {
|
||||||
return MARRIAGE_GIFT_COSTS;
|
return MARRIAGE_GIFT_COSTS;
|
||||||
},
|
},
|
||||||
|
loverAffectionActionCost() {
|
||||||
|
return LOVER_AFFECTION_ACTION_COST;
|
||||||
|
},
|
||||||
partnerSummaryLine() {
|
partnerSummaryLine() {
|
||||||
if (this.relationships?.length > 0) {
|
if (this.relationships?.length > 0) {
|
||||||
const r = this.relationships[0];
|
const r = this.relationships[0];
|
||||||
@@ -847,6 +858,25 @@ export default {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
async improveLoverAffection(lover) {
|
||||||
|
try {
|
||||||
|
const { data } = await apiClient.post(`/api/falukant/family/lover/${lover.relationshipId}/improve-affection`);
|
||||||
|
await this.loadFamilyData();
|
||||||
|
showSuccess(
|
||||||
|
this,
|
||||||
|
this.$t('falukant.family.lovers.actions.improveAffectionSuccess', {
|
||||||
|
cost: this.formatCost(data?.cost ?? this.loverAffectionActionCost),
|
||||||
|
affection: data?.affection ?? '—',
|
||||||
|
visibility: data?.visibility ?? '—',
|
||||||
|
discretion: data?.discretion ?? '—',
|
||||||
|
})
|
||||||
|
);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Error improving lover affection:', error);
|
||||||
|
showError(this, this.$t('falukant.family.lovers.actions.improveAffectionError'));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
async endLoverRelationship(lover) {
|
async endLoverRelationship(lover) {
|
||||||
const confirmed = await confirmAction(this, {
|
const confirmed = await confirmAction(this, {
|
||||||
title: this.$t('falukant.family.lovers.actions.end'),
|
title: this.$t('falukant.family.lovers.actions.end'),
|
||||||
|
|||||||
Reference in New Issue
Block a user