UX·FX v1.5 — 햅틱 단계 · 라이브 띠 · HERO 전광판 · Push 우선순위 · Shield · 이클립스 성공·실패 연출

This commit is contained in:
Sn-Kinos
2026-10-06 20:12:44 +09:00
parent a04626b003
commit 62b9637db9
30 changed files with 851 additions and 118 deletions
@@ -4,6 +4,8 @@ class PlanetVisualState {
this.stage,
this.level,
this.isEclipsed = false,
this.eclipseFailed = false,
this.eclipseSuccessId,
this.isHibernating = false,
this.isHeroTime = false,
this.heroEventIds,
@@ -42,6 +44,13 @@ class PlanetVisualState {
final String? planetType;
final int? level;
final bool isEclipsed;
/// 최근 이클립스 회차가 서버 판정 실패로 끝났는가 — v1.5 §5 실패 「밝기·Glow·Particle 감소」.
/// 다음 회차가 열리면(최신 회차가 바뀌면) 풀린다.
final bool eclipseFailed;
/// 서버 판정 성공 회차 ID — 바뀌는 순간 Orbit Burst 한 번(v1.5 §5 성공).
final String? eclipseSuccessId;
final bool isHibernating;
final bool isHeroTime;
+19 -3
View File
@@ -156,6 +156,8 @@ class Repositories {
Stream<PlanetVisualState> _openPlanet(String fandomId) => Stream.multi((out) {
PlanetVisualState? planet;
var isEclipsed = false;
var eclipseFailed = false;
String? eclipseSuccessId;
var isHeroTime = false;
Set<String>? heroEventIds;
Timer? heroExpiry;
@@ -174,6 +176,8 @@ class Repositories {
level: current.level,
evolutionImminent: current.evolutionImminent,
isEclipsed: isEclipsed,
eclipseFailed: eclipseFailed,
eclipseSuccessId: eclipseSuccessId,
isHeroTime: isHeroTime,
heroEventIds: heroEventIds,
heroEndsAt: heroEndsAt,
@@ -191,9 +195,9 @@ class Repositories {
planet = PlanetVisualState.fromDocument(s.data() ?? const {});
emit();
}, onError: out.addError);
final danger = eclipse.watch(fandomId: fandomId).listen((state) {
isEclipsed =
state != null && !state.defended && !state.isExpired(DateTime.now());
// 판정 결과까지 받는다 — 활성 회차만 보면 마감 순간 null 이 되어 성공 · 실패를 가를 수 없다.
final danger = eclipse.watch(fandomId: fandomId, includeResults: true).listen((state) {
(isEclipsed, eclipseFailed, eclipseSuccessId) = eclipseLook(state, DateTime.now());
emit();
}, onError: out.addError);
// 기존 선물 이벤트만 읽는다. 구매 시도/로컬 캐시는 축제 확정이 아니다.
@@ -264,3 +268,15 @@ class Repositories {
// 눌러도 같은 상세가 열린다.
: SamplePlanetRepository(fandomId: fandomId);
}
/// 최근 이클립스 회차 → 행성 표현 (진행 중 감소 · 실패 감소 · 성공 회차 ID).
/// 판정 대기(마감 후 결과 전)는 셋 다 아니다 — 오류를 실패처럼 보이지 않는다(v1.5 §5 집계 오류).
(bool, bool, String?) eclipseLook(EclipseState? state, DateTime now) {
if (state == null) return (false, false, null);
final won = state.defended || state.result == EclipseResult.success;
return (
state.result == null && !won && !state.isExpired(now),
state.result == EclipseResult.failure,
won ? state.eclipseId : null,
);
}