diff --git a/.bauke/Deno.md b/.bauke/Deno.md index 3f3bc7a..01d6cbc 100644 --- a/.bauke/Deno.md +++ b/.bauke/Deno.md @@ -5,6 +5,7 @@ - [`codium-extensions`]: save and install VS Codium extensions using their identifier. - [`copy-nixos-config`]: copies NixOS configuration from `$BAUKE_DIR/nix//` to `/etc/nixos/`. - [`desktop-wallpaper`]: desktop wallpaper changer. +- [`drg-data-entry`]: Deep Rock Galactic data tracker. - [`edit-youtube-video`]: edit a YouTube video via the Data API. - [`project-avatar`]: image generator for projects. - [`simple-git-push`]: `git push` with extra semantics. @@ -13,6 +14,7 @@ [`codium-extensions`]: ./scripts/codium-extensions.ts [`copy-nixos-config`]: ./scripts/copy-nixos-config.ts [`desktop-wallpaper`]: ./scripts/desktop-wallpaper.ts +[`drg-data-entry`]: ./scripts/drg-data-entry.ts [`edit-youtube-video`]: ./scripts/edit-youtube-video.ts [`project-avatar`]: ./scripts/project-avatar.ts [`simple-git-push`]: ./scripts/simple-git-push.ts diff --git a/.bauke/bin/drg-data-entry b/.bauke/bin/drg-data-entry new file mode 100755 index 0000000..1f05493 --- /dev/null +++ b/.bauke/bin/drg-data-entry @@ -0,0 +1,9 @@ +#!/usr/bin/env zsh + +data_file="$BAUKE_DIR/data/drg-data.json" + +deno run \ + --allow-read="$data_file" \ + --allow-write="$data_file" \ + "$BAUKE_DIR/scripts/drg-data-entry.ts" \ + "$@" diff --git a/.bauke/data/drg-data.json b/.bauke/data/drg-data.json new file mode 100644 index 0000000..fe51488 --- /dev/null +++ b/.bauke/data/drg-data.json @@ -0,0 +1 @@ +[] diff --git a/.bauke/scripts/drg-data-entry.ts b/.bauke/scripts/drg-data-entry.ts new file mode 100644 index 0000000..f6957c0 --- /dev/null +++ b/.bauke/scripts/drg-data-entry.ts @@ -0,0 +1,215 @@ +import { Command } from "https://deno.land/x/cliffy@v0.25.5/command/mod.ts"; +import * as prompt from "https://deno.land/x/cliffy@v0.25.5/prompt/mod.ts"; + +const CaveComplexity = [1, 2, 3] as const; +const CaveLength = [1, 2, 3] as const; +const HazardLevel = [1, 2, 3, 4, 5] as const; + +const MissionTypes = [ + "Egg Hunt", + "Elimination", + "Escort Duty", + "Industrial Sabotage", + "Mining Expedition", + "On-site Refining", + "Point Extraction", + "Salvage Operation", +] as const; + +const Minerals = [ + "Barley Bulb", + "Bismor", + "Croppa", + "Enor Pearl", + "Jadiz", + "Magnite", + "Malt Star", + "Phazyonite", + "Plagueheart", + "Starch Nut", + "Umanite", + "Yeast Cone", +] as const; + +type Mission = { + "Date": string; + "Index": number; + + "Class Level": number; + "Profile Rank": number; + "Solo": boolean; + + "Cave Complexity": typeof CaveComplexity[number]; + "Cave Length": typeof CaveLength[number]; + "Duration": number; + "Hazard Level": typeof HazardLevel[number]; + "Mission Status": "Completed" | "Failed"; + "Mission Type": typeof MissionTypes[number]; + + "Credits": number; + "Experience": number; + "Items Collected": Record; + + "Credit Breakdown": { + "Primary Objective": number; + "Secondary Objective": number; + "Survival Bonus": number; + "Gold Mined": number; + + "Bittergem"?: number; + "Ebonite Mutation"?: number; + "Kursite Infection"?: number; + "OMEN Modular Exterminator"?: number; + "Tritilyte Shard"?: number; + "Tyrant Shard"?: number; + }; + + "Experience Breakdown": { + "Primary Objective": number; + "Secondary Objective": number; + "Minerals Mined": number; + "Hostiles Killed": number; + + "Double XP"?: number; + "Ebonite Mutation"?: number; + "Kursite Infection"?: number; + "OMEN Modular Exterminator"?: number; + "Plagueheart"?: number; + "Tritilyte Shard"?: number; + "Tyrant Shard"?: number; + }; +}; + +async function main(): Promise { + const { options } = await new Command() + .name("drg-data-entry") + .description("Deep Rock Galactic data tracker") + .option("--data-file ", "The JSON file to store data in.", { + default: new URL("../data/drg-data.json", import.meta.url).pathname, + }) + .option("--add", "Add a new mission.") + .option("--testing", "Don't write anything to file.") + .parse(Deno.args); + + const dataMissions: Mission[] = JSON.parse( + await Deno.readTextFile(options.dataFile), + ); + dataMissions.sort((a, b) => b.Index - a.Index); + + if (options.add) { + const promptResults = await prompt.prompt( + [ + { + type: prompt.Input, + name: "Date", + message: "Date", + default: new Date().toISOString().slice(0, 10), + }, + { + type: prompt.Number, + name: "Class Level", + message: "Class Level", + }, + { + type: prompt.Number, + name: "Profile Rank", + message: "Profile Rank", + }, + { + type: prompt.Confirm, + name: "Solo", + message: "Solo", + default: true, + }, + { + type: prompt.Select, + name: "Cave Complexity", + message: "Cave Complexity", + options: CaveComplexity.map((value) => ({ + name: `Complexity ${value}`, + value: value.toString(), + })), + }, + { + type: prompt.Select, + name: "Cave Length", + message: "Cave Length", + options: CaveLength.map((value) => ({ + name: `Length ${value}`, + value: value.toString(), + })), + }, + { + type: prompt.Number, + name: "Duration", + message: "Duration", + }, + { + type: prompt.Select, + name: "Hazard Level", + message: "Hazard Level", + options: HazardLevel.map((value) => ({ + name: `Hazard ${value}`, + value: value.toString(), + })), + }, + { + type: prompt.Select, + name: "Mission Status", + message: "Mission Status", + options: ["Completed", "Failed"].map((value) => ({ + name: value, + value, + })), + }, + { + type: prompt.Select, + name: "Mission Type", + message: "Mission Type", + options: MissionTypes.map((value) => ({ + name: value, + value, + })), + }, + ], + ); + + const newMission: Mission = { + "Date": promptResults["Date"]!, + "Index": (dataMissions[0]?.Index ?? 0) + 1, + + "Class Level": promptResults["Class Level"]!, + "Profile Rank": promptResults["Profile Rank"]!, + "Solo": promptResults["Solo"]!, + + "Cave Complexity": Number( + promptResults["Cave Complexity"], + ) as Mission["Cave Complexity"], + "Cave Length": Number( + promptResults["Cave Length"], + ) as Mission["Cave Length"], + "Duration": promptResults["Duration"]!, + "Hazard Level": Number( + promptResults["Hazard Level"], + ) as Mission["Hazard Level"], + "Mission Status": + promptResults["Mission Status"] as Mission["Mission Status"], + "Mission Type": promptResults["Mission Type"] as Mission["Mission Type"], + }; + + if (options.testing) { + console.log(newMission); + return; + } + + dataMissions.push(newMission); + await Deno.writeTextFile( + options.dataFile, + JSON.stringify(dataMissions, null, 2) + "\n", + ); + } +} + +if (import.meta.main) { + void main(); +}