diff --git a/CLAUDE.md b/CLAUDE.md index d968e57..e16eab9 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -150,7 +150,10 @@ and `extractNames..` under no strings — adding a language is a locale-only change. `factions` is an array because one physical exit can serve multiple sides -(PMC + Scav share the same door). At render time the client **merges +(PMC + Scav share the same door). `transit` is a fourth pseudo-faction for +map-to-map transit points — not a real side (PMC-only mechanic), but riding +the faction pipeline gives icons/tooltips/filter/auto-hide for free; the +destination map lives only in the i18n display name, not in the data. At render time the client **merges co-located extracts** that round to the same `(x, z)` bucket — Customs has dorms V-Ex (PMC) and old road gate (Scav) ~1m apart, they become a single composite marker. See "Map rendering layers" below for how that composite @@ -190,7 +193,11 @@ key back in the running app. (derived from registry `subgroup`: today only `player`, with `loot`/`quests` dimmed future icons). Clicking a category icon opens a flyout listing its layers: each row has a visibility `ToggleSwitch`, layer name, and a gear button - that expands that layer's settings component inline. Floor stepper at the rail's + that expands that layer's settings component inline. A layer may also register + a `filterComponent` — quick controls rendered always-expanded under its row + while the layer is visible, no gear click (extracts: the faction toggles, with + factions that have no exits on the current map auto-hidden via + `factionsForMap`). Floor stepper at the rail's bottom (multi-floor maps only) is a vertical ▲/level/▼. Rail hides when the overlay is click-through-locked. When locked on a multi-floor map, a compact read-only floor chip appears bottom-left. Flyouts position relative to the rail @@ -237,24 +244,21 @@ vertical span is pushed out to the rail's right edge (RAIL_GAP px beyond). Measu each frame via `.layer-rail` rect so arrows flow dynamically as the rail animates in/out on lock transitions. -Extract markers are `L.divIcon` instances (not `L.icon`) — the composite -PNG split via CSS `clip-path: polygon(...)` is built inline as HTML. -Single-faction = one ``; 2 or 3 factions = stacked ``s with `/`- -diagonal clip slices (area-balanced thirds for the 3-faction case). The -icon reacts to the faction filter dynamically: turning Scav off on a -PMC+Scav exit re-renders the icon as a clean PMC. Tailwind's preflight -gives `` `max-width: 100%` which collapses the icon to 0 inside -Leaflet's positioned wrapper, so `styles.css` keeps an override: - -``` -.leaflet-extracts-pane .extract-icon-divicon img { - max-width: none !important; max-height: none !important; -} -``` +Extract markers are `L.divIcon` instances (not `L.icon`) — the icon is +**inline SVG generated in `icon.ts`** (one hand-drawn shield+runner shape, +interior recoloured per faction from `FACTION_COLORS`; no static image +assets, nothing under `public/icons/`). Inline rather than `` +because an external SVG can't be recoloured from outside. Single-faction = +one ``; 2 or 3 factions = stacked recoloured copies with `/`-diagonal +CSS `clip-path` slices (area-balanced thirds for the 3-faction case; ≥4 +co-located kinds show the first three per `FACTION_ORDER`). The icon +reacts to the faction filter dynamically: turning Scav off on a PMC+Scav +exit re-renders the icon as a clean PMC. Tooltip is multi-row (one row per distinct name), each row carries a -faction-coloured left stripe via `.extract-tooltip-row--{pmc|scav|shared}` -or `.extract-tooltip-row--multi` when factions share a name. `direction: +faction-coloured left stripe — the colour is inlined from `FACTION_COLORS` +in `tooltip.ts` (no per-faction CSS classes); rows where multiple factions +share a name keep the neutral stripe from the base CSS rule. `direction: 'top'` keeps the tooltip above the icon; `tooltipAnchor` inside the icon's top edge gives a few pixels of overlap for visual cohesion. diff --git a/apps/client/public/icons/extracts/extract_pmc.png b/apps/client/public/icons/extracts/extract_pmc.png deleted file mode 100644 index b6d33bb..0000000 Binary files a/apps/client/public/icons/extracts/extract_pmc.png and /dev/null differ diff --git a/apps/client/public/icons/extracts/extract_scav.png b/apps/client/public/icons/extracts/extract_scav.png deleted file mode 100644 index e2ead3a..0000000 Binary files a/apps/client/public/icons/extracts/extract_scav.png and /dev/null differ diff --git a/apps/client/public/icons/extracts/extract_shared.png b/apps/client/public/icons/extracts/extract_shared.png deleted file mode 100644 index 84d0da9..0000000 Binary files a/apps/client/public/icons/extracts/extract_shared.png and /dev/null differ diff --git a/apps/client/src/features/i18n/locales/en.json b/apps/client/src/features/i18n/locales/en.json index 0531ebf..c31fcc6 100644 --- a/apps/client/src/features/i18n/locales/en.json +++ b/apps/client/src/features/i18n/locales/en.json @@ -41,7 +41,8 @@ "factions": { "pmc": "PMC", "scav": "Scav", - "shared": "Shared" + "shared": "Shared", + "transit": "Transits" }, "paths": { "heading": "Game integration", @@ -174,7 +175,6 @@ "railroad_to_port": "Railroad to Port", "trailer_park_workers_shack": "Trailer Park Workers' Shack", "railroad_to_tarkov": "Railroad to Tarkov", - "ruaf_roadblock_2": "RUAF Roadblock", "warehouse_17": "Warehouse 17", "factory_shacks": "Factory Shacks", "warehouse_4": "Warehouse 4", @@ -185,21 +185,28 @@ "scav_checkpoint": "Scav Checkpoint", "boiler_room_basement_co_op": "Boiler Room Basement (Co-op)", "smugglers_boat": "Smugglers' Boat", - "smugglers_bunker_zb_1012": "Smugglers' Bunker (ZB-1012)" + "smugglers_bunker_zb_1012": "Smugglers' Bunker (ZB-1012)", + "transit_reserve": "Transit to Reserve", + "transit_factory": "Transit to Factory", + "transit_interchange": "Transit to Interchange", + "transit_shoreline": "Transit to Shoreline" }, "factory4_day": { "cellars": "Cellars", "gate_3": "Gate 3", - "gate_3_2": "Gate 3", "camera_bunker_door": "Camera Bunker Door", "office_window": "Office Window", "gate_0": "Gate 0", "med_tent_gate": "Med Tent Gate", "courtyard_gate": "Courtyard Gate", - "smugglers_passage": "Smugglers' Passage" + "smugglers_passage": "Smugglers' Passage", + "transit_woods": "Transit to Woods", + "transit_customs": "Transit to Customs", + "transit_lab": "Transit to The Lab" }, "woods": { - "friendship_bridge_co_op": "Friendship Bridge (Co-Op)", + "scav_bridge": "Scav Bridge", + "scav_bridge_co_op": "Scav Bridge (Co-op)", "ruaf_gate": "RUAF Gate", "zb_016": "ZB-016", "zb_014": "ZB-014", @@ -213,12 +220,14 @@ "mountain_stash": "Mountain Stash", "eastern_rocks": "Eastern Rocks", "old_railway_depot": "Old Railway Depot", - "un_roadblock_2": "UN Roadblock", "ruaf_roadblock": "RUAF Roadblock", - "outskirts_2": "Outskirts", "northern_un_roadblock": "Northern UN Roadblock", "power_line_passage_flare": "Power Line Passage (Flare)", - "railway_bridge_to_tarkov": "Railway Bridge to Tarkov" + "railway_bridge_to_tarkov": "Railway Bridge to Tarkov", + "transit_factory": "Transit to Factory", + "transit_reserve": "Transit to Reserve", + "transit_lighthouse": "Transit to Lighthouse", + "transit_customs": "Transit to Customs" }, "shoreline": { "road_to_north_v_ex": "Road to North V-Ex", @@ -233,7 +242,10 @@ "smugglers_path_co_op": "Smugglers' Path (Co-op)", "pier_boat": "Pier Boat", "climber_s_trail": "Climber's Trail", - "mountain_bunker": "Mountain Bunker" + "mountain_bunker": "Mountain Bunker", + "transit_lighthouse": "Transit to Lighthouse", + "transit_terminal": "Transit to Terminal", + "transit_labyrinth": "Transit to Labyrinth?" }, "rezervbase": { "armored_train": "Armored Train", @@ -246,15 +258,21 @@ "heating_pipe": "Heating Pipe", "depot_hermetic_door": "Depot Hermetic Door", "checkpoint_fence": "Checkpoint Fence", - "exit_to_woods": "Exit to Woods" + "exit_to_woods": "Exit to Woods", + "transit_customs": "Transit to Customs", + "transit_woods": "Transit to Woods", + "transit_lighthouse": "Transit to Lighthouse" }, "interchange": { "emercom_checkpoint": "Emercom Checkpoint", "railway_exfil": "Railway Exfil", "power_station_v_ex": "Power Station V-Ex", "scav_camp_co_op": "Scav Camp (Co-Op)", - "hole_in_the_fence": "Hole in the Fence", - "saferoom_exfil": "Saferoom Exfil" + "saferoom_exfil": "Saferoom Exfil", + "smugglers_tunnel": "Smugglers' Tunnel", + "path_to_river": "Path to River", + "transit_customs": "Transit to Customs", + "transit_streets": "Transit to Streets of Tarkov" }, "lighthouse": { "armored_train": "Armored Train", @@ -268,7 +286,10 @@ "hideout_under_the_landing_stage": "Hideout Under the Landing Stage", "scav_hideout_at_the_grotto": "Scav Hideout at the Grotto", "industrial_zone_gates": "Industrial Zone Gates", - "passage_by_the_lake": "Passage by the Lake" + "passage_by_the_lake": "Passage by the Lake", + "transit_shoreline": "Transit to Shoreline", + "transit_reserve": "Transit to Reserve", + "transit_woods": "Transit to Woods" }, "tarkovstreets": { "entrance_to_catacombs": "Entrance to Catacombs", @@ -287,7 +308,10 @@ "klimov_street_flare": "Klimov Street (Flare)", "pinewood_basement_co_op": "Pinewood Basement (Co-Op)", "expo_checkpoint": "Expo Checkpoint", - "smugglers_basement": "Smugglers' Basement" + "smugglers_basement": "Smugglers' Basement", + "transit_ground_zero": "Transit to Ground Zero", + "transit_interchange": "Transit to Interchange", + "transit_lab": "Transit to The Lab" }, "laboratory": { "medical_block_elevator": "Medical Block Elevator", @@ -296,7 +320,8 @@ "ventilation_shaft": "Ventilation Shaft", "sewage_conduit": "Sewage Conduit", "parking_gate": "Parking Gate", - "hangar_gate": "Hangar Gate" + "hangar_gate": "Hangar Gate", + "transit_streets": "Transit to Streets of Tarkov" }, "sandbox": { "police_cordon_v_ex": "Police Cordon V-Ex", @@ -304,7 +329,8 @@ "scav_checkpoint_co_op": "Scav Checkpoint (Co-op)", "nakatani_basement_stairs": "Nakatani Basement Stairs", "mira_ave_flare": "Mira Ave (Flare)", - "tartowers_sales_office": "Tartowers Sales Office" + "tartowers_sales_office": "Tartowers Sales Office", + "transit_streets": "Transit to Streets of Tarkov" } }, "mapNames": { diff --git a/apps/client/src/features/i18n/locales/ru.json b/apps/client/src/features/i18n/locales/ru.json index e524c8b..7ac7323 100644 --- a/apps/client/src/features/i18n/locales/ru.json +++ b/apps/client/src/features/i18n/locales/ru.json @@ -41,7 +41,8 @@ "factions": { "pmc": "ЧВК", "scav": "Дикие", - "shared": "Общие" + "shared": "Общие", + "transit": "Переходы" }, "paths": { "heading": "Интеграция с игрой", @@ -174,7 +175,6 @@ "railroad_to_port": "ЖД к порту", "trailer_park_workers_shack": "Времянка у трейл. парка", "railroad_to_tarkov": "ЖД до Таркова", - "ruaf_roadblock_2": "Блокпост ВС РФ", "warehouse_17": "Склад 17", "factory_shacks": "Заводские времянки", "warehouse_4": "Склад 4", @@ -185,21 +185,28 @@ "scav_checkpoint": "КПП Диких", "boiler_room_basement_co_op": "Подвал котельной (Совм.)", "smugglers_boat": "Лодка Контрабандистов", - "smugglers_bunker_zb_1012": "Бункер Контрабандистов (ЗБ-1012)" + "smugglers_bunker_zb_1012": "Бункер Контрабандистов (ЗБ-1012)", + "transit_reserve": "Переход на Резерв", + "transit_factory": "Переход на Завод", + "transit_interchange": "Переход на Развязку", + "transit_shoreline": "Переход на Берег" }, "factory4_day": { "cellars": "Подвалы", "gate_3": "Ворота 3", - "gate_3_2": "Ворота 3", "camera_bunker_door": "Бункерная дверь с камерой", "office_window": "Офисное окно", "gate_0": "Ворота 0", "med_tent_gate": "Ворота у медицинской палатки", "courtyard_gate": "Ворота во дворе", - "smugglers_passage": "Проход Контрабандистов" + "smugglers_passage": "Проход Контрабандистов", + "transit_woods": "Переход на Лес", + "transit_customs": "Переход на Таможню", + "transit_lab": "Переход на Лабораторию" }, "woods": { - "friendship_bridge_co_op": "Мост дружбы (Совм.)", + "scav_bridge": "Дикий мост", + "scav_bridge_co_op": "Дикий мост (Совм.)", "ruaf_gate": "Ворота ВС РФ", "zb_016": "ЗБ-016", "zb_014": "ЗБ-014", @@ -213,12 +220,14 @@ "mountain_stash": "Горный тайник", "eastern_rocks": "Восточные скалы", "old_railway_depot": "Старое депо", - "un_roadblock_2": "Южный пост ООН", "ruaf_roadblock": "Блокпост ВС РФ", - "outskirts_2": "Окраины", "northern_un_roadblock": "Северный пост ООН", "power_line_passage_flare": "Проход у ЛЭП (Сигнал)", - "railway_bridge_to_tarkov": "ЖД-мост к Таркову" + "railway_bridge_to_tarkov": "ЖД-мост к Таркову", + "transit_factory": "Переход на Завод", + "transit_reserve": "Переход на Резерв", + "transit_lighthouse": "Переход на Маяк", + "transit_customs": "Переход на Таможню" }, "shoreline": { "road_to_north_v_ex": "А-Выход дорога на север", @@ -233,7 +242,10 @@ "smugglers_path_co_op": "Путь контрабандиста (Совм.)", "pier_boat": "Лодка на причале", "climber_s_trail": "Тропа альпиниста", - "mountain_bunker": "Бункер в горе" + "mountain_bunker": "Бункер в горе", + "transit_lighthouse": "Переход на Маяк", + "transit_terminal": "Переход на Терминал", + "transit_labyrinth": "Переход на Лабиринт?" }, "rezervbase": { "armored_train": "Бронепоезд", @@ -246,15 +258,21 @@ "heating_pipe": "Трубопровод отопления", "depot_hermetic_door": "Гермодверь к депо", "checkpoint_fence": "Забор у КПП", - "exit_to_woods": "Выход в сторону Леса" + "exit_to_woods": "Выход в сторону Леса", + "transit_customs": "Переход на Таможню", + "transit_woods": "Переход на Лес", + "transit_lighthouse": "Переход на Маяк" }, "interchange": { "emercom_checkpoint": "КПП МЧС", "railway_exfil": "Выход на железной дороге", "power_station_v_ex": "А-Выход у ТЭЦ", "scav_camp_co_op": "Лагерь Диких (Совм.)", - "hole_in_the_fence": "Дыра в заборе", - "saferoom_exfil": "Безопасная комната" + "saferoom_exfil": "Безопасная комната", + "smugglers_tunnel": "Тропа контрабандистов", + "path_to_river": "Тропа к реке", + "transit_customs": "Переход на Таможню", + "transit_streets": "Переход на Улицы Таркова" }, "lighthouse": { "armored_train": "Бронепоезд", @@ -268,7 +286,10 @@ "hideout_under_the_landing_stage": "Схрон под дебаркадером", "scav_hideout_at_the_grotto": "Укрытие в гроте", "industrial_zone_gates": "Ворота промзоны", - "passage_by_the_lake": "Проход у озера" + "passage_by_the_lake": "Проход у озера", + "transit_shoreline": "Переход на Берег", + "transit_reserve": "Переход на Резерв", + "transit_woods": "Переход на Лес" }, "tarkovstreets": { "entrance_to_catacombs": "Вход в катакомбы", @@ -287,7 +308,10 @@ "klimov_street_flare": "Улица Климова (Сигнал)", "pinewood_basement_co_op": "Подвал в Pinewood (Совм.)", "expo_checkpoint": "КПП у выставочного центра", - "smugglers_basement": "Подвал Контрабандистов" + "smugglers_basement": "Подвал Контрабандистов", + "transit_ground_zero": "Переход на Эпицентр", + "transit_interchange": "Переход на Развязку", + "transit_lab": "Переход на Лабораторию" }, "laboratory": { "medical_block_elevator": "Лифт медблока", @@ -296,7 +320,8 @@ "ventilation_shaft": "Вентиляционная шахта", "sewage_conduit": "Накопительный коллектор", "parking_gate": "Парковка", - "hangar_gate": "Ангар" + "hangar_gate": "Ангар", + "transit_streets": "Переход на Улицы Таркова" }, "sandbox": { "police_cordon_v_ex": "А-Выход полицейский кордон", @@ -304,7 +329,8 @@ "scav_checkpoint_co_op": "Блокпост Диких (Совм.)", "nakatani_basement_stairs": "Спуск в подвал в Nakatani", "mira_ave_flare": "Проспект Мира (Сигнал)", - "tartowers_sales_office": "Офис продаж Tartowers" + "tartowers_sales_office": "Офис продаж Tartowers", + "transit_streets": "Переход на Улицы Таркова" } }, "mapNames": { diff --git a/apps/client/src/features/map/components/LayerRail.vue b/apps/client/src/features/map/components/LayerRail.vue index 418a804..23ab825 100644 --- a/apps/client/src/features/map/components/LayerRail.vue +++ b/apps/client/src/features/map/components/LayerRail.vue @@ -219,6 +219,11 @@ function stepFloor(delta: number): void { + +
+ +
diff --git a/apps/client/src/features/map/components/MapView.vue b/apps/client/src/features/map/components/MapView.vue index 35343b8..6234255 100644 --- a/apps/client/src/features/map/components/MapView.vue +++ b/apps/client/src/features/map/components/MapView.vue @@ -1,5 +1,6 @@ + + diff --git a/apps/client/src/features/settings/sections/ExtractsSection.vue b/apps/client/src/features/settings/sections/ExtractsSection.vue index 188e7c0..19fc756 100644 --- a/apps/client/src/features/settings/sections/ExtractsSection.vue +++ b/apps/client/src/features/settings/sections/ExtractsSection.vue @@ -1,20 +1,12 @@