Files
server/laf-cloud/functions/dailyTaskConfig.ts
T

123 lines
4.3 KiB
TypeScript

export type DailyTaskState = 0 | 1 | 2;
export type RewardItem = {
type: "coin" | "freeze" | "hammer" | "magic_wand" | "infinite_health"
| "hourglass" | "rocket" | "infinite_hourglass" | "infinite_rocket";
count: number;
};
export type DailyTask = {
slot: number;
taskId: string;
trackingId?: string;
metric: string;
target: number;
value: number;
stars: number;
state: DailyTaskState;
locked: boolean;
rewards: RewardItem[];
params?: Record<string, string | number | boolean>;
};
export type WeeklyReward = {
rewardId: string;
target: number;
state: DailyTaskState;
rewards: RewardItem[];
};
export type DailyWeeklyTaskData = {
version: 2;
dayKey: string;
weekKey: string;
dayEndsAt: number;
weekEndsAt: number;
serverNow: number;
dailyTasks: DailyTask[];
weeklyStars: number;
weeklyRewards: WeeklyReward[];
previousTaskIds: string[];
};
/** 普通可消除方块;11 为特殊暗灰色,不进入随机池。 */
export const TASK_COLOR_IDS = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
type Candidate = {
taskId: string;
trackingId: string;
metric: string;
target: number;
minLevel?: number;
params?: Record<string, string | number | boolean>;
rewardOptions: RewardItem[];
};
const reward = (type: RewardItem["type"], count: number): RewardItem => ({ type, count });
// 每组中的条目为等概率互斥选项,生成任务时选定一个并写入 rewards。
// 沙漏、火箭及其无限时长奖励尚未开放,暂不加入候选;类型定义保留以兼容历史数据。
export const DAILY_REWARD_OPTIONS: Record<string, Record<number, RewardItem[]>> = {
A: {
2: [reward("coin", 100)],
3: [reward("coin", 150)],
4: [reward("infinite_health", 900)],
5: [reward("coin", 200), reward("freeze", 1)],
6: [reward("coin", 300), reward("magic_wand", 1)],
},
B: {
3: [reward("coin", 150)],
4: [reward("freeze", 1)],
5: [reward("magic_wand", 1)],
6: [reward("hammer", 1)],
},
C: {
2: [reward("coin", 150)],
3: [reward("infinite_health", 900)],
4: [reward("coin", 300)],
5: [reward("infinite_health", 1800)],
6: [reward("coin", 500)],
},
D: {
2: [reward("infinite_health", 900)],
3: [reward("coin", 100)],
4: [reward("infinite_health", 900)],
5: [reward("coin", 200)],
6: [reward("coin", 300)],
},
E: { 2: [reward("infinite_health", 900)], 3: [reward("infinite_health", 900)] },
};
export const DAILY_TASK_POOLS: Record<number, Candidate[]> = { 2: [], 3: [], 4: [], 5: [], 6: [] };
function add(suffix: number, metric: string, targets: number[], group: string, params?: Candidate["params"]) {
targets.forEach((target, index) => {
if (!target) return;
const stars = index + 2;
DAILY_TASK_POOLS[stars].push({
taskId: "daily_" + stars + "_" + suffix, trackingId: stars + "-" + suffix, metric, target,
rewardOptions: DAILY_REWARD_OPTIONS[group][stars],
...(params ? { params } : {}),
...(metric === "use_prop" ? { minLevel: 8 } : {}),
});
});
}
add(1, "clear_blocks", [10, 25, 50, 75, 100], "A");
add(2, "clear_color", [1, 3, 6, 10, 15], "A");
add(3, "clear_size", [3, 5, 8, 10, 15], "A", { cellCount: 1 });
add(4, "clear_size", [5, 10, 15, 20, 30], "A", { cellCount: 2 });
add(5, "clear_size", [2, 3, 4, 6, 9], "A", { cellCount: 3 });
add(6, "pass_levels", [1, 3, 4, 6, 8], "A");
add(7, "collect_coin", [40, 120, 160, 240, 320], "A");
add(11, "first_try_pass", [0, 2, 3, 4, 6], "B");
add(12, "win_streak", [0, 0, 2, 3, 5], "B");
add(13, "spend_coin", [0, 0, 500, 600, 1200], "B");
add(16, "use_prop", [1, 2, 3, 4, 5], "C");
add(29, "online_seconds", [300, 600, 1200, 1800, 2700], "D");
add(22, "share", [1, 1, 0, 0, 0], "E");
export const WEEKLY_REWARDS: WeeklyReward[] = [
{ rewardId: "weekly_35", target: 30, state: 0, rewards: [reward("coin", 300), reward("infinite_health", 900), reward("freeze", 1)] },
{ rewardId: "weekly_70", target: 60, state: 0, rewards: [reward("coin", 600), reward("infinite_health", 1800), reward("magic_wand", 1)] },
{ rewardId: "weekly_105", target: 90, state: 0, rewards: [reward("coin", 1000), reward("infinite_health", 2700), reward("hammer", 1)] },
{ rewardId: "weekly_140", target: 120, state: 0, rewards: [reward("coin", 2000), reward("infinite_health", 3600), reward("freeze", 1), reward("magic_wand", 1), reward("hammer", 1)] },
];