fchat-rising/learn/recommend/profile-recommendation.ts

204 lines
8.3 KiB
TypeScript
Raw Normal View History

2023-03-12 05:43:58 +00:00
import _ from 'lodash';
import { CharacterAnalysis, Matcher } from '../matcher';
import { FurryPreference, Kink, mammalSpecies, Species } from '../matcher-types';
export enum ProfileRecommendationLevel {
INFO = 'info',
NOTE = 'note',
CRITICAL = 'critical'
}
export interface ProfileRecommendationUrlParams {
// TBD
}
export interface ProfileRecommendation {
code: string;
level: ProfileRecommendationLevel;
title: string;
desc: string;
urlParams?: ProfileRecommendationUrlParams
}
export class ProfileRecommendationAnalyzer {
protected recommendations: ProfileRecommendation[] = [];
constructor(protected readonly profile: CharacterAnalysis) {
//
}
protected add(code: string, level: ProfileRecommendationLevel, title: string, desc: string, urlParams?: ProfileRecommendationUrlParams): void {
this.recommendations.push({ code, level, title, desc, urlParams });
}
analyze(): ProfileRecommendation[] {
this.recommendations = [];
this.checkMissingProperties();
this.checkSpeciesPreferences();
this.checkKinkCounts();
this.checkCustomKinks();
this.checkPortrait();
this.checkImages();
this.checkInlineImage();
this.checkDescriptionLength();
return this.recommendations;
}
protected checkPortrait(): void {
// this.profile.character.
// do nothing
}
protected checkImages(): void {
if (!this.profile.character.image_count) {
this.add(`ADD_IMAGE`, ProfileRecommendationLevel.CRITICAL, 'Add a profile image', 'Profiles with images are more attractive to other players.');
} else if (this.profile.character.image_count > 1 && this.profile.character.image_count < 3) {
this.add(`ADD_MORE_IMAGES`, ProfileRecommendationLevel.NOTE, 'Add more profile images', 'Profiles with images are more attractive try to have at least 3 images in your profile.');
}
}
protected checkInlineImage(): void {
if (_.keys(this.profile.character.inlines).length < 1) {
this.add(`ADD_INLINE_IMAGE`, ProfileRecommendationLevel.NOTE, 'Add an inline image', 'Profiles with inline images are more engaging to other players.');
}
}
protected checkDescriptionLength(): void {
const desc = this.profile.character.description.trim();
if (desc.length < 20) {
this.add(`ADD_DESCRIPTION`, ProfileRecommendationLevel.CRITICAL, 'Add description', 'Profiles with descriptions are more likely to draw attention from other players.');
} else if (desc.length < 400) {
this.add(`EXPAND_DESCRIPTION`, ProfileRecommendationLevel.NOTE, 'Extend your description', 'Long descriptions are more attractive to other players. Try expanding your description to at least 400 characters.');
}
}
protected checkCustomKinks(): void {
const counts = _.reduce(this.profile.character.customs, (accum, kink) => {
if (kink) {
accum.total += 1;
if (kink.description) {
accum.filled += 1;
}
}
return accum;
}, { filled: 0, total: 0 });
if (counts.total === 0) {
this.add(`ADD_CUSTOM_KINK`, ProfileRecommendationLevel.CRITICAL, 'Add custom kinks', `Custom kinks will help your profile stand out. Try adding at least 5 custom kinks.`);
} else if (counts.total < 5) {
this.add(`ADD_MORE_CUSTOM_KINKS`, ProfileRecommendationLevel.NOTE, 'Add more custom kinks', `Players pay a lot of attention to custom kinks. Try adding at least 5 custom kinks.`);
}
if (counts.filled < counts.total && counts.total > 0) {
this.add(`ADD_MORE_CUSTOM_KINK_DESCRIPTIONS`, ProfileRecommendationLevel.NOTE, 'Add descriptions to custom kinks', `Some or all of your custom kinks are missing descriptions. Add descriptions to your custom kinks to attract more players.`);
}
}
protected checkKinkCounts(): void {
const counts = _.reduce(this.profile.character.kinks, (accum, kinkLevel) => {
if (_.isString(kinkLevel) && kinkLevel) {
accum[kinkLevel as keyof typeof accum] += 1;
}
return accum;
}, { favorite: 0, yes: 0, maybe: 0, no: 0 });
const minCountPerType = 5;
const totalCount = counts.favorite + counts.yes + counts.maybe + counts.no;
if (totalCount < 10) {
this.add(`ADD_MORE_KINKS`, ProfileRecommendationLevel.CRITICAL, `Add more kinks`, `You should have at least 10 kinks for the matching algorithm to work well.`);
} else {
_.each(counts, (count, key) => {
if (count < minCountPerType) {
this.add(`ADD_MORE_KINKS_${key.toString().toUpperCase()}`, ProfileRecommendationLevel.CRITICAL, `Add more '${key}' kinks`, `You should have at least ${minCountPerType} '${key}' kinks for the matching algorithm to work well.`);
}
});
}
}
protected checkMissingProperties(): void {
const p = this.profile;
if (p.age === null) {
this.add('AGE', ProfileRecommendationLevel.CRITICAL, 'Enter age', 'Specifying the age of your character will improve your matches with other players.');
}
if (p.orientation === null) {
this.add('ORIENTATION', ProfileRecommendationLevel.CRITICAL, 'Enter sexual orientation', 'Specifying the sexual orientation of your character will improve your matches with other players.');
}
if (p.species === null) {
this.add('SPECIES', ProfileRecommendationLevel.CRITICAL, 'Enter species', 'Specifying the species of your character even if it\'s \'human\' will improve your matches with other players.');
}
if (p.furryPreference === null) {
this.add('FURRY_PREFERENCE', ProfileRecommendationLevel.CRITICAL, 'Enter furry preference', 'Specifying whether you like to play with anthro characters will improve your matches with other players.');
}
if (p.subDomRole === null) {
this.add('SUB_DOM_ROLE', ProfileRecommendationLevel.CRITICAL, 'Enter sub/dom role', 'Specifying your preferred sub/dom role will improve your matches with other players.');
}
if (p.position === null) {
this.add('POSITION', ProfileRecommendationLevel.CRITICAL, 'Enter position', 'Specifying your preferred position (e.g. "top", "bottom") will improve your matches with other players.');
}
if (p.postLengthPreference === null) {
this.add('POST_LENGTH', ProfileRecommendationLevel.CRITICAL, 'Enter post length preference', 'Specifying your post length preference will improve your matches with other players.');
}
if (p.bodyType === null) {
this.add('BODY_TYPE', ProfileRecommendationLevel.CRITICAL, 'Enter body type', 'Specifying your character\'s body type will improve your matches with other players.');
}
}
protected checkSpeciesPreferences(): void {
const p = this.profile;
const c = this.profile.character;
if (p.furryPreference === null) {
return;
}
if (p.furryPreference === FurryPreference.FurriesOnly) {
if (Matcher.getKinkPreference(c, Kink.Humans)! > 0) {
this.add('KINK_MISMATCH_FURRIES_ONLY_HUMAN', ProfileRecommendationLevel.NOTE, 'Inconsistent kink', 'Your "furries-only" profile has a positive "humans" kink. If you are open to playing with humans, consider updating your preference from "furries only" to "furs and humans".');
}
}
if (p.furryPreference === FurryPreference.HumansOnly) {
if (Matcher.getKinkPreference(c, Kink.AnimalsFerals)! >= 0 || Matcher.getKinkPreference(c, Kink.Zoophilia)! >= 0) {
// do nothing
} else {
const likedAnthros = this.getLikedAnimals();
_.each(likedAnthros, (species) => {
this.add('KINK_MISMATCH_HUMANS_ONLY_ANTHRO', ProfileRecommendationLevel.NOTE, 'Inconsistent kink', `Your "humans-only" profile has a positive "furry" kink (${Matcher.getSpeciesName(species)}). If you are open to playing with anthros, consider updating your preference from "humans only" to "furs and humans"`);
});
}
}
if (p.furryPreference !== FurryPreference.HumansOnly) {
const likedAnthros = this.getLikedAnimals();
if (likedAnthros && !_.difference(likedAnthros, [Kink.AnthroCharacters, Kink.Mammals, Kink.Humans] as any as Species[])) {
this.add('KINK_NO_SPECIES', ProfileRecommendationLevel.NOTE, 'Add preferred species', 'Specifying which anthro species you like (e.g. "equines", or "canines") in your kinks can improve your matches.');
}
}
}
protected getLikedAnimals(): Species[] {
const c = this.profile.character;
return _.filter(mammalSpecies, (species) => Matcher.getKinkPreference(c, species)! > 0);
}
}