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
|
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 = {
|
const whereClause = {
|
||||||
id: { [Op.ne]: requestingCharacterId },
|
id: { [Op.ne]: requestingCharacterId },
|
||||||
gender: { [Op.ne]: requestingCharacterGender },
|
gender: { [Op.ne]: requestingCharacterGender },
|
||||||
regionId: requestingRegionId,
|
regionId: requestingRegionId,
|
||||||
createdAt: { [Op.lt]: new Date(new Date() - 12 * 24 * 60 * 60 * 1000) },
|
createdAt: { [Op.lt]: minAgeDate },
|
||||||
titleOfNobility: { [Op.between]: [Math.max(1, requestingCharacterTitleOfNobility - 1), requestingCharacterTitleOfNobility + 1] }
|
titleOfNobility: { [Op.between]: [titleMin, titleMax] },
|
||||||
|
userId: null // Nur NPCs suchen
|
||||||
};
|
};
|
||||||
|
|
||||||
// Nur NPCs suchen (userId ist null)
|
let potentialPartners = await FalukantCharacter.findAll({
|
||||||
whereClause.userId = null;
|
|
||||||
|
|
||||||
console.log(`[createPossiblePartners] Where clause:`, JSON.stringify(whereClause, null, 2));
|
|
||||||
|
|
||||||
const potentialPartners = await FalukantCharacter.findAll({
|
|
||||||
where: whereClause,
|
where: whereClause,
|
||||||
order: [
|
order: [
|
||||||
[Sequelize.literal(`ABS((EXTRACT(EPOCH FROM (NOW() - "birthdate")) / 86400) - ${ownAge})`), 'ASC']
|
[Sequelize.literal(`ABS((EXTRACT(EPOCH FROM (NOW() - "birthdate")) / 86400) - ${ownAge})`), 'ASC']
|
||||||
@@ -3211,11 +3220,54 @@ class FalukantService extends BaseService {
|
|||||||
limit: 5,
|
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) {
|
if (potentialPartners.length === 0) {
|
||||||
console.warn(`[createPossiblePartners] No partners found with criteria. Consider creating NPCs.`);
|
console.log(`[createPossiblePartners] No partners found, creating new NPCs...`);
|
||||||
return; // Keine Partner gefunden, aber kein Fehler
|
// 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 => {
|
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) {
|
async acceptMarriageProposal(hashedUserId, proposedCharacterId) {
|
||||||
const user = await this.getFalukantUserByHashedId(hashedUserId);
|
const user = await this.getFalukantUserByHashedId(hashedUserId);
|
||||||
const character = await FalukantCharacter.findOne({ where: { userId: user.id } });
|
const character = await FalukantCharacter.findOne({ where: { userId: user.id } });
|
||||||
|
|||||||
Reference in New Issue
Block a user