Implement enhanced partner search and NPC creation logic in FalukantService
- Added detailed logging for partner search criteria and results, improving traceability. - Refactored partner search logic to include a fallback mechanism for searching across all regions if no partners are found in the specified region. - Introduced a new method for creating NPCs when no suitable partners are available, ensuring a continuous flow in the partner matching process. - Improved the handling of character attributes such as age and title of nobility during partner searches and NPC creation.
This commit is contained in:
@@ -3190,20 +3190,29 @@ class FalukantService extends BaseService {
|
||||
ownAge
|
||||
});
|
||||
|
||||
const minAgeDate = new Date(new Date() - 12 * 24 * 60 * 60 * 1000);
|
||||
const titleMin = Math.max(1, requestingCharacterTitleOfNobility - 1);
|
||||
const titleMax = requestingCharacterTitleOfNobility + 1;
|
||||
|
||||
console.log(`[createPossiblePartners] Search criteria:`, {
|
||||
excludeId: requestingCharacterId,
|
||||
gender: `not ${requestingCharacterGender}`,
|
||||
regionId: requestingRegionId,
|
||||
minAge: '12 days old',
|
||||
titleRange: `${titleMin}-${titleMax}`,
|
||||
userId: 'null (NPCs only)'
|
||||
});
|
||||
|
||||
const whereClause = {
|
||||
id: { [Op.ne]: requestingCharacterId },
|
||||
gender: { [Op.ne]: requestingCharacterGender },
|
||||
regionId: requestingRegionId,
|
||||
createdAt: { [Op.lt]: new Date(new Date() - 12 * 24 * 60 * 60 * 1000) },
|
||||
titleOfNobility: { [Op.between]: [Math.max(1, requestingCharacterTitleOfNobility - 1), requestingCharacterTitleOfNobility + 1] }
|
||||
createdAt: { [Op.lt]: minAgeDate },
|
||||
titleOfNobility: { [Op.between]: [titleMin, titleMax] },
|
||||
userId: null // Nur NPCs suchen
|
||||
};
|
||||
|
||||
// Nur NPCs suchen (userId ist null)
|
||||
whereClause.userId = null;
|
||||
|
||||
console.log(`[createPossiblePartners] Where clause:`, JSON.stringify(whereClause, null, 2));
|
||||
|
||||
const potentialPartners = await FalukantCharacter.findAll({
|
||||
let potentialPartners = await FalukantCharacter.findAll({
|
||||
where: whereClause,
|
||||
order: [
|
||||
[Sequelize.literal(`ABS((EXTRACT(EPOCH FROM (NOW() - "birthdate")) / 86400) - ${ownAge})`), 'ASC']
|
||||
@@ -3211,11 +3220,54 @@ class FalukantService extends BaseService {
|
||||
limit: 5,
|
||||
});
|
||||
|
||||
console.log(`[createPossiblePartners] Found ${potentialPartners.length} potential partners`);
|
||||
console.log(`[createPossiblePartners] Found ${potentialPartners.length} potential partners in region ${requestingRegionId}`);
|
||||
|
||||
// Fallback: Wenn keine Partner in der gleichen Region gefunden werden, suche in allen Regionen
|
||||
if (potentialPartners.length === 0) {
|
||||
console.log(`[createPossiblePartners] No partners in region ${requestingRegionId}, trying all regions...`);
|
||||
const fallbackWhereClause = {
|
||||
id: { [Op.ne]: requestingCharacterId },
|
||||
gender: { [Op.ne]: requestingCharacterGender },
|
||||
createdAt: { [Op.lt]: minAgeDate },
|
||||
titleOfNobility: { [Op.between]: [titleMin, titleMax] },
|
||||
userId: null
|
||||
};
|
||||
|
||||
potentialPartners = await FalukantCharacter.findAll({
|
||||
where: fallbackWhereClause,
|
||||
order: [
|
||||
[Sequelize.literal(`ABS((EXTRACT(EPOCH FROM (NOW() - "birthdate")) / 86400) - ${ownAge})`), 'ASC']
|
||||
],
|
||||
limit: 5,
|
||||
});
|
||||
|
||||
console.log(`[createPossiblePartners] Found ${potentialPartners.length} potential partners in all regions`);
|
||||
}
|
||||
|
||||
if (potentialPartners.length === 0) {
|
||||
console.warn(`[createPossiblePartners] No partners found with criteria. Consider creating NPCs.`);
|
||||
return; // Keine Partner gefunden, aber kein Fehler
|
||||
console.log(`[createPossiblePartners] No partners found, creating new NPCs...`);
|
||||
// Erstelle automatisch 5 neue NPCs, die den Kriterien entsprechen
|
||||
const targetGender = requestingCharacterGender === 'male' ? 'female' : 'male';
|
||||
const createdNPCs = await this._createNPCsForMarriage(
|
||||
requestingRegionId,
|
||||
targetGender,
|
||||
titleMin,
|
||||
titleMax,
|
||||
ownAge,
|
||||
5
|
||||
);
|
||||
|
||||
if (createdNPCs.length > 0) {
|
||||
console.log(`[createPossiblePartners] Created ${createdNPCs.length} new NPCs, using them as partners`);
|
||||
potentialPartners = createdNPCs;
|
||||
} else {
|
||||
console.warn(`[createPossiblePartners] Failed to create NPCs. Consider creating NPCs manually with:`);
|
||||
console.warn(` - gender: ${targetGender}`);
|
||||
console.warn(` - regionId: ${requestingRegionId}`);
|
||||
console.warn(` - titleOfNobility: ${titleMin}-${titleMax}`);
|
||||
console.warn(` - age: ~${ownAge} years`);
|
||||
return; // Keine Partner gefunden, aber kein Fehler
|
||||
}
|
||||
}
|
||||
|
||||
const proposals = potentialPartners.map(partner => {
|
||||
@@ -3235,6 +3287,74 @@ class FalukantService extends BaseService {
|
||||
}
|
||||
}
|
||||
|
||||
async _createNPCsForMarriage(regionId, gender, minTitle, maxTitle, targetAge, count = 5) {
|
||||
try {
|
||||
const sequelize = FalukantCharacter.sequelize;
|
||||
const createdNPCs = [];
|
||||
|
||||
await sequelize.transaction(async (t) => {
|
||||
for (let i = 0; i < count; i++) {
|
||||
// Zufälliger Titel im Bereich
|
||||
const randomTitle = Math.floor(Math.random() * (maxTitle - minTitle + 1)) + minTitle;
|
||||
|
||||
// Alter: ±2 Jahre um targetAge
|
||||
const ageVariation = Math.floor(Math.random() * 5) - 2; // -2 bis +2
|
||||
const randomAge = Math.max(12, targetAge + ageVariation); // Mindestens 12 Jahre
|
||||
|
||||
// Zufälliger Vorname für das Geschlecht
|
||||
const firstName = await FalukantPredefineFirstname.findAll({
|
||||
where: { gender },
|
||||
order: sequelize.fn('RANDOM'),
|
||||
limit: 1,
|
||||
transaction: t
|
||||
});
|
||||
|
||||
if (!firstName || firstName.length === 0) {
|
||||
console.warn(`[_createNPCsForMarriage] No first names found for gender ${gender}`);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Zufälliger Nachname
|
||||
const lastName = await FalukantPredefineLastname.findAll({
|
||||
order: sequelize.fn('RANDOM'),
|
||||
limit: 1,
|
||||
transaction: t
|
||||
});
|
||||
|
||||
if (!lastName || lastName.length === 0) {
|
||||
console.warn(`[_createNPCsForMarriage] No last names found`);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Geburtsdatum berechnen (Alter in Tagen)
|
||||
const birthdate = new Date();
|
||||
birthdate.setDate(birthdate.getDate() - randomAge);
|
||||
|
||||
// Erstelle den NPC-Charakter
|
||||
const npc = await FalukantCharacter.create({
|
||||
userId: null, // Wichtig: null = NPC
|
||||
regionId: regionId,
|
||||
firstName: firstName[0].id,
|
||||
lastName: lastName[0].id,
|
||||
gender: gender,
|
||||
birthdate: birthdate,
|
||||
titleOfNobility: randomTitle,
|
||||
health: 100,
|
||||
moodId: 1
|
||||
}, { transaction: t });
|
||||
|
||||
createdNPCs.push(npc);
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`[_createNPCsForMarriage] Created ${createdNPCs.length} NPCs`);
|
||||
return createdNPCs;
|
||||
} catch (error) {
|
||||
console.error('[_createNPCsForMarriage] Error creating NPCs:', error);
|
||||
return []; // Bei Fehler leeres Array zurückgeben
|
||||
}
|
||||
}
|
||||
|
||||
async acceptMarriageProposal(hashedUserId, proposedCharacterId) {
|
||||
const user = await this.getFalukantUserByHashedId(hashedUserId);
|
||||
const character = await FalukantCharacter.findOne({ where: { userId: user.id } });
|
||||
|
||||
Reference in New Issue
Block a user