From 4efa49f59b37e8e3b71f5848520ba60749d75700 Mon Sep 17 00:00:00 2001 From: leok18 <178525594+leok18@users.noreply.github.com> Date: Tue, 24 Mar 2026 09:37:20 -0700 Subject: [PATCH 1/4] add stealing to post match and change other stuff --- app/game/post-match.tsx | 61 ++++++++++++++++++++---------- lib/collection/FeederType.ts | 7 ++++ lib/collection/ReportState.ts | 3 ++ lib/collection/RobotRole.ts | 8 ++++ lib/collection/ScoutReport.ts | 9 ++++- lib/collection/StealerType.ts | 28 ++++++++++++++ lib/collection/reportStateStore.ts | 30 +++++++++++++-- 7 files changed, 120 insertions(+), 26 deletions(-) create mode 100644 lib/collection/StealerType.ts diff --git a/app/game/post-match.tsx b/app/game/post-match.tsx index 9d529a8..1360064 100644 --- a/app/game/post-match.tsx +++ b/app/game/post-match.tsx @@ -35,6 +35,7 @@ import React from "react"; import { Checkbox } from "../../lib/components/Checkbox"; import { RobotRole } from "../../lib/collection/RobotRole"; import { MatchEventType } from "../../lib/collection/MatchEventType"; +import { stealerTypeDescriptions } from "../../lib/collection/StealerType"; export default function PostMatch() { const reportState = useReportStateStore(); @@ -59,7 +60,7 @@ export default function PostMatch() { ); const hasEndgameClimbEvent = reportState.hasEndgameClimbEvent(); - + const hasAutoClimbEvent = reportState.hasAutoClimbEvent(); const endgameClimbIsMismatched = hasEndgameClimbEvent && reportState.climbResult === EndgameClimb.NotAttempted; @@ -128,6 +129,19 @@ export default function PostMatch() { multiSelect /> )} + {reportState.robotRole.includes(RobotRole.Stealing) && ( + ({ + label: desc.localizedDescription, + description: desc.localizedLongDescription, + value: desc.stealerType, + }))} + selected={reportState.stealingType} + onChange={reportState.setStealerType} + multiSelect + /> + )} {shouldShowDefenseEffectiveness && ( - ({ - label: desc.localizedDescription, - description: desc.localizedLongDescription, - value: desc.climb, - }))} - selected={reportState.autoClimb} - onChange={reportState.setAutoClimb} - /> + {hasAutoClimbEvent && ( + ({ + label: desc.localizedDescription, + description: desc.localizedLongDescription, + value: desc.climb, + }))} + selected={reportState.autoClimb} + onChange={reportState.setAutoClimb} + /> + )} + {hasEndgameClimbEvent && ( - ({ - label: desc.localizedDescription, - description: desc.localizedLongDescription, - value: desc.scoresWhileMoving, - }))} - selected={reportState.scoresWhileMoving} - onChange={reportState.setScoresWhileMoving} - /> + {reportState.hasEventOfType(MatchEventType.StartScoring) && ( + ({ + label: desc.localizedDescription, + description: desc.localizedLongDescription, + value: desc.scoresWhileMoving, + }))} + selected={reportState.scoresWhileMoving} + onChange={reportState.setScoresWhileMoving} + /> + )} void; setIntakeType: (value: IntakeType) => void; setFeederType: (value: FeederType[]) => void; + setStealerType: (value: StealerType[]) => void; setBeached: (value: Beached) => void; setDefenseEffectiveness: (value: DefenseEffectiveness) => void; setScoresWhileMoving: (value: ScoresWhileMoving) => void; diff --git a/lib/collection/RobotRole.ts b/lib/collection/RobotRole.ts index f401675..50af709 100644 --- a/lib/collection/RobotRole.ts +++ b/lib/collection/RobotRole.ts @@ -4,6 +4,7 @@ export enum RobotRole { Feeding, Defending, Immobile, + Stealing, } export type RobotRoleDescription = { @@ -49,4 +50,11 @@ export const robotRoleDescriptions = [ "The robot was immobile or non-functional during the match.", num: 4, }, + { + role: RobotRole.Stealing, + localizedDescription: "Stealing", + localizedLongDescription: + "The robot focuses on stealing fuel from the opposing alliance.", + num: 5, + }, ] as const satisfies RobotRoleDescription[]; diff --git a/lib/collection/ScoutReport.ts b/lib/collection/ScoutReport.ts index 66bd774..108132a 100644 --- a/lib/collection/ScoutReport.ts +++ b/lib/collection/ScoutReport.ts @@ -28,7 +28,13 @@ export const IntakeTypeString = z.enum([ "BOTH", "NEITHER", ]); -export const FeederTypeString = z.enum(["CONTINUOUS", "STOP_TO_SHOOT", "DUMP"]); +export const FeederTypeString = z.enum([ + "CONTINUOUS", + "STOP_TO_SHOOT", + "DUMP", + "PUSH", +]); +export const StealerTypeString = z.enum(["TO_ALLIANCE", "TO_NEUTRAL"]); export const BeachedString = z.enum(["ON_FUEL", "ON_BUMP", "BOTH", "NEITHER"]); export const EndgameClimbString = z.enum([ "NOT_ATTEMPTED", @@ -55,6 +61,7 @@ export const scoutReportSchema = z.object({ autoClimb: AutoClimbString, intakeType: IntakeTypeString, feederTypes: z.array(FeederTypeString), + stealerType: z.array(StealerTypeString), beached: BeachedString, defenseEffectiveness: z.number(), scoresWhileMoving: z.boolean(), diff --git a/lib/collection/StealerType.ts b/lib/collection/StealerType.ts new file mode 100644 index 0000000..edbe6bc --- /dev/null +++ b/lib/collection/StealerType.ts @@ -0,0 +1,28 @@ +export enum StealerType { + toAlliance, + toNeutral, +} + +export type StealerTypeDescription = { + stealerType: StealerType; + localizedDescription: string; + localizedLongDescription: string; + num: number; +}; + +export const stealerTypeDescriptions = [ + { + stealerType: StealerType.toAlliance, + localizedDescription: "To Alliance", + localizedLongDescription: + "The robot steals fuel and brings it to the alliance zone.", + num: 0, + }, + { + stealerType: StealerType.toNeutral, + localizedDescription: "To Neutral", + localizedLongDescription: + "The robot steals fuel and brings it to the neutral zone.", + num: 1, + }, +] as const satisfies StealerTypeDescription[]; diff --git a/lib/collection/reportStateStore.ts b/lib/collection/reportStateStore.ts index 6a66cee..b597a10 100644 --- a/lib/collection/reportStateStore.ts +++ b/lib/collection/reportStateStore.ts @@ -21,6 +21,7 @@ import { ScoresWhileMoving } from "./ScoresWhileMoving"; import { EndgameClimb } from "./EndgameClimb"; import { MatchEventType } from "./MatchEventType"; import Constants from "expo-constants"; +import { StealerType } from "./StealerType"; const initialState = { events: [], @@ -39,6 +40,7 @@ const initialState = { climbResult: EndgameClimb.NotAttempted, driverAbility: DriverAbility.Average, notes: "", + stealingType: [] as StealerType[], }; export const useReportStateStore = create((set, get) => ({ @@ -75,6 +77,7 @@ export const useReportStateStore = create((set, get) => ({ setClimbResult: (value) => set({ climbResult: value }), setDriverAbility: (value) => set({ driverAbility: value }), setNotes: (value) => set({ notes: value }), + setStealerType: (value) => set({ notes: value }), hasEventOfType: (...types: MatchEventType[]) => { const reportState = get(); @@ -220,7 +223,8 @@ export const useReportStateStore = create((set, get) => ({ // Map RobotRole enum to string const robotRoleToString = ( role: RobotRole, - ): "CYCLING" | "SCORING" | "FEEDING" | "DEFENDING" | "IMMOBILE" => { + ): "CYCLING" | "SCORING" | "FEEDING" | "DEFENDING" | "IMMOBILE" + | "STEALING" => { switch (role) { case RobotRole.Cycling: return "CYCLING"; @@ -231,7 +235,10 @@ export const useReportStateStore = create((set, get) => ({ case RobotRole.Defending: return "DEFENDING"; case RobotRole.Immobile: + default: return "IMMOBILE"; + case RobotRole.Stealing: + return "STEALING"; } }; @@ -284,14 +291,28 @@ export const useReportStateStore = create((set, get) => ({ // Map FeederType enum to string const feederTypeToString = ( feederType: FeederType, - ): "CONTINUOUS" | "STOP_TO_SHOOT" | "DUMP" => { + ): "CONTINUOUS" | "STOP_TO_SHOOT" | "PUSH" => { switch (feederType) { case FeederType.Continuous: return "CONTINUOUS"; case FeederType.StopToShoot: return "STOP_TO_SHOOT"; - case FeederType.Dump: - return "DUMP"; + case FeederType.Push: + return "PUSH"; + default: + return "PUSH"; + } + }; + + const stealerTypeToString = ( + stealerType: StealerType, + ): "TO_ALLIANCE" | "TO_NEUTRAL" => { + switch (stealerType) { + case StealerType.toAlliance: + return "TO_ALLIANCE"; + case StealerType.toNeutral: + return "TO_NEUTRAL"; + } }; @@ -367,6 +388,7 @@ export const useReportStateStore = create((set, get) => ({ scoresWhileMoving: reportState.scoresWhileMoving === ScoresWhileMoving.Yes, endgameClimb: endgameClimbToString(reportState.climbResult), + stealerTypes: reportState.stealerType.map() driverAbility: driverAbilityDescriptions.find( (desc) => desc.ability === reportState.driverAbility, )!.numericalRating, From a10d19807dc1d80c216b093dd5353fd86627c9b8 Mon Sep 17 00:00:00 2001 From: leok18 <178525594+leok18@users.noreply.github.com> Date: Fri, 27 Mar 2026 06:49:17 -0700 Subject: [PATCH 2/4] fix error --- lib/collection/ScoutReport.ts | 3 ++- lib/collection/reportStateStore.ts | 16 ++++++++++------ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/lib/collection/ScoutReport.ts b/lib/collection/ScoutReport.ts index 108132a..0a46ec1 100644 --- a/lib/collection/ScoutReport.ts +++ b/lib/collection/ScoutReport.ts @@ -20,6 +20,7 @@ export const RobotRoleString = z.enum([ "FEEDING", "DEFENDING", "IMMOBILE", + "STEALING", ]); export const AutoClimbString = z.enum(["NOT_ATTEMPTED", "FAILED", "SUCCEEDED"]); export const IntakeTypeString = z.enum([ @@ -63,7 +64,7 @@ export const scoutReportSchema = z.object({ feederTypes: z.array(FeederTypeString), stealerType: z.array(StealerTypeString), beached: BeachedString, - defenseEffectiveness: z.number(), + defenseEffectiveness: z.number().or(z.null()), scoresWhileMoving: z.boolean(), endgameClimb: EndgameClimbString, driverAbility: z.number(), diff --git a/lib/collection/reportStateStore.ts b/lib/collection/reportStateStore.ts index b597a10..1713a03 100644 --- a/lib/collection/reportStateStore.ts +++ b/lib/collection/reportStateStore.ts @@ -77,7 +77,7 @@ export const useReportStateStore = create((set, get) => ({ setClimbResult: (value) => set({ climbResult: value }), setDriverAbility: (value) => set({ driverAbility: value }), setNotes: (value) => set({ notes: value }), - setStealerType: (value) => set({ notes: value }), + setStealerType: (value) => set({ stealingType: value }), hasEventOfType: (...types: MatchEventType[]) => { const reportState = get(); @@ -223,8 +223,13 @@ export const useReportStateStore = create((set, get) => ({ // Map RobotRole enum to string const robotRoleToString = ( role: RobotRole, - ): "CYCLING" | "SCORING" | "FEEDING" | "DEFENDING" | "IMMOBILE" - | "STEALING" => { + ): + | "CYCLING" + | "SCORING" + | "FEEDING" + | "DEFENDING" + | "IMMOBILE" + | "STEALING" => { switch (role) { case RobotRole.Cycling: return "CYCLING"; @@ -306,13 +311,12 @@ export const useReportStateStore = create((set, get) => ({ const stealerTypeToString = ( stealerType: StealerType, - ): "TO_ALLIANCE" | "TO_NEUTRAL" => { + ): "TO_ALLIANCE" | "TO_NEUTRAL" => { switch (stealerType) { case StealerType.toAlliance: return "TO_ALLIANCE"; case StealerType.toNeutral: return "TO_NEUTRAL"; - } }; @@ -388,7 +392,7 @@ export const useReportStateStore = create((set, get) => ({ scoresWhileMoving: reportState.scoresWhileMoving === ScoresWhileMoving.Yes, endgameClimb: endgameClimbToString(reportState.climbResult), - stealerTypes: reportState.stealerType.map() + stealerType: reportState.stealingType.map(stealerTypeToString), driverAbility: driverAbilityDescriptions.find( (desc) => desc.ability === reportState.driverAbility, )!.numericalRating, From 93d39e32795cbffc4e43d314f1bf2adc66ad4875 Mon Sep 17 00:00:00 2001 From: leok18 <178525594+leok18@users.noreply.github.com> Date: Fri, 27 Mar 2026 07:01:46 -0700 Subject: [PATCH 3/4] adjust language --- app/game/post-match.tsx | 8 ++++---- app/settings/qrcode-size.tsx | 1 + lib/collection/ReportState.ts | 6 +++--- lib/collection/RobotRole.ts | 2 +- lib/collection/ScoutReport.ts | 4 ++-- lib/collection/StealerType.ts | 28 ---------------------------- lib/collection/StealingType.ts | 28 ++++++++++++++++++++++++++++ lib/collection/reportStateStore.ts | 18 +++++++++--------- 8 files changed, 48 insertions(+), 47 deletions(-) delete mode 100644 lib/collection/StealerType.ts create mode 100644 lib/collection/StealingType.ts diff --git a/app/game/post-match.tsx b/app/game/post-match.tsx index 1360064..746dae0 100644 --- a/app/game/post-match.tsx +++ b/app/game/post-match.tsx @@ -35,7 +35,7 @@ import React from "react"; import { Checkbox } from "../../lib/components/Checkbox"; import { RobotRole } from "../../lib/collection/RobotRole"; import { MatchEventType } from "../../lib/collection/MatchEventType"; -import { stealerTypeDescriptions } from "../../lib/collection/StealerType"; +import { stealingTypeDescriptions } from "../../lib/collection/StealingType"; export default function PostMatch() { const reportState = useReportStateStore(); @@ -132,13 +132,13 @@ export default function PostMatch() { {reportState.robotRole.includes(RobotRole.Stealing) && ( ({ + items={stealingTypeDescriptions.map((desc) => ({ label: desc.localizedDescription, description: desc.localizedLongDescription, - value: desc.stealerType, + value: desc.stealingType, }))} selected={reportState.stealingType} - onChange={reportState.setStealerType} + onChange={reportState.setStealingType} multiSelect /> )} diff --git a/app/settings/qrcode-size.tsx b/app/settings/qrcode-size.tsx index d433d21..e87a0cf 100644 --- a/app/settings/qrcode-size.tsx +++ b/app/settings/qrcode-size.tsx @@ -29,6 +29,7 @@ const EXAMPLE_SCOUT_REPORT: ScoutReport = { autoClimb: "FAILED", intakeType: "GROUND", feederTypes: ["STOP_TO_SHOOT"], + stealingType: ["TO_ALLIANCE", "TO_NEUTRAL"], beached: "ON_FUEL", defenseEffectiveness: 4, scoresWhileMoving: true, diff --git a/lib/collection/ReportState.ts b/lib/collection/ReportState.ts index a180176..d8dc572 100644 --- a/lib/collection/ReportState.ts +++ b/lib/collection/ReportState.ts @@ -14,7 +14,7 @@ import { Beached } from "./Beached"; import { DefenseEffectiveness } from "./DefenseEffectiveness"; import { ScoresWhileMoving } from "./ScoresWhileMoving"; import { EndgameClimb } from "./EndgameClimb"; -import { StealerType } from "./StealerType"; +import { StealingType } from "./StealingType"; export enum GamePhase { Auto, @@ -46,7 +46,7 @@ export type ReportState = { scoresWhileMoving: ScoresWhileMoving; climbResult: EndgameClimb; driverAbility: DriverAbility; - stealingType: StealerType[]; + stealingType: StealingType[]; notes: string; // Actions @@ -63,7 +63,7 @@ export type ReportState = { setAutoClimb: (value: AutoClimb) => void; setIntakeType: (value: IntakeType) => void; setFeederType: (value: FeederType[]) => void; - setStealerType: (value: StealerType[]) => void; + setStealingType: (value: StealingType[]) => void; setBeached: (value: Beached) => void; setDefenseEffectiveness: (value: DefenseEffectiveness) => void; setScoresWhileMoving: (value: ScoresWhileMoving) => void; diff --git a/lib/collection/RobotRole.ts b/lib/collection/RobotRole.ts index 50af709..de2e4c6 100644 --- a/lib/collection/RobotRole.ts +++ b/lib/collection/RobotRole.ts @@ -54,7 +54,7 @@ export const robotRoleDescriptions = [ role: RobotRole.Stealing, localizedDescription: "Stealing", localizedLongDescription: - "The robot focuses on stealing fuel from the opposing alliance.", + "The robot steals fuel from the opposing alliance.", num: 5, }, ] as const satisfies RobotRoleDescription[]; diff --git a/lib/collection/ScoutReport.ts b/lib/collection/ScoutReport.ts index 0a46ec1..13e3264 100644 --- a/lib/collection/ScoutReport.ts +++ b/lib/collection/ScoutReport.ts @@ -35,7 +35,7 @@ export const FeederTypeString = z.enum([ "DUMP", "PUSH", ]); -export const StealerTypeString = z.enum(["TO_ALLIANCE", "TO_NEUTRAL"]); +export const StealingTypeString = z.enum(["TO_ALLIANCE", "TO_NEUTRAL"]); export const BeachedString = z.enum(["ON_FUEL", "ON_BUMP", "BOTH", "NEITHER"]); export const EndgameClimbString = z.enum([ "NOT_ATTEMPTED", @@ -62,7 +62,7 @@ export const scoutReportSchema = z.object({ autoClimb: AutoClimbString, intakeType: IntakeTypeString, feederTypes: z.array(FeederTypeString), - stealerType: z.array(StealerTypeString), + stealingType: z.array(StealingTypeString), beached: BeachedString, defenseEffectiveness: z.number().or(z.null()), scoresWhileMoving: z.boolean(), diff --git a/lib/collection/StealerType.ts b/lib/collection/StealerType.ts deleted file mode 100644 index edbe6bc..0000000 --- a/lib/collection/StealerType.ts +++ /dev/null @@ -1,28 +0,0 @@ -export enum StealerType { - toAlliance, - toNeutral, -} - -export type StealerTypeDescription = { - stealerType: StealerType; - localizedDescription: string; - localizedLongDescription: string; - num: number; -}; - -export const stealerTypeDescriptions = [ - { - stealerType: StealerType.toAlliance, - localizedDescription: "To Alliance", - localizedLongDescription: - "The robot steals fuel and brings it to the alliance zone.", - num: 0, - }, - { - stealerType: StealerType.toNeutral, - localizedDescription: "To Neutral", - localizedLongDescription: - "The robot steals fuel and brings it to the neutral zone.", - num: 1, - }, -] as const satisfies StealerTypeDescription[]; diff --git a/lib/collection/StealingType.ts b/lib/collection/StealingType.ts new file mode 100644 index 0000000..1e5ff0c --- /dev/null +++ b/lib/collection/StealingType.ts @@ -0,0 +1,28 @@ +export enum StealingType { + toAlliance, + toNeutral, +} + +export type StealingTypeDescription = { + stealingType: StealingType; + localizedDescription: string; + localizedLongDescription: string; + num: number; +}; + +export const stealingTypeDescriptions = [ + { + stealingType: StealingType.toAlliance, + localizedDescription: "To Alliance", + localizedLongDescription: + "The robot moves fuel from the opposing alliance zone to its alliance zone.", + num: 0, + }, + { + stealingType: StealingType.toNeutral, + localizedDescription: "To Neutral", + localizedLongDescription: + "The robot moves fuel from the opposing alliance zone to the neutral zone..", + num: 1, + }, +] as const satisfies StealingTypeDescription[]; diff --git a/lib/collection/reportStateStore.ts b/lib/collection/reportStateStore.ts index 1713a03..e2bf07b 100644 --- a/lib/collection/reportStateStore.ts +++ b/lib/collection/reportStateStore.ts @@ -21,7 +21,7 @@ import { ScoresWhileMoving } from "./ScoresWhileMoving"; import { EndgameClimb } from "./EndgameClimb"; import { MatchEventType } from "./MatchEventType"; import Constants from "expo-constants"; -import { StealerType } from "./StealerType"; +import { StealingType } from "./StealingType"; const initialState = { events: [], @@ -40,7 +40,7 @@ const initialState = { climbResult: EndgameClimb.NotAttempted, driverAbility: DriverAbility.Average, notes: "", - stealingType: [] as StealerType[], + stealingType: [] as StealingType[], }; export const useReportStateStore = create((set, get) => ({ @@ -77,7 +77,7 @@ export const useReportStateStore = create((set, get) => ({ setClimbResult: (value) => set({ climbResult: value }), setDriverAbility: (value) => set({ driverAbility: value }), setNotes: (value) => set({ notes: value }), - setStealerType: (value) => set({ stealingType: value }), + setStealingType: (value) => set({ stealingType: value }), hasEventOfType: (...types: MatchEventType[]) => { const reportState = get(); @@ -309,13 +309,13 @@ export const useReportStateStore = create((set, get) => ({ } }; - const stealerTypeToString = ( - stealerType: StealerType, + const stealingTypeToString = ( + stealingType: StealingType, ): "TO_ALLIANCE" | "TO_NEUTRAL" => { - switch (stealerType) { - case StealerType.toAlliance: + switch (stealingType) { + case StealingType.toAlliance: return "TO_ALLIANCE"; - case StealerType.toNeutral: + case StealingType.toNeutral: return "TO_NEUTRAL"; } }; @@ -392,7 +392,7 @@ export const useReportStateStore = create((set, get) => ({ scoresWhileMoving: reportState.scoresWhileMoving === ScoresWhileMoving.Yes, endgameClimb: endgameClimbToString(reportState.climbResult), - stealerType: reportState.stealingType.map(stealerTypeToString), + stealingType: reportState.stealingType.map(stealingTypeToString), driverAbility: driverAbilityDescriptions.find( (desc) => desc.ability === reportState.driverAbility, )!.numericalRating, From 9b078498bde75ba0338beaf2c6402e96f7f196ab Mon Sep 17 00:00:00 2001 From: MangoSwirl Date: Sat, 28 Mar 2026 12:25:15 -0700 Subject: [PATCH 4/4] Remove extra period --- lib/collection/StealingType.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/collection/StealingType.ts b/lib/collection/StealingType.ts index 1e5ff0c..b968a2e 100644 --- a/lib/collection/StealingType.ts +++ b/lib/collection/StealingType.ts @@ -22,7 +22,7 @@ export const stealingTypeDescriptions = [ stealingType: StealingType.toNeutral, localizedDescription: "To Neutral", localizedLongDescription: - "The robot moves fuel from the opposing alliance zone to the neutral zone..", + "The robot moves fuel from the opposing alliance zone to the neutral zone.", num: 1, }, ] as const satisfies StealingTypeDescription[];