Enhance NobilityView with new house position and condition formatting: Introduce methods to format house position labels and house condition descriptions based on numeric values. Update requirement translations to utilize these new methods for improved clarity and localization.
This commit is contained in:
@@ -5223,22 +5223,28 @@ class FalukantService extends BaseService {
|
||||
nextAdvanceAt = next.toISOString();
|
||||
}
|
||||
const currentTitleLevel = nobility.level;
|
||||
const nextTitle = await TitleOfNobility.findOne({
|
||||
where: {
|
||||
level: currentTitleLevel + 1
|
||||
},
|
||||
include: [
|
||||
{
|
||||
model: TitleRequirement,
|
||||
as: 'requirements',
|
||||
}
|
||||
],
|
||||
attributes: ['labelTr']
|
||||
});
|
||||
const [nextTitle, highestPoliticalOffice, highestOfficeAny] = await Promise.all([
|
||||
TitleOfNobility.findOne({
|
||||
where: {
|
||||
level: currentTitleLevel + 1
|
||||
},
|
||||
include: [
|
||||
{
|
||||
model: TitleRequirement,
|
||||
as: 'requirements',
|
||||
}
|
||||
],
|
||||
attributes: ['labelTr']
|
||||
}),
|
||||
this.getHighestPoliticalOfficeInfo(falukantUser.id),
|
||||
this.getHighestOfficeAnyInfo(falukantUser.id)
|
||||
]);
|
||||
return {
|
||||
current: nobility,
|
||||
next: nextTitle,
|
||||
nextAdvanceAt
|
||||
nextAdvanceAt,
|
||||
highestPoliticalOffice,
|
||||
highestOfficeAny
|
||||
};
|
||||
}
|
||||
|
||||
@@ -5283,9 +5289,15 @@ class FalukantService extends BaseService {
|
||||
case 'office_rank_any':
|
||||
fulfilled = fulfilled && await this.checkOfficeRankAnyRequirement(user, requirement);
|
||||
break;
|
||||
case 'office_rank_political':
|
||||
fulfilled = fulfilled && await this.checkOfficeRankPoliticalRequirement(user, requirement);
|
||||
break;
|
||||
case 'lover_count_max':
|
||||
fulfilled = fulfilled && await this.checkLoverCountMaxRequirement(user, requirement);
|
||||
break;
|
||||
case 'lover_count_min':
|
||||
fulfilled = fulfilled && await this.checkLoverCountMinRequirement(user, requirement);
|
||||
break;
|
||||
default:
|
||||
fulfilled = false;
|
||||
};
|
||||
@@ -5351,12 +5363,46 @@ class FalukantService extends BaseService {
|
||||
return averageCondition >= Number(requirement.requirementValue || 0);
|
||||
}
|
||||
|
||||
async getHighestOfficeRankAny(userId) {
|
||||
async getHighestPoliticalOfficeInfo(userId) {
|
||||
const character = await FalukantCharacter.findOne({
|
||||
where: { userId },
|
||||
attributes: ['id']
|
||||
});
|
||||
if (!character) return 0;
|
||||
if (!character) return { rank: 0, name: null };
|
||||
|
||||
const [politicalOffices, politicalHistories] = await Promise.all([
|
||||
PoliticalOffice.findAll({
|
||||
where: { characterId: character.id },
|
||||
include: [{ model: PoliticalOfficeType, as: 'officeType', attributes: ['name'] }],
|
||||
attributes: ['officeTypeId']
|
||||
}),
|
||||
PoliticalOfficeHistory.findAll({
|
||||
where: { characterId: character.id },
|
||||
include: [{ model: PoliticalOfficeType, as: 'officeTypeHistory', attributes: ['name'] }],
|
||||
attributes: ['officeTypeId']
|
||||
})
|
||||
]);
|
||||
|
||||
const candidates = [
|
||||
...politicalOffices.map((office) => ({
|
||||
rank: POLITICAL_OFFICE_RANKS[office.officeType?.name] || 0,
|
||||
name: office.officeType?.name || null
|
||||
})),
|
||||
...politicalHistories.map((history) => ({
|
||||
rank: POLITICAL_OFFICE_RANKS[history.officeTypeHistory?.name] || 0,
|
||||
name: history.officeTypeHistory?.name || null
|
||||
}))
|
||||
].sort((a, b) => b.rank - a.rank);
|
||||
|
||||
return candidates[0] || { rank: 0, name: null };
|
||||
}
|
||||
|
||||
async getHighestOfficeAnyInfo(userId) {
|
||||
const character = await FalukantCharacter.findOne({
|
||||
where: { userId },
|
||||
attributes: ['id']
|
||||
});
|
||||
if (!character) return { rank: 0, name: null, source: null };
|
||||
|
||||
const [politicalOffices, politicalHistories, churchOffices] = await Promise.all([
|
||||
PoliticalOffice.findAll({
|
||||
@@ -5371,16 +5417,35 @@ class FalukantService extends BaseService {
|
||||
}),
|
||||
ChurchOffice.findAll({
|
||||
where: { characterId: character.id },
|
||||
include: [{ model: ChurchOfficeType, as: 'type', attributes: ['hierarchyLevel'] }],
|
||||
include: [{ model: ChurchOfficeType, as: 'type', attributes: ['name', 'hierarchyLevel'] }],
|
||||
attributes: ['officeTypeId']
|
||||
})
|
||||
]);
|
||||
|
||||
const politicalRanks = politicalOffices.map((office) => POLITICAL_OFFICE_RANKS[office.officeType?.name] || 0);
|
||||
const politicalHistoryRanks = politicalHistories.map((history) => POLITICAL_OFFICE_RANKS[history.officeTypeHistory?.name] || 0);
|
||||
const churchRanks = churchOffices.map((office) => Number(office.type?.hierarchyLevel || 0));
|
||||
const candidates = [
|
||||
...politicalOffices.map((office) => ({
|
||||
rank: POLITICAL_OFFICE_RANKS[office.officeType?.name] || 0,
|
||||
name: office.officeType?.name || null,
|
||||
source: 'political'
|
||||
})),
|
||||
...politicalHistories.map((history) => ({
|
||||
rank: POLITICAL_OFFICE_RANKS[history.officeTypeHistory?.name] || 0,
|
||||
name: history.officeTypeHistory?.name || null,
|
||||
source: 'political'
|
||||
})),
|
||||
...churchOffices.map((office) => ({
|
||||
rank: Number(office.type?.hierarchyLevel || 0),
|
||||
name: office.type?.name || null,
|
||||
source: 'church'
|
||||
}))
|
||||
].sort((a, b) => b.rank - a.rank);
|
||||
|
||||
return Math.max(0, ...politicalRanks, ...politicalHistoryRanks, ...churchRanks);
|
||||
return candidates[0] || { rank: 0, name: null, source: null };
|
||||
}
|
||||
|
||||
async getHighestOfficeRankAny(userId) {
|
||||
const highest = await this.getHighestOfficeAnyInfo(userId);
|
||||
return Number(highest?.rank || 0);
|
||||
}
|
||||
|
||||
async checkOfficeRankAnyRequirement(user, requirement) {
|
||||
@@ -5388,18 +5453,33 @@ class FalukantService extends BaseService {
|
||||
return highestRank >= Number(requirement.requirementValue || 0);
|
||||
}
|
||||
|
||||
async checkOfficeRankPoliticalRequirement(user, requirement) {
|
||||
const highest = await this.getHighestPoliticalOfficeInfo(user.id);
|
||||
return Number(highest?.rank || 0) >= Number(requirement.requirementValue || 0);
|
||||
}
|
||||
|
||||
async checkLoverCountMaxRequirement(user, requirement) {
|
||||
const activeLoverCount = await this.getActiveLoverCount(user);
|
||||
return activeLoverCount <= Number(requirement.requirementValue || 0);
|
||||
}
|
||||
|
||||
async checkLoverCountMinRequirement(user, requirement) {
|
||||
const activeLoverCount = await this.getActiveLoverCount(user);
|
||||
return activeLoverCount >= Number(requirement.requirementValue || 0);
|
||||
}
|
||||
|
||||
async getActiveLoverCount(user) {
|
||||
const character = user.character || await FalukantCharacter.findOne({
|
||||
where: { userId: user.id },
|
||||
attributes: ['id']
|
||||
});
|
||||
if (!character) return false;
|
||||
if (!character) return 0;
|
||||
|
||||
const loverType = await RelationshipType.findOne({
|
||||
where: { tr: 'lover' },
|
||||
attributes: ['id']
|
||||
});
|
||||
if (!loverType) return true;
|
||||
if (!loverType) return 0;
|
||||
|
||||
const loverRelationships = await Relationship.findAll({
|
||||
where: {
|
||||
@@ -5413,8 +5493,7 @@ class FalukantService extends BaseService {
|
||||
}]
|
||||
});
|
||||
|
||||
const activeLoverCount = loverRelationships.filter((rel) => (rel.state?.active ?? true) !== false).length;
|
||||
return activeLoverCount <= Number(requirement.requirementValue || 0);
|
||||
return loverRelationships.filter((rel) => (rel.state?.active ?? true) !== false).length;
|
||||
}
|
||||
|
||||
async getHealth(hashedUserId) {
|
||||
|
||||
@@ -69,7 +69,7 @@ JOIN (
|
||||
('margrave', 'money', 165000::numeric),
|
||||
('margrave', 'reputation', 40::numeric),
|
||||
('margrave', 'house_condition', 72::numeric),
|
||||
('margrave', 'lover_count_max', 2::numeric),
|
||||
('margrave', 'lover_count_min', 1::numeric),
|
||||
|
||||
('landgrave', 'cost', 62000::numeric),
|
||||
('landgrave', 'money', 230000::numeric),
|
||||
@@ -83,9 +83,9 @@ JOIN (
|
||||
|
||||
('elector', 'cost', 115000::numeric),
|
||||
('elector', 'money', 440000::numeric),
|
||||
('elector', 'office_rank_any', 4::numeric),
|
||||
('elector', 'office_rank_political', 4::numeric),
|
||||
('elector', 'house_position', 5::numeric),
|
||||
('elector', 'lover_count_max', 2::numeric),
|
||||
('elector', 'lover_count_max', 3::numeric),
|
||||
|
||||
('imperial-prince', 'cost', 155000::numeric),
|
||||
('imperial-prince', 'money', 600000::numeric),
|
||||
@@ -101,7 +101,8 @@ JOIN (
|
||||
('grand-duke', 'money', 1120000::numeric),
|
||||
('grand-duke', 'reputation', 64::numeric),
|
||||
('grand-duke', 'house_condition', 84::numeric),
|
||||
('grand-duke', 'lover_count_max', 1::numeric),
|
||||
('grand-duke', 'lover_count_min', 1::numeric),
|
||||
('grand-duke', 'lover_count_max', 3::numeric),
|
||||
|
||||
('prince-regent', 'cost', 360000::numeric),
|
||||
('prince-regent', 'money', 1520000::numeric),
|
||||
@@ -113,7 +114,8 @@ JOIN (
|
||||
('king', 'reputation', 72::numeric),
|
||||
('king', 'house_position', 8::numeric),
|
||||
('king', 'house_condition', 88::numeric),
|
||||
('king', 'lover_count_max', 1::numeric)
|
||||
('king', 'lover_count_min', 1::numeric),
|
||||
('king', 'lover_count_max', 4::numeric)
|
||||
) AS req(label_tr, requirement_type, requirement_value)
|
||||
ON req.label_tr = tm.label_tr
|
||||
ON CONFLICT (title_id, requirement_type)
|
||||
|
||||
@@ -306,15 +306,15 @@ async function initializeFalukantTitleRequirements() {
|
||||
{ labelTr: "baron", requirements: [{ type: "branches", value: 4 }, { type: "cost", value: 16000 }, { type: "money", value: 55000 }, { type: "house_position", value: 2 }] },
|
||||
{ labelTr: "count", requirements: [{ type: "cost", value: 23000 }, { type: "money", value: 80000 }, { type: "reputation", value: 32 }, { type: "house_condition", value: 68 }] },
|
||||
{ labelTr: "palsgrave", requirements: [{ type: "cost", value: 32000 }, { type: "money", value: 115000 }, { type: "office_rank_any", value: 2 }, { type: "house_position", value: 3 }] },
|
||||
{ labelTr: "margrave", requirements: [{ type: "cost", value: 45000 }, { type: "money", value: 165000 }, { type: "reputation", value: 40 }, { type: "house_condition", value: 72 }, { type: "lover_count_max", value: 2 }] },
|
||||
{ labelTr: "margrave", requirements: [{ type: "cost", value: 45000 }, { type: "money", value: 165000 }, { type: "reputation", value: 40 }, { type: "house_condition", value: 72 }, { type: "lover_count_min", value: 1 }] },
|
||||
{ labelTr: "landgrave", requirements: [{ type: "cost", value: 62000 }, { type: "money", value: 230000 }, { type: "office_rank_any", value: 3 }, { type: "house_position", value: 4 }] },
|
||||
{ labelTr: "ruler", requirements: [{ type: "cost", value: 85000 }, { type: "money", value: 320000 }, { type: "reputation", value: 48 }, { type: "house_condition", value: 76 }] },
|
||||
{ labelTr: "elector", requirements: [{ type: "cost", value: 115000 }, { type: "money", value: 440000 }, { type: "office_rank_any", value: 4 }, { type: "house_position", value: 5 }, { type: "lover_count_max", value: 2 }] },
|
||||
{ labelTr: "elector", requirements: [{ type: "cost", value: 115000 }, { type: "money", value: 440000 }, { type: "office_rank_political", value: 4 }, { type: "house_position", value: 5 }, { type: "lover_count_max", value: 3 }] },
|
||||
{ labelTr: "imperial-prince", requirements: [{ type: "cost", value: 155000 }, { type: "money", value: 600000 }, { type: "reputation", value: 56 }, { type: "house_condition", value: 80 }] },
|
||||
{ labelTr: "duke", requirements: [{ type: "cost", value: 205000 }, { type: "money", value: 820000 }, { type: "office_rank_any", value: 5 }, { type: "house_position", value: 6 }] },
|
||||
{ labelTr: "grand-duke",requirements: [{ type: "cost", value: 270000 }, { type: "money", value: 1120000 }, { type: "reputation", value: 64 }, { type: "house_condition", value: 84 }, { type: "lover_count_max", value: 1 }] },
|
||||
{ labelTr: "grand-duke",requirements: [{ type: "cost", value: 270000 }, { type: "money", value: 1120000 }, { type: "reputation", value: 64 }, { type: "house_condition", value: 84 }, { type: "lover_count_min", value: 1 }, { type: "lover_count_max", value: 3 }] },
|
||||
{ labelTr: "prince-regent", requirements: [{ type: "cost", value: 360000 }, { type: "money", value: 1520000 }, { type: "office_rank_any", value: 6 }, { type: "house_position", value: 7 }] },
|
||||
{ labelTr: "king", requirements: [{ type: "cost", value: 500000 }, { type: "money", value: 2100000 }, { type: "reputation", value: 72 }, { type: "house_position", value: 8 }, { type: "house_condition", value: 88 }, { type: "lover_count_max", value: 1 }] },
|
||||
{ labelTr: "king", requirements: [{ type: "cost", value: 500000 }, { type: "money", value: 2100000 }, { type: "reputation", value: 72 }, { type: "house_position", value: 8 }, { type: "house_condition", value: 88 }, { type: "lover_count_min", value: 1 }, { type: "lover_count_max", value: 4 }] },
|
||||
];
|
||||
|
||||
const titles = await TitleOfNobility.findAll();
|
||||
|
||||
Reference in New Issue
Block a user