diff --git a/slp/techTest.slp b/slp/techTest.slp new file mode 100644 index 00000000..3af4903c Binary files /dev/null and b/slp/techTest.slp differ diff --git a/src/stats/actions.ts b/src/stats/actions.ts index 3d0b9c01..93f88b65 100644 --- a/src/stats/actions.ts +++ b/src/stats/actions.ts @@ -43,6 +43,16 @@ export class ActionsComputer implements StatComputer { back: 0, down: 0, }, + groundTechCount: { + backward: 0, + forward: 0, + neutral: 0, + fail: 0, + }, + wallTechCount: { + success: 0, + fail: 0, + }, }; const playerState: PlayerActionState = { playerCounts: playerCounts, @@ -66,6 +76,10 @@ export class ActionsComputer implements StatComputer { } } +function didMissGroundTech(animation: State): boolean { + return animation === State.TECH_MISS_DOWN || animation === State.TECH_MISS_UP; +} + function isRolling(animation: State): boolean { return animation === State.ROLL_BACKWARD || animation === State.ROLL_FORWARD; } @@ -166,6 +180,17 @@ function handleActionCompute(state: PlayerActionState, indices: PlayerIndexedTyp incrementCount("throwCount.down", currentAnimation === State.THROW_DOWN && newAnimation); incrementCount("throwCount.back", currentAnimation === State.THROW_BACK && newAnimation); + if (newAnimation) { + const didMissTech = didMissGroundTech(currentAnimation); + incrementCount("groundTechCount.fail", didMissTech); + incrementCount("groundTechCount.forward", currentAnimation === State.FORWARD_TECH); + incrementCount("groundTechCount.neutral", currentAnimation === State.NEUTRAL_TECH); + incrementCount("groundTechCount.backward", currentAnimation === State.BACKWARD_TECH); + + incrementCount("wallTechCount.success", currentAnimation === State.WALL_TECH); + incrementCount("wallTechCount.fail", currentAnimation === State.MISSED_WALL_TECH); + } + if (isAerialAttack(currentAnimation)) { incrementCount("lCancelCount.success", playerFrame.lCancelStatus === 1); incrementCount("lCancelCount.fail", playerFrame.lCancelStatus === 2); diff --git a/src/stats/common.ts b/src/stats/common.ts index d18aaf17..5687d468 100644 --- a/src/stats/common.ts +++ b/src/stats/common.ts @@ -83,6 +83,16 @@ export interface ActionCountsType { back: number; down: number; }; + groundTechCount: { + backward: number; + forward: number; + neutral: number; + fail: number; + }; + wallTechCount: { + success: number; + fail: number; + }; } export interface InputCountsType { @@ -145,6 +155,11 @@ export enum State { GUARD_ON = 0xb2, TECH_MISS_UP = 0xb7, TECH_MISS_DOWN = 0xbf, + NEUTRAL_TECH = 0xc7, + FORWARD_TECH = 0xc8, + BACKWARD_TECH = 0xc9, + WALL_TECH = 0xca, + MISSED_WALL_TECH = 0xf7, DASH = 0x14, TURN = 0x12, LANDING_FALL_SPECIAL = 0x2b, diff --git a/test/stats.spec.ts b/test/stats.spec.ts index 2bd92951..4bda0f5b 100644 --- a/test/stats.spec.ts +++ b/test/stats.spec.ts @@ -131,6 +131,13 @@ describe("when calculating stats", () => { expect(fox.conversionCount).toBe(2); }); }); + + it("should count techs only a single time", () => { + const game = new SlippiGame("slp/techTest.slp"); + const stats = game.getStats(); + expect(stats?.actionCounts[1].groundTechCount).toEqual({ backward: 2, forward: 1, neutral: 8, fail: 4 }); + expect(stats?.actionCounts[1].wallTechCount).toEqual({ success: 0, fail: 0 }); + }); }); describe("when calculating stock information", () => {