feat(FalukantService): implement marriage honeymoon pregnancy scheduling logic
All checks were successful
Deploy to production / deploy (push) Successful in 2m5s
All checks were successful
Deploy to production / deploy (push) Successful in 2m5s
- Added a new method to ensure pregnancy scheduling for married couples after the wedding, allowing the system to manage pregnancy due dates effectively. - Integrated checks for existing pregnancy and relationship flags to prevent duplicate scheduling. - Updated family retrieval logic to include pregnancy status based on the new scheduling method, enhancing user experience in family management.
This commit is contained in:
@@ -3534,6 +3534,97 @@ class FalukantService extends BaseService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Nach der Trauung (relationship = married): geplante Geburt auf der Mutter-Charakterzeile setzen,
|
||||||
|
* damit der Daemon den UserCharacterWorker-Pfad mit pregnancy_due_at nutzen kann.
|
||||||
|
* Läuft idempotent pro Ehe über relationship_state.flags_json.honeymoonPregnancyScheduled.
|
||||||
|
* @returns {{ scheduled: boolean, motherCharacterId?: number }}
|
||||||
|
*/
|
||||||
|
async _ensureMarriageHoneymoonPregnancyScheduled({
|
||||||
|
playerCharacterId,
|
||||||
|
playerGender,
|
||||||
|
spouseCharacterId,
|
||||||
|
spouseGender,
|
||||||
|
relationshipId,
|
||||||
|
}) {
|
||||||
|
if (!relationshipId || !playerCharacterId || !spouseCharacterId) {
|
||||||
|
return { scheduled: false };
|
||||||
|
}
|
||||||
|
const norm = (g) => String(g || '').trim().toLowerCase();
|
||||||
|
const isFemale = (g) => {
|
||||||
|
const s = norm(g);
|
||||||
|
return s === 'female' || s === 'f';
|
||||||
|
};
|
||||||
|
const isMale = (g) => {
|
||||||
|
const s = norm(g);
|
||||||
|
return s === 'male' || s === 'm';
|
||||||
|
};
|
||||||
|
let motherId;
|
||||||
|
let fatherId;
|
||||||
|
if (isFemale(playerGender) && isMale(spouseGender)) {
|
||||||
|
motherId = playerCharacterId;
|
||||||
|
fatherId = spouseCharacterId;
|
||||||
|
} else if (isFemale(spouseGender) && isMale(playerGender)) {
|
||||||
|
motherId = spouseCharacterId;
|
||||||
|
fatherId = playerCharacterId;
|
||||||
|
} else {
|
||||||
|
return { scheduled: false };
|
||||||
|
}
|
||||||
|
|
||||||
|
const stateRow = await RelationshipState.findOne({ where: { relationshipId } });
|
||||||
|
const flags = stateRow?.flagsJson && typeof stateRow.flagsJson === 'object'
|
||||||
|
? { ...stateRow.flagsJson }
|
||||||
|
: {};
|
||||||
|
if (flags.honeymoonPregnancyScheduled) {
|
||||||
|
return { scheduled: false };
|
||||||
|
}
|
||||||
|
|
||||||
|
const pregRows = await sequelize.query(
|
||||||
|
`SELECT pregnancy_due_at FROM falukant_data."character" WHERE id = :id`,
|
||||||
|
{ replacements: { id: motherId }, type: Sequelize.QueryTypes.SELECT }
|
||||||
|
);
|
||||||
|
if (pregRows[0]?.pregnancy_due_at) {
|
||||||
|
return { scheduled: false };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gleicher Default wie adminForceFalukantPregnancy (21 Tage bis Geburt — komprimierte Spielzeit).
|
||||||
|
const BIRTH_DUE_DAYS = 21;
|
||||||
|
const due = new Date();
|
||||||
|
due.setDate(due.getDate() + BIRTH_DUE_DAYS);
|
||||||
|
|
||||||
|
await FalukantCharacter.unscoped().update(
|
||||||
|
{
|
||||||
|
pregnancyDueAt: due,
|
||||||
|
pregnancyFatherCharacterId: fatherId,
|
||||||
|
},
|
||||||
|
{ where: { id: motherId } }
|
||||||
|
);
|
||||||
|
|
||||||
|
const mergedFlags = { ...flags, honeymoonPregnancyScheduled: true };
|
||||||
|
if (stateRow) {
|
||||||
|
await stateRow.update({ flagsJson: mergedFlags });
|
||||||
|
} else {
|
||||||
|
await RelationshipState.create({
|
||||||
|
relationshipId,
|
||||||
|
...this.buildDefaultRelationshipState('married'),
|
||||||
|
flagsJson: mergedFlags,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const mother = await FalukantCharacter.unscoped().findByPk(motherId, { attributes: ['id', 'userId'] });
|
||||||
|
if (mother?.userId) {
|
||||||
|
const fu = await FalukantUser.findByPk(mother.userId);
|
||||||
|
if (fu) {
|
||||||
|
const u = await User.findByPk(fu.userId);
|
||||||
|
if (u?.hashedId) {
|
||||||
|
await notifyUser(u.hashedId, 'familychanged', {});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return { scheduled: true, motherCharacterId: motherId };
|
||||||
|
}
|
||||||
|
|
||||||
async getFamily(hashedUserId) {
|
async getFamily(hashedUserId) {
|
||||||
const user = await this.getFalukantUserByHashedId(hashedUserId);
|
const user = await this.getFalukantUserByHashedId(hashedUserId);
|
||||||
if (!user) throw new Error('User not found');
|
if (!user) throw new Error('User not found');
|
||||||
@@ -3824,6 +3915,19 @@ class FalukantService extends BaseService {
|
|||||||
family.possiblePartners = await this.getPossiblePartners(character.id);
|
family.possiblePartners = await this.getPossiblePartners(character.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const marriedRel = family.relationships.find((r) => r.relationshipType === 'married');
|
||||||
|
if (marriedRel?.id && marriedRel.character2?.id != null) {
|
||||||
|
const honeymoon = await this._ensureMarriageHoneymoonPregnancyScheduled({
|
||||||
|
playerCharacterId: character.id,
|
||||||
|
playerGender: character.gender,
|
||||||
|
spouseCharacterId: marriedRel.character2.id,
|
||||||
|
spouseGender: marriedRel.character2.gender,
|
||||||
|
relationshipId: marriedRel.id,
|
||||||
|
});
|
||||||
|
if (honeymoon.scheduled && honeymoon.motherCharacterId === character.id) {
|
||||||
|
family.pregnancy = await this._getCharacterPregnancyOptional(character.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
return family;
|
return family;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user