Exact source used by this build. SHA-256: f5c583baf1ac38d855cbdbb5a7c5ed8ea0cc6397eae6e324ff890ba60058299d.

1 import type { Clock, Player, SimRules, WorldState } from '../../types';
2 import type { Friendship, HeartTier, ScheduleEntry, VillagerDefinition, VillagersContent, VillagersPlayer, VillagersWorld } from './types';
3 export * from './types';
4 export function villagersContent(rules: SimRules): VillagersContent | undefined { const data = rules.content?.villagers; return data && typeof data === 'object' && 'villagers' in data && 'config' in data ? data as VillagersContent : undefined; }
5 export function villagersDay(clock: Clock): number { return (clock.year - 1) * 112 + ['spring', 'summer', 'autumn', 'winter'].indexOf(clock.season) * 28 + clock.day - 1; }
6 export function villagersDayKey(clock: Clock): string { return `${clock.year}:${clock.season}:${clock.day}`; }
7 export function giftWeek(clock: Clock, resetDay: number): number { return Math.floor((villagersDay(clock) + (7 - resetDay) % 7) / 7); }
8 export function blankFriendship(): Friendship { return { points: 0, met: false, talkedDay: null, giftDay: null, giftWeek: -1, giftsThisWeek: 0, status: 'friend', weddingDay: null }; }
9 export function blankVillagersPlayer(): VillagersPlayer { return { friendships: {}, dialogue: null, activeEvent: null, seenEvents: [], eventChoices: {}, mailbox: [], knownRecipes: [], quests: [], completedQuestIds: [], lastProcessedDay: null, spouseChores: [] }; }
10 export function getVillagersPlayer(player: Player): VillagersPlayer { return { ...blankVillagersPlayer(), ...player.systems.villagers as Partial<VillagersPlayer> | undefined }; }
11 export function getFriendship(player: Player, villagerId: string): Friendship { return { ...blankFriendship(), ...getVillagersPlayer(player).friendships[villagerId] }; }
12 export function getVillagersWorld(state: WorldState): VillagersWorld { return state.systems.villagers as VillagersWorld | undefined ?? { day: '', npcs: {}, board: null }; }
13 export function setVillagersPlayer(player: Player, slice: VillagersPlayer): Player { return { ...player, systems: { ...player.systems, villagers: slice } }; }
14 export function setFriendship(player: Player, villagerId: string, friendship: Friendship): Player { const slice = getVillagersPlayer(player); return setVillagersPlayer(player, { ...slice, friendships: { ...slice.friendships, [villagerId]: friendship } }); }
15 export function friendshipCap(friendship: Friendship, villager: VillagerDefinition, data: VillagersContent): number { return friendship.status === 'spouse' ? data.config.spouseCap : villager.marriageCandidate && friendship.status === 'friend' ? data.config.candidateCap : data.config.friendshipCap; }
16 export function changeFriendship(player: Player, villager: VillagerDefinition, points: number, data: VillagersContent): Player { const friendship = getFriendship(player, villager.id); return setFriendship(player, villager.id, { ...friendship, points: Math.max(0, Math.min(friendshipCap(friendship, villager, data), friendship.points + points)) }); }
17 export function friendshipHearts(points: number, data: VillagersContent): number { return Math.floor(points / data.config.pointsPerHeart); }
18 export function friendshipTier(points: number, data: VillagersContent): HeartTier { return [...data.config.heartTiers].sort((a, b) => b.minHearts - a.minHearts).find((tier) => friendshipHearts(points, data) >= tier.minHearts)?.id ?? 'blue'; }
19 /** Festival > rain/storm > seasonal > weekday override > ordinary schedule. */
20 export function villagerSchedule(villager: VillagerDefinition, state: WorldState, data: VillagersContent): ScheduleEntry[] {
21   const festival = data.festivalDays.find((day) => day.day === state.clock.day && day.season === state.clock.season);
22   return (festival && villager.schedules.festivals[festival.id]) || ((state.weather === 'rain' || state.weather === 'storm') && villager.schedules.rain.length ? villager.schedules.rain : undefined) || villager.schedules.seasons[state.clock.season] || villager.schedules.weekdays[String(state.clock.weekday)] || villager.schedules.weekday;
23 }
24 export function scheduledEntry(villager: VillagerDefinition, state: WorldState, data: VillagersContent, minute = state.clock.minuteOfDay): ScheduleEntry | undefined { const schedule = villagerSchedule(villager, state, data); return [...schedule].reverse().find((entry) => entry.time <= minute) ?? schedule[0]; }
25