diff --git a/CHANGELOG.md b/CHANGELOG.md index 7eb22a8..e0dcbc9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.3 + +feat: add eggstra work mode + ## 0.3.2 feat: update `WEB_VIEW_VERSION` and query hashes diff --git a/gui/src-tauri/tauri.conf.json b/gui/src-tauri/tauri.conf.json index 89f9049..dfc7c73 100644 --- a/gui/src-tauri/tauri.conf.json +++ b/gui/src-tauri/tauri.conf.json @@ -8,7 +8,7 @@ }, "package": { "productName": "s3si-ts", - "version": "0.2.1" + "version": "0.3.3" }, "tauri": { "allowlist": { diff --git a/src/constant.ts b/src/constant.ts index 4e24f4d..ba7b64d 100644 --- a/src/constant.ts +++ b/src/constant.ts @@ -2,7 +2,7 @@ import type { StatInkPostBody, VsHistoryDetail } from "./types.ts"; export const AGENT_NAME = "splashcat / s3si.ts"; export const AGENT_VERSION = "1.1.1"; -export const S3SI_VERSION = "0.3.2"; +export const S3SI_VERSION = "0.3.3"; export const COMBINED_VERSION = `${AGENT_VERSION}/${S3SI_VERSION}`; export const NSOAPP_VERSION = "2.5.0"; export const WEB_VIEW_VERSION = "3.0.0-0742bda0"; diff --git a/src/exporters/stat.ink.ts b/src/exporters/stat.ink.ts index 834cfa5..3f0d5bb 100644 --- a/src/exporters/stat.ink.ts +++ b/src/exporters/stat.ink.ts @@ -724,6 +724,8 @@ export class StatInkExporter implements GameExporter { golden_appearances: wave.goldenPopCount, golden_delivered: wave.teamDeliverCount, special_uses, + // fill it later + danger_rate: null, }; } async mapCoop( @@ -767,10 +769,13 @@ export class StatInkExporter implements GameExporter { : undefined; const title_exp_after = detail.afterGradePoint; + const maxWaves = detail.rule === "TEAM_CONTEST" ? 5 : 3; let clear_waves: number; if (waveResults.length > 0) { // when cleared, resultWave === 0, so we need to add 1. - clear_waves = waveResults.filter((i) => i.waveNumber < 4).length - + clear_waves = waveResults.filter((i) => + i.waveNumber < maxWaves + 1 + ).length - 1 + (resultWave === 0 ? 1 : 0); } else { clear_waves = 0; @@ -811,7 +816,7 @@ export class StatInkExporter implements GameExporter { let fail_reason: StatInkCoopPostBody["fail_reason"] = null; // failed - if (clear_waves !== 3 && waveResults.length > 0) { + if (clear_waves !== maxWaves && waveResults.length > 0) { const lastWave = waveResults[waveResults.length - 1]; if (lastWave.teamDeliverCount >= lastWave.deliverNorm) { fail_reason = "wipe_out"; @@ -822,8 +827,9 @@ export class StatInkExporter implements GameExporter { uuid: await gameId(detail.id), private: groupInfo?.mode === "PRIVATE_CUSTOM" ? "yes" : "no", big_run: detail.rule === "BIG_RUN" ? "yes" : "no", + eggstra_work: detail.rule === "TEAM_CONTEST" ? "yes" : "no", stage: b64Number(detail.coopStage.id).toString(), - danger_rate: dangerRate * 100, + danger_rate: detail.rule === "TEAM_CONTEST" ? null : dangerRate * 100, clear_waves, fail_reason, king_smell: smellMeter, @@ -856,6 +862,57 @@ export class StatInkExporter implements GameExporter { automated: "yes", start_at: startedAt, }; + // caculate wave danger_rate. + // translated from here: https://github.com/frozenpandaman/s3s/commit/d46ece00e5a7706688eaf025f18c5a8ea1c54c0f#diff-819571ec7b067d2398cd1f9dbc737160312efc4128ba4a2f0e165c70225dea0eR1050 + if (detail.rule === "TEAM_CONTEST") { + let lastWave: StatInkCoopWave | undefined; + for ( + const [wave] of result.waves + .map((p, i) => [p, i] as const) + ) { + let haz_level: number; + if (!lastWave) { + haz_level = 60; + } else { + const num_players = result.players.length; + const quota = lastWave.golden_quota; // last wave, most recent one added to the list + const delivered = lastWave.golden_delivered; + let added_percent = 0; // default, no increase if less than 1.5x quota delivered + if (num_players == 4) { + if (delivered >= quota * 2) { + added_percent = 60; + } else if (delivered >= quota * 1.5) { + added_percent = 30; + } + } else if (num_players == 3) { + if (delivered >= quota * 2) { + added_percent = 40; + } else if (delivered >= quota * 1.5) { + added_percent = 20; + } + } else if (num_players == 2) { + if (delivered >= quota * 2) { + added_percent = 20; + } else if (delivered >= quota * 1.5) { + added_percent = 10; + added_percent = 5; + } + } else if (num_players == 1) { + if (delivered >= quota * 2) { + added_percent = 10; + } else if (delivered >= quota * 1.5) { + added_percent = 5; + } + } + + const prev_percent = lastWave.danger_rate!; + + haz_level = prev_percent + added_percent; + } + wave.danger_rate = haz_level; + lastWave = wave; + } + } return result; } } diff --git a/src/types.ts b/src/types.ts index 62ac8ac..6ab874c 100644 --- a/src/types.ts +++ b/src/types.ts @@ -290,7 +290,7 @@ export type CoopHistoryDetail = { name: string; id: string; }; - rule: "REGULAR" | "BIG_RUN"; + rule: "REGULAR" | "BIG_RUN" | "TEAM_CONTEST"; myResult: CoopHistoryPlayerResult; memberResults: CoopHistoryPlayerResult[]; bossResult: null | { @@ -681,6 +681,8 @@ export type StatInkCoopWave = { golden_delivered: number; golden_appearances: number; special_uses?: Record; + // [0, 333] + danger_rate: number | null; }; export type StatInkCoopPlayer = { @@ -719,9 +721,10 @@ export type StatInkCoopPostBody = { uuid: string; private: "yes" | "no"; big_run: "yes" | "no"; + eggstra_work: "yes" | "no"; stage: string; // [0, 333] - danger_rate: number; + danger_rate: number | null; // [0, 3] clear_waves: number; fail_reason?: null | "wipe_out" | "time_limit";