Exact source used by this build. SHA-256: 8fb5dc899ed86b1b2ef6138b05f1049c1d9884c0c1301930e683d02e0d0726af.
1 import { z } from "zod";
2 import { ShopSchema } from "../shops/schema";
3
4 const Id = z.string().min(1);
5 const Count = z.number().int().nonnegative();
6 const Positive = z.number().int().positive();
7 const Probability = z.number().min(0).max(1);
8 const Position = z.object({ x: Count, y: Count }).strict();
9 const Named = { name: z.literal("TBD"), description: z.literal("TBD"), manifestKey: Id };
10
11 export const AnimalBuildingSchema = z.object({
12 id: Id, ...Named,
13 kind: z.enum(["coop", "big_coop", "deluxe_coop", "barn", "big_barn", "deluxe_barn", "silo", "well", "shed", "stable", "fish_pond"]),
14 family: z.enum(["coop", "barn", "utility"]), tier: z.number().int().min(1).max(3),
15 upgradeFrom: Id.nullable(), cost: Count,
16 materials: z.array(z.object({ itemId: Id, quantity: Positive }).strict()),
17 buildDays: z.number().int().min(2).max(3), width: Positive, height: Positive, capacity: Count,
18 interior: z.object({ width: Positive, height: Positive, troughs: Count, hayHopper: z.boolean(), heaterSlot: z.boolean(), incubator: z.boolean(), autoGrabberSlot: z.boolean() }).strict(),
19 autoFeed: z.boolean(), siloCapacity: Count,
20 }).strict();
21
22 export const AnimalSpeciesSchema = z.object({
23 id: z.string().regex(/^animal_\d{2}$/), ...Named,
24 role: z.enum(["daily_layer", "alternate_layer", "daily_milker", "alternate_milker", "wool", "truffle"]),
25 buildingFamily: z.enum(["coop", "barn"]), minTier: z.number().int().min(1).max(3),
26 purchasePrice: Positive, matureDays: Positive, productCycleDays: Positive,
27 productItemId: Id, largeProductItemId: Id.nullable(), bonusProductItemId: Id.nullable(), toolItemId: Id.nullable(),
28 outdoorOnly: z.boolean(), grassTufts: Positive,
29 petMoodGain: Positive, fedMoodGain: Positive, neglectedMoodPenalty: Positive, weatherMoodDelta: Positive,
30 incubationMinutes: Positive.nullable(), harvestXp: Count,
31 }).strict();
32
33 export const AnimalsSchema = z.object({
34 farmAreaId: Id, buildingPlacementPoiId: Id, carpenterShopId: Id, ranchShopId: Id,
35 hayItemId: Id, grassStarterItemId: Id, heaterItemId: Id, autoGrabberItemId: Id,
36 buildings: AnimalBuildingSchema.array().min(1), species: AnimalSpeciesSchema.array().min(1),
37 shops: z.intersection(ShopSchema, z.object({ poiId: Id })).array().min(2),
38 care: z.object({
39 friendshipMax: Positive, moodMax: Positive, initialFriendship: Count, initialMood: Count,
40 petFriendship: Positive, harvestFriendship: Positive, grassFriendship: Positive,
41 unfedFriendshipPenalty: Positive, outsideFriendshipPenalty: Positive,
42 unpettedPenaltyBase: Positive, unpettedPenaltyFriendshipDivisor: Positive,
43 unfedMoodPenalty: Positive, outsideMoodMultiplier: Probability,
44 returnMinute: Count, sleepMinute: Count, eveningMinute: Count,
45 productionMoodThreshold: Positive, qualityMoodThreshold: Positive,
46 qualityFriendshipDivisor: Positive, qualityMoodDivisor: Positive,
47 qualityIridiumThreshold: Probability, qualityGoldDivisor: Positive,
48 largeMinFriendship: Positive, largeProductDivisor: Positive, bonusProductDivisor: Positive,
49 moodHighThreshold: Positive, moodHighMultiplier: z.number().positive(), moodLowThreshold: Positive,
50 sellBaseMultiplier: Probability, woolFriendshipThreshold: Positive, woolFriendshipDaysReduction: Positive,
51 truffleChancePerFrame: Probability, truffleExtraFriendshipDivisor: Positive, simulationFramesPerSecond: Positive,
52 dailyLuck: z.number().min(-1).max(1), autoGrabberFarmingLevel: z.number().int().min(0).max(10),
53 closedDoorMoodGain: Count, petXp: Count, harvestToolEnergy: Count,
54 }).strict(),
55 grass: z.object({
56 manifestKey: Id, maxTufts: Positive, starterTufts: Positive,
57 growChance: Probability, growMin: Positive, growMax: Positive, extraGrowMin: Count, extraGrowMax: Count,
58 spreadChance: Probability, spreadMin: Positive, spreadMax: Positive, springGrowthPasses: Positive,
59 hayChance: Probability, winterHayChance: Probability, growthSeasons: z.array(z.enum(["spring", "summer", "autumn", "winter"])),
60 initialPatches: z.array(Position.extend({ tufts: Positive }).strict()),
61 }).strict(),
62 pets: z.object({
63 choices: z.array(z.object({ id: z.enum(["cat", "dog"]), ...Named }).strict()).length(2),
64 freeCount: z.literal(1), friendshipMax: Positive, petFriendship: Positive, waterFriendship: Positive,
65 missingBowlPenalty: Positive, bowl: Position.extend({ manifestKey: Id }).strict(), start: Position,
66 }).strict(),
67 horse: z.object({ ...Named, speedMultiplier: z.number().gt(1), verticalClearance: Positive }).strict(),
68 tools: z.array(z.object({ itemId: Id, manifestKey: Id, price: Positive, energyCost: Count, farmingXp: Count }).strict()),
69 itemVisuals: z.record(Id, Id),
70 visuals: z.record(Id, z.object({ color: z.number().int().min(0).max(0xffffff), icon: z.string().min(1).max(8) }).strict()),
71 sources: z.array(z.string().url()).min(1),
72 }).strict();
73
74 export type AnimalBuildingDefinition = z.infer<typeof AnimalBuildingSchema>;
75 export type AnimalSpeciesDefinition = z.infer<typeof AnimalSpeciesSchema>;
76 export type AnimalsContent = z.infer<typeof AnimalsSchema>;
77