diff --git a/app_manifest.json b/app_manifest.json index 056e9cc..b498e50 100644 --- a/app_manifest.json +++ b/app_manifest.json @@ -1,5 +1,5 @@ { - "version": "16.07.09", + "version": "38.00.00", "css": [ "css/base.css", "css/layout.css", @@ -19,15 +19,35 @@ "js/input_mode_manager.js", "js/math.js", "js/physics_helpers.js", + "js/collision_footprint_system.js", + "js/mechanical_system.js", + "js/constraint_system.js", "js/assets.js", "js/audio.js", "js/perf_profiler.js", "js/render.js", "js/sim_core.js", + "js/tarinai_seed_factory.js", "js/structures.js", "js/items.js", "js/item_type_initializers.js", + "js/item_lifecycle_support.js", "js/item_lifecycle_runtime.js", + "js/item_update_policy.js", + "js/item_dynamic_tool_system.js", + "js/item_dynamic_ball_system.js", + "js/item_dynamic_duplicator_system.js", + "js/item_dynamic_pin_system.js", + "js/item_dynamic_zunchi_system.js", + "js/item_dynamic_system.js", + "js/item_lifecycle_decay_system.js", + "js/item_lifecycle_growth_system.js", + "js/item_lifecycle_step_frame.js", + "js/item_lifecycle_step_decay.js", + "js/item_lifecycle_step_dynamic.js", + "js/item_lifecycle_step_growth.js", + "js/item_lifecycle_pipeline.js", + "js/item_runtime.js", "js/structure_lifecycle.js", "js/item_render_runtime.js", "js/ants.js", @@ -48,7 +68,24 @@ "js/tarinai_building_behavior.js", "js/tarinai_action_definitions.js", "js/tarinai_needs_items.js", + "js/tarinai_forced_action_planner_system.js", + "js/tarinai_action_planner_system.js", + "js/tarinai_need_planner_system.js", + "js/tarinai_item_interaction_context.js", + "js/tarinai_food_interaction_system.js", + "js/tarinai_contact_item_system.js", + "js/tarinai_item_interaction_system.js", + "js/tarinai_sunbath_system.js", + "js/tarinai_cursor_care_system.js", + "js/tarinai_local_environment_system.js", "js/tarinai_social_move_life.js", + "js/tarinai_update_step_frame.js", + "js/tarinai_update_step_ai.js", + "js/tarinai_update_step_environment.js", + "js/tarinai_update_step_movement.js", + "js/tarinai_update_step_health.js", + "js/tarinai_update_pipeline.js", + "js/tarinai_runtime.js", "js/tarinai_render.js", "js/world.js", "js/world_view.js", @@ -60,27 +97,36 @@ "js/world_ants_system.js", "js/weather_system.js", "js/item_update_scheduler.js", + "js/simulation_runtime_helpers.js", + "js/tarinai_update_policy.js", + "js/simulation_environment_system.js", + "js/simulation_item_ant_system.js", + "js/simulation_effects_system.js", + "js/simulation_creature_system.js", + "js/simulation_maintenance_system.js", + "js/simulation_ambient_system.js", + "js/simulation_systems.js", "js/world_update_phases.js", + "js/system_order.js", + "js/simulation.js", "js/world_update.js", "js/world_tool_actions.js", "js/world_placement_log.js", "js/world_event_effects.js", - "js/world_bootstrap.js", + "js/command_dispatcher.js", "js/text_catalog.js", "js/ui.js", "js/ui_log.js", "js/ui_helpers.js", "js/ui_selected.js", + "js/save_schema.js", "js/snapshot_system.js", "js/restore_coordinator.js", + "js/history_system.js", "js/save_codec.js", "js/save_storage.js", "js/save_system.js", "js/patch_helpers.js", - "js/freeze_store.js", - "js/freeze_snapshot_adapter.js", - "js/freeze_panel.js", - "js/freeze_system.js", "js/ui_tooltips.js", "js/ui_layout_dialogs.js", "js/ui_ground.js", @@ -103,7 +149,8 @@ "assets/objects/*.webp", "assets/sprites/*.webp", "assets/sounds/*.wav", - "assets/sounds/*.mp3" + "assets/sounds/*.mp3", + "assets/objects/*.png" ], - "notes": "Source of truth for static loading order; generated files are index.html script/link tags and service-worker.js cache list. Item definitions are centralized in js/item_registry.js. Save compatibility migration is intentionally not retained. Snapshot restore is data-only; save and freeze are split into coordinator/codec/storage/panel/adapter modules. EventBus owns phase audio and log UI/audio notification side effects. World.update is phase-driven through js/world_update_phases.js; UI field input is split into shared/touch/mouse modules. Item construction, lifecycle, rendering, Tarinai targeting, ActionSpec definitions, consumable behavior, social action ticks, and building behavior are split into dedicated modules. Lightweight cleanup: item type constructor initialization is isolated; action selection bonus logic is shared; diagnostics no longer use removed performance-quality fields. Ground definitions, structure lifecycle, delete-tool actions, shared tooltips, and ground UI helpers are split into dedicated modules. FPS work: profiler, static/dynamic spatial buckets, item update scheduler, visible-cell rendering, chunked terrain cache, adaptive DPR, and render quality LOD are included." + "notes": "Boundary cleanup v38: freezer removed, washing expanded and continuous, laboratory ground added, and save schema synchronized." } diff --git a/assets/objects/plushie_bear.png b/assets/objects/plushie_bear.png new file mode 100644 index 0000000..46f25f9 Binary files /dev/null and b/assets/objects/plushie_bear.png differ diff --git a/assets/ui/apple-touch-icon.png b/assets/ui/apple-touch-icon.png new file mode 100644 index 0000000..6ea8bf4 Binary files /dev/null and b/assets/ui/apple-touch-icon.png differ diff --git a/assets/ui/favicon-64.png b/assets/ui/favicon-64.png new file mode 100644 index 0000000..92594d7 Binary files /dev/null and b/assets/ui/favicon-64.png differ diff --git a/assets/ui/favicon.png b/assets/ui/favicon.png new file mode 100644 index 0000000..09ecce9 Binary files /dev/null and b/assets/ui/favicon.png differ diff --git a/css/base.css b/css/base.css index 1e8c35d..5a72a27 100644 --- a/css/base.css +++ b/css/base.css @@ -347,38 +347,40 @@ h1 { .tool-grid { display: grid; grid-template-columns: repeat(3, minmax(0,1fr)); - gap: 8px; + gap: 6px; } .tool { - --tool-main-icon-size: 30px; + --tool-main-icon-size: 28px; + --tool-icon-zoom: 1.05; --tool-watermark-size: 0px; border-radius: 12px; display: grid; - grid-template-rows: 27px minmax(1.05em, auto); - align-items: start; - justify-items: center; - gap: 0; - padding: 3px 5px 4px; - min-height: 36px; - font-size: 12px; - line-height: 1.08; + grid-template-columns: 29px minmax(0,1fr); + align-items: center; + justify-items: stretch; + gap: 3px; + padding: 4px 4px 4px 2px; + min-height: 47px; + font-size: 10.2px; + line-height: 1.06; letter-spacing: -0.015em; - text-align: center; + text-align: left; position: relative; overflow: hidden; background-repeat: no-repeat; - background-position: center 4px, center; + background-position: left 3px center, center; background-size: var(--tool-main-icon-size) var(--tool-main-icon-size), cover; } .tool::before { content: ""; position: absolute; - left: 50%; - top: 3px; + left: 3px; + top: 50%; width: var(--tool-main-icon-size); height: var(--tool-main-icon-size); - transform: translateX(-50%); + transform: translateY(-50%) scale(var(--tool-icon-zoom, 1)); + transform-origin: center; background: var(--tool-icon) center / contain no-repeat; opacity: 0.98; z-index: 1; @@ -397,33 +399,41 @@ h1 { position: relative; z-index: 2; display: block; - grid-row: 2; - align-self: start; + grid-column: 2; + align-self: center; + justify-self: start; max-width: 100%; min-width: 0; overflow-wrap: anywhere; - font-size: 12px; - line-height: 1.12; + font-size: 10.2px; + line-height: 1.10; font-weight: 700; + max-width: 5.05em; + word-break: normal; + overflow-wrap: anywhere; text-shadow: 0 1px 0 rgba(255,255,255,0.62); } -.tool.tool-has-canvas-icon { --tool-icon: none; grid-template-rows: 34px minmax(1.05em, auto); min-height: 44px; padding-top: 1px; } +.tool.tool-has-canvas-icon { --tool-icon: none; grid-template-columns: 29px minmax(0,1fr); min-height: 47px; padding-top: 4px; } .tool.tool-has-canvas-icon::before, .tool.tool-has-canvas-icon::after { background: none !important; } .tool-sprite-preview { position: absolute; - left: 50%; - top: -5px; - width: 48px; - height: 48px; - transform: translateX(-50%); + left: 1px; + top: 50%; + width: 30px; + height: 30px; + transform: translateY(-50%); pointer-events: none; z-index: 1; filter: drop-shadow(0 2px 3px rgba(52,40,26,0.12)); } .tool-sprite-watermark { display: none !important; } +.tool[data-tool="giant_drug"] .tool-sprite-preview { width: 39px; height: 39px; left: -4px; } +.tool[data-tool="dwarf_drug"] .tool-sprite-preview, +.tool[data-tool="oshibyo"] .tool-sprite-preview { width: 22px; height: 22px; left: 5px; } +.tool[data-tool="poke"], .tool[data-tool="water_hose"] { --tool-icon-zoom: 0.92; } .tool[data-tool="observe"] { --tool-icon: url("../assets/ui/tool_observe.webp"); } .tool[data-tool="zunchi"] { --tool-icon: url("../assets/ui/tool_zunchi.webp"); } .tool[data-tool="sweet"] { --tool-icon: url("../assets/ui/tool_sweet.webp"); } @@ -436,7 +446,6 @@ h1 { .tool[data-tool="bed"] { --tool-icon: url("../assets/ui/tool_bed.webp"); } .tool[data-tool="love_mochi"] { --tool-icon: url("../assets/ui/tool_love_mochi.webp"); } .tool[data-tool="fight_mochi"] { --tool-icon: url("../assets/ui/tool_fight_mochi.webp"); } -.tool[data-tool="water_bowl"] { --tool-icon: url("../assets/ui/tool_water_bowl.webp"); } .tool[data-tool="signboard"] { --tool-icon: url("../assets/ui/tool_signboard.webp"); } .tool[data-tool="duplicator"] { --tool-icon: url("../assets/ui/tool_duplicator.webp"); } @@ -574,3 +583,113 @@ h1 { background: #efffde; border-color: rgba(103,178,44,0.46); } + +.rotator-editor { + position: fixed; + inset: 0; + z-index: 43; + display: grid; + place-items: center; + padding: 18px; + background: rgba(34, 29, 22, 0.34); + backdrop-filter: blur(3px); +} +.rotator-editor.hidden { display: none; } +.rotator-editor-panel { + width: min(620px, calc(100vw - 28px)); + border-radius: 14px; + padding: 14px; + background: linear-gradient(180deg, rgba(255,253,247,0.98), rgba(245,237,221,0.97)); + border: 1px solid rgba(94, 70, 42, 0.20); + box-shadow: 0 22px 60px rgba(36, 28, 20, 0.28), inset 0 1px 0 rgba(255,255,255,0.72); +} +.rotator-editor-titlebar { + display: flex; + align-items: center; + justify-content: space-between; + gap: 10px; + margin-bottom: 10px; + padding-bottom: 8px; + border-bottom: 1px solid rgba(94, 70, 42, 0.13); +} +.rotator-editor-titlebar h2 { margin: 0; font-size: 16px; letter-spacing: .03em; } +.rotator-editor-close { + width: 30px; + height: 30px; + border-radius: 999px; + border: 1px solid rgba(84,68,48,0.16); + background: rgba(255,255,255,0.72); + color: var(--ink); + font-size: 19px; + line-height: 1; + cursor: pointer; +} +.rotator-editor-close:hover { background: rgba(255,248,232,0.96); } +.rotator-editor-controls { + display: grid; + grid-template-columns: 1fr; + gap: 8px; + margin-bottom: 8px; +} +.rotator-editor-controls label { + display: grid; + grid-template-columns: auto 1fr 72px auto; + align-items: center; + gap: 8px; + font-size: 13px; + color: var(--ink); +} +.rotator-editor-controls input[type="number"] { + width: 72px; + box-sizing: border-box; + border-radius: 8px; + border: 1px solid rgba(84,68,48,0.18); + background: rgba(255,255,255,0.84); + padding: 4px 6px; +} +.rotator-editor-tools { + display: flex; + flex-wrap: wrap; + gap: 6px; + margin-bottom: 8px; +} +.rotator-editor-tools button { + border: 1px solid rgba(84,68,48,0.16); + background: rgba(255,255,255,0.74); + color: var(--ink); + border-radius: 999px; + padding: 5px 10px; + font-size: 12px; + cursor: pointer; +} +.rotator-editor-tools button.active { + background: rgba(137, 101, 198, 0.18); + border-color: rgba(112, 80, 170, 0.38); + font-weight: 700; +} +#rotatorCanvas { + width: 100%; + height: min(58vh, 360px); + display: block; + border-radius: 12px; + border: 1px solid rgba(84,68,48,0.20); + background: #f7f3ea; + touch-action: none; + cursor: crosshair; +} +.rotator-editor-hint { + margin: 7px 2px 0; + color: var(--muted); + font-size: 12px; +} +.rotator-editor-actions { + display: flex; + justify-content: flex-end; + gap: 8px; + margin-top: 12px; +} +@media (max-width: 560px) { + .rotator-editor-panel { padding: 10px; } + .rotator-editor-controls label { grid-template-columns: 1fr; align-items: stretch; } + #rotatorCanvas { height: 320px; } +} diff --git a/css/components.css b/css/components.css index 052e0ca..d5fdc33 100644 --- a/css/components.css +++ b/css/components.css @@ -675,3 +675,113 @@ font-size: 16px; line-height: 1.2; } +.ground-stat[data-ground-toggle] { + cursor: pointer; + user-select: none; +} +.ground-stat[data-ground-toggle]:focus-visible, +.ground-type-btn:focus-visible { + outline: 2px solid rgba(103,178,44,0.58); + outline-offset: 2px; +} +.save-hash-profile { + display: grid; + gap: 8px; + padding: 9px 10px; + border: 1px solid rgba(115, 91, 62, 0.18); + border-radius: 12px; + background: rgba(255,255,255,0.56); + color: #4a3929; + font-size: 12px; +} +.save-hash-profile:empty { + display: none; +} +.save-profile-summary { + display: flex; + flex-wrap: wrap; + gap: 6px 10px; +} +.save-profile-summary span { + padding: 3px 7px; + border-radius: 999px; + background: rgba(115, 91, 62, 0.08); +} +.save-profile-grid { + display: grid; + grid-template-columns: repeat(auto-fit, minmax(132px, 1fr)); + gap: 5px; +} +.save-profile-grid > div { + display: grid; + grid-template-columns: 1fr auto auto; + gap: 6px; + align-items: center; + padding: 4px 6px; + border-radius: 8px; + background: rgba(255,255,255,0.54); +} +.save-profile-grid em { + opacity: 0.62; + font-style: normal; +} +.save-profile-items { + display: flex; + flex-wrap: wrap; + gap: 5px 7px; + align-items: center; +} +.save-profile-items span { + padding: 2px 6px; + border-radius: 999px; + background: rgba(111, 153, 102, 0.13); +} + + +/* v36: pin only the operation tool category under the quick-scroll tabs. */ +.tool-category[data-tool-category="operate"]:not(.collapsed) { + position: sticky; + top: 58px; + z-index: 11; + overflow: hidden; + background: linear-gradient(180deg, rgba(238, 247, 255, 0.98), rgba(221, 237, 255, 0.98)); + border-color: rgba(82,128,190,0.36); + box-shadow: 0 8px 18px rgba(58, 82, 112, 0.13), inset 0 1px 0 rgba(255,255,255,0.82); +} +.tool-category[data-tool-category="operate"] .tool-category-toggle { + background: linear-gradient(180deg, rgba(255,255,255,0.98), rgba(231, 243, 255, 0.98)); + border-bottom-color: rgba(82,128,190,0.30); +} +.tool-category[data-tool-category="operate"] .tool-category-body { + background: rgba(238, 247, 255, 0.98); +} +.tool-category[data-tool-category="operate"] .tool-category-body { + grid-template-columns: repeat(5, minmax(0, 1fr)); + gap: 5px; +} +.tool-category[data-tool-category="operate"] .tool { + grid-template-columns: 1fr; + min-height: 38px; + padding: 4px; + justify-items: center; + align-items: center; + text-align: center; + background: rgba(255,255,255,0.96); + border-color: rgba(82,128,190,0.28); +} +.tool-category[data-tool-category="operate"] .tool-label { + display: none; +} +.tool-category[data-tool-category="operate"] .tool::before { + left: 50%; + top: 50%; + transform: translate(-50%, -50%) scale(var(--tool-icon-zoom, 1)); +} +.tool-category[data-tool-category="operate"] .tool-sprite-preview { + left: 50%; + top: 50%; + transform: translate(-50%, -50%); +} +@media (max-width: 980px) { + .tool-category[data-tool-category="operate"]:not(.collapsed) { top: 58px; } +} diff --git a/css/layout.css b/css/layout.css index 5a73860..c7b4fec 100644 --- a/css/layout.css +++ b/css/layout.css @@ -4,11 +4,19 @@ .tool[data-tool="ant_nest"] { --tool-icon: url("../assets/ui/tool_ant_nest.webp"); } .tool[data-tool="ball"] { --tool-icon: url("../assets/ui/tool_ball.webp"); } .tool[data-tool="delete"] { --tool-icon: url("../assets/ui/tool_delete.webp"); } +.tool[data-tool="area_delete"] { --tool-icon: url("../assets/ui/tool_delete.webp"); } .tool[data-tool="new"] { --tool-icon: url("../assets/ui/tool_new.webp"); } .tool[data-tool="poke"] { --tool-emoji: "\1F448"; } .tool[data-tool="pinch"] { --tool-emoji: "\1F90F"; } .tool[data-tool="water_hose"] { --tool-emoji: "\1F6BF"; } +.tool[data-tool="copy"] { --tool-emoji: "⧉"; } +.tool[data-tool="area_delete"] { --tool-emoji: "✕"; } +.tool[data-tool="rope"] { --tool-emoji: "╰"; } +.tool[data-tool="rod"] { --tool-emoji: "━"; } +.tool[data-tool="reciprocator"] { --tool-emoji: "⇄"; } +.tool[data-tool="undo"] { --tool-emoji: "↶"; } +.tool[data-tool="redo"] { --tool-emoji: "↷"; } .tool.tool-emoji-icon { --tool-icon: none; } .tool.tool-emoji-icon::before { content: var(--tool-emoji); @@ -16,11 +24,35 @@ display: grid; place-items: center; font-family: "Apple Color Emoji", "Segoe UI Emoji", "Noto Color Emoji", sans-serif; - font-size: 29px; + font-size: 34px; line-height: 1; filter: drop-shadow(0 2px 3px rgba(52,40,26,0.12)); } .tool.tool-emoji-icon::after { content: none; display: none; } + +.tool[data-tool="poke"].tool-emoji-icon::before, +.tool[data-tool="water_hose"].tool-emoji-icon::before { font-size: 25px; } +.tool[data-tool="rope"].tool-emoji-icon::before, +.tool[data-tool="rod"].tool-emoji-icon::before, +.tool[data-tool="reciprocator"].tool-emoji-icon::before, +.tool[data-tool="undo"].tool-emoji-icon::before, +.tool[data-tool="redo"].tool-emoji-icon::before { font-size: 29px; font-family: var(--font, sans-serif); } +.tool[data-tool="delete"], +.tool[data-tool="area_delete"] { --tool-icon-zoom: 1.42; } +.tool[data-tool="pinch"].tool-emoji-icon::before { font-size: 22px; } +.tool[data-tool="area_delete"].tool-emoji-icon::before { + font-size: 30px; + color: #f3a7aa; + text-shadow: 0 1px 0 rgba(255,255,255,0.65), 0 2px 5px rgba(146,54,62,0.16); + filter: none; +} + +.tool[data-tool="ball"] { --tool-icon-zoom: 1.36; } +.tool[data-tool="observe"], +.tool[data-tool="new"] { --tool-icon-zoom: 1.20; } +.tool[data-tool="giant_drug"] { --tool-icon-zoom: 1.58; } +.tool[data-tool="dwarf_drug"], +.tool[data-tool="oshibyo"] { --tool-icon-zoom: 0.62; } .tool.selected { background: linear-gradient(180deg, #ffffff, #efffde); border-color: rgba(103, 178, 44, 0.52); @@ -105,7 +137,7 @@ box-shadow: 0 1px 4px rgba(42,36,29,0.16); pointer-events: none; } -.chart-tabs { display: grid; grid-template-columns: repeat(4, 1fr); gap: 5px; margin: 3px 0 8px; } +.chart-tabs { display: grid; grid-template-columns: repeat(3, 1fr); gap: 5px; margin: 3px 0 8px; } .chart-tabs button { border: 1px solid var(--line); background: rgba(255,255,255,0.62); border-radius: 999px; padding: 5px 4px; font-size: 11px; cursor: pointer; } .chart-tabs button.active { background: #efffde; border-color: rgba(103,178,44,0.46); font-weight: 700; } .log-accident { border-left-color: rgba(226, 136, 54, 0.76); } @@ -316,6 +348,7 @@ meter { .tool-category[data-tool-category="food"] { --tool-cat-a: rgba(236,252,219,0.82); --tool-cat-b: rgba(214,244,194,0.74); --tool-cat-line: rgba(96,156,72,0.26); } .tool-category[data-tool-category="medicine"] { --tool-cat-a: rgba(243,231,255,0.84); --tool-cat-b: rgba(230,214,252,0.78); --tool-cat-line: rgba(136,94,184,0.28); } .tool-category[data-tool-category="habitat"] { --tool-cat-a: rgba(255,245,218,0.84); --tool-cat-b: rgba(250,229,186,0.76); --tool-cat-line: rgba(174,125,54,0.28); } +.tool-category[data-tool-category="physics"] { --tool-cat-a: rgba(226,247,246,0.84); --tool-cat-b: rgba(199,232,231,0.76); --tool-cat-line: rgba(70,145,148,0.28); } .tool-category[data-tool-category="hazard"] { --tool-cat-a: rgba(255,230,224,0.84); --tool-cat-b: rgba(250,207,197,0.78); --tool-cat-line: rgba(189,88,66,0.30); } .tool-category { border-color: var(--tool-cat-line, rgba(84,68,48,0.10)); background: linear-gradient(180deg, var(--tool-cat-a, rgba(255,255,255,0.36)), rgba(255,255,255,0.28)); } .tool-category-toggle { background: linear-gradient(180deg, var(--tool-cat-a, rgba(255,252,244,0.66)), var(--tool-cat-b, rgba(255,252,244,0.54))); border-bottom-color: var(--tool-cat-line, rgba(84,68,48,0.08)); } diff --git a/favicon.ico b/favicon.ico new file mode 100644 index 0000000..f5ef16a Binary files /dev/null and b/favicon.ico differ diff --git a/index.html b/index.html index 01d2715..2fe75ae 100644 --- a/index.html +++ b/index.html @@ -3,24 +3,25 @@
-準備しています。
初期表示に必要な画像だけ先に読み込み、残りは後から順次ロードします。